surrealpatch/util/keys/reader.go

197 lines
3.9 KiB
Go
Raw Normal View History

// 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 (
"encoding/binary"
"math"
"time"
"github.com/abcum/bump"
)
type reader struct {
r *bump.Reader
}
func newReader() *reader {
return &reader{
r: bump.NewReader(nil),
}
}
func (r *reader) unread() {
}
func (r *reader) lookNext() (byt byte) {
byt, _ = r.r.PeekByte()
return
}
func (r *reader) readNext(exp byte) (fnd bool) {
if byt, _ := r.r.PeekByte(); byt == exp {
r.r.ReadByte()
return true
}
return false
}
func (r *reader) readSize(sze int) (byt []byte) {
byt, _ = r.r.ReadBytes(sze)
return byt
}
func (r *reader) readUpto(exp ...byte) (byt []byte) {
2016-05-23 12:31:16 +00:00
LOOP:
for {
bit, _ := r.r.ReadByte()
byt = append(byt, bit)
if bit != exp[0] {
continue
2016-05-23 12:31:16 +00:00
}
for j := 1; j < len(exp); j++ {
if r.readNext(exp[j]) {
byt = append(byt, bit)
2016-05-23 12:31:16 +00:00
continue
}
break LOOP
2016-05-23 12:31:16 +00:00
}
break
2016-05-23 12:31:16 +00:00
}
return byt[:len(byt)-len(exp)]
}
// --------------------------------------------------
// --------------------------------------------------
// --------------------------------------------------
// --------------------------------------------------
// --------------------------------------------------
func (r *reader) readAny() (val interface{}) {
return r.readUpto(bEND)
}
func (r *reader) readNull() (val interface{}) {
if r.readNext(bNIL) {
r.readNext(bEND)
}
return
}
func (r *reader) readTime() (val time.Time) {
if r.readNext(bTME) {
bin := r.readSize(8)
dec := binary.BigEndian.Uint64(bin)
val = time.Unix(0, int64(dec)).UTC()
r.readNext(bEND)
}
return
}
func (r *reader) readBool() (val bool) {
if r.readNext(bVAL) {
val = r.readNext(bVAL)
r.readNext(bEND)
}
return
}
func (r *reader) readBytes() (val []byte) {
if r.readNext(bSTR) {
val = r.readUpto(bEND, bEND)
}
return
}
func (r *reader) readFloat() (val float64) {
if r.readNext(bNEG) {
bin := r.readSize(8)
dec := binary.BigEndian.Uint64(bin)
val = math.Float64frombits(^dec)
r.readNext(bEND)
} else if r.readNext(bPOS) {
bin := r.readSize(8)
dec := binary.BigEndian.Uint64(bin)
val = math.Float64frombits(dec)
r.readNext(bEND)
}
return
}
func (r *reader) readString() (val string) {
if r.readNext(bSTR) {
val = string(r.readUpto(bEND, bEND))
} else if r.readNext(bPRE) {
val = Prefix
r.readNext(bEND)
} else if r.readNext(bSUF) {
val = Suffix
r.readNext(bEND)
}
return
}
func (r *reader) readNumber() (val interface{}) {
var num float64
if r.readNext(bNEG) {
bin := r.readSize(8)
dec := binary.BigEndian.Uint64(bin)
num = math.Float64frombits(^dec)
r.readNext(bEND)
} else if r.readNext(bPOS) {
bin := r.readSize(8)
dec := binary.BigEndian.Uint64(bin)
num = math.Float64frombits(dec)
r.readNext(bEND)
}
if math.Trunc(num) == num {
return int64(math.Trunc(num))
}
return num
}
func (r *reader) readArray() (val []interface{}) {
if r.readNext(bARR) {
for !r.readNext(bEND) {
switch r.lookNext() {
default:
val = append(val, []interface{}{r.readAny()}...)
case bNIL:
val = append(val, []interface{}{r.readNull()}...)
case bVAL:
val = append(val, []interface{}{r.readBool()}...)
case bTME:
val = append(val, []interface{}{r.readTime()}...)
case bNEG, bPOS:
val = append(val, []interface{}{r.readNumber()}...)
case bSTR, bPRE, bSUF:
val = append(val, []interface{}{r.readString()}...)
case bARR:
val = append(val, []interface{}{r.readArray()}...)
}
}
r.readNext(bEND)
}
return
}