djson: github.com/a8m/djson Index | Examples | Files | Directories

package djson

import "github.com/a8m/djson"

Index

Examples

Package Files

bytes.go decode.go interface.go

Variables

var (
    ErrUnexpectedEOF    = &SyntaxError{"unexpected end of JSON input", -1}
    ErrInvalidHexEscape = &SyntaxError{"invalid hexadecimal escape sequence", -1}
    ErrStringEscape     = &SyntaxError{"encountered an invalid escape sequence in a string", -1}
)

Predefined errors

func Decode Uses

func Decode(data []byte) (interface{}, error)

Decode parses the JSON-encoded data and returns an interface value. The interface value could be one of these:

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null

Note that the Decode is compatible with the the following insructions:

var v interface{}
err := json.Unmarshal(data, &v)

Code:

var data = []byte(`[
		{"Name": "Platypus", "Order": "Monotremata"},
		{"Name": "Quoll",    "Order": "Dasyuromorphia"}
	]`)

val, err := djson.Decode(data)
if err != nil {
    log.Fatal("error:", err)
}

fmt.Printf("%+v", val)

// - Output:
// [map[Name:Platypus Order:Monotremata] map[Name:Quoll Order:Dasyuromorphia]]

func DecodeArray Uses

func DecodeArray(data []byte) ([]interface{}, error)

DecodeArray is the same as Decode but it returns []interface{}. You should use it to parse JSON arrays.

Code:

var data = []byte(`[
		"John",
		"Dan",
		"Kory",
		"Ariel"
	]`)

users, err := djson.DecodeArray(data)
if err != nil {
    log.Fatal("error:", err)
}
for i, user := range users {
    fmt.Printf("[%d]: %v\n", i, user)
}

func DecodeObject Uses

func DecodeObject(data []byte) (map[string]interface{}, error)

DecodeObject is the same as Decode but it returns map[string]interface{}. You should use it to parse JSON objects.

Example that demonstrate the basic transformation I do on each incoming event. `lowerKeys` and `fixEncoding` are two generic methods, and they don't care about the schema. The three others(`maxMindGeo`, `dateFormat`and `refererURL`) process and extend the events dynamically based on the "APP_ID" field.

Code:

var data = []byte(`{
		"ID": 76523,
		"IP": "69.89.31.226"
		"APP_ID": "BD311",
		"Name": "Ariel",
		"Username": "a8m",
		"Score": 99,
		"Date": 1475332371532,
		"Image": {
			"Src": "images/67.png",
			"Height": 450,
			"Width":  370,
			"Alignment": "center"
		},
		"RefererURL": "http://..."
	}`)
event, err := djson.DecodeObject(data)
if err != nil {
    log.Fatal("error:", err)
}

fmt.Printf("Value: %v", event)

// Process the event
//
// lowerKeys(event)
// fixEncoding(event)
// dateFormat(event)
// maxMindGeo(event)
// refererURL(event)
//
// pipeline.Pipe(event)

type Decoder Uses

type Decoder struct {
    // contains filtered or unexported fields
}

Decoder is the object that holds the state of the decoding

func NewDecoder Uses

func NewDecoder(data []byte) *Decoder

NewDecoder creates new Decoder from the JSON-encoded data

func (*Decoder) AllocString Uses

func (d *Decoder) AllocString()

AllocString pre-allocates a string version of the data before starting to decode the data. It is used to make the decode operation faster(see below) by doing one allocation operation for string conversion(from bytes), and then uses "slicing" to create non-escaped strings in the "Decoder.string" method. However, string is a read-only slice, and since the slice references the original array, as long as the slice is kept around, the garbage collector can't release the array. For this reason, you want to use this method only when the Decoder's result is a "read-only" or you are adding more elements to it. see example below.

Here are the improvements:

small payload  - 0.13~ time faster, does 0.45~ less memory allocations but
		 the total number of bytes that are allocated is 0.03~ bigger

medium payload - 0.16~ time faster, does 0.5~ less memory allocations but
		 the total number of bytes that are allocated is 0.05~ bigger

large payload  - 0.13~ time faster, does 0.50~ less memory allocations but
		 the total number of bytes that are allocated is 0.02~ bigger

Here is an example to illustrate when you don't want to use this method

str := fmt.Sprintf(`{"foo": "bar", "baz": "%s"}`, strings.Repeat("#", 1024 * 1024))
dec := djson.NewDecoder([]byte(str))
dec.AllocString()
ev, err := dec.DecodeObject()

// inpect memory stats here; MemStats.Alloc ~= 1M

delete(ev, "baz") // or ev["baz"] = "qux"

// inpect memory stats again; MemStats.Alloc ~= 1M
// it means that the chunk that was located in the "baz" value is not freed

Code:

var data = []byte(`{"event_type":"click","count":"93","userid":"4234A"}`)
dec := djson.NewDecoder(data)
dec.AllocString()

val, err := dec.DecodeObject()
if err != nil {
    log.Fatal("error:", err)
}

fmt.Printf("Value: %+v", val)

// - Output:
// map[count:93 userid:4234A event_type:click]

func (*Decoder) Decode Uses

func (d *Decoder) Decode() (interface{}, error)

Decode parses the JSON-encoded data and returns an interface value. The interface value could be one of these:

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null

Note that the Decode is compatible with the the following insructions:

var v interface{}
err := json.Unmarshal(data, &v)

func (*Decoder) DecodeArray Uses

func (d *Decoder) DecodeArray() ([]interface{}, error)

DecodeArray is the same as Decode but it returns []interface{}. You should use it to parse JSON arrays.

func (*Decoder) DecodeObject Uses

func (d *Decoder) DecodeObject() (map[string]interface{}, error)

DecodeObject is the same as Decode but it returns map[string]interface{}. You should use it to parse JSON objects.

type SyntaxError Uses

type SyntaxError struct {
    Offset int // error occurred after reading Offset bytes
    // contains filtered or unexported fields
}

A SyntaxError is a description of a JSON syntax error.

func (*SyntaxError) Error Uses

func (e *SyntaxError) Error() string

type ValueType Uses

type ValueType int

ValueType identifies the type of a parsed value.

const (
    Null ValueType = iota
    Bool
    String
    Number
    Object
    Array
    Unknown
)

func Type Uses

func Type(v interface{}) ValueType

Type returns the JSON-type of the given value

func (ValueType) String Uses

func (v ValueType) String() string

Directories

PathSynopsis
benchmark

Package djson imports 4 packages (graph) and is imported by 5 packages. Updated 2018-06-18. Refresh now. Tools for package owners.