1// Copyright 2013-2020 Aerospike, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package aerospike
16
17import (
18	"fmt"
19	"reflect"
20	"strconv"
21
22	ParticleType "github.com/aerospike/aerospike-client-go/internal/particle_type"
23	. "github.com/aerospike/aerospike-client-go/types"
24	Buffer "github.com/aerospike/aerospike-client-go/utils/buffer"
25)
26
27// this function will be set in value_slow file if included
28var newValueReflect func(interface{}) Value
29
30// Map pair is used when the client returns sorted maps from the server
31// Since the default map in Go is a hash map, we will use a slice
32// to return the results in server order
33type MapPair struct{ Key, Value interface{} }
34
35// Value interface is used to efficiently serialize objects into the wire protocol.
36type Value interface {
37
38	// Calculate number of vl.bytes necessary to serialize the value in the wire protocol.
39	EstimateSize() (int, error)
40
41	// Serialize the value in the wire protocol.
42	write(cmd BufferEx) (int, error)
43
44	// Serialize the value using MessagePack.
45	pack(cmd BufferEx) (int, error)
46
47	// GetType returns wire protocol value type.
48	GetType() int
49
50	// GetObject returns original value as an interface{}.
51	GetObject() interface{}
52
53	// String implements Stringer interface.
54	String() string
55}
56
57type AerospikeBlob interface {
58	// EncodeBlob returns a byte slice representing the encoding of the
59	// receiver for transmission to a Decoder, usually of the same
60	// concrete type.
61	EncodeBlob() ([]byte, error)
62}
63
64// tryConcreteValue will return an aerospike value.
65// If the encoder does not exist, it will not try to use reflection.
66func tryConcreteValue(v interface{}) Value {
67	switch val := v.(type) {
68	case Value:
69		return val
70	case int:
71		return IntegerValue(val)
72	case int64:
73		return LongValue(val)
74	case string:
75		return StringValue(val)
76	case []interface{}:
77		return ListValue(val)
78	case map[string]interface{}:
79		return JsonValue(val)
80	case map[interface{}]interface{}:
81		return NewMapValue(val)
82	case nil:
83		return nullValue
84	case []Value:
85		return NewValueArray(val)
86	case []byte:
87		return BytesValue(val)
88	case int8:
89		return IntegerValue(int(val))
90	case int16:
91		return IntegerValue(int(val))
92	case int32:
93		return IntegerValue(int(val))
94	case uint8: // byte supported here
95		return IntegerValue(int(val))
96	case uint16:
97		return IntegerValue(int(val))
98	case uint32:
99		return IntegerValue(int(val))
100	case float32:
101		return FloatValue(float64(val))
102	case float64:
103		return FloatValue(val)
104	case uint:
105		// if it doesn't overflow int64, it is OK
106		if int64(val) >= 0 {
107			return LongValue(int64(val))
108		}
109	case MapIter:
110		return NewMapperValue(val)
111	case ListIter:
112		return NewListerValue(val)
113	case AerospikeBlob:
114		return NewBlobValue(val)
115
116	/*
117		The following cases will try to avoid using reflection by matching against the
118		internal generic types.
119		If you have custom type aliases in your code, you can use the same aerospike types to cast your type into,
120		to avoid hitting the reflection.
121	*/
122	case []string:
123		return NewListerValue(stringSlice(val))
124	case []int:
125		return NewListerValue(intSlice(val))
126	case []int8:
127		return NewListerValue(int8Slice(val))
128	case []int16:
129		return NewListerValue(int16Slice(val))
130	case []int32:
131		return NewListerValue(int32Slice(val))
132	case []int64:
133		return NewListerValue(int64Slice(val))
134	case []uint16:
135		return NewListerValue(uint16Slice(val))
136	case []uint32:
137		return NewListerValue(uint32Slice(val))
138	case []uint64:
139		return NewListerValue(uint64Slice(val))
140	case []float32:
141		return NewListerValue(float32Slice(val))
142	case []float64:
143		return NewListerValue(float64Slice(val))
144	case map[string]string:
145		return NewMapperValue(stringStringMap(val))
146	case map[string]int:
147		return NewMapperValue(stringIntMap(val))
148	case map[string]int8:
149		return NewMapperValue(stringInt8Map(val))
150	case map[string]int16:
151		return NewMapperValue(stringInt16Map(val))
152	case map[string]int32:
153		return NewMapperValue(stringInt32Map(val))
154	case map[string]int64:
155		return NewMapperValue(stringInt64Map(val))
156	case map[string]uint16:
157		return NewMapperValue(stringUint16Map(val))
158	case map[string]uint32:
159		return NewMapperValue(stringUint32Map(val))
160	case map[string]float32:
161		return NewMapperValue(stringFloat32Map(val))
162	case map[string]float64:
163		return NewMapperValue(stringFloat64Map(val))
164	case map[int]string:
165		return NewMapperValue(intStringMap(val))
166	case map[int]int:
167		return NewMapperValue(intIntMap(val))
168	case map[int]int8:
169		return NewMapperValue(intInt8Map(val))
170	case map[int]int16:
171		return NewMapperValue(intInt16Map(val))
172	case map[int]int32:
173		return NewMapperValue(intInt32Map(val))
174	case map[int]int64:
175		return NewMapperValue(intInt64Map(val))
176	case map[int]uint16:
177		return NewMapperValue(intUint16Map(val))
178	case map[int]uint32:
179		return NewMapperValue(intUint32Map(val))
180	case map[int]float32:
181		return NewMapperValue(intFloat32Map(val))
182	case map[int]float64:
183		return NewMapperValue(intFloat64Map(val))
184	case map[int]interface{}:
185		return NewMapperValue(intInterfaceMap(val))
186	case map[int8]string:
187		return NewMapperValue(int8StringMap(val))
188	case map[int8]int:
189		return NewMapperValue(int8IntMap(val))
190	case map[int8]int8:
191		return NewMapperValue(int8Int8Map(val))
192	case map[int8]int16:
193		return NewMapperValue(int8Int16Map(val))
194	case map[int8]int32:
195		return NewMapperValue(int8Int32Map(val))
196	case map[int8]int64:
197		return NewMapperValue(int8Int64Map(val))
198	case map[int8]uint16:
199		return NewMapperValue(int8Uint16Map(val))
200	case map[int8]uint32:
201		return NewMapperValue(int8Uint32Map(val))
202	case map[int8]float32:
203		return NewMapperValue(int8Float32Map(val))
204	case map[int8]float64:
205		return NewMapperValue(int8Float64Map(val))
206	case map[int8]interface{}:
207		return NewMapperValue(int8InterfaceMap(val))
208	case map[int16]string:
209		return NewMapperValue(int16StringMap(val))
210	case map[int16]int:
211		return NewMapperValue(int16IntMap(val))
212	case map[int16]int8:
213		return NewMapperValue(int16Int8Map(val))
214	case map[int16]int16:
215		return NewMapperValue(int16Int16Map(val))
216	case map[int16]int32:
217		return NewMapperValue(int16Int32Map(val))
218	case map[int16]int64:
219		return NewMapperValue(int16Int64Map(val))
220	case map[int16]uint16:
221		return NewMapperValue(int16Uint16Map(val))
222	case map[int16]uint32:
223		return NewMapperValue(int16Uint32Map(val))
224	case map[int16]float32:
225		return NewMapperValue(int16Float32Map(val))
226	case map[int16]float64:
227		return NewMapperValue(int16Float64Map(val))
228	case map[int16]interface{}:
229		return NewMapperValue(int16InterfaceMap(val))
230	case map[int32]string:
231		return NewMapperValue(int32StringMap(val))
232	case map[int32]int:
233		return NewMapperValue(int32IntMap(val))
234	case map[int32]int8:
235		return NewMapperValue(int32Int8Map(val))
236	case map[int32]int16:
237		return NewMapperValue(int32Int16Map(val))
238	case map[int32]int32:
239		return NewMapperValue(int32Int32Map(val))
240	case map[int32]int64:
241		return NewMapperValue(int32Int64Map(val))
242	case map[int32]uint16:
243		return NewMapperValue(int32Uint16Map(val))
244	case map[int32]uint32:
245		return NewMapperValue(int32Uint32Map(val))
246	case map[int32]float32:
247		return NewMapperValue(int32Float32Map(val))
248	case map[int32]float64:
249		return NewMapperValue(int32Float64Map(val))
250	case map[int32]interface{}:
251		return NewMapperValue(int32InterfaceMap(val))
252	case map[int64]string:
253		return NewMapperValue(int64StringMap(val))
254	case map[int64]int:
255		return NewMapperValue(int64IntMap(val))
256	case map[int64]int8:
257		return NewMapperValue(int64Int8Map(val))
258	case map[int64]int16:
259		return NewMapperValue(int64Int16Map(val))
260	case map[int64]int32:
261		return NewMapperValue(int64Int32Map(val))
262	case map[int64]int64:
263		return NewMapperValue(int64Int64Map(val))
264	case map[int64]uint16:
265		return NewMapperValue(int64Uint16Map(val))
266	case map[int64]uint32:
267		return NewMapperValue(int64Uint32Map(val))
268	case map[int64]float32:
269		return NewMapperValue(int64Float32Map(val))
270	case map[int64]float64:
271		return NewMapperValue(int64Float64Map(val))
272	case map[int64]interface{}:
273		return NewMapperValue(int64InterfaceMap(val))
274	case map[uint16]string:
275		return NewMapperValue(uint16StringMap(val))
276	case map[uint16]int:
277		return NewMapperValue(uint16IntMap(val))
278	case map[uint16]int8:
279		return NewMapperValue(uint16Int8Map(val))
280	case map[uint16]int16:
281		return NewMapperValue(uint16Int16Map(val))
282	case map[uint16]int32:
283		return NewMapperValue(uint16Int32Map(val))
284	case map[uint16]int64:
285		return NewMapperValue(uint16Int64Map(val))
286	case map[uint16]uint16:
287		return NewMapperValue(uint16Uint16Map(val))
288	case map[uint16]uint32:
289		return NewMapperValue(uint16Uint32Map(val))
290	case map[uint16]float32:
291		return NewMapperValue(uint16Float32Map(val))
292	case map[uint16]float64:
293		return NewMapperValue(uint16Float64Map(val))
294	case map[uint16]interface{}:
295		return NewMapperValue(uint16InterfaceMap(val))
296	case map[uint32]string:
297		return NewMapperValue(uint32StringMap(val))
298	case map[uint32]int:
299		return NewMapperValue(uint32IntMap(val))
300	case map[uint32]int8:
301		return NewMapperValue(uint32Int8Map(val))
302	case map[uint32]int16:
303		return NewMapperValue(uint32Int16Map(val))
304	case map[uint32]int32:
305		return NewMapperValue(uint32Int32Map(val))
306	case map[uint32]int64:
307		return NewMapperValue(uint32Int64Map(val))
308	case map[uint32]uint16:
309		return NewMapperValue(uint32Uint16Map(val))
310	case map[uint32]uint32:
311		return NewMapperValue(uint32Uint32Map(val))
312	case map[uint32]float32:
313		return NewMapperValue(uint32Float32Map(val))
314	case map[uint32]float64:
315		return NewMapperValue(uint32Float64Map(val))
316	case map[uint32]interface{}:
317		return NewMapperValue(uint32InterfaceMap(val))
318	case map[float32]string:
319		return NewMapperValue(float32StringMap(val))
320	case map[float32]int:
321		return NewMapperValue(float32IntMap(val))
322	case map[float32]int8:
323		return NewMapperValue(float32Int8Map(val))
324	case map[float32]int16:
325		return NewMapperValue(float32Int16Map(val))
326	case map[float32]int32:
327		return NewMapperValue(float32Int32Map(val))
328	case map[float32]int64:
329		return NewMapperValue(float32Int64Map(val))
330	case map[float32]uint16:
331		return NewMapperValue(float32Uint16Map(val))
332	case map[float32]uint32:
333		return NewMapperValue(float32Uint32Map(val))
334	case map[float32]float32:
335		return NewMapperValue(float32Float32Map(val))
336	case map[float32]float64:
337		return NewMapperValue(float32Float64Map(val))
338	case map[float32]interface{}:
339		return NewMapperValue(float32InterfaceMap(val))
340	case map[float64]string:
341		return NewMapperValue(float64StringMap(val))
342	case map[float64]int:
343		return NewMapperValue(float64IntMap(val))
344	case map[float64]int8:
345		return NewMapperValue(float64Int8Map(val))
346	case map[float64]int16:
347		return NewMapperValue(float64Int16Map(val))
348	case map[float64]int32:
349		return NewMapperValue(float64Int32Map(val))
350	case map[float64]int64:
351		return NewMapperValue(float64Int64Map(val))
352	case map[float64]uint16:
353		return NewMapperValue(float64Uint16Map(val))
354	case map[float64]uint32:
355		return NewMapperValue(float64Uint32Map(val))
356	case map[float64]float32:
357		return NewMapperValue(float64Float32Map(val))
358	case map[float64]float64:
359		return NewMapperValue(float64Float64Map(val))
360	case map[float64]interface{}:
361		return NewMapperValue(float64InterfaceMap(val))
362	case map[string]uint64:
363		return NewMapperValue(stringUint64Map(val))
364	case map[int]uint64:
365		return NewMapperValue(intUint64Map(val))
366	case map[int8]uint64:
367		return NewMapperValue(int8Uint64Map(val))
368	case map[int16]uint64:
369		return NewMapperValue(int16Uint64Map(val))
370	case map[int32]uint64:
371		return NewMapperValue(int32Uint64Map(val))
372	case map[int64]uint64:
373		return NewMapperValue(int64Uint64Map(val))
374	case map[uint16]uint64:
375		return NewMapperValue(uint16Uint64Map(val))
376	case map[uint32]uint64:
377		return NewMapperValue(uint32Uint64Map(val))
378	case map[float32]uint64:
379		return NewMapperValue(float32Uint64Map(val))
380	case map[float64]uint64:
381		return NewMapperValue(float64Uint64Map(val))
382	case map[uint64]string:
383		return NewMapperValue(uint64StringMap(val))
384	case map[uint64]int:
385		return NewMapperValue(uint64IntMap(val))
386	case map[uint64]int8:
387		return NewMapperValue(uint64Int8Map(val))
388	case map[uint64]int16:
389		return NewMapperValue(uint64Int16Map(val))
390	case map[uint64]int32:
391		return NewMapperValue(uint64Int32Map(val))
392	case map[uint64]int64:
393		return NewMapperValue(uint64Int64Map(val))
394	case map[uint64]uint16:
395		return NewMapperValue(uint64Uint16Map(val))
396	case map[uint64]uint32:
397		return NewMapperValue(uint64Uint32Map(val))
398	case map[uint64]uint64:
399		return NewMapperValue(uint64Uint64Map(val))
400	case map[uint64]float32:
401		return NewMapperValue(uint64Float32Map(val))
402	case map[uint64]float64:
403		return NewMapperValue(uint64Float64Map(val))
404	case map[uint64]interface{}:
405		return NewMapperValue(uint64InterfaceMap(val))
406	}
407
408	return nil
409}
410
411// NewValue generates a new Value object based on the type.
412// If the type is not supported, NewValue will panic.
413// This method is a convenience method, and should not be used
414// when absolute performance is required unless for the reason mentioned below.
415//
416// If you have custom maps or slices like:
417//     type MyMap map[primitive1]primitive2, eg: map[int]string
418// or
419//     type MySlice []primitive, eg: []float64
420// cast them to their primitive type when passing them to this method:
421//     v := NewValue(map[int]string(myVar))
422//     v := NewValue([]float64(myVar))
423// This way you will avoid hitting reflection.
424// To completely avoid reflection in the library,
425// use the build tag: as_performance while building your program.
426func NewValue(v interface{}) Value {
427	if value := tryConcreteValue(v); value != nil {
428		return value
429	}
430
431	if newValueReflect != nil {
432		if res := newValueReflect(v); res != nil {
433			return res
434		}
435	}
436
437	// panic for anything that is not supported.
438	panic(NewAerospikeError(TYPE_NOT_SUPPORTED, fmt.Sprintf("Value type '%v' (%s) not supported (if you are compiling via 'as_performance' tag, use cast either to primitives, or use ListIter or MapIter interfaces.)", v, reflect.TypeOf(v).String())))
439}
440
441// NullValue is an empty value.
442type NullValue struct{}
443
444var nullValue NullValue
445
446// NewNullValue generates a NullValue instance.
447func NewNullValue() NullValue {
448	return nullValue
449}
450
451func (vl NullValue) EstimateSize() (int, error) {
452	return 0, nil
453}
454
455func (vl NullValue) write(cmd BufferEx) (int, error) {
456	return 0, nil
457}
458
459func (vl NullValue) pack(cmd BufferEx) (int, error) {
460	return packNil(cmd)
461}
462
463// GetType returns wire protocol value type.
464func (vl NullValue) GetType() int {
465	return ParticleType.NULL
466}
467
468// GetObject returns original value as an interface{}.
469func (vl NullValue) GetObject() interface{} {
470	return nil
471}
472
473func (vl NullValue) String() string {
474	return ""
475}
476
477///////////////////////////////////////////////////////////////////////////////
478
479// InfinityValue is an empty value.
480type InfinityValue struct{}
481
482var infinityValue InfinityValue
483
484// NewInfinityValue generates a InfinityValue instance.
485func NewInfinityValue() InfinityValue {
486	return infinityValue
487}
488
489func (vl InfinityValue) EstimateSize() (int, error) {
490	return 0, nil
491}
492
493func (vl InfinityValue) write(cmd BufferEx) (int, error) {
494	return 0, nil
495}
496
497func (vl InfinityValue) pack(cmd BufferEx) (int, error) {
498	return packInfinity(cmd)
499}
500
501// GetType returns wire protocol value type.
502func (vl InfinityValue) GetType() int {
503	panic("Invalid particle type: INF")
504}
505
506// GetObject returns original value as an interface{}.
507func (vl InfinityValue) GetObject() interface{} {
508	return nil
509}
510
511func (vl InfinityValue) String() string {
512	return "INF"
513}
514
515///////////////////////////////////////////////////////////////////////////////
516
517// InfinityValue is an empty value.
518type WildCardValue struct{}
519
520var wildCardValue WildCardValue
521
522// NewWildCardValue generates a WildCardValue instance.
523func NewWildCardValue() WildCardValue {
524	return wildCardValue
525}
526
527func (vl WildCardValue) EstimateSize() (int, error) {
528	return 0, nil
529}
530
531func (vl WildCardValue) write(cmd BufferEx) (int, error) {
532	return 0, nil
533}
534
535func (vl WildCardValue) pack(cmd BufferEx) (int, error) {
536	return packWildCard(cmd)
537}
538
539// GetType returns wire protocol value type.
540func (vl WildCardValue) GetType() int {
541	panic("Invalid particle type: WildCard")
542}
543
544// GetObject returns original value as an interface{}.
545func (vl WildCardValue) GetObject() interface{} {
546	return nil
547}
548
549func (vl WildCardValue) String() string {
550	return "*"
551}
552
553///////////////////////////////////////////////////////////////////////////////
554
555// BytesValue encapsulates an array of bytes.
556type BytesValue []byte
557
558// NewBytesValue generates a ByteValue instance.
559func NewBytesValue(bytes []byte) BytesValue {
560	return BytesValue(bytes)
561}
562
563// NewBlobValue accepts an AerospikeBlob interface, and automatically
564// converts it to a BytesValue.
565// If Encode returns an err, it will panic.
566func NewBlobValue(object AerospikeBlob) BytesValue {
567	buf, err := object.EncodeBlob()
568	if err != nil {
569		panic(err)
570	}
571
572	return NewBytesValue(buf)
573}
574
575func (vl BytesValue) EstimateSize() (int, error) {
576	return len(vl), nil
577}
578
579func (vl BytesValue) write(cmd BufferEx) (int, error) {
580	return cmd.Write(vl)
581}
582
583func (vl BytesValue) pack(cmd BufferEx) (int, error) {
584	return packBytes(cmd, vl)
585}
586
587// GetType returns wire protocol value type.
588func (vl BytesValue) GetType() int {
589	return ParticleType.BLOB
590}
591
592// GetObject returns original value as an interface{}.
593func (vl BytesValue) GetObject() interface{} {
594	return []byte(vl)
595}
596
597// String implements Stringer interface.
598func (vl BytesValue) String() string {
599	return Buffer.BytesToHexString(vl)
600}
601
602///////////////////////////////////////////////////////////////////////////////
603
604// StringValue encapsulates a string value.
605type StringValue string
606
607// NewStringValue generates a StringValue instance.
608func NewStringValue(value string) StringValue {
609	return StringValue(value)
610}
611
612func (vl StringValue) EstimateSize() (int, error) {
613	return len(vl), nil
614}
615
616func (vl StringValue) write(cmd BufferEx) (int, error) {
617	return cmd.WriteString(string(vl))
618}
619
620func (vl StringValue) pack(cmd BufferEx) (int, error) {
621	return packString(cmd, string(vl))
622}
623
624// GetType returns wire protocol value type.
625func (vl StringValue) GetType() int {
626	return ParticleType.STRING
627}
628
629// GetObject returns original value as an interface{}.
630func (vl StringValue) GetObject() interface{} {
631	return string(vl)
632}
633
634// String implements Stringer interface.
635func (vl StringValue) String() string {
636	return string(vl)
637}
638
639///////////////////////////////////////////////////////////////////////////////
640
641// IntegerValue encapsulates an integer value.
642type IntegerValue int
643
644// NewIntegerValue generates an IntegerValue instance.
645func NewIntegerValue(value int) IntegerValue {
646	return IntegerValue(value)
647}
648
649func (vl IntegerValue) EstimateSize() (int, error) {
650	return 8, nil
651}
652
653func (vl IntegerValue) write(cmd BufferEx) (int, error) {
654	return cmd.WriteInt64(int64(vl))
655}
656
657func (vl IntegerValue) pack(cmd BufferEx) (int, error) {
658	return packAInt64(cmd, int64(vl))
659}
660
661// GetType returns wire protocol value type.
662func (vl IntegerValue) GetType() int {
663	return ParticleType.INTEGER
664}
665
666// GetObject returns original value as an interface{}.
667func (vl IntegerValue) GetObject() interface{} {
668	return int(vl)
669}
670
671// String implements Stringer interface.
672func (vl IntegerValue) String() string {
673	return strconv.Itoa(int(vl))
674}
675
676///////////////////////////////////////////////////////////////////////////////
677
678// LongValue encapsulates an int64 value.
679type LongValue int64
680
681// NewLongValue generates a LongValue instance.
682func NewLongValue(value int64) LongValue {
683	return LongValue(value)
684}
685
686func (vl LongValue) EstimateSize() (int, error) {
687	return 8, nil
688}
689
690func (vl LongValue) write(cmd BufferEx) (int, error) {
691	return cmd.WriteInt64(int64(vl))
692}
693
694func (vl LongValue) pack(cmd BufferEx) (int, error) {
695	return packAInt64(cmd, int64(vl))
696}
697
698// GetType returns wire protocol value type.
699func (vl LongValue) GetType() int {
700	return ParticleType.INTEGER
701}
702
703// GetObject returns original value as an interface{}.
704func (vl LongValue) GetObject() interface{} {
705	return int64(vl)
706}
707
708// String implements Stringer interface.
709func (vl LongValue) String() string {
710	return strconv.Itoa(int(vl))
711}
712
713///////////////////////////////////////////////////////////////////////////////
714
715// FloatValue encapsulates an float64 value.
716type FloatValue float64
717
718// NewFloatValue generates a FloatValue instance.
719func NewFloatValue(value float64) FloatValue {
720	return FloatValue(value)
721}
722
723func (vl FloatValue) EstimateSize() (int, error) {
724	return 8, nil
725}
726
727func (vl FloatValue) write(cmd BufferEx) (int, error) {
728	return cmd.WriteFloat64(float64(vl))
729}
730
731func (vl FloatValue) pack(cmd BufferEx) (int, error) {
732	return packFloat64(cmd, float64(vl))
733}
734
735// GetType returns wire protocol value type.
736func (vl FloatValue) GetType() int {
737	return ParticleType.FLOAT
738}
739
740// GetObject returns original value as an interface{}.
741func (vl FloatValue) GetObject() interface{} {
742	return float64(vl)
743}
744
745// String implements Stringer interface.
746func (vl FloatValue) String() string {
747	return (fmt.Sprintf("%f", vl))
748}
749
750///////////////////////////////////////////////////////////////////////////////
751
752// _BoolValue encapsulates a bool value.
753// This method is only used in bitwise CDT operations internally.
754type _BoolValue bool
755
756func (vb _BoolValue) EstimateSize() (int, error) {
757	return PackBool(nil, bool(vb))
758}
759
760func (vb _BoolValue) write(cmd BufferEx) (int, error) {
761	panic("Unreachable")
762}
763
764func (vb _BoolValue) pack(cmd BufferEx) (int, error) {
765	return PackBool(cmd, bool(vb))
766}
767
768// GetType returns wire protocol value type.
769func (vb _BoolValue) GetType() int {
770	panic("Unreachable")
771}
772
773// GetObject returns original value as an interface{}.
774func (vb _BoolValue) GetObject() interface{} {
775	return bool(vb)
776}
777
778// String implements Stringer interface.
779func (vb _BoolValue) String() string {
780	return (fmt.Sprintf("%v", bool(vb)))
781}
782
783///////////////////////////////////////////////////////////////////////////////
784
785// ValueArray encapsulates an array of Value.
786// Supported by Aerospike 3+ servers only.
787type ValueArray []Value
788
789// NewValueArray generates a ValueArray instance.
790func NewValueArray(array []Value) *ValueArray {
791	// return &ValueArray{*NewListerValue(valueList(array))}
792	res := ValueArray(array)
793	return &res
794}
795
796func (va ValueArray) EstimateSize() (int, error) {
797	return packValueArray(nil, va)
798}
799
800func (va ValueArray) write(cmd BufferEx) (int, error) {
801	return packValueArray(cmd, va)
802}
803
804func (va ValueArray) pack(cmd BufferEx) (int, error) {
805	return packValueArray(cmd, []Value(va))
806}
807
808// GetType returns wire protocol value type.
809func (va ValueArray) GetType() int {
810	return ParticleType.LIST
811}
812
813// GetObject returns original value as an interface{}.
814func (va ValueArray) GetObject() interface{} {
815	return []Value(va)
816}
817
818// String implements Stringer interface.
819func (va ValueArray) String() string {
820	return fmt.Sprintf("%v", []Value(va))
821}
822
823///////////////////////////////////////////////////////////////////////////////
824
825// ListValue encapsulates any arbitrary array.
826// Supported by Aerospike 3+ servers only.
827type ListValue []interface{}
828
829// NewListValue generates a ListValue instance.
830func NewListValue(list []interface{}) ListValue {
831	return ListValue(list)
832}
833
834func (vl ListValue) EstimateSize() (int, error) {
835	return packIfcList(nil, vl)
836}
837
838func (vl ListValue) write(cmd BufferEx) (int, error) {
839	return packIfcList(cmd, vl)
840}
841
842func (vl ListValue) pack(cmd BufferEx) (int, error) {
843	return packIfcList(cmd, []interface{}(vl))
844}
845
846// GetType returns wire protocol value type.
847func (vl ListValue) GetType() int {
848	return ParticleType.LIST
849}
850
851// GetObject returns original value as an interface{}.
852func (vl ListValue) GetObject() interface{} {
853	return []interface{}(vl)
854}
855
856// String implements Stringer interface.
857func (vl ListValue) String() string {
858	return fmt.Sprintf("%v", []interface{}(vl))
859}
860
861///////////////////////////////////////////////////////////////////////////////
862
863// ListerValue encapsulates any arbitrary array.
864// Supported by Aerospike 3+ servers only.
865type ListerValue struct {
866	list ListIter
867}
868
869// NewListValue generates a ListValue instance.
870func NewListerValue(list ListIter) *ListerValue {
871	res := &ListerValue{
872		list: list,
873	}
874
875	return res
876}
877
878func (vl *ListerValue) EstimateSize() (int, error) {
879	return packList(nil, vl.list)
880}
881
882func (vl *ListerValue) write(cmd BufferEx) (int, error) {
883	return packList(cmd, vl.list)
884}
885
886func (vl *ListerValue) pack(cmd BufferEx) (int, error) {
887	return packList(cmd, vl.list)
888}
889
890// GetType returns wire protocol value type.
891func (vl *ListerValue) GetType() int {
892	return ParticleType.LIST
893}
894
895// GetObject returns original value as an interface{}.
896func (vl *ListerValue) GetObject() interface{} {
897	return vl.list
898}
899
900// String implements Stringer interface.
901func (vl *ListerValue) String() string {
902	return fmt.Sprintf("%v", vl.list)
903}
904
905///////////////////////////////////////////////////////////////////////////////
906
907// MapValue encapsulates an arbitrary map.
908// Supported by Aerospike 3+ servers only.
909type MapValue map[interface{}]interface{}
910
911// NewMapValue generates a MapValue instance.
912func NewMapValue(vmap map[interface{}]interface{}) MapValue {
913	return MapValue(vmap)
914}
915
916func (vl MapValue) EstimateSize() (int, error) {
917	return packIfcMap(nil, vl)
918}
919
920func (vl MapValue) write(cmd BufferEx) (int, error) {
921	return packIfcMap(cmd, vl)
922}
923
924func (vl MapValue) pack(cmd BufferEx) (int, error) {
925	return packIfcMap(cmd, vl)
926}
927
928// GetType returns wire protocol value type.
929func (vl MapValue) GetType() int {
930	return ParticleType.MAP
931}
932
933// GetObject returns original value as an interface{}.
934func (vl MapValue) GetObject() interface{} {
935	return map[interface{}]interface{}(vl)
936}
937
938func (vl MapValue) String() string {
939	return fmt.Sprintf("%v", map[interface{}]interface{}(vl))
940}
941
942///////////////////////////////////////////////////////////////////////////////
943
944// JsonValue encapsulates a Json map.
945// Supported by Aerospike 3+ servers only.
946type JsonValue map[string]interface{}
947
948// NewMapValue generates a JsonValue instance.
949func NewJsonValue(vmap map[string]interface{}) JsonValue {
950	return JsonValue(vmap)
951}
952
953func (vl JsonValue) EstimateSize() (int, error) {
954	return packJsonMap(nil, vl)
955}
956
957func (vl JsonValue) write(cmd BufferEx) (int, error) {
958	return packJsonMap(cmd, vl)
959}
960
961func (vl JsonValue) pack(cmd BufferEx) (int, error) {
962	return packJsonMap(cmd, vl)
963}
964
965// GetType returns wire protocol value type.
966func (vl JsonValue) GetType() int {
967	return ParticleType.MAP
968}
969
970// GetObject returns original value as an interface{}.
971func (vl JsonValue) GetObject() interface{} {
972	return map[string]interface{}(vl)
973}
974
975func (vl JsonValue) String() string {
976	return fmt.Sprintf("%v", map[string]interface{}(vl))
977}
978
979///////////////////////////////////////////////////////////////////////////////
980
981// MapperValue encapsulates an arbitrary map which implements a MapIter interface.
982// Supported by Aerospike 3+ servers only.
983type MapperValue struct {
984	vmap MapIter
985}
986
987// NewMapValue generates a MapperValue instance.
988func NewMapperValue(vmap MapIter) *MapperValue {
989	res := &MapperValue{
990		vmap: vmap,
991	}
992
993	return res
994}
995
996func (vl *MapperValue) EstimateSize() (int, error) {
997	return packMap(nil, vl.vmap)
998}
999
1000func (vl *MapperValue) write(cmd BufferEx) (int, error) {
1001	return packMap(cmd, vl.vmap)
1002}
1003
1004func (vl *MapperValue) pack(cmd BufferEx) (int, error) {
1005	return packMap(cmd, vl.vmap)
1006}
1007
1008// GetType returns wire protocol value type.
1009func (vl *MapperValue) GetType() int {
1010	return ParticleType.MAP
1011}
1012
1013// GetObject returns original value as an interface{}.
1014func (vl *MapperValue) GetObject() interface{} {
1015	return vl.vmap
1016}
1017
1018func (vl *MapperValue) String() string {
1019	return fmt.Sprintf("%v", vl.vmap)
1020}
1021
1022///////////////////////////////////////////////////////////////////////////////
1023
1024// GeoJSONValue encapsulates a 2D Geo point.
1025// Supported by Aerospike 3.6.1 servers and later only.
1026type GeoJSONValue string
1027
1028// NewMapValue generates a GeoJSONValue instance.
1029func NewGeoJSONValue(value string) GeoJSONValue {
1030	res := GeoJSONValue(value)
1031	return res
1032}
1033
1034func (vl GeoJSONValue) EstimateSize() (int, error) {
1035	// flags + ncells + jsonstr
1036	return 1 + 2 + len(string(vl)), nil
1037}
1038
1039func (vl GeoJSONValue) write(cmd BufferEx) (int, error) {
1040	cmd.WriteByte(0) // flags
1041	cmd.WriteByte(0) // flags
1042	cmd.WriteByte(0) // flags
1043
1044	return cmd.WriteString(string(vl))
1045}
1046
1047func (vl GeoJSONValue) pack(cmd BufferEx) (int, error) {
1048	return packGeoJson(cmd, string(vl))
1049}
1050
1051// GetType returns wire protocol value type.
1052func (vl GeoJSONValue) GetType() int {
1053	return ParticleType.GEOJSON
1054}
1055
1056// GetObject returns original value as an interface{}.
1057func (vl GeoJSONValue) GetObject() interface{} {
1058	return string(vl)
1059}
1060
1061// String implements Stringer interface.
1062func (vl GeoJSONValue) String() string {
1063	return string(vl)
1064}
1065
1066///////////////////////////////////////////////////////////////////////////////
1067
1068// HLLValue encapsulates a HyperLogLog value.
1069type HLLValue []byte
1070
1071// NewHLLValue generates a ByteValue instance.
1072func NewHLLValue(bytes []byte) HLLValue {
1073	return HLLValue(bytes)
1074}
1075
1076func (vl HLLValue) EstimateSize() (int, error) {
1077	return len(vl), nil
1078}
1079
1080func (vl HLLValue) write(cmd BufferEx) (int, error) {
1081	return cmd.Write(vl)
1082}
1083
1084func (vl HLLValue) pack(cmd BufferEx) (int, error) {
1085	return packBytes(cmd, vl)
1086}
1087
1088// GetType returns wire protocol value type.
1089func (vl HLLValue) GetType() int {
1090	return ParticleType.HLL
1091}
1092
1093// GetObject returns original value as an interface{}.
1094func (vl HLLValue) GetObject() interface{} {
1095	return []byte(vl)
1096}
1097
1098// String implements Stringer interface.
1099func (vl HLLValue) String() string {
1100	return Buffer.BytesToHexString([]byte(vl))
1101}
1102
1103//////////////////////////////////////////////////////////////////////////////
1104
1105func bytesToParticle(ptype int, buf []byte, offset int, length int) (interface{}, error) {
1106
1107	switch ptype {
1108	case ParticleType.INTEGER:
1109		// return `int` for 64bit platforms for compatibility reasons
1110		if Buffer.Arch64Bits {
1111			return int(Buffer.VarBytesToInt64(buf, offset, length)), nil
1112		}
1113		return Buffer.VarBytesToInt64(buf, offset, length), nil
1114
1115	case ParticleType.STRING:
1116		return string(buf[offset : offset+length]), nil
1117
1118	case ParticleType.FLOAT:
1119		return Buffer.BytesToFloat64(buf, offset), nil
1120
1121	case ParticleType.MAP:
1122		return newUnpacker(buf, offset, length).UnpackMap()
1123
1124	case ParticleType.LIST:
1125		return newUnpacker(buf, offset, length).UnpackList()
1126
1127	case ParticleType.GEOJSON:
1128		ncells := int(Buffer.BytesToInt16(buf, offset+1))
1129		headerSize := 1 + 2 + (ncells * 8)
1130		return string(buf[offset+headerSize : offset+length]), nil
1131
1132	case ParticleType.HLL:
1133		newObj := make([]byte, length)
1134		copy(newObj, buf[offset:offset+length])
1135		return newObj, nil
1136
1137	case ParticleType.BLOB:
1138		newObj := make([]byte, length)
1139		copy(newObj, buf[offset:offset+length])
1140		return newObj, nil
1141
1142	case ParticleType.LDT:
1143		return newUnpacker(buf, offset, length).unpackObjects()
1144
1145	}
1146	return nil, nil
1147}
1148
1149func bytesToKeyValue(pType int, buf []byte, offset int, len int) (Value, error) {
1150
1151	switch pType {
1152	case ParticleType.STRING:
1153		return NewStringValue(string(buf[offset : offset+len])), nil
1154
1155	case ParticleType.INTEGER:
1156		return NewLongValue(Buffer.VarBytesToInt64(buf, offset, len)), nil
1157
1158	case ParticleType.FLOAT:
1159		return NewFloatValue(Buffer.BytesToFloat64(buf, offset)), nil
1160
1161	case ParticleType.BLOB:
1162		bytes := make([]byte, len, len)
1163		copy(bytes, buf[offset:offset+len])
1164		return NewBytesValue(bytes), nil
1165
1166	default:
1167		return nil, NewAerospikeError(PARSE_ERROR, fmt.Sprintf("ParticleType %d not recognized. Please file a github issue.", pType))
1168	}
1169}
1170
1171func unwrapValue(v interface{}) interface{} {
1172	if v == nil {
1173		return nil
1174	}
1175
1176	if uv, ok := v.(Value); ok {
1177		return unwrapValue(uv.GetObject())
1178	} else if uv, ok := v.([]Value); ok {
1179		a := make([]interface{}, len(uv))
1180		for i := range uv {
1181			a[i] = unwrapValue(uv[i].GetObject())
1182		}
1183		return a
1184	}
1185
1186	return v
1187}
1188