diff --git a/datum_writer.go b/datum_writer.go index 624b84b..cd9e2ea 100644 --- a/datum_writer.go +++ b/datum_writer.go @@ -534,7 +534,15 @@ func (writer *GenericDatumWriter) isWritableAs(v interface{}, s Schema) bool { } func (writer *GenericDatumWriter) writeFixed(v interface{}, enc Encoder, s Schema) error { - return writer.writeBytes(v, enc) + fs := s.(*FixedSchema) + + if !fs.Validate(reflect.ValueOf(v)) { + return fmt.Errorf("Invalid fixed value: %v", v) + } + + // Write the raw bytes. The length is known by the schema + enc.WriteRaw(v.([]byte)) + return nil } func (writer *GenericDatumWriter) writeRecord(v interface{}, enc Encoder, s Schema) error { diff --git a/datum_writer_test.go b/datum_writer_test.go index 6148961..45cd817 100644 --- a/datum_writer_test.go +++ b/datum_writer_test.go @@ -247,6 +247,40 @@ func TestGenericDatumWriterEmptyArray(t *testing.T) { assert(t, buffer.Bytes(), []byte{0x00}) } +func TestGenericDatumWriterFixed(t *testing.T) { + schema := MustParseSchema(`{ + "type": "record", + "name": "Rec", + "fields": [ + { + "name": "fixed", + "type": {"name": "fixed5", "type": "fixed", "size": 5} + } + ] + }`) + + w := NewGenericDatumWriter() + w.SetSchema(schema) + + testit := func(rec *GenericRecord) ([]byte, error) { + var buf bytes.Buffer + err := w.Write(rec, NewBinaryEncoder(&buf)) + return buf.Bytes(), err + } + + rec := NewGenericRecord(schema) + rec.Set("fixed", []byte{1, 2, 3, 4}) // 1 byte too short, should error + buf, err := testit(rec) + assert(t, len(buf), 0) + assert(t, err.Error(), "Invalid fixed value: [1 2 3 4]") + + rec = NewGenericRecord(schema) + rec.Set("fixed", []byte{1, 2, 3, 4, 5}) + buf, err = testit(rec) + assert(t, len(buf), 5) // make sure we're not adding the extra padding + assert(t, err, nil) +} + func randomPrimitiveObject() *primitive { p := &primitive{} p.BooleanField = rand.Int()%2 == 0