e300e9c423
Make use of the github.com/abcum/bump package to efficiently encode and decode from and to byte slices, whilst at the same time using encoder and decoder pools, instead of creating a new buffer for each encoding / decoding process.
231 lines
4.3 KiB
Go
231 lines
4.3 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 (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type decoder struct {
|
|
r *reader
|
|
}
|
|
|
|
var decoders = sync.Pool{
|
|
New: func() interface{} {
|
|
return &decoder{
|
|
r: newReader(),
|
|
}
|
|
},
|
|
}
|
|
|
|
// decode decodes an encoded string using the unicode collation algorithm.
|
|
func decode(data []byte, items ...interface{}) {
|
|
dec := newDecoder(data)
|
|
dec.Decode(items...)
|
|
dec.Reset()
|
|
return
|
|
}
|
|
|
|
func newDecoder(b []byte) *decoder {
|
|
d := decoders.Get().(*decoder)
|
|
d.r.r.ResetBytes(b)
|
|
return d
|
|
}
|
|
|
|
func (d *decoder) Reset() {
|
|
decoders.Put(d)
|
|
}
|
|
|
|
func (d *decoder) Decode(items ...interface{}) {
|
|
|
|
for _, item := range items {
|
|
|
|
switch value := item.(type) {
|
|
|
|
case *time.Time:
|
|
*value = d.r.readTime()
|
|
|
|
case *bool:
|
|
*value = d.r.readBool()
|
|
|
|
case *[]byte:
|
|
*value = d.r.readBytes()
|
|
|
|
case *string:
|
|
*value = d.r.readString()
|
|
|
|
case *int:
|
|
*value = int(d.r.readFloat())
|
|
|
|
case *int8:
|
|
*value = int8(d.r.readFloat())
|
|
|
|
case *int16:
|
|
*value = int16(d.r.readFloat())
|
|
|
|
case *int32:
|
|
*value = int32(d.r.readFloat())
|
|
|
|
case *int64:
|
|
*value = int64(d.r.readFloat())
|
|
|
|
case *uint:
|
|
*value = uint(d.r.readFloat())
|
|
|
|
case *uint8:
|
|
*value = uint8(d.r.readFloat())
|
|
|
|
case *uint16:
|
|
*value = uint16(d.r.readFloat())
|
|
|
|
case *uint32:
|
|
*value = uint32(d.r.readFloat())
|
|
|
|
case *uint64:
|
|
*value = uint64(d.r.readFloat())
|
|
|
|
case *float32:
|
|
*value = float32(d.r.readFloat())
|
|
|
|
case *float64:
|
|
*value = float64(d.r.readFloat())
|
|
|
|
case *[]time.Time:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, d.r.readTime())
|
|
}
|
|
}
|
|
|
|
case *[]bool:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, d.r.readBool())
|
|
}
|
|
}
|
|
|
|
case *[]string:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, d.r.readString())
|
|
}
|
|
}
|
|
|
|
case *[]int:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, int(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]int8:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, int8(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]int16:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, int16(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]int32:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, int32(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]int64:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, int64(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]uint:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, uint(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]uint16:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, uint16(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]uint32:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, uint32(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]uint64:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, uint64(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]float32:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, float32(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]float64:
|
|
if d.r.readNext(bARR) {
|
|
for !d.r.readNext(bEND) {
|
|
*value = append(*value, float64(d.r.readFloat()))
|
|
}
|
|
}
|
|
|
|
case *[]interface{}:
|
|
*value = d.r.readArray()
|
|
|
|
case *interface{}:
|
|
|
|
switch d.r.lookNext() {
|
|
default:
|
|
*value = d.r.readAny()
|
|
case bNIL:
|
|
*value = d.r.readNull()
|
|
case bVAL:
|
|
*value = d.r.readBool()
|
|
case bTME:
|
|
*value = d.r.readTime()
|
|
case bNEG, bPOS:
|
|
*value = d.r.readFloat()
|
|
case bSTR, bPRE, bSUF:
|
|
*value = d.r.readString()
|
|
case bARR:
|
|
*value = d.r.readArray()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|