surrealpatch/util/keys/dec.go
2016-05-18 00:55:50 +01:00

249 lines
5.4 KiB
Go

// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package keys
import (
"bytes"
"io"
"log"
"time"
)
type decoder struct {
r *reader
}
// Decode decodes an encoded string using the unicode collation algorithm.
func decode(data []byte, items ...interface{}) {
newDecoder(bytes.NewReader(data)).Decode(items...)
}
func newDecoder(r io.Reader) *decoder {
return &decoder{
r: newReader(r),
}
}
func (d *decoder) Decode(items ...interface{}) {
for _, item := range items {
switch value := item.(type) {
case *time.Time:
*value = d.r.FindTime()
case *bool:
*value = d.r.FindBool()
case *[]byte:
*value = d.r.FindBytes()
case *string:
*value = d.r.FindString()
case *int:
*value = d.r.FindNumberInt()
case *int8:
*value = d.r.FindNumberInt8()
case *int16:
*value = d.r.FindNumberInt16()
case *int32:
*value = d.r.FindNumberInt32()
case *int64:
*value = d.r.FindNumberInt64()
case *uint:
*value = d.r.FindNumberUint()
case *uint8:
*value = d.r.FindNumberUint8()
case *uint16:
*value = d.r.FindNumberUint16()
case *uint32:
*value = d.r.FindNumberUint32()
case *uint64:
*value = d.r.FindNumberUint64()
case *float32:
*value = d.r.FindNumberFloat32()
case *float64:
*value = d.r.FindNumberFloat64()
case *[]bool:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindBool())
}
}
case *[]string:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindString())
}
}
case *[]int:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberInt())
}
}
case *[]int8:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberInt8())
}
}
case *[]int16:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberInt16())
}
}
case *[]int32:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberInt32())
}
}
case *[]int64:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberInt64())
}
}
case *[]uint:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberUint())
}
}
case *[]uint16:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberUint16())
}
}
case *[]uint32:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberUint32())
}
}
case *[]uint64:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberUint64())
}
}
case *[]float32:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberFloat32())
}
}
case *[]float64:
if d.r.ReadNext(cARRAY) {
for !d.r.ReadNext(cTERM) {
*value = append(*value, d.r.FindNumberFloat64())
}
}
case *[]interface{}:
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{}:
switch fnd := d.r.FindNext(); fnd {
default:
log.Panicf("No item found in *interface{} - but found %#v %#q", fnd, fnd)
case cNILL:
*value = d.r.FindNull()
case cBOOL:
*value = d.r.FindBool()
case cTIME:
*value = d.r.FindTime()
case cNUMBER:
*value = d.r.FindNumber()
case cSTRING, cPREFIX, cSUFFIX:
*value = d.r.FindString()
case cARRAY:
if d.r.ReadNext(cARRAY) {
*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)
}
}
}
}
}