in lib/go/thrift/simple_json_protocol.go [1183:1305]
func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) {
isNull, err := p.readIfNull()
if isNull || err != nil {
return NUMERIC_NULL, err
}
hasDecimalPoint := false
nextCanBeSign := true
hasE := false
MAX_LEN := 40
buf := bytes.NewBuffer(make([]byte, 0, MAX_LEN))
continueFor := true
inQuotes := false
for continueFor {
c, err := p.reader.ReadByte()
if err != nil {
if errors.Is(err, io.EOF) {
break
}
return NUMERIC_NULL, NewTProtocolException(err)
}
switch c {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
buf.WriteByte(c)
nextCanBeSign = false
case '.':
if hasDecimalPoint {
e := fmt.Errorf("Unable to parse number with multiple decimal points '%s.'", buf.String())
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
if hasE {
e := fmt.Errorf("Unable to parse number with decimal points in the exponent '%s.'", buf.String())
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
buf.WriteByte(c)
hasDecimalPoint, nextCanBeSign = true, false
case 'e', 'E':
if hasE {
e := fmt.Errorf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c)
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
buf.WriteByte(c)
hasE, nextCanBeSign = true, true
case '-', '+':
if !nextCanBeSign {
e := fmt.Errorf("Negative sign within number")
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
buf.WriteByte(c)
nextCanBeSign = false
case ' ', 0, '\t', '\n', '\r', JSON_RBRACE[0], JSON_RBRACKET[0], JSON_COMMA[0], JSON_COLON[0]:
p.reader.UnreadByte()
continueFor = false
case JSON_NAN[0]:
if buf.Len() == 0 {
buffer := make([]byte, len(JSON_NAN))
buffer[0] = c
_, e := p.reader.Read(buffer[1:])
if e != nil {
return NUMERIC_NULL, NewTProtocolException(e)
}
if JSON_NAN != string(buffer) {
e := mismatch(JSON_NAN, string(buffer))
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
if inQuotes {
p.readQuoteIfNext()
}
return NAN, nil
} else {
e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
case JSON_INFINITY[0]:
if buf.Len() == 0 || (buf.Len() == 1 && buf.Bytes()[0] == '+') {
buffer := make([]byte, len(JSON_INFINITY))
buffer[0] = c
_, e := p.reader.Read(buffer[1:])
if e != nil {
return NUMERIC_NULL, NewTProtocolException(e)
}
if JSON_INFINITY != string(buffer) {
e := mismatch(JSON_INFINITY, string(buffer))
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
if inQuotes {
p.readQuoteIfNext()
}
return INFINITY, nil
} else if buf.Len() == 1 && buf.Bytes()[0] == JSON_NEGATIVE_INFINITY[0] {
buffer := make([]byte, len(JSON_NEGATIVE_INFINITY))
buffer[0] = JSON_NEGATIVE_INFINITY[0]
buffer[1] = c
_, e := p.reader.Read(buffer[2:])
if e != nil {
return NUMERIC_NULL, NewTProtocolException(e)
}
if JSON_NEGATIVE_INFINITY != string(buffer) {
e := mismatch(JSON_NEGATIVE_INFINITY, string(buffer))
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
if inQuotes {
p.readQuoteIfNext()
}
return NEGATIVE_INFINITY, nil
} else {
e := fmt.Errorf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String())
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
case JSON_QUOTE:
if !inQuotes {
inQuotes = true
}
default:
e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
}
if buf.Len() == 0 {
e := fmt.Errorf("Unable to parse number from empty string ''")
return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
}
return NewNumericFromJSONString(buf.String(), false), nil
}