OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // 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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 // way that it does for WriteKey, but only has an effect if `p` contains a | 215 // way that it does for WriteKey, but only has an effect if `p` contains a |
216 // Key as its Value. | 216 // Key as its Value. |
217 func WriteProperty(buf Buffer, context KeyContext, p ds.Property) (err error) { | 217 func WriteProperty(buf Buffer, context KeyContext, p ds.Property) (err error) { |
218 defer recoverTo(&err) | 218 defer recoverTo(&err) |
219 typb := byte(p.Type()) | 219 typb := byte(p.Type()) |
220 if p.IndexSetting() != ds.NoIndex { | 220 if p.IndexSetting() != ds.NoIndex { |
221 typb |= 0x80 | 221 typb |= 0x80 |
222 } | 222 } |
223 panicIf(buf.WriteByte(typb)) | 223 panicIf(buf.WriteByte(typb)) |
224 switch p.Type() { | 224 switch p.Type() { |
225 » case ds.PTNull, ds.PTBoolTrue, ds.PTBoolFalse: | 225 » case ds.PTNull: |
| 226 » case ds.PTBool: |
| 227 » » b := p.Value().(bool) |
| 228 » » if b { |
| 229 » » » err = buf.WriteByte(1) |
| 230 » » } else { |
| 231 » » » err = buf.WriteByte(0) |
| 232 » » } |
226 case ds.PTInt: | 233 case ds.PTInt: |
227 _, err = cmpbin.WriteInt(buf, p.Value().(int64)) | 234 _, err = cmpbin.WriteInt(buf, p.Value().(int64)) |
228 case ds.PTFloat: | 235 case ds.PTFloat: |
229 _, err = cmpbin.WriteFloat64(buf, p.Value().(float64)) | 236 _, err = cmpbin.WriteFloat64(buf, p.Value().(float64)) |
230 case ds.PTString: | 237 case ds.PTString: |
231 _, err = cmpbin.WriteString(buf, p.Value().(string)) | 238 _, err = cmpbin.WriteString(buf, p.Value().(string)) |
232 case ds.PTBytes: | 239 case ds.PTBytes: |
233 » » if p.IndexSetting() == ds.NoIndex { | 240 » » _, err = cmpbin.WriteBytes(buf, p.Value().([]byte)) |
234 » » » _, err = cmpbin.WriteBytes(buf, p.Value().([]byte)) | |
235 » » } else { | |
236 » » » _, err = cmpbin.WriteBytes(buf, p.Value().(ds.ByteString
)) | |
237 » » } | |
238 case ds.PTTime: | 241 case ds.PTTime: |
239 err = WriteTime(buf, p.Value().(time.Time)) | 242 err = WriteTime(buf, p.Value().(time.Time)) |
240 case ds.PTGeoPoint: | 243 case ds.PTGeoPoint: |
241 err = WriteGeoPoint(buf, p.Value().(ds.GeoPoint)) | 244 err = WriteGeoPoint(buf, p.Value().(ds.GeoPoint)) |
242 case ds.PTKey: | 245 case ds.PTKey: |
243 err = WriteKey(buf, context, p.Value().(ds.Key)) | 246 err = WriteKey(buf, context, p.Value().(ds.Key)) |
244 case ds.PTBlobKey: | 247 case ds.PTBlobKey: |
245 _, err = cmpbin.WriteString(buf, string(p.Value().(blobstore.Key
))) | 248 _, err = cmpbin.WriteString(buf, string(p.Value().(blobstore.Key
))) |
246 } | 249 } |
247 return | 250 return |
248 } | 251 } |
249 | 252 |
250 // ReadProperty reads a Property from the buffer. `context`, `appid`, and | 253 // ReadProperty reads a Property from the buffer. `context`, `appid`, and |
251 // `namespace` behave the same way they do for ReadKey, but only have an | 254 // `namespace` behave the same way they do for ReadKey, but only have an |
252 // effect if the decoded property has a Key value. | 255 // effect if the decoded property has a Key value. |
253 func ReadProperty(buf Buffer, context KeyContext, appid, namespace string) (p ds
.Property, err error) { | 256 func ReadProperty(buf Buffer, context KeyContext, appid, namespace string) (p ds
.Property, err error) { |
254 val := interface{}(nil) | 257 val := interface{}(nil) |
255 » typb, err := buf.ReadByte() | 258 » b, err := buf.ReadByte() |
256 if err != nil { | 259 if err != nil { |
257 return | 260 return |
258 } | 261 } |
259 is := ds.ShouldIndex | 262 is := ds.ShouldIndex |
260 » if (typb & 0x80) == 0 { | 263 » if (b & 0x80) == 0 { |
261 is = ds.NoIndex | 264 is = ds.NoIndex |
262 } | 265 } |
263 » switch ds.PropertyType(typb & 0x7f) { | 266 » switch ds.PropertyType(b & 0x7f) { |
264 case ds.PTNull: | 267 case ds.PTNull: |
265 » case ds.PTBoolTrue: | 268 » case ds.PTBool: |
266 » » val = true | 269 » » b, err = buf.ReadByte() |
267 » case ds.PTBoolFalse: | 270 » » if b == 0 { |
268 » » val = false | 271 » » » val = false |
| 272 » » } else { |
| 273 » » » val = true |
| 274 » » } |
269 case ds.PTInt: | 275 case ds.PTInt: |
270 val, _, err = cmpbin.ReadInt(buf) | 276 val, _, err = cmpbin.ReadInt(buf) |
271 case ds.PTFloat: | 277 case ds.PTFloat: |
272 val, _, err = cmpbin.ReadFloat64(buf) | 278 val, _, err = cmpbin.ReadFloat64(buf) |
273 case ds.PTString: | 279 case ds.PTString: |
274 val, _, err = cmpbin.ReadString(buf) | 280 val, _, err = cmpbin.ReadString(buf) |
275 case ds.PTBytes: | 281 case ds.PTBytes: |
276 » » b := []byte(nil) | 282 » » val, _, err = cmpbin.ReadBytes(buf) |
277 » » if b, _, err = cmpbin.ReadBytes(buf); err != nil { | |
278 » » » break | |
279 » » } | |
280 » » if is == ds.NoIndex { | |
281 » » » val = b | |
282 » » } else { | |
283 » » » val = ds.ByteString(b) | |
284 » » } | |
285 case ds.PTTime: | 283 case ds.PTTime: |
286 val, err = ReadTime(buf) | 284 val, err = ReadTime(buf) |
287 case ds.PTGeoPoint: | 285 case ds.PTGeoPoint: |
288 val, err = ReadGeoPoint(buf) | 286 val, err = ReadGeoPoint(buf) |
289 case ds.PTKey: | 287 case ds.PTKey: |
290 val, err = ReadKey(buf, context, appid, namespace) | 288 val, err = ReadKey(buf, context, appid, namespace) |
291 case ds.PTBlobKey: | 289 case ds.PTBlobKey: |
292 s := "" | 290 s := "" |
293 if s, _, err = cmpbin.ReadString(buf); err != nil { | 291 if s, _, err = cmpbin.ReadString(buf); err != nil { |
294 break | 292 break |
295 } | 293 } |
296 val = blobstore.Key(s) | 294 val = blobstore.Key(s) |
297 default: | 295 default: |
298 » » err = fmt.Errorf("read: unknown type! %v", typb) | 296 » » err = fmt.Errorf("read: unknown type! %v", b) |
299 } | 297 } |
300 if err == nil { | 298 if err == nil { |
301 err = p.SetValue(val, is) | 299 err = p.SetValue(val, is) |
302 } | 300 } |
303 return | 301 return |
304 } | 302 } |
305 | 303 |
306 // WritePropertyMap writes an entire PropertyMap to the buffer. `context` behave
s the same | 304 // WritePropertyMap writes an entire PropertyMap to the buffer. `context` behave
s the same |
307 // way that it does for WriteKey. If WritePropertyMapDeterministic is true, then | 305 // way that it does for WriteKey. If WritePropertyMapDeterministic is true, then |
308 // the rows will be sorted by property name before they're serialized to buf | 306 // the rows will be sorted by property name before they're serialized to buf |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 } | 546 } |
549 } | 547 } |
550 | 548 |
551 func recoverTo(err *error) { | 549 func recoverTo(err *error) { |
552 if r := recover(); r != nil { | 550 if r := recover(); r != nil { |
553 if rerr := r.(parseError); rerr != nil { | 551 if rerr := r.(parseError); rerr != nil { |
554 *err = error(rerr) | 552 *err = error(rerr) |
555 } | 553 } |
556 } | 554 } |
557 } | 555 } |
OLD | NEW |