Skip to content

Commit 9079d99

Browse files
fixed DecodeSchema() logic for custom types
1 parent 2825c32 commit 9079d99

File tree

5 files changed

+63
-66
lines changed

5 files changed

+63
-66
lines changed

date.go

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package schemer
22

33
import (
4-
"bufio"
54
"encoding/json"
65
"fmt"
76
"io"
@@ -11,7 +10,7 @@ import (
1110
)
1211

1312
// each custom type has a unique name an a unique UUID
14-
const dateSchemaUUID byte = 1 // each custom type has a unique id
13+
const dateSchemaUUID byte = 1
1514

1615
type DateSchema struct {
1716
SchemaOptions
@@ -39,16 +38,16 @@ func (sg dateSchemaGenerator) SchemaOfType(t reflect.Type) (Schema, error) {
3938
return nil, nil
4039
}
4140

42-
func (sg dateSchemaGenerator) DecodeSchema(br *bufio.Reader) (Schema, error) {
41+
func (sg dateSchemaGenerator) DecodeSchema(r io.Reader) (Schema, error) {
4342

44-
tmpBuf, err := br.Peek(2)
43+
tmpBuf := make([]byte, 1)
44+
_, err := r.Read(tmpBuf)
4545
if err != nil {
4646
return nil, err
4747
}
4848

49-
if tmpBuf[0] == CustomSchemaMask {
50-
// don't advance byte index if we don't have a date schema
51-
if tmpBuf[1] != dateSchemaUUID {
49+
if tmpBuf[0]&CustomSchemaMask == CustomSchemaMask {
50+
if tmpBuf[0]&(dateSchemaUUID<<4) != (dateSchemaUUID << 4) {
5251
return nil, nil
5352
}
5453
} else {
@@ -60,6 +59,7 @@ func (sg dateSchemaGenerator) DecodeSchema(br *bufio.Reader) (Schema, error) {
6059
s := DateSchema{}
6160
s.SetNullable(nullable)
6261
return &s, nil
62+
6363
}
6464

6565
func (sg dateSchemaGenerator) DecodeSchemaJSON(r io.Reader) (Schema, error) {
@@ -125,20 +125,19 @@ func (s *DateSchema) MarshalJSON() ([]byte, error) {
125125
// Bytes encodes the schema in a portable binary format
126126
func (s *DateSchema) MarshalSchemer() ([]byte, error) {
127127

128-
const schemerDateSize byte = 1 + 1 // 1 byte for the schema + 1 bytes for the UUID
128+
const schemerDateSize byte = 1
129129

130130
// string schemas are 1 byte long
131131
var schema []byte = make([]byte, schemerDateSize)
132132

133-
schema[0] = CustomSchemaMask
133+
schema[0] |= CustomSchemaMask
134+
schema[0] |= (dateSchemaUUID<<4)
134135

135136
// The most signifiant bit indicates whether or not the type is nullable
136137
if s.Nullable() {
137138
schema[0] |= 0x80
138139
}
139140

140-
schema[1] = dateSchemaUUID
141-
142141
return schema, nil
143142
}
144143

date_test.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package schemer
22

3-
/*
3+
import (
4+
"bytes"
5+
"testing"
6+
"time"
7+
)
48

59
// uses a time.Time directly...
610
func testRegisteredType1(useJSON bool, t *testing.T) {
@@ -179,4 +183,4 @@ func TestCustomDates(t *testing.T) {
179183
testRegisteredType2(false, t)
180184
}
181185

182-
*/
186+
// 0x 29 06 02 09 49 6e 74 46 69 65 6c 64 31 11 02 04 44 61 74 65 3f01020353747220

ipv4.go

+18-24
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ import (
1010
)
1111

1212
// each custom type has a unique name an a unique UUID
13-
//const ipV4SchemaName string = "ipv4"
14-
const ipV4SchemaUUID byte = 02
13+
const ipV4SchemaUUID byte = 2
1514

1615
type ipv4Schema struct {
1716
SchemaOptions
@@ -41,29 +40,25 @@ func (sg ipv4SchemaGenerator) SchemaOfType(t reflect.Type) (Schema, error) {
4140

4241
func (sg ipv4SchemaGenerator) DecodeSchema(r io.Reader) (Schema, error) {
4342

44-
return nil, nil
45-
46-
/*
43+
tmpBuf := make([]byte, 1)
44+
_, err := r.Read(tmpBuf)
45+
if err != nil {
46+
return nil, err
47+
}
4748

48-
if buf[*byteIndex] == CustomSchemaMask {
49-
// don't advance byte index if we don't have an IPv4 schema
50-
if buf[*byteIndex+1] != ipV4SchemaUUID {
51-
return nil, nil
52-
}
53-
} else {
49+
if tmpBuf[0]&CustomSchemaMask == CustomSchemaMask {
50+
if tmpBuf[0]&(ipV4SchemaUUID<<4) != (ipV4SchemaUUID << 4) {
5451
return nil, nil
5552
}
53+
} else {
54+
return nil, nil
55+
}
5656

57-
nullable := (buf[*byteIndex]&SchemaNullBit == SchemaNullBit)
58-
59-
// advance past customSchemaMask and UUID
60-
*byteIndex++
61-
*byteIndex++
57+
nullable := (tmpBuf[0]&SchemaNullBit == SchemaNullBit)
6258

63-
s := ipv4Schema{}
64-
s.SetNullable(nullable)
65-
return &s, nil
66-
*/
59+
s := ipv4Schema{}
60+
s.SetNullable(nullable)
61+
return &s, nil
6762

6863
}
6964

@@ -138,20 +133,19 @@ func (s *ipv4Schema) MarshalJSON() ([]byte, error) {
138133
// Bytes encodes the schema in a portable binary format
139134
func (s *ipv4Schema) MarshalSchemer() ([]byte, error) {
140135

141-
const schemerDateSize byte = 1 + 1 // 1 byte for the schema + 1 bytes for the UUID
136+
const schemerDateSize byte = 1
142137

143138
// string schemas are 1 byte long
144139
var schema []byte = make([]byte, schemerDateSize)
145140

146-
schema[0] = CustomSchemaMask
141+
schema[0] |= CustomSchemaMask
142+
schema[0] |= (ipV4SchemaUUID << 4)
147143

148144
// The most signifiant bit indicates whether or not the type is nullable
149145
if s.Nullable() {
150146
schema[0] |= 0x80
151147
}
152148

153-
schema[1] = ipV4SchemaUUID
154-
155149
return schema, nil
156150
}
157151

ipv4_test.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package schemer
22

3-
/*
3+
import (
4+
"bytes"
5+
"net"
6+
"testing"
7+
)
48

59
// uses a net.IP directly...
610
func testIPv41(useJSON bool, t *testing.T) {
@@ -171,5 +175,3 @@ func TestIPv41(t *testing.T) {
171175
testIPv42(true, t)
172176
testIPv42(false, t)
173177
}
174-
175-
*/

schemer.go

+24-26
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package schemer
22

3+
// TODO:
4+
// -> type TypeByte byte
5+
// - -> model decode after decodeJSON
6+
// - -> squeze custom type into 6 bits , based on reserved type (CustomSchemaMask to be 0x40)
7+
//
8+
39
import (
4-
"bufio"
510
"bytes"
611
"encoding/json"
712
"fmt"
@@ -26,7 +31,7 @@ const (
2631
VarArraySchemaMask = 0x24
2732
FixedObjectSchemaMask = 0x29 // 0b10 100f where f indicates that the object has fixed number of fields
2833
VarObjectSchemaMask = 0x28
29-
CustomSchemaMask = 0x3F // 0b11 1111
34+
CustomSchemaMask = 0x40 // bit 7 indicates custom schema type
3035
SchemaNullBit = 0x80 // The most signifiant bit indicates whether or not the type is nullable
3136
)
3237

@@ -69,7 +74,7 @@ type Marshaler interface {
6974
// then the built-in logic for returning a Schema is used.
7075
type SchemaGenerator interface {
7176
SchemaOfType(t reflect.Type) (Schema, error)
72-
DecodeSchema(b *bufio.Reader) (Schema, error)
77+
DecodeSchema(r io.Reader) (Schema, error)
7378
DecodeSchemaJSON(r io.Reader) (Schema, error)
7479
}
7580

@@ -612,15 +617,11 @@ func DecodeSchemaJSON(r io.Reader) (Schema, error) {
612617
return nil, fmt.Errorf("invalid schema type: %s", typeStr)
613618
}
614619

615-
func DecodeSchema(r io.Reader) (Schema, error) {
616-
br := bufio.NewReader(r)
617-
return decodeSchema(br)
618-
}
619-
620620
// decodeSchema processes buf[] to actually decode the binary schema.
621621
// As each byte is processed, this routine advances *byteIndex, which indicates
622622
// how far into the buffer we have processed already.
623-
func decodeSchema(r io.Reader) (Schema, error) {
623+
func DecodeSchema(r io.Reader) (Schema, error) {
624+
624625
const (
625626
TwoBitSchemaMask = 0x30
626627
FourBitSchemaMask = 0x3C
@@ -630,21 +631,19 @@ func decodeSchema(r io.Reader) (Schema, error) {
630631

631632
var err error
632633

633-
// Call registered schema generators
634-
635-
/*
636-
for _, sg := range regDecodeSchema {
637-
if s, err := sg.DecodeSchema(r); s != nil || err != nil {
638-
return s, err
639-
}
640-
}
641-
*/
642-
643634
buf := make([]byte, 1)
644635
_, err = r.Read(buf)
645636
if err != nil {
646637
return nil, err
647638
}
639+
640+
// Call registered schema generators
641+
for _, sg := range regDecodeSchema {
642+
if s, err := sg.DecodeSchema(bytes.NewReader(buf)); s != nil || err != nil {
643+
return s, err
644+
}
645+
}
646+
648647
curByte := buf[0]
649648

650649
// decode fixed int schema
@@ -763,7 +762,7 @@ func decodeSchema(r io.Reader) (Schema, error) {
763762
return nil, err
764763
}
765764

766-
FixedArraySchema.Element, err = decodeSchema(r)
765+
FixedArraySchema.Element, err = DecodeSchema(r)
767766
if err != nil {
768767
return nil, err
769768
}
@@ -777,7 +776,7 @@ func decodeSchema(r io.Reader) (Schema, error) {
777776

778777
varArraySchema.SchemaOptions.nullable = (curByte&SchemaNullBit == SchemaNullBit)
779778

780-
varArraySchema.Element, err = decodeSchema(r)
779+
varArraySchema.Element, err = DecodeSchema(r)
781780
if err != nil {
782781
return nil, err
783782
}
@@ -818,8 +817,7 @@ func decodeSchema(r io.Reader) (Schema, error) {
818817

819818
}
820819

821-
// decodeSchema recursive call will advance *byteIndex for each field...
822-
of.Schema, err = decodeSchema(r)
820+
of.Schema, err = DecodeSchema(r)
823821
if err != nil {
824822
return nil, err
825823
}
@@ -836,12 +834,12 @@ func decodeSchema(r io.Reader) (Schema, error) {
836834

837835
varObjectSchema.SchemaOptions.nullable = (curByte&SchemaNullBit == SchemaNullBit)
838836

839-
varObjectSchema.Key, err = decodeSchema(r)
837+
varObjectSchema.Key, err = DecodeSchema(r)
840838
if err != nil {
841839
return nil, err
842840
}
843841

844-
varObjectSchema.Value, err = decodeSchema(r)
842+
varObjectSchema.Value, err = DecodeSchema(r)
845843
if err != nil {
846844
return nil, err
847845
}
@@ -948,5 +946,5 @@ func PreDecode(nullable bool, r io.Reader, v reflect.Value) (reflect.Value, erro
948946
// initialization function for the Schemer Library
949947
func init() {
950948
Register(dateSchemaGenerator{})
951-
//Register(ipv4SchemaGenerator{})
949+
Register(ipv4SchemaGenerator{})
952950
}

0 commit comments

Comments
 (0)