Documentation ¶
Index ¶
- Constants
- Variables
- func ParseNDStream(r io.Reader, res chan<- Stream, reuse <-chan *ParsedJson)
- func SupportedCPU() bool
- type Array
- func (a *Array) AsFloat() ([]float64, error)
- func (a *Array) AsInteger() ([]int64, error)
- func (a *Array) AsString() ([]string, error)
- func (a *Array) AsStringCvt() ([]string, error)
- func (a *Array) AsUint64() ([]uint64, error)
- func (a *Array) DeleteElems(fn func(i Iter) bool)
- func (a *Array) FirstType() Type
- func (a *Array) ForEach(fn func(i Iter))
- func (a *Array) Interface() ([]interface{}, error)
- func (a *Array) Iter() Iter
- func (a *Array) MarshalJSON() ([]byte, error)
- func (a *Array) MarshalJSONBuffer(dst []byte) ([]byte, error)
- type CompressMode
- type Element
- type Elements
- type FloatFlag
- type FloatFlags
- type Iter
- func (i *Iter) Advance() Type
- func (i *Iter) AdvanceInto() Tag
- func (i *Iter) AdvanceIter(dst *Iter) (Type, error)
- func (i *Iter) Array(dst *Array) (*Array, error)
- func (i *Iter) Bool() (bool, error)
- func (i *Iter) FindElement(dst *Element, path ...string) (*Element, error)
- func (i *Iter) Float() (float64, error)
- func (i *Iter) FloatFlags() (float64, FloatFlags, error)
- func (i *Iter) Int() (int64, error)
- func (i *Iter) Interface() (interface{}, error)
- func (i *Iter) MarshalJSON() ([]byte, error)
- func (i *Iter) MarshalJSONBuffer(dst []byte) ([]byte, error)
- func (i *Iter) Object(dst *Object) (*Object, error)
- func (i *Iter) PeekNext() Type
- func (i *Iter) PeekNextTag() Tag
- func (i *Iter) Root(dst *Iter) (Type, *Iter, error)
- func (i *Iter) SetBool(v bool) error
- func (i *Iter) SetFloat(v float64) error
- func (i *Iter) SetInt(v int64) error
- func (i *Iter) SetNull() error
- func (i *Iter) SetString(v string) error
- func (i *Iter) SetStringBytes(v []byte) error
- func (i *Iter) SetUInt(v uint64) error
- func (i *Iter) String() (string, error)
- func (i *Iter) StringBytes() ([]byte, error)
- func (i *Iter) StringCvt() (string, error)
- func (i *Iter) Type() Type
- func (i *Iter) Uint() (uint64, error)
- type Object
- func (o *Object) DeleteElems(fn func(key []byte, i Iter) bool, onlyKeys map[string]struct{}) error
- func (o *Object) FindKey(key string, dst *Element) *Element
- func (o *Object) FindPath(dst *Element, path ...string) (*Element, error)
- func (o *Object) ForEach(fn func(key []byte, i Iter), onlyKeys map[string]struct{}) error
- func (o *Object) Map(dst map[string]interface{}) (map[string]interface{}, error)
- func (o *Object) NextElement(dst *Iter) (name string, t Type, err error)
- func (o *Object) NextElementBytes(dst *Iter) (name []byte, t Type, err error)
- func (o *Object) Parse(dst *Elements) (*Elements, error)
- type ParsedJson
- type ParserOption
- type Serializer
- type Stream
- type TStrings
- type Tag
- type Type
Examples ¶
Constants ¶
const ( TagString = Tag('"') TagInteger = Tag('l') TagUint = Tag('u') TagFloat = Tag('d') TagNull = Tag('n') TagBoolTrue = Tag('t') TagBoolFalse = Tag('f') TagObjectStart = Tag('{') TagObjectEnd = Tag('}') TagArrayStart = Tag('[') TagArrayEnd = Tag(']') TagRoot = Tag('r') TagNop = Tag('N') TagEnd = Tag(0) )
const JSONTAGMASK = 0xff << JSONTAGOFFSET
const JSONTAGOFFSET = 56
const JSONVALUEMASK = 0xff_ffff_ffff_ffff
const STRINGBUFBIT = 0x80_0000_0000_0000
const STRINGBUFMASK = 0x7fffffffffffff
Variables ¶
var ErrPathNotFound = errors.New("path not found")
ErrPathNotFound is returned
var TagToType = [256]Type{ TagString: TypeString, TagInteger: TypeInt, TagUint: TypeUint, TagFloat: TypeFloat, TagNull: TypeNull, TagBoolTrue: TypeBool, TagBoolFalse: TypeBool, TagObjectStart: TypeObject, TagArrayStart: TypeArray, TagRoot: TypeRoot, }
TagToType converts a tag to type. For arrays and objects only the start tag will return types. All non-existing tags returns TypeNone.
Functions ¶
func ParseNDStream ¶
func ParseNDStream(r io.Reader, res chan<- Stream, reuse <-chan *ParsedJson)
ParseNDStream will parse a stream and return parsed JSON to the supplied result channel. The method will return immediately. Each element is contained within a root tag.
<root>Element 1</root><root>Element 2</root>...
Each result will contain an unspecified number of full elements, so it can be assumed that each result starts and ends with a root tag. The parser will keep parsing until writes to the result stream blocks. A stream is finished when a non-nil Error is returned. If the stream was parsed until the end the Error value will be io.EOF The channel will be closed after an error has been returned. An optional channel for returning consumed results can be provided. There is no guarantee that elements will be consumed, so always use non-blocking writes to the reuse channel.
Types ¶
type Array ¶
type Array struct {
// contains filtered or unexported fields
}
Array represents a JSON array. There are methods that allows to get full arrays if the value type is the same. Otherwise an iterator can be retrieved.
Example ¶
if !SupportedCPU() { // Fake it fmt.Println("Found array\nType: int value: 116\nType: int value: 943\nType: int value: 234\nType: int value: 38793") return } input := `{ "Image": { "Animated": false, "Height": 600, "IDs": [ 116, 943, 234, 38793 ], "Thumbnail": { "Height": 125, "Url": "http://www.example.com/image/481989943", "Width": 100 }, "Title": "View from 15th Floor", "Width": 800 }, "Alt": "Image of city" }` pj, err := Parse([]byte(input), nil) if err != nil { log.Fatal(err) } i := pj.Iter() i.AdvanceInto() // Grab root _, root, err := i.Root(nil) if err != nil { log.Fatal(err) } // Grab top object obj, err := root.Object(nil) if err != nil { log.Fatal(err) } // Find element in path. elem, err := obj.FindPath(nil, "Image", "IDs") if err != nil { log.Fatal(err) } fmt.Println("Found", elem.Type) if elem.Type == TypeArray { array, err := elem.Iter.Array(nil) if err != nil { log.Fatal(err) } array.ForEach(func(i Iter) { asString, _ := i.StringCvt() fmt.Println("Type:", i.Type(), "value:", asString) }) }
Output: Found array Type: int value: 116 Type: int value: 943 Type: int value: 234 Type: int value: 38793
func (*Array) AsFloat ¶
AsFloat returns the array values as float. Integers are automatically converted to float.
func (*Array) AsInteger ¶
AsInteger returns the array values as int64 values. Uints/Floats are automatically converted to int64 if they fit within the range.
func (*Array) AsString ¶
AsString returns the array values as a slice of strings. No conversion is done.
func (*Array) AsStringCvt ¶ added in v0.2.1
AsStringCvt returns the array values as a slice of strings. Scalar types are converted. Root, Object and Arrays are not supported an will return an error if found.
func (*Array) AsUint64 ¶ added in v0.2.1
AsUint64 returns the array values as float. Uints/Floats are automatically converted to uint64 if they fit within the range.
func (*Array) DeleteElems ¶ added in v0.4.3
DeleteElems calls the provided function for every element. If the function returns true the element is deleted in the array.
Example ¶
if !SupportedCPU() { // Fake it fmt.Println("Found array\nModified: {\"Image\":{\"Animated\":false,\"Height\":600,\"IDs\":[943,38793]},\"Alt\":\"Image of city\"}") return } input := `{ "Image": { "Animated": false, "Height": 600, "IDs": [ 116, 943, 234, 38793 ] }, "Alt": "Image of city" }` pj, err := Parse([]byte(input), nil) if err != nil { log.Fatal(err) } i := pj.Iter() i.AdvanceInto() // Grab root _, root, err := i.Root(nil) if err != nil { log.Fatal(err) } // Grab top object obj, err := root.Object(nil) if err != nil { log.Fatal(err) } // Find element in path. elem, err := obj.FindPath(nil, "Image", "IDs") if err != nil { log.Fatal(err) } fmt.Println("Found", elem.Type) if elem.Type == TypeArray { array, err := elem.Iter.Array(nil) if err != nil { log.Fatal(err) } // Delete all integer elements that are < 500 array.DeleteElems(func(i Iter) bool { if id, err := i.Int(); err == nil { return id < 500 } return false }) } b, err := root.MarshalJSON() if err != nil { log.Fatal(err) } fmt.Println("Modified:", string(b))
Output: Found array Modified: {"Image":{"Animated":false,"Height":600,"IDs":[943,38793]},"Alt":"Image of city"}
func (*Array) FirstType ¶
FirstType will return the type of the first element. If there are no elements, TypeNone is returned.
func (*Array) Interface ¶
Interface returns the array as a slice of interfaces. See Iter.Interface() for a reference on value types.
func (*Array) Iter ¶
Iter returns the array as an iterator. This can be used for parsing mixed content arrays. The first value is ready with a call to Advance. Calling after last element should have TypeNone.
func (*Array) MarshalJSON ¶
MarshalJSON will marshal the entire remaining scope of the iterator.
type CompressMode ¶ added in v0.1.4
type CompressMode uint8
const ( // CompressNone no compression whatsoever. CompressNone CompressMode = iota // CompressFast will apply light compression, // but will not deduplicate strings which may affect deserialization speed. CompressFast // CompressDefault applies light compression and deduplicates strings. CompressDefault // CompressBest CompressBest )
type Element ¶
type Element struct { // Name of the element Name string // Type of the element Type Type // Iter containing the element Iter Iter }
Element represents an element in an object.
type Elements ¶
Elements contains all elements in an object kept in original order. And index contains lookup for object keys.
func (Elements) Lookup ¶
Lookup a key in elements and return the element. Returns nil if key doesn't exist. Keys are case sensitive.
func (Elements) MarshalJSON ¶
MarshalJSON will marshal the entire remaining scope of the iterator.
type FloatFlag ¶ added in v0.2.1
type FloatFlag uint64
FloatFlag is a flag recorded when parsing floats.
func (FloatFlag) Flags ¶ added in v0.2.1
func (f FloatFlag) Flags(more ...FloatFlag) FloatFlags
Flags converts the flag to FloatFlags and optionally merges more flags.
type FloatFlags ¶ added in v0.2.1
type FloatFlags uint64
FloatFlags are flags recorded when converting floats.
func (FloatFlags) Contains ¶ added in v0.2.1
func (f FloatFlags) Contains(flag FloatFlag) bool
Contains returns whether f contains the specified flag.
type Iter ¶
type Iter struct {
// contains filtered or unexported fields
}
Iter represents a section of JSON. To start iterating it, use Advance() or AdvanceIter() methods which will queue the first element. If an Iter is copied, the copy will be independent.
func (*Iter) Advance ¶
Advance will read the type of the next element and queues up the value on the same level.
func (*Iter) AdvanceInto ¶
AdvanceInto will read the tag of the next element and move into and out of arrays , objects and root elements. This should only be used for strictly manual parsing.
func (*Iter) AdvanceIter ¶
AdvanceIter will read the type of the next element and return an iterator only containing the object. If dst and i are the same, both will contain the value inside.
func (*Iter) Array ¶
Array will return the next element as an array. An optional destination can be given.
func (*Iter) FindElement ¶ added in v0.3.0
FindElement allows searching for fields and objects by path from the iter and forward, moving into root and objects, but not arrays. For example "Image", "Url" will search the current root/object for an "Image" object and return the value of the "Url" element. ErrPathNotFound is returned if any part of the path cannot be found. If the tape contains an error it will be returned. The iter will *not* be advanced.
Example ¶
if !SupportedCPU() { // Fake it fmt.Println("int\n100 <nil>") return } input := `{ "Image": { "Animated": false, "Height": 600, "IDs": [ 116, 943, 234, 38793 ], "Thumbnail": { "Height": 125, "Url": "http://www.example.com/image/481989943", "Width": 100 }, "Title": "View from 15th Floor", "Width": 800 }, "Alt": "Image of city" }` pj, err := Parse([]byte(input), nil) if err != nil { log.Fatal(err) } i := pj.Iter() // Find element in path. elem, err := i.FindElement(nil, "Image", "Thumbnail", "Width") if err != nil { log.Fatal(err) } // Print result: fmt.Println(elem.Type) fmt.Println(elem.Iter.StringCvt())
Output: int 100 <nil>
func (*Iter) Float ¶
Float returns the float value of the next element. Integers are automatically converted to float.
func (*Iter) FloatFlags ¶ added in v0.2.1
func (i *Iter) FloatFlags() (float64, FloatFlags, error)
FloatFlags returns the float value of the next element. This will include flags from parsing. Integers are automatically converted to float.
func (*Iter) Int ¶
Int returns the integer value of the next element. Integers and floats within range are automatically converted.
func (*Iter) Interface ¶
Interface returns the value as an interface. Objects are returned as map[string]interface{}. Arrays are returned as []interface{}. Float values are returned as float64. Integer values are returned as int64 or uint64. String values are returned as string. Boolean values are returned as bool. Null values are returned as nil. Root objects are returned as []interface{}.
func (*Iter) MarshalJSON ¶
MarshalJSON will marshal the entire remaining scope of the iterator.
func (*Iter) MarshalJSONBuffer ¶
MarshalJSONBuffer will marshal the remaining scope of the iterator including the current value. An optional buffer can be provided for fewer allocations. Output will be appended to the destination.
func (*Iter) Object ¶
Object will return the next element as an object. An optional destination can be given.
func (*Iter) PeekNext ¶
PeekNext will return the next value type. Returns TypeNone if next ends iterator.
func (*Iter) PeekNextTag ¶
PeekNextTag will return the tag at the current offset. Will return TagEnd if at end of iterator.
func (*Iter) Root ¶
Root returns the object embedded in root as an iterator along with the type of the content of the first element of the iterator. An optional destination can be supplied to avoid allocations.
func (*Iter) SetBool ¶ added in v0.3.0
SetBool can change a bool or null type to bool with the specified value. Attempting to change other types will return an error.
func (*Iter) SetFloat ¶ added in v0.3.0
SetFloat can change a float, int, uint or string with the specified value. Attempting to change other types will return an error.
func (*Iter) SetInt ¶ added in v0.3.0
SetInt can change a float, int, uint or string with the specified value. Attempting to change other types will return an error.
func (*Iter) SetNull ¶ added in v0.3.0
SetNull can change the following types to null: Bool, String, (Unsigned) Integer, Float, Objects and Arrays. Attempting to change other types will return an error.
func (*Iter) SetString ¶ added in v0.3.0
SetString can change a string, int, uint or float with the specified string. Attempting to change other types will return an error.
func (*Iter) SetStringBytes ¶ added in v0.3.0
SetStringBytes can change a string, int, uint or float with the specified string. Attempting to change other types will return an error. Sending nil will add an empty string.
func (*Iter) SetUInt ¶ added in v0.3.0
SetUInt can change a float, int, uint or string with the specified value. Attempting to change other types will return an error.
func (*Iter) StringBytes ¶
StringBytes returns a string as byte array.
func (*Iter) StringCvt ¶
StringCvt returns a string representation of the value. Root, Object and Arrays are not supported.
type Object ¶
type Object struct {
// contains filtered or unexported fields
}
Object represents a JSON object.
func (*Object) DeleteElems ¶ added in v0.4.3
DeleteElems will call back fn for each key. If true is returned, the key+value is deleted. A key filter can be provided for optional filtering. If fn is nil all elements in onlyKeys will be deleted. If both are nil all elements are deleted.
func (*Object) FindKey ¶
FindKey will return a single named element. An optional destination can be given. The method will return nil if the element cannot be found. This should only be used to locate a single key where the object is no longer needed. The object will not be advanced.
func (*Object) FindPath ¶ added in v0.3.0
FindPath allows searching for fields and objects by path. Separate each object name by /. For example `Image/Url` will search the current object for an "Image" object and return the value of the "Url" element. ErrPathNotFound is returned if any part of the path cannot be found. If the tape contains an error it will be returned. The object will not be advanced.
Example ¶
if !SupportedCPU() { // Fake it fmt.Println("string\nhttp://www.example.com/image/481989943 <nil>") return } input := `{ "Image": { "Animated": false, "Height": 600, "IDs": [ 116, 943, 234, 38793 ], "Thumbnail": { "Height": 125, "Url": "http://www.example.com/image/481989943", "Width": 100 }, "Title": "View from 15th Floor", "Width": 800 }, "Alt": "Image of city" }` pj, err := Parse([]byte(input), nil) if err != nil { log.Fatal(err) } i := pj.Iter() i.AdvanceInto() // Grab root _, root, err := i.Root(nil) if err != nil { log.Fatal(err) } // Grab top object obj, err := root.Object(nil) if err != nil { log.Fatal(err) } // Find element in path. elem, err := obj.FindPath(nil, "Image", "Thumbnail", "Url") if err != nil { log.Fatal(err) } // Print result: fmt.Println(elem.Type) fmt.Println(elem.Iter.String())
Output: string http://www.example.com/image/481989943 <nil>
func (*Object) ForEach ¶ added in v0.4.0
ForEach will call back fn for each key. A key filter can be provided for optional filtering.
func (*Object) Map ¶
Map will unmarshal into a map[string]interface{} See Iter.Interface() for a reference on value types.
func (*Object) NextElement ¶
NextElement sets dst to the next element and returns the name. TypeNone with nil error will be returned if there are no more elements.
func (*Object) NextElementBytes ¶
NextElementBytes sets dst to the next element and returns the name. TypeNone with nil error will be returned if there are no more elements. Contrary to NextElement this will not cause allocations.
type ParsedJson ¶
type ParsedJson struct { Message []byte Tape []uint64 Strings *TStrings // contains filtered or unexported fields }
func Parse ¶
func Parse(b []byte, reuse *ParsedJson, opts ...ParserOption) (*ParsedJson, error)
Parse an object or array from a block of data and return the parsed JSON. An optional block of previously parsed json can be supplied to reduce allocations.
func ParseND ¶
func ParseND(b []byte, reuse *ParsedJson, opts ...ParserOption) (*ParsedJson, error)
ParseND will parse newline delimited JSON objects or arrays. An optional block of previously parsed json can be supplied to reduce allocations.
func (*ParsedJson) Clone ¶ added in v0.3.0
func (pj *ParsedJson) Clone(dst *ParsedJson) *ParsedJson
Clone returns a deep clone of the ParsedJson. If a nil destination is sent a new will be created.
func (*ParsedJson) ForEach ¶ added in v0.4.0
func (pj *ParsedJson) ForEach(fn func(i Iter) error) error
ForEach returns each line in NDJSON, or the top element in non-ndjson. This will usually be an object or an array. If the callback returns a non-nil error parsing stops and the errors is returned.
Example ¶
if !SupportedCPU() { // Fake results fmt.Println("Got iterator for type: object\nFound element: URL Type: string Value: http://example.com/example.gif") return } // Parse JSON: pj, err := Parse([]byte(`{"Image":{"URL":"http://example.com/example.gif"}}`), nil) if err != nil { log.Fatal(err) } // Create an element we can reuse. var element *Element err = pj.ForEach(func(i Iter) error { fmt.Println("Got iterator for type:", i.Type()) element, err = i.FindElement(element, "Image", "URL") if err == nil { value, _ := element.Iter.StringCvt() fmt.Println("Found element:", element.Name, "Type:", element.Type, "Value:", value) } return nil }) if err != nil { log.Fatal(err) }
Output: Got iterator for type: object Found element: URL Type: string Value: http://example.com/example.gif
func (*ParsedJson) Reset ¶
func (pj *ParsedJson) Reset()
type ParserOption ¶ added in v0.2.2
type ParserOption func(pj *internalParsedJson) error
ParserOption is a parser option.
func WithCopyStrings ¶ added in v0.2.2
func WithCopyStrings(b bool) ParserOption
WithCopyStrings will copy strings so they no longer reference the input. For enhanced performance, simdjson-go can point back into the original JSON buffer for strings, however this can lead to issues in streaming use cases scenarios, or scenarios in which the underlying JSON buffer is reused. So the default behaviour is to create copies of all strings (not just those transformed anyway for unicode escape characters) into the separate Strings buffer (at the expense of using more memory and less performance). Default: true - strings are copied.
type Serializer ¶ added in v0.1.4
type Serializer struct {
// contains filtered or unexported fields
}
Serializer allows to serialize parsed json and read it back. A Serializer can be reused, but not used concurrently.
func NewSerializer ¶ added in v0.1.4
func NewSerializer() *Serializer
NewSerializer will create and initialize a Serializer.
func (*Serializer) CompressMode ¶ added in v0.1.4
func (s *Serializer) CompressMode(c CompressMode)
func (*Serializer) Deserialize ¶ added in v0.1.4
func (s *Serializer) Deserialize(src []byte, dst *ParsedJson) (*ParsedJson, error)
Deserialize the content in src. Only basic sanity checks will be performed. Slight corruption will likely go through unnoticed. And optional destination can be provided.
func (*Serializer) Serialize ¶ added in v0.1.4
func (s *Serializer) Serialize(dst []byte, pj ParsedJson) []byte
Serialize the data in pj and return the data. An optional destination can be provided.
type Stream ¶
type Stream struct { Value *ParsedJson Error error }
A Stream is used to stream back results. Either Error or Value will be set on returned results.