Skip to content

Commit

Permalink
Add generic support for deserializing binary data
Browse files Browse the repository at this point in the history
  • Loading branch information
actgardner committed Nov 4, 2020
1 parent bdf5208 commit dd1bf3d
Show file tree
Hide file tree
Showing 13 changed files with 488 additions and 7 deletions.
6 changes: 3 additions & 3 deletions v7/compiler/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ import (
// If you're reading records from an OCF you can use the New<RecordType>Reader()
// method that's generated for you, which will parse the schemas automatically.
func CompileSchemaBytes(writer, reader []byte, opts ...Option) (*vm.Program, error) {
readerType, err := parseSchema(reader)
readerType, err := ParseSchema(reader)
if err != nil {
return nil, err
}

writerType, err := parseSchema(writer)
writerType, err := ParseSchema(writer)
if err != nil {
return nil, err
}

return Compile(writerType, readerType, opts...)
}

func parseSchema(s []byte) (schema.AvroType, error) {
func ParseSchema(s []byte) (schema.AvroType, error) {
ns := parser.NewNamespace(false)
sType, err := ns.TypeForSchema(s)
if err != nil {
Expand Down
42 changes: 42 additions & 0 deletions v7/generic/array.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package generic

import (
"github.com/actgardner/gogen-avro/v7/schema"
"github.com/actgardner/gogen-avro/v7/vm/types"
)

type arrayDatum struct {
itemType schema.AvroType
items []Datum
}

func (r *arrayDatum) Datum() interface{} {
v := make([]interface{}, len(r.items))
for i, item := range r.items {
v[i] = item.Datum()
}
return v
}

func (r *arrayDatum) SetBoolean(v bool) {}

func (r *arrayDatum) SetInt(v int32) {}
func (r *arrayDatum) SetLong(v int64) {}
func (r *arrayDatum) SetFloat(v float32) {}
func (r *arrayDatum) SetDouble(v float64) {}
func (r *arrayDatum) SetBytes(v []byte) {}
func (r *arrayDatum) SetString(v string) {}

func (r *arrayDatum) Get(i int) types.Field { panic("") }
func (r *arrayDatum) SetDefault(i int) {}

func (r *arrayDatum) AppendMap(key string) types.Field { panic("") }

func (r *arrayDatum) AppendArray() types.Field {
d := DatumForType(r.itemType)
r.items = append(r.items, d)
return d
}

func (r *arrayDatum) NullField(t int) {}
func (r *arrayDatum) Finalize() {}
39 changes: 39 additions & 0 deletions v7/generic/datum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package generic

import (
"github.com/actgardner/gogen-avro/v7/schema"
"github.com/actgardner/gogen-avro/v7/vm/types"
)

type Datum interface {
types.Field
Datum() interface{}
}

func DatumForType(t schema.AvroType) Datum {
switch st := t.(type) {
case *schema.BoolField, *schema.BytesField, *schema.FloatField, *schema.DoubleField, *schema.IntField, *schema.LongField, *schema.StringField, *schema.NullField:
return &primitiveDatum{}
case *schema.MapField:
return &mapDatum{itemType: st.ItemType()}
case *schema.ArrayField:
return &arrayDatum{itemType: st.ItemType()}
case *schema.Reference:
return datumForReference(st)
case *schema.UnionField:
return &unionDatum{itemTypes: st.ItemTypes()}
}
panic("")
}

func datumForReference(ref *schema.Reference) Datum {
switch d := ref.Def.(type) {
case *schema.RecordDefinition:
return newRecordDatum(d)
case *schema.EnumDefinition:
return newEnumDatum(d)
case *schema.FixedDefinition:
return &primitiveDatum{}
}
panic("")
}
37 changes: 37 additions & 0 deletions v7/generic/enum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package generic

import (
"github.com/actgardner/gogen-avro/v7/schema"
"github.com/actgardner/gogen-avro/v7/vm/types"
)

type enumDatum struct {
symbols []string
value string
}

func newEnumDatum(def *schema.EnumDefinition) *enumDatum {
return &enumDatum{
symbols: def.Symbols(),
}
}

func (r *enumDatum) Datum() interface{} {
return r.value
}

func (r *enumDatum) SetBoolean(v bool) { panic("") }
func (r *enumDatum) SetInt(v int32) { panic("") }
func (r *enumDatum) SetLong(v int64) {
r.value = r.symbols[v]
}
func (r *enumDatum) SetFloat(v float32) { panic("") }
func (r *enumDatum) SetDouble(v float64) { panic("") }
func (r *enumDatum) SetBytes(v []byte) { panic("") }
func (r *enumDatum) SetString(v string) { panic("") }
func (r *enumDatum) Get(i int) types.Field { panic("") }
func (r *enumDatum) SetDefault(i int) {}
func (r *enumDatum) AppendMap(key string) types.Field { panic("") }
func (r *enumDatum) AppendArray() types.Field { panic("") }
func (r *enumDatum) NullField(t int) { panic("") }
func (r *enumDatum) Finalize() { panic("") }
45 changes: 45 additions & 0 deletions v7/generic/map.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package generic

import (
"github.com/actgardner/gogen-avro/v7/schema"
"github.com/actgardner/gogen-avro/v7/vm/types"
)

type mapDatum struct {
itemType schema.AvroType
items map[string]Datum
}

func (r *mapDatum) Datum() interface{} {
v := make(map[string]interface{})
for k, item := range r.items {
v[k] = item.Datum()
}
return v
}

func (r *mapDatum) SetBoolean(v bool) {}

func (r *mapDatum) SetInt(v int32) {}
func (r *mapDatum) SetLong(v int64) {}
func (r *mapDatum) SetFloat(v float32) {}
func (r *mapDatum) SetDouble(v float64) {}
func (r *mapDatum) SetBytes(v []byte) {}
func (r *mapDatum) SetString(v string) {}

func (r *mapDatum) Get(i int) types.Field { panic("") }
func (r *mapDatum) SetDefault(i int) {}

func (r *mapDatum) AppendMap(key string) types.Field {
if r.items == nil {
r.items = make(map[string]Datum)
}
d := DatumForType(r.itemType)
r.items[key] = d
return d
}

func (r *mapDatum) AppendArray() types.Field { panic("") }

func (r *mapDatum) NullField(t int) {}
func (r *mapDatum) Finalize() {}
45 changes: 45 additions & 0 deletions v7/generic/primitive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package generic

import (
"github.com/actgardner/gogen-avro/v7/vm/types"
)

type primitiveDatum struct {
value interface{}
}

func (r *primitiveDatum) Datum() interface{} {
return r.value
}

func (r *primitiveDatum) SetBoolean(v bool) {
r.value = v
}

func (r *primitiveDatum) SetInt(v int32) {
r.value = v
}
func (r *primitiveDatum) SetLong(v int64) {
r.value = v
}
func (r *primitiveDatum) SetFloat(v float32) {
r.value = v
}
func (r *primitiveDatum) SetDouble(v float64) {
r.value = v
}
func (r *primitiveDatum) SetBytes(v []byte) {
r.value = v
}
func (r *primitiveDatum) SetString(v string) {
r.value = v
}
func (r *primitiveDatum) Get(i int) types.Field { panic("") }
func (r *primitiveDatum) SetDefault(i int) {}

func (r *primitiveDatum) AppendMap(key string) types.Field { panic("") }

func (r *primitiveDatum) AppendArray() types.Field { panic("") }

func (r *primitiveDatum) NullField(t int) {}
func (r *primitiveDatum) Finalize() {}
49 changes: 49 additions & 0 deletions v7/generic/record.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package generic

import (
"github.com/actgardner/gogen-avro/v7/schema"
"github.com/actgardner/gogen-avro/v7/vm/types"
)

type recordDatum struct {
def *schema.RecordDefinition
fields []Datum
}

func newRecordDatum(def *schema.RecordDefinition) *recordDatum {
return &recordDatum{
def: def,
fields: make([]Datum, len(def.Fields())),
}
}

func (r *recordDatum) Datum() interface{} {
m := make(map[string]interface{})
for i, f := range r.def.Fields() {
m[f.Name()] = r.fields[i].Datum()
}
return m
}

func (r *recordDatum) SetBoolean(v bool) { panic("") }
func (r *recordDatum) SetInt(v int32) { panic("") }
func (r *recordDatum) SetLong(v int64) { panic("") }
func (r *recordDatum) SetFloat(v float32) { panic("") }
func (r *recordDatum) SetDouble(v float64) { panic("") }
func (r *recordDatum) SetBytes(v []byte) { panic("") }
func (r *recordDatum) SetString(v string) { panic("") }
func (r *recordDatum) Get(i int) types.Field {
field := r.def.Fields()[i]
r.fields[i] = DatumForType(field.Type())
return r.fields[i]
}
func (r *recordDatum) SetDefault(i int) {
field := r.def.Fields()[i]
r.fields[i] = &primitiveDatum{field.Default()}
}
func (r *recordDatum) AppendMap(key string) types.Field { panic("") }
func (r *recordDatum) AppendArray() types.Field { panic("") }
func (r *recordDatum) NullField(t int) {
r.fields[t] = &primitiveDatum{nil}
}
func (r *recordDatum) Finalize() {}
Loading

0 comments on commit dd1bf3d

Please sign in to comment.