You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
5.1 KiB
199 lines
5.1 KiB
//
|
|
// DISCLAIMER
|
|
//
|
|
// Copyright 2017 ArangoDB GmbH, Cologne, Germany
|
|
//
|
|
// 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.
|
|
//
|
|
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
|
//
|
|
// Author Ewout Prangsma
|
|
//
|
|
|
|
package velocypack
|
|
|
|
import (
|
|
"reflect"
|
|
"time"
|
|
)
|
|
|
|
// Value is a helper structure used to build VPack structures.
|
|
// It holds a single data value with a specific type.
|
|
type Value struct {
|
|
vt ValueType
|
|
data interface{}
|
|
unindexed bool
|
|
}
|
|
|
|
// NewValue creates a new Value with type derived from Go type of given value.
|
|
// If the given value is not a supported type, a Value of type Illegal is returned.
|
|
func NewValue(value interface{}) Value {
|
|
v := reflect.ValueOf(value)
|
|
return NewReflectValue(v)
|
|
}
|
|
|
|
// NewReflectValue creates a new Value with type derived from Go type of given reflect value.
|
|
// If the given value is not a supported type, a Value of type Illegal is returned.
|
|
func NewReflectValue(v reflect.Value) Value {
|
|
vt := v.Type()
|
|
switch vt.Kind() {
|
|
case reflect.Bool:
|
|
return NewBoolValue(v.Bool())
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return NewIntValue(v.Int())
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
return NewUIntValue(v.Uint())
|
|
case reflect.Float32, reflect.Float64:
|
|
return NewDoubleValue(v.Float())
|
|
case reflect.String:
|
|
return NewStringValue(v.String())
|
|
case reflect.Slice:
|
|
if vt.Elem().Kind() == reflect.Uint8 {
|
|
}
|
|
}
|
|
if v.CanInterface() {
|
|
raw := v.Interface()
|
|
if v, ok := raw.([]byte); ok {
|
|
return NewBinaryValue(v)
|
|
}
|
|
if v, ok := raw.(Slice); ok {
|
|
return NewSliceValue(v)
|
|
}
|
|
if v, ok := raw.(time.Time); ok {
|
|
return NewUTCDateValue(v)
|
|
}
|
|
if v, ok := raw.(Value); ok {
|
|
return v
|
|
}
|
|
}
|
|
return Value{Illegal, nil, false}
|
|
}
|
|
|
|
// NewBoolValue creates a new Value of type Bool with given value.
|
|
func NewBoolValue(value bool) Value {
|
|
return Value{Bool, value, false}
|
|
}
|
|
|
|
// NewIntValue creates a new Value of type Int with given value.
|
|
func NewIntValue(value int64) Value {
|
|
if value >= -6 && value <= 9 {
|
|
return Value{SmallInt, value, false}
|
|
}
|
|
return Value{Int, value, false}
|
|
}
|
|
|
|
// NewUIntValue creates a new Value of type UInt with given value.
|
|
func NewUIntValue(value uint64) Value {
|
|
return Value{UInt, value, false}
|
|
}
|
|
|
|
// NewDoubleValue creates a new Value of type Double with given value.
|
|
func NewDoubleValue(value float64) Value {
|
|
return Value{Double, value, false}
|
|
}
|
|
|
|
// NewStringValue creates a new Value of type String with given value.
|
|
func NewStringValue(value string) Value {
|
|
return Value{String, value, false}
|
|
}
|
|
|
|
// NewBinaryValue creates a new Value of type Binary with given value.
|
|
func NewBinaryValue(value []byte) Value {
|
|
return Value{Binary, value, false}
|
|
}
|
|
|
|
// NewUTCDateValue creates a new Value of type UTCDate with given value.
|
|
func NewUTCDateValue(value time.Time) Value {
|
|
return Value{UTCDate, value, false}
|
|
}
|
|
|
|
// NewSliceValue creates a new Value of from the given slice.
|
|
func NewSliceValue(value Slice) Value {
|
|
return Value{value.Type(), value, false}
|
|
}
|
|
|
|
// NewObjectValue creates a new Value that opens a new object.
|
|
func NewObjectValue(unindexed ...bool) Value {
|
|
return Value{Object, nil, optionalBool(unindexed, false)}
|
|
}
|
|
|
|
// NewArrayValue creates a new Value that opens a new array.
|
|
func NewArrayValue(unindexed ...bool) Value {
|
|
return Value{Array, nil, optionalBool(unindexed, false)}
|
|
}
|
|
|
|
// NewNullValue creates a new Value of type Null.
|
|
func NewNullValue() Value {
|
|
return Value{Null, nil, false}
|
|
}
|
|
|
|
// NewMinKeyValue creates a new Value of type MinKey.
|
|
func NewMinKeyValue() Value {
|
|
return Value{MinKey, nil, false}
|
|
}
|
|
|
|
// NewMaxKeyValue creates a new Value of type MaxKey.
|
|
func NewMaxKeyValue() Value {
|
|
return Value{MaxKey, nil, false}
|
|
}
|
|
|
|
// Type returns the ValueType of this value.
|
|
func (v Value) Type() ValueType {
|
|
return v.vt
|
|
}
|
|
|
|
// IsSlice returns true when the value already contains a slice.
|
|
func (v Value) IsSlice() bool {
|
|
_, ok := v.data.(Slice)
|
|
return ok
|
|
}
|
|
|
|
// IsIllegal returns true if the type of value is Illegal.
|
|
func (v Value) IsIllegal() bool {
|
|
return v.vt == Illegal
|
|
}
|
|
|
|
func (v Value) boolValue() bool {
|
|
return v.data.(bool)
|
|
}
|
|
|
|
func (v Value) intValue() int64 {
|
|
return v.data.(int64)
|
|
}
|
|
|
|
func (v Value) uintValue() uint64 {
|
|
return v.data.(uint64)
|
|
}
|
|
|
|
func (v Value) doubleValue() float64 {
|
|
return v.data.(float64)
|
|
}
|
|
|
|
func (v Value) stringValue() string {
|
|
return v.data.(string)
|
|
}
|
|
|
|
func (v Value) binaryValue() []byte {
|
|
return v.data.([]byte)
|
|
}
|
|
|
|
func (v Value) utcDateValue() int64 {
|
|
time := v.data.(time.Time)
|
|
sec := time.Unix()
|
|
nsec := int64(time.Nanosecond())
|
|
return sec*1000 + nsec/1000000
|
|
}
|
|
|
|
func (v Value) sliceValue() Slice {
|
|
return v.data.(Slice)
|
|
}
|
|
|