in memstore/common/data_value.go [350:503]
func ValueFromString(str string, dataType DataType) (val DataValue, err error) {
val.DataType = dataType
if len(str) == 0 || str == "null" {
return
}
var b bool
var i int64
var f float64
var ui uint64
switch dataType {
case Bool:
val.IsBool = true
b, err = strconv.ParseBool(str)
if err != nil {
err = utils.StackError(err, "")
return
}
val.Valid = true
val.BoolVal = b
return
case Int8:
i, err = strconv.ParseInt(str, 10, 8)
if err != nil {
err = utils.StackError(err, "")
return
}
// We need to convert it from i64 to i8 since strconv.ParseXXX
// always returns the largest bit size value.
i8 := int8(i)
val.Valid = true
val.OtherVal = unsafe.Pointer(&i8)
return
case Uint8, SmallEnum:
ui, err = strconv.ParseUint(str, 10, 8)
if err != nil {
err = utils.StackError(err, "")
return
}
ui8 := uint8(ui)
val.Valid = true
val.OtherVal = unsafe.Pointer(&ui8)
return
case Int16:
i, err = strconv.ParseInt(str, 10, 16)
if err != nil {
err = utils.StackError(err, "")
return
}
i16 := int16(i)
val.Valid = true
val.OtherVal = unsafe.Pointer(&i16)
return
case Uint16, BigEnum:
ui, err = strconv.ParseUint(str, 10, 16)
if err != nil {
err = utils.StackError(err, "")
return
}
ui16 := uint16(ui)
val.Valid = true
val.OtherVal = unsafe.Pointer(&ui16)
return
case Int32:
i, err = strconv.ParseInt(str, 10, 32)
if err != nil {
err = utils.StackError(err, "")
return
}
i32 := int32(i)
val.Valid = true
val.OtherVal = unsafe.Pointer(&i32)
return
case Uint32:
ui, err = strconv.ParseUint(str, 10, 32)
if err != nil {
err = utils.StackError(err, "")
return
}
ui32 := uint32(ui)
val.Valid = true
val.OtherVal = unsafe.Pointer(&ui32)
return
case Int64:
i, err = strconv.ParseInt(str, 10, 64)
if err != nil {
err = utils.StackError(err, "")
return
}
val.Valid = true
val.OtherVal = unsafe.Pointer(&i)
return
case Float32:
f, err = strconv.ParseFloat(str, 32)
if err != nil {
err = utils.StackError(err, "")
return
}
f32 := float32(f)
val.Valid = true
val.OtherVal = unsafe.Pointer(&f32)
return
case UUID:
var uuidBytes []byte
if strings.HasPrefix(str, "0x") {
str = str[2:]
}
uuidBytes, err = hex.DecodeString(strings.Replace(str, "-", "", -1))
if err != nil || len(uuidBytes) != 16 {
err = utils.StackError(err, "Failed to decode uuid string: %s", str)
return
}
val.Valid = true
val.OtherVal = unsafe.Pointer(&uuidBytes[0])
return
case GeoPoint:
var point [2]float32
point, err = GeoPointFromString(str)
if err != nil {
err = utils.StackError(err, "Failed to read geopoint string: %s", str)
return
}
val.Valid = true
val.OtherVal = unsafe.Pointer(&point[0])
return
default:
if IsArrayType(dataType) {
var value interface{}
value, err = ArrayValueFromString(str, GetElementDataType(dataType))
if err != nil {
err = utils.StackError(err, "Failed to read array string: %s", str)
return
}
arrayValue := value.(*ArrayValue)
bytes := arrayValue.GetSerBytes()
buffer := make([]byte, bytes)
valueWriter := utils.NewBufferWriter(buffer)
err = arrayValue.Write(&valueWriter)
if err != nil {
err = utils.StackError(err, "Unable to write array value to buffer: %s", str)
return
}
val.Valid = true
val.OtherVal = unsafe.Pointer(&buffer[0])
return
}
err = utils.StackError(nil, "Unsupported data type value %#x", dataType)
return
}
}