Improve array, and interface encoding / decoding

This commit is contained in:
Tobie Morgan Hitchcock 2016-09-10 00:24:32 +01:00
parent 529ddbbec2
commit 2f12feeaaa
4 changed files with 48 additions and 63 deletions

View file

@ -17,7 +17,6 @@ package keys
import ( import (
"bytes" "bytes"
"io" "io"
"log"
"time" "time"
) )
@ -90,6 +89,13 @@ func (d *decoder) Decode(items ...interface{}) {
case *float64: case *float64:
*value = d.r.FindNumberFloat64() *value = d.r.FindNumberFloat64()
case *[]time.Time:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindTime())
}
}
case *[]bool: case *[]bool:
if d.r.ReadNext(cARRAY) { if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) { for !d.r.ReadNext(cTERM) {
@ -182,32 +188,13 @@ func (d *decoder) Decode(items ...interface{}) {
} }
case *[]interface{}: case *[]interface{}:
*value = d.r.FindArray()
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
switch fnd := d.r.FindNext(); fnd {
default:
log.Panicf("No item found in *[]interface{} - but found %#v %#q", fnd, fnd)
case cNILL:
*value = append(*value, d.r.FindNull())
case cBOOL:
*value = append(*value, d.r.FindBool())
case cTIME:
*value = append(*value, d.r.FindTime())
case cNUMBER:
*value = append(*value, d.r.FindNumber())
case cSTRING, cPREFIX, cSUFFIX:
*value = append(*value, d.r.FindString())
}
}
d.r.ReadNext(cTERM)
}
case *interface{}: case *interface{}:
switch fnd := d.r.FindNext(); fnd { switch fnd := d.r.FindNext(); fnd {
default: default:
log.Panicf("No item found in *interface{} - but found %#v %#q", fnd, fnd) *value = d.r.FindAny()
case cNILL: case cNILL:
*value = d.r.FindNull() *value = d.r.FindNull()
case cBOOL: case cBOOL:
@ -219,26 +206,7 @@ func (d *decoder) Decode(items ...interface{}) {
case cSTRING, cPREFIX, cSUFFIX: case cSTRING, cPREFIX, cSUFFIX:
*value = d.r.FindString() *value = d.r.FindString()
case cARRAY: case cARRAY:
if d.r.ReadNext(cARRAY) { *value = d.r.FindArray()
*value = []interface{}{}
for !d.r.ReadNext(cTERM) {
switch d.r.FindNext() {
default:
log.Panicf("No item found in *interface{}...[]interface{} - but found %#v %#q", fnd, fnd)
case cNILL:
*value = append((*value).([]interface{}), []interface{}{d.r.FindNull()}...)
case cBOOL:
*value = append((*value).([]interface{}), []interface{}{d.r.FindBool()}...)
case cTIME:
*value = append((*value).([]interface{}), []interface{}{d.r.FindTime()}...)
case cNUMBER:
*value = append((*value).([]interface{}), []interface{}{d.r.FindNumber()}...)
case cSTRING, cPREFIX, cSUFFIX:
*value = append((*value).([]interface{}), []interface{}{d.r.FindString()}...)
}
}
d.r.ReadNext(cTERM)
}
} }

View file

@ -16,7 +16,6 @@ package keys
import ( import (
"bytes" "bytes"
"encoding"
"io" "io"
"time" "time"
) )
@ -231,15 +230,6 @@ func (e *encoder) Encode(items ...interface{}) {
} }
e.w.Write(bTERM) e.w.Write(bTERM)
case encoding.TextMarshaler:
buf, _ := value.MarshalText()
e.w.Write(bSTRING)
e.w.Write(buf)
e.w.Write(bTERM)
e.w.Write(bTERM)
} }
} }

View file

@ -108,6 +108,11 @@ func TestMain(t *testing.T) {
obj: &Thing{KV: "surreal", NS: "abcum", DB: "database", TB: "person", ID: "873c2f37-ea03-4c5e-843e-cf393af44155"}, obj: &Thing{KV: "surreal", NS: "abcum", DB: "database", TB: "person", ID: "873c2f37-ea03-4c5e-843e-cf393af44155"},
new: &Thing{}, new: &Thing{},
}, },
{
str: "/surreal/abcum/database/person",
obj: &Table{KV: "surreal", NS: "abcum", DB: "database", TB: "person"},
new: &Table{},
},
{ {
str: "/surreal/abcum/database/person/*/\xff", str: "/surreal/abcum/database/person/*/\xff",
obj: &Thing{KV: "surreal", NS: "abcum", DB: "database", TB: "person", ID: Suffix}, obj: &Thing{KV: "surreal", NS: "abcum", DB: "database", TB: "person", ID: Suffix},
@ -225,6 +230,8 @@ func TestMain(t *testing.T) {
sorts = []Key{ sorts = []Key{
&Table{KV: "kv", NS: "ns", DB: "db", TB: "person"},
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: Prefix}, &Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: Prefix},
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: nil}, &Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: nil},
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: false}, &Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: false},

View file

@ -73,10 +73,13 @@ func (r *reader) FindNext() (byt byte) {
return return
} }
func (r *reader) FindAny() (val interface{}) {
return r.ReadUpto(cTERM)
}
func (r *reader) FindNull() (val interface{}) { func (r *reader) FindNull() (val interface{}) {
if r.ReadNext(cNILL) { if r.ReadNext(cNILL) {
r.ReadNext(cTERM) r.ReadNext(cTERM)
return
} }
return return
} }
@ -87,7 +90,6 @@ func (r *reader) FindTime() (val time.Time) {
binary.Read(r.Reader, binary.BigEndian, &out) binary.Read(r.Reader, binary.BigEndian, &out)
val = time.Unix(0, out).UTC() val = time.Unix(0, out).UTC()
r.ReadNext(cTERM) r.ReadNext(cTERM)
return
} }
return return
} }
@ -96,7 +98,6 @@ func (r *reader) FindBool() (val bool) {
if r.ReadNext(cBOOL) { if r.ReadNext(cBOOL) {
val = r.ReadNext(cBOOL) val = r.ReadNext(cBOOL)
r.ReadNext(cTERM) r.ReadNext(cTERM)
return
} }
return return
} }
@ -104,7 +105,6 @@ func (r *reader) FindBool() (val bool) {
func (r *reader) FindBytes() (val []byte) { func (r *reader) FindBytes() (val []byte) {
if r.ReadNext(cSTRING) { if r.ReadNext(cSTRING) {
val = r.ReadUpto(cTERM, cTERM) val = r.ReadUpto(cTERM, cTERM)
return
} }
return return
} }
@ -113,16 +113,11 @@ func (r *reader) FindString() (val string) {
if r.ReadNext(cPREFIX) { if r.ReadNext(cPREFIX) {
val = Prefix val = Prefix
r.ReadNext(cTERM) r.ReadNext(cTERM)
return } else if r.ReadNext(cSUFFIX) {
}
if r.ReadNext(cSUFFIX) {
val = Suffix val = Suffix
r.ReadNext(cTERM) r.ReadNext(cTERM)
return } else if r.ReadNext(cSTRING) {
}
if r.ReadNext(cSTRING) {
val = string(r.ReadUpto(cTERM, cTERM)) val = string(r.ReadUpto(cTERM, cTERM))
return
} }
return return
} }
@ -188,3 +183,28 @@ func (r *reader) FindNumberFloat32() (val float32) {
func (r *reader) FindNumberFloat64() (val float64) { func (r *reader) FindNumberFloat64() (val float64) {
return float64(r.FindNumber()) return float64(r.FindNumber())
} }
func (r *reader) FindArray() (val []interface{}) {
if r.ReadNext(cARRAY) {
for !r.ReadNext(cTERM) {
switch fnd := r.FindNext(); fnd {
default:
val = append(val, []interface{}{r.FindAny()}...)
case cNILL:
val = append(val, []interface{}{r.FindNull()}...)
case cBOOL:
val = append(val, []interface{}{r.FindBool()}...)
case cTIME:
val = append(val, []interface{}{r.FindTime()}...)
case cNUMBER:
val = append(val, []interface{}{r.FindNumber()}...)
case cSTRING, cPREFIX, cSUFFIX:
val = append(val, []interface{}{r.FindString()}...)
case cARRAY:
val = append(val, []interface{}{r.FindArray()}...)
}
}
r.ReadNext(cTERM)
}
return
}