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 // HEAVILY adapted from github.com/golang/appengine/datastore | 5 // HEAVILY adapted from github.com/golang/appengine/datastore |
6 | 6 |
7 package datastore | 7 package datastore |
8 | 8 |
9 import ( | 9 import ( |
10 "fmt" | 10 "fmt" |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 | 163 |
164 project := PTNull | 164 project := PTNull |
165 overflow := (func(interface{}) bool)(nil) | 165 overflow := (func(interface{}) bool)(nil) |
166 set := (func(interface{}))(nil) | 166 set := (func(interface{}))(nil) |
167 | 167 |
168 switch knd { | 168 switch knd { |
169 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, re
flect.Int64: | 169 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, re
flect.Int64: |
170 project = PTInt | 170 project = PTInt |
171 overflow = func(x interface{}) bool { return v.OverflowI
nt(x.(int64)) } | 171 overflow = func(x interface{}) bool { return v.OverflowI
nt(x.(int64)) } |
172 set = func(x interface{}) { v.SetInt(x.(int64)) } | 172 set = func(x interface{}) { v.SetInt(x.(int64)) } |
| 173 case reflect.Uint8, reflect.Uint16, reflect.Uint32: |
| 174 project = PTInt |
| 175 overflow = func(x interface{}) bool { |
| 176 xi := x.(int64) |
| 177 return xi < 0 || v.OverflowUint(uint64(xi)) |
| 178 } |
| 179 set = func(x interface{}) { v.SetUint(uint64(x.(int64)))
} |
173 case reflect.Bool: | 180 case reflect.Bool: |
174 project = PTBool | 181 project = PTBool |
175 set = func(x interface{}) { v.SetBool(x.(bool)) } | 182 set = func(x interface{}) { v.SetBool(x.(bool)) } |
176 case reflect.String: | 183 case reflect.String: |
177 project = PTString | 184 project = PTString |
178 set = func(x interface{}) { v.SetString(x.(string)) } | 185 set = func(x interface{}) { v.SetString(x.(string)) } |
179 case reflect.Float32, reflect.Float64: | 186 case reflect.Float32, reflect.Float64: |
180 project = PTFloat | 187 project = PTFloat |
181 overflow = func(x interface{}) bool { return v.OverflowF
loat(x.(float64)) } | 188 overflow = func(x interface{}) bool { return v.OverflowF
loat(x.(float64)) } |
182 set = func(x interface{}) { v.SetFloat(x.(float64)) } | 189 set = func(x interface{}) { v.SetFloat(x.(float64)) } |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 st := p.c.byIndex[idx] | 384 st := p.c.byIndex[idx] |
378 if !st.canSet { | 385 if !st.canSet { |
379 return false | 386 return false |
380 } | 387 } |
381 if st.convert { | 388 if st.convert { |
382 err := p.o.Field(idx).Addr().Interface().(PropertyConverter).Fro
mProperty( | 389 err := p.o.Field(idx).Addr().Interface().(PropertyConverter).Fro
mProperty( |
383 MkPropertyNI(val)) | 390 MkPropertyNI(val)) |
384 return err == nil | 391 return err == nil |
385 } | 392 } |
386 | 393 |
387 » // setting a BoolField | 394 » val = UpconvertUnderlyingType(val) |
| 395 |
| 396 » // setting a Toggle |
388 if b, ok := val.(bool); ok { | 397 if b, ok := val.(bool); ok { |
389 if b { | 398 if b { |
390 val = On | 399 val = On |
391 } else { | 400 } else { |
392 val = Off | 401 val = Off |
393 } | 402 } |
394 } | 403 } |
395 f := p.o.Field(idx) | 404 f := p.o.Field(idx) |
396 if val == nil { | 405 if val == nil { |
397 f.Set(reflect.Zero(f.Type())) | 406 f.Set(reflect.Zero(f.Type())) |
398 } else { | 407 } else { |
399 value := reflect.ValueOf(val) | 408 value := reflect.ValueOf(val) |
400 » » f.Set(value.Convert(f.Type())) | 409 » » switch f.Kind() { |
| 410 » » case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
| 411 » » » intVal := value.Int() |
| 412 » » » if f.OverflowInt(intVal) { |
| 413 » » » » return false |
| 414 » » » } |
| 415 » » » f.SetInt(intVal) |
| 416 » » case reflect.Uint8, reflect.Uint16, reflect.Uint32: |
| 417 » » » if f.Type() != typeOfToggle { |
| 418 » » » » intVal := value.Int() |
| 419 » » » » if intVal < 0 || f.OverflowUint(uint64(intVal))
{ |
| 420 » » » » » return false |
| 421 » » » » } |
| 422 » » » » f.SetUint(uint64(intVal)) |
| 423 » » » » break |
| 424 » » » } |
| 425 » » » fallthrough |
| 426 » » default: |
| 427 » » » f.Set(value.Convert(f.Type())) |
| 428 » » } |
401 } | 429 } |
402 return true | 430 return true |
403 } | 431 } |
404 | 432 |
405 var ( | 433 var ( |
406 // The RWMutex is chosen intentionally, as the majority of access to the | 434 // The RWMutex is chosen intentionally, as the majority of access to the |
407 // structCodecs map will be in parallel and will be to read an existing
codec. | 435 // structCodecs map will be in parallel and will be to read an existing
codec. |
408 // There's no reason to serialize goroutines on every | 436 // There's no reason to serialize goroutines on every |
409 // gae.Interface.{Get,Put}{,Multi} call. | 437 // gae.Interface.{Get,Put}{,Multi} call. |
410 structCodecsMutex sync.RWMutex | 438 structCodecsMutex sync.RWMutex |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 | 645 |
618 func convertMeta(val string, t reflect.Type) (interface{}, error) { | 646 func convertMeta(val string, t reflect.Type) (interface{}, error) { |
619 switch t.Kind() { | 647 switch t.Kind() { |
620 case reflect.String: | 648 case reflect.String: |
621 return val, nil | 649 return val, nil |
622 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.In
t64: | 650 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.In
t64: |
623 if val == "" { | 651 if val == "" { |
624 return int64(0), nil | 652 return int64(0), nil |
625 } | 653 } |
626 return strconv.ParseInt(val, 10, 64) | 654 return strconv.ParseInt(val, 10, 64) |
| 655 case reflect.Uint8, reflect.Uint16, reflect.Uint32: |
| 656 if t == typeOfToggle { // special case this |
| 657 break |
| 658 } |
| 659 if val == "" { |
| 660 return int64(0), nil |
| 661 } |
| 662 ret, err := strconv.ParseUint(val, 10, 32) |
| 663 return int64(ret), err |
627 } | 664 } |
628 switch t { | 665 switch t { |
629 case typeOfKey: | 666 case typeOfKey: |
630 if val != "" { | 667 if val != "" { |
631 return nil, fmt.Errorf("key field is not allowed to have
a default: %q", val) | 668 return nil, fmt.Errorf("key field is not allowed to have
a default: %q", val) |
632 } | 669 } |
633 return nil, nil | 670 return nil, nil |
634 case typeOfToggle: | 671 case typeOfToggle: |
635 switch val { | 672 switch val { |
636 case "on", "On", "true": | 673 case "on", "On", "true": |
637 return true, nil | 674 return true, nil |
638 case "off", "Off", "false": | 675 case "off", "Off", "false": |
639 return false, nil | 676 return false, nil |
640 } | 677 } |
641 return nil, fmt.Errorf("Toggle field has bad/missing default, go
t %q", val) | 678 return nil, fmt.Errorf("Toggle field has bad/missing default, go
t %q", val) |
642 } | 679 } |
643 return nil, fmt.Errorf("helper: meta field with bad type/value %s/%q", t
, val) | 680 return nil, fmt.Errorf("helper: meta field with bad type/value %s/%q", t
, val) |
644 } | 681 } |
OLD | NEW |