json

所属分类:WEB开发
开发工具:GO
文件大小:0KB
下载次数:0
上传日期:2023-11-09 19:44:30
上 传 者sh-1993
说明:  轻量级非结构化JSON解析器和类似jq的处理器。
(Lightweight unstructured JSON parser and jq-like processor.)

文件列表:
.circleci/ (0, 2023-12-08)
.circleci/config.yml (460, 2023-12-08)
.travis.yml (254, 2023-12-08)
LICENSE (1073, 2023-12-08)
benchmarks_data/ (0, 2023-12-08)
benchmarks_data/data.go (31990, 2023-12-08)
benchmarks_test.go (568, 2023-12-08)
decoder.go (12507, 2023-12-08)
decoder_test.go (2410, 2023-12-08)
encoder.go (2062, 2023-12-08)
examples_test.go (1709, 2023-12-08)
fuzz/ (0, 2023-12-08)
fuzz/json_test.go (3261, 2023-12-08)
fuzz/testdata/ (0, 2023-12-08)
fuzz/testdata/fuzz/ (0, 2023-12-08)
fuzz/testdata/fuzz/FuzzSkip/ (0, 2023-12-08)
fuzz/testdata/fuzz/FuzzSkip/5cacc5a28459e1b7 (32, 2023-12-08)
fuzz/testdata/fuzz/FuzzStringDecode/ (0, 2023-12-08)
fuzz/testdata/fuzz/FuzzStringDecode/21aa9c53900c1972 (35, 2023-12-08)
fuzz/testdata/fuzz/FuzzStringDecode/2aa4389a8451962d (45, 2023-12-08)
fuzz/testdata/fuzz/FuzzStringDecode/517a84f57f72369e (33, 2023-12-08)
fuzz/testdata/fuzz/FuzzStringDecode/903e210213c0347b (36, 2023-12-08)
fuzz/testdata/fuzz/FuzzStringDecode/a506f0597b54c6a9 (44, 2023-12-08)
fuzz/testdata/fuzz/FuzzStringDecode/c02ba8275dc20bc2 (35, 2023-12-08)
fuzz/testdata/fuzz/FuzzStringEncodeDecode/ (0, 2023-12-08)
fuzz/testdata/fuzz/FuzzStringEncodeDecode/3b3c20bf6150c168 (36, 2023-12-08)
fuzz/testdata/fuzz/FuzzStringEncodeDecode/5d9a586f11d453fc (53, 2023-12-08)
go.mod (385, 2023-12-08)
go.sum (2287, 2023-12-08)
jq/ (0, 2023-12-08)
jq/base64.go (1804, 2023-12-08)
jq/base64_test.go (533, 2023-12-08)
jq/benchmarks_test.go (1137, 2023-12-08)
jq/examples_test.go (1490, 2023-12-08)
jq/iter.go (975, 2023-12-08)
... ...

[![Documentation](https://pkg.go.dev/badge/nikand.dev/go/json)](https://pkg.go.dev/nikand.dev/go/json?tab=doc) [![Go workflow](https://github.com/nikandfor/json/actions/workflows/go.yml/badge.svg)](https://github.com/nikandfor/json/actions/workflows/go.yml) [![CircleCI](https://circleci.com/gh/nikandfor/json.svg?style=svg)](https://circleci.com/gh/nikandfor/json) [![codecov](https://codecov.io/gh/nikandfor/json/branch/master/graph/badge.svg)](https://codecov.io/gh/nikandfor/json) [![Go Report Card](https://goreportcard.com/badge/nikand.dev/go/json)](https://goreportcard.com/report/nikand.dev/go/json) ![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/nikandfor/json?sort=semver) # json Yet another json library. It's created to process unstructured json in a convenient and efficient way. There is also some set of [jq](https://jqlang.github.io/jq/manual/) filters implemented on top of `json.Decoder`. ## json usage `Decoder` is stateless. Most of the methods take source buffer and index where to start parsing and return a result and index where they stopped parsing. None of methods make a copy or allocate except these which take destination buffer in arguments. The code is from [examples](./examples_test.go). ```go // Parsing single object. var d json.Decoder data := []byte(`{"key": "value", "another": 1234}`) i := 0 // initial position i, err := d.Enter(data, i, json.Object) if err != nil { // not an object } var key []byte // to not to shadow i and err in a loop // extracted values var value, another []byte for d.ForMore(data, &i, json.Object, &err) { key, i, err = d.Key(data, i) // key decodes a string but don't decode '\n', '\"', '\xXX' and others if err != nil { // ... } switch string(key) { case "key": value, i, err = d.DecodeString(data, i, value[:0]) // reuse value buffer if we are in a loop or something case "another": another, i, err = d.Raw(data, i) default: // skip additional keys i, err = d.Skip(data, i) } // check error for all switch cases if err != nil { // ... } } if err != nil { // ForMore error } ``` ```go // Parsing jsonl: newline (or space, or comma) delimited values. var err error // to not to shadow i in a loop var d json.Decoder data := []byte(`"a", 2 3 ["array"] `) for i := d.SkipSpaces(data, 0); i < len(data); i = d.SkipSpaces(data, i) { // eat trailing spaces and not try to read the value from string "\n" i, err = processOneObject(data, i) // do not use := here as it shadow i and loop will restart from the same index if err != nil { // ... } } ``` ## jq usage jq package is a set of Filters that take data from one buffer, process it, and add result to another buffer. Aside from buffers filters take src buffer start position and return where reader stopped. Also there is a state taken and returned. It's used by filters to return multiple values one by one. The caller must provide `nil` on the first iteration and returned state on the rest of iterations. Iteration must stop when returned state is `nil`. Filter may or may not add a value to dst buffer. `Empty` filter for example adds no value and returns nil state. Destination buffer is returned even in case of error. This is mostly done for avoiding allocs in case the buffer was grown but error happened. The code is from [examples](./jq/examples_test.go). ```go // Extract some inside value. data := []byte(`{"key0":"skip it", "key1": {"next_key": ["array", null, {"obj":"val"}, "trailing element"]}} "next"`) f := jq.Index{"key1", "next_key", 2} // string keys and int array indexes are supported var res []byte // reusable buffer var i int // start index // Most filters only parse single value and return index where the value ended. // Use jq.ApplyToAll(f, res[:0], data, 0, []byte("\n")) to process all values in a buffer. res, i, _, err := f.Next(res[:0], data, i, nil) if err != nil { // i is an index in a source buffer where the error occurred. } fmt.Printf("value: %s\n", res) fmt.Printf("final position: %d of %d\n", i, len(data)) // object was parsed to the end of the first value to be able to read next one _ = i < len(data) // but not the next value // Output: // value: {"obj":"val"} // final position: 92 of 100 ``` This is especially convenient if you need to extract a value from *json inside base64 inside json*. Yes, I've seen such cases and they motivated me to create this package. ```go // generated by command // jq -nc '{key3: "value"} | {key2: (. | tojson)} | @base64 | {key1: .}' data := []byte(`{"key1":"eyJrZXkyIjoie1wia2V5M1wiOlwidmFsdWVcIn0ifQ=="}`) f := jq.NewPipe( jq.Index{"key1"}, &jq.Base64d{ Encoding: base64.StdEncoding, }, &jq.JSONDecoder{}, jq.Index{"key2"}, &jq.JSONDecoder{}, jq.Index{"key3"}, ) res, _, _, err := f.Next(nil, data, 0, nil) if err != nil { panic(err) } // res is []byte(`"value"`) ```

近期下载者

相关文件


收藏者