@@ -11,13 +11,14 @@ import (
1111
1212// Errors
1313var (
14- KeyPathNotFoundError = errors .New ("Key path not found" )
14+ KeyPathNotFoundError = errors .New ("Key path not found" )
1515 UnknownValueTypeError = errors .New ("Unknown value type" )
16- MalformedJsonError = errors .New ("Malformed JSON error" )
17- MalformedStringError = errors .New ("Value is string, but can't find closing '\" ' symbol" )
18- MalformedArrayError = errors .New ("Value is array, but can't find closing ']' symbol" )
19- MalformedObjectError = errors .New ("Value looks like object, but can't find closing '}' symbol" )
20- MalformedValueError = errors .New ("Value looks like Number/Boolean/None, but can't find its end: ',' or '}' symbol" )
16+ MalformedJsonError = errors .New ("Malformed JSON error" )
17+ MalformedStringError = errors .New ("Value is string, but can't find closing '\" ' symbol" )
18+ MalformedArrayError = errors .New ("Value is array, but can't find closing ']' symbol" )
19+ MalformedObjectError = errors .New ("Value looks like object, but can't find closing '}' symbol" )
20+ MalformedValueError = errors .New ("Value looks like Number/Boolean/None, but can't find its end: ',' or '}' symbol" )
21+ NotAPrimitiveError = errors .New ("Cannot parse a non-primitive value in ParsePrimitiveValue" )
2122)
2223
2324func tokenEnd (data []byte ) int {
@@ -31,7 +32,6 @@ func tokenEnd(data []byte) int {
3132 return - 1
3233}
3334
34-
3535// Find position of next character which is not ' ', ',', '}' or ']'
3636func nextToken (data []byte , skipComma bool ) int {
3737 for i , c := range data {
@@ -133,10 +133,10 @@ func searchKeys(data []byte, keys ...string) int {
133133 i += valueOffset
134134
135135 // if string is a Key, and key level match
136- if data [i ] == ':' {
136+ if data [i ] == ':' {
137137 key := unsafeBytesToString (data [keyBegin :keyEnd ])
138138
139- if keyLevel == level - 1 && // If key nesting level match current object nested level
139+ if keyLevel == level - 1 && // If key nesting level match current object nested level
140140 keys [level - 1 ] == key {
141141 keyLevel ++
142142 // If we found all keys in path
@@ -462,3 +462,34 @@ func unsafeBytesToString(data []byte) string {
462462 sh := reflect.StringHeader {Data : h .Data , Len : h .Len }
463463 return * (* string )(unsafe .Pointer (& sh ))
464464}
465+
466+ // ParsePrimitiveValue takes a []byte value returned by Get(), passed to ArrayEach() callback, etc.
467+ // and parses/converts it into a Go type (wrapped in an interface{}) as follows:
468+ //
469+ // Null -> nil
470+ // Boolean -> bool
471+ // String -> string (unescaped)
472+ // Number -> float64
473+ // anything else -> error
474+ //
475+ // This function will likely a memory allocation to return an interface{}, but often user code
476+ // needs an interface{} value, so we provide an efficient implementation for when it is needed.
477+ //
478+ func ParsePrimitiveValue (vbytes []byte , jtype ValueType ) (interface {}, error ) {
479+ switch jtype {
480+ case Null :
481+ return nil , nil
482+ case Boolean :
483+ return (vbytes [0 ] == 't' ), nil // assumes value is already validated by Get(), etc. since we're given jtype == Boolean
484+ case String :
485+ return string (vbytes ), nil // TODO: this does not unescape the string; use unescaper whenever it becomes available
486+ case Number :
487+ if v , err := strconv .ParseFloat (unsafeBytesToString (vbytes ), 64 ); err != nil { // TODO: use better BytesParseFloat in PR #25
488+ return nil , MalformedValueError
489+ } else {
490+ return v , nil
491+ }
492+ default :
493+ return nil , NotAPrimitiveError
494+ }
495+ }
0 commit comments