Skip to content

Commit

Permalink
Merge pull request linkedin#58 from joe-roth/add_fixed_type
Browse files Browse the repository at this point in the history
Add fixed type

Perfect PR with tests and documentation. Thanks!
  • Loading branch information
karrick authored Aug 11, 2016
2 parents 1eb9373 + 4fff893 commit 45cf6da
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
25 changes: 19 additions & 6 deletions codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,8 @@ func (st symtab) makeUnionCodec(enclosingNamespace string, schema interface{}) (
name = "null"
case Enum:
name = datum.(Enum).Name
case Fixed:
name = datum.(Fixed).Name
case *Record:
name = datum.(*Record).Name
}
Expand Down Expand Up @@ -514,6 +516,17 @@ func (st symtab) makeEnumCodec(enclosingNamespace string, schema interface{}) (*
return c, nil
}

// Fixed is an abstract data type used to hold data corresponding to an Avro
// 'Fixed' type. Whenever an Avro schema specifies a "Fixed" type, this library's
// Decode method will return a Fixed value initialized to the Fixed name, and
// value read from the io.Reader. Likewise, when using Encode to convert data to
// an Avro record, it is necessary to create and send a Fixed instance to the
// Encode method.
type Fixed struct {
Name string
Value []byte
}

func (st symtab) makeFixedCodec(enclosingNamespace string, schema interface{}) (*codec, error) {
errorNamespace := "null namespace"
if enclosingNamespace != nullNamespace {
Expand Down Expand Up @@ -551,17 +564,17 @@ func (st symtab) makeFixedCodec(enclosingNamespace string, schema interface{}) (
if n < int(size) {
return nil, newDecoderError(friendlyName, "buffer underrun")
}
return buf, nil
return Fixed{Name: nm.n, Value: buf}, nil
},
ef: func(w io.Writer, datum interface{}) error {
someBytes, ok := datum.([]byte)
someFixed, ok := datum.(Fixed)
if !ok {
return newEncoderError(friendlyName, "expected: []byte; received: %T", datum)
return newEncoderError(friendlyName, "expected: Fixed; received: %T", datum)
}
if len(someBytes) != int(size) {
return newEncoderError(friendlyName, "expected: %d bytes; received: %d", size, len(someBytes))
if len(someFixed.Value) != int(size) {
return newEncoderError(friendlyName, "expected: %d bytes; received: %d", size, len(someFixed.Value))
}
n, err := w.Write(someBytes)
n, err := w.Write(someFixed.Value)
if err != nil {
return newEncoderError(friendlyName, err)
}
Expand Down
17 changes: 12 additions & 5 deletions codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,19 +488,26 @@ func TestCodecFixed(t *testing.T) {
schema := `{"type":"fixed","name":"fixed1","size":5}`
checkCodecDecoderError(t, schema, []byte(""), "EOF")
checkCodecDecoderError(t, schema, []byte("hap"), "buffer underrun")
checkCodecEncoderError(t, schema, "happy day", "expected: []byte; received: string")
checkCodecEncoderError(t, schema, []byte("day"), "expected: 5 bytes; received: 3")
checkCodecEncoderError(t, schema, []byte("happy day"), "expected: 5 bytes; received: 9")
checkCodecEncoderResult(t, schema, []byte("happy"), []byte("happy"))
checkCodecEncoderError(t, schema, "happy day", "expected: Fixed; received: string")
checkCodecEncoderError(t, schema, Fixed{Name: "fixed1", Value: []byte("day")}, "expected: 5 bytes; received: 3")
checkCodecEncoderError(t, schema, Fixed{Name: "fixed1", Value: []byte("happy day")}, "expected: 5 bytes; received: 9")
checkCodecEncoderResult(t, schema, Fixed{Name: "fixed1", Value: []byte("happy")}, []byte("happy"))
}

func TestCodecNamedTypes(t *testing.T) {
func TestCodecNamedTypesCheckSchema(t *testing.T) {
schema := `{"name":"guid","type":{"type":"fixed","name":"fixed_16","size":16},"doc":"event unique id"}`
var err error
_, err = NewCodec(schema)
checkError(t, err, nil)
}

func TestCodecNamedTypes(t *testing.T) {
schema := `{"name":"guid","type":["null",{"type":"fixed","name":"fixed_16","size":16}],"doc":"event unique id"}`
// The 0x2 byte is an avro encoded int(1), which refers to the index of the
// `fixed_16` type in the schema's union array.
checkCodecEncoderResult(t, schema, Fixed{Name: "fixed_16", Value: []byte("0123456789abcdef")}, append([]byte{0x2}, []byte("0123456789abcdef")...))
}

func TestCodecReferToNamedTypes(t *testing.T) {
schema := `{"type":"record","name":"record1","fields":[{"name":"guid","type":{"type":"fixed","name":"fixed_16","size":16},"doc":"event unique id"},{"name":"treeId","type":"fixed_16","doc":"call tree uuid"}]}`
_, err := NewCodec(schema)
Expand Down

0 comments on commit 45cf6da

Please sign in to comment.