Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(464)

Side by Side Diff: service/datastore/serialize/serialize.go

Issue 2302743002: Interface update, per-method Contexts. (Closed)
Patch Set: Lightning talk licenses. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « service/datastore/raw_interface.go ('k') | service/datastore/serialize/serialize_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package serialize 5 package serialize
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "errors" 9 "errors"
10 "fmt" 10 "fmt"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 panicIf(buf.WriteByte(1)) 68 panicIf(buf.WriteByte(1))
69 panicIf(WriteKeyTok(buf, tok)) 69 panicIf(WriteKeyTok(buf, tok))
70 } 70 }
71 return buf.WriteByte(0) 71 return buf.WriteByte(0)
72 } 72 }
73 73
74 // ReadKey deserializes a key from the buffer. The value of context must match 74 // ReadKey deserializes a key from the buffer. The value of context must match
75 // the value of context that was passed to WriteKey when the key was encoded. 75 // the value of context that was passed to WriteKey when the key was encoded.
76 // If context == WithoutContext, then the appid and namespace parameters are 76 // If context == WithoutContext, then the appid and namespace parameters are
77 // used in the decoded Key. Otherwise they're ignored. 77 // used in the decoded Key. Otherwise they're ignored.
78 func ReadKey(buf Buffer, context KeyContext, appid, namespace string) (ret *ds.K ey, err error) { 78 func ReadKey(buf Buffer, context KeyContext, inKC ds.KeyContext) (ret *ds.Key, e rr error) {
79 defer recoverTo(&err) 79 defer recoverTo(&err)
80 actualCtx, e := buf.ReadByte() 80 actualCtx, e := buf.ReadByte()
81 panicIf(e) 81 panicIf(e)
82 82
83 » actualAid, actualNS := "", "" 83 » var kc ds.KeyContext
84 if actualCtx == 1 { 84 if actualCtx == 1 {
85 » » actualAid, _, e = cmpbin.ReadString(buf) 85 » » kc.AppID, _, e = cmpbin.ReadString(buf)
86 panicIf(e) 86 panicIf(e)
87 » » actualNS, _, e = cmpbin.ReadString(buf) 87 » » kc.Namespace, _, e = cmpbin.ReadString(buf)
88 panicIf(e) 88 panicIf(e)
89 } else if actualCtx != 0 { 89 } else if actualCtx != 0 {
90 err = fmt.Errorf("helper: expected actualCtx to be 0 or 1, got % d", actualCtx) 90 err = fmt.Errorf("helper: expected actualCtx to be 0 or 1, got % d", actualCtx)
91 return 91 return
92 } 92 }
93 93
94 if context == WithoutContext { 94 if context == WithoutContext {
95 // overrwrite with the supplied ones 95 // overrwrite with the supplied ones
96 » » actualAid = appid 96 » » kc = inKC
97 » » actualNS = namespace
98 } 97 }
99 98
100 toks := []ds.KeyTok{} 99 toks := []ds.KeyTok{}
101 for { 100 for {
102 ctrlByte, e := buf.ReadByte() 101 ctrlByte, e := buf.ReadByte()
103 panicIf(e) 102 panicIf(e)
104 if ctrlByte == 0 { 103 if ctrlByte == 0 {
105 break 104 break
106 } 105 }
107 if len(toks)+1 > ReadKeyNumToksReasonableLimit { 106 if len(toks)+1 > ReadKeyNumToksReasonableLimit {
108 err = fmt.Errorf( 107 err = fmt.Errorf(
109 "helper: tried to decode huge key with > %d toke ns", 108 "helper: tried to decode huge key with > %d toke ns",
110 ReadKeyNumToksReasonableLimit) 109 ReadKeyNumToksReasonableLimit)
111 return 110 return
112 } 111 }
113 112
114 tok, e := ReadKeyTok(buf) 113 tok, e := ReadKeyTok(buf)
115 panicIf(e) 114 panicIf(e)
116 115
117 toks = append(toks, tok) 116 toks = append(toks, tok)
118 } 117 }
119 118
120 » return ds.NewKeyToks(actualAid, actualNS, toks), nil 119 » return kc.NewKeyToks(toks), nil
121 } 120 }
122 121
123 // WriteKeyTok writes a KeyTok to the buffer. You usually want WriteKey 122 // WriteKeyTok writes a KeyTok to the buffer. You usually want WriteKey
124 // instead of this. 123 // instead of this.
125 func WriteKeyTok(buf Buffer, tok ds.KeyTok) (err error) { 124 func WriteKeyTok(buf Buffer, tok ds.KeyTok) (err error) {
126 // tok.kind ++ typ ++ [tok.stringID || tok.intID] 125 // tok.kind ++ typ ++ [tok.stringID || tok.intID]
127 defer recoverTo(&err) 126 defer recoverTo(&err)
128 _, e := cmpbin.WriteString(buf, tok.Kind) 127 _, e := cmpbin.WriteString(buf, tok.Kind)
129 panicIf(e) 128 panicIf(e)
130 if tok.StringID != "" { 129 if tok.StringID != "" {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 err = WriteGeoPoint(buf, t) 269 err = WriteGeoPoint(buf, t)
271 case *ds.Key: 270 case *ds.Key:
272 err = WriteKey(buf, context, t) 271 err = WriteKey(buf, context, t)
273 272
274 default: 273 default:
275 err = fmt.Errorf("unsupported type: %T", t) 274 err = fmt.Errorf("unsupported type: %T", t)
276 } 275 }
277 return 276 return
278 } 277 }
279 278
280 // ReadProperty reads a Property from the buffer. `context`, `appid`, and 279 // ReadProperty reads a Property from the buffer. `context` and `kc` behave the
281 // `namespace` behave the same way they do for ReadKey, but only have an 280 // same way they do for ReadKey, but only have an effect if the decoded property
282 // effect if the decoded property has a Key value. 281 // has a Key value.
283 func ReadProperty(buf Buffer, context KeyContext, appid, namespace string) (p ds .Property, err error) { 282 func ReadProperty(buf Buffer, context KeyContext, kc ds.KeyContext) (p ds.Proper ty, err error) {
284 val := interface{}(nil) 283 val := interface{}(nil)
285 b, err := buf.ReadByte() 284 b, err := buf.ReadByte()
286 if err != nil { 285 if err != nil {
287 return 286 return
288 } 287 }
289 is := ds.ShouldIndex 288 is := ds.ShouldIndex
290 if (b & 0x80) == 0 { 289 if (b & 0x80) == 0 {
291 is = ds.NoIndex 290 is = ds.NoIndex
292 } 291 }
293 switch ds.PropertyType(b & 0x7f) { 292 switch ds.PropertyType(b & 0x7f) {
294 case ds.PTNull: 293 case ds.PTNull:
295 case ds.PTBool: 294 case ds.PTBool:
296 b, err = buf.ReadByte() 295 b, err = buf.ReadByte()
297 val = (b != 0) 296 val = (b != 0)
298 case ds.PTInt: 297 case ds.PTInt:
299 val, _, err = cmpbin.ReadInt(buf) 298 val, _, err = cmpbin.ReadInt(buf)
300 case ds.PTFloat: 299 case ds.PTFloat:
301 val, _, err = cmpbin.ReadFloat64(buf) 300 val, _, err = cmpbin.ReadFloat64(buf)
302 case ds.PTString: 301 case ds.PTString:
303 val, _, err = cmpbin.ReadString(buf) 302 val, _, err = cmpbin.ReadString(buf)
304 case ds.PTBytes: 303 case ds.PTBytes:
305 val, _, err = cmpbin.ReadBytes(buf) 304 val, _, err = cmpbin.ReadBytes(buf)
306 case ds.PTTime: 305 case ds.PTTime:
307 val, err = ReadTime(buf) 306 val, err = ReadTime(buf)
308 case ds.PTGeoPoint: 307 case ds.PTGeoPoint:
309 val, err = ReadGeoPoint(buf) 308 val, err = ReadGeoPoint(buf)
310 case ds.PTKey: 309 case ds.PTKey:
311 » » val, err = ReadKey(buf, context, appid, namespace) 310 » » val, err = ReadKey(buf, context, kc)
312 case ds.PTBlobKey: 311 case ds.PTBlobKey:
313 s := "" 312 s := ""
314 if s, _, err = cmpbin.ReadString(buf); err != nil { 313 if s, _, err = cmpbin.ReadString(buf); err != nil {
315 break 314 break
316 } 315 }
317 val = blobstore.Key(s) 316 val = blobstore.Key(s)
318 default: 317 default:
319 err = fmt.Errorf("read: unknown type! %v", b) 318 err = fmt.Errorf("read: unknown type! %v", b)
320 } 319 }
321 if err == nil { 320 if err == nil {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 panicIf(e) 368 panicIf(e)
370 for _, r := range rows { 369 for _, r := range rows {
371 _, e := buf.WriteString(r) 370 _, e := buf.WriteString(r)
372 panicIf(e) 371 panicIf(e)
373 } 372 }
374 return 373 return
375 } 374 }
376 375
377 // ReadPropertyMap reads a PropertyMap from the buffer. `context` and 376 // ReadPropertyMap reads a PropertyMap from the buffer. `context` and
378 // friends behave the same way that they do for ReadKey. 377 // friends behave the same way that they do for ReadKey.
379 func ReadPropertyMap(buf Buffer, context KeyContext, appid, namespace string) (p m ds.PropertyMap, err error) { 378 func ReadPropertyMap(buf Buffer, context KeyContext, kc ds.KeyContext) (pm ds.Pr opertyMap, err error) {
380 defer recoverTo(&err) 379 defer recoverTo(&err)
381 380
382 numRows := uint64(0) 381 numRows := uint64(0)
383 numRows, _, e := cmpbin.ReadUint(buf) 382 numRows, _, e := cmpbin.ReadUint(buf)
384 panicIf(e) 383 panicIf(e)
385 if numRows > ReadPropertyMapReasonableLimit { 384 if numRows > ReadPropertyMapReasonableLimit {
386 err = fmt.Errorf("helper: tried to decode map with huge number o f rows %d", numRows) 385 err = fmt.Errorf("helper: tried to decode map with huge number o f rows %d", numRows)
387 return 386 return
388 } 387 }
389 388
390 pm = make(ds.PropertyMap, numRows) 389 pm = make(ds.PropertyMap, numRows)
391 390
392 name, prop := "", ds.Property{} 391 name, prop := "", ds.Property{}
393 for i := uint64(0); i < numRows; i++ { 392 for i := uint64(0); i < numRows; i++ {
394 name, _, e = cmpbin.ReadString(buf) 393 name, _, e = cmpbin.ReadString(buf)
395 panicIf(e) 394 panicIf(e)
396 395
397 numProps, _, e := cmpbin.ReadInt(buf) 396 numProps, _, e := cmpbin.ReadInt(buf)
398 panicIf(e) 397 panicIf(e)
399 switch { 398 switch {
400 case numProps < 0: 399 case numProps < 0:
401 // Single property. 400 // Single property.
402 » » » prop, err = ReadProperty(buf, context, appid, namespace) 401 » » » prop, err = ReadProperty(buf, context, kc)
403 panicIf(err) 402 panicIf(err)
404 pm[name] = prop 403 pm[name] = prop
405 404
406 case uint64(numProps) > ReadPropertyMapReasonableLimit: 405 case uint64(numProps) > ReadPropertyMapReasonableLimit:
407 err = fmt.Errorf("helper: tried to decode map with huge number of properties %d", numProps) 406 err = fmt.Errorf("helper: tried to decode map with huge number of properties %d", numProps)
408 return 407 return
409 408
410 default: 409 default:
411 props := make(ds.PropertySlice, 0, numProps) 410 props := make(ds.PropertySlice, 0, numProps)
412 for j := int64(0); j < numProps; j++ { 411 for j := int64(0); j < numProps; j++ {
413 » » » » prop, err = ReadProperty(buf, context, appid, na mespace) 412 » » » » prop, err = ReadProperty(buf, context, kc)
414 panicIf(err) 413 panicIf(err)
415 props = append(props, prop) 414 props = append(props, prop)
416 } 415 }
417 pm[name] = props 416 pm[name] = props
418 } 417 }
419 } 418 }
420 return 419 return
421 } 420 }
422 421
423 // WriteIndexColumn writes an IndexColumn to the buffer. 422 // WriteIndexColumn writes an IndexColumn to the buffer.
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 } 634 }
636 } 635 }
637 636
638 func recoverTo(err *error) { 637 func recoverTo(err *error) {
639 if r := recover(); r != nil { 638 if r := recover(); r != nil {
640 if rerr := r.(parseError); rerr != nil { 639 if rerr := r.(parseError); rerr != nil {
641 *err = error(rerr) 640 *err = error(rerr)
642 } 641 }
643 } 642 }
644 } 643 }
OLDNEW
« no previous file with comments | « service/datastore/raw_interface.go ('k') | service/datastore/serialize/serialize_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698