OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package memory | |
6 | |
7 import ( | |
8 "bytes" | |
9 "fmt" | |
10 "reflect" | |
11 "time" | |
12 | |
13 "appengine/datastore" | |
14 | |
15 "github.com/luci/luci-go/common/cmpbin" | |
16 ) | |
17 | |
18 type kv struct{ k, v []byte } | |
19 | |
20 func indx(kind string, orders ...string) *qIndex { | |
21 ancestor := false | |
22 if kind[len(kind)-1] == '!' { | |
23 ancestor = true | |
24 kind = kind[:len(kind)-1] | |
25 } | |
26 ret := &qIndex{kind, ancestor, nil} | |
27 for _, o := range orders { | |
28 dir := qASC | |
29 if o[0] == '-' { | |
30 dir = qDEC | |
31 o = o[1:] | |
32 } | |
33 ret.sortby = append(ret.sortby, qSortBy{o, dir}) | |
34 } | |
35 return ret | |
36 } | |
37 | |
38 func pl(props ...datastore.Property) *propertyList { | |
39 return (*propertyList)(&props) | |
40 } | |
41 | |
42 func prop(name string, val interface{}, noIndex ...bool) (ret datastore.Property
) { | |
43 ret.Name = name | |
44 ret.Value = val | |
45 if len(noIndex) > 0 { | |
46 ret.NoIndex = noIndex[0] | |
47 } | |
48 return | |
49 } | |
50 | |
51 func key(kind string, id interface{}, parent ...*datastore.Key) *datastore.Key { | |
52 stringID := "" | |
53 intID := int64(0) | |
54 switch x := id.(type) { | |
55 case string: | |
56 stringID = x | |
57 case int: | |
58 intID = int64(x) | |
59 default: | |
60 panic(fmt.Errorf("what the %T: %v", id, id)) | |
61 } | |
62 par := (*datastore.Key)(nil) | |
63 if len(parent) > 0 { | |
64 par = parent[0] | |
65 } | |
66 return newKey("ns", kind, stringID, intID, par) | |
67 } | |
68 | |
69 func mustLoadLocation(loc string) *time.Location { | |
70 if z, err := time.LoadLocation(loc); err != nil { | |
71 panic(err) | |
72 } else { | |
73 return z | |
74 } | |
75 } | |
76 | |
77 // cat is a convenience method for concatenating anything with an underlying | |
78 // byte representation into a single []byte. | |
79 func cat(bytethings ...interface{}) []byte { | |
80 buf := &bytes.Buffer{} | |
81 for _, thing := range bytethings { | |
82 switch x := thing.(type) { | |
83 case int, int64: | |
84 cmpbin.WriteInt(buf, reflect.ValueOf(x).Int()) | |
85 case uint, uint64: | |
86 cmpbin.WriteUint(buf, reflect.ValueOf(x).Uint()) | |
87 case float64: | |
88 writeFloat64(buf, x) | |
89 case byte, propValType: | |
90 buf.WriteByte(byte(reflect.ValueOf(x).Uint())) | |
91 case []byte, serializedPval: | |
92 buf.Write(reflect.ValueOf(x).Convert(byteSliceType).Inte
rface().([]byte)) | |
93 case string: | |
94 writeString(buf, x) | |
95 case time.Time: | |
96 writeTime(buf, x) | |
97 case *datastore.Key: | |
98 writeKey(buf, noNS, x) | |
99 case *qIndex: | |
100 x.WriteBinary(buf) | |
101 default: | |
102 panic(fmt.Errorf("I don't know how to deal with %T: %#v"
, thing, thing)) | |
103 } | |
104 } | |
105 ret := buf.Bytes() | |
106 if ret == nil { | |
107 ret = []byte{} | |
108 } | |
109 return ret | |
110 } | |
111 | |
112 func icat(bytethings ...interface{}) []byte { | |
113 ret := cat(bytethings...) | |
114 for i := range ret { | |
115 ret[i] ^= 0xFF | |
116 } | |
117 return ret | |
118 } | |
119 | |
120 func sat(bytethings ...interface{}) string { | |
121 return string(cat(bytethings...)) | |
122 } | |
OLD | NEW |