| 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 |