summaryrefslogtreecommitdiff
path: root/cmd/ponzu/vendor/github.com/tidwall/sjson
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/ponzu/vendor/github.com/tidwall/sjson')
-rw-r--r--cmd/ponzu/vendor/github.com/tidwall/sjson/.travis.yml1
-rw-r--r--cmd/ponzu/vendor/github.com/tidwall/sjson/LICENSE21
-rw-r--r--cmd/ponzu/vendor/github.com/tidwall/sjson/README.md278
-rw-r--r--cmd/ponzu/vendor/github.com/tidwall/sjson/logo.pngbin16874 -> 0 bytes
-rw-r--r--cmd/ponzu/vendor/github.com/tidwall/sjson/sjson.go653
5 files changed, 0 insertions, 953 deletions
diff --git a/cmd/ponzu/vendor/github.com/tidwall/sjson/.travis.yml b/cmd/ponzu/vendor/github.com/tidwall/sjson/.travis.yml
deleted file mode 100644
index 4f2ee4d..0000000
--- a/cmd/ponzu/vendor/github.com/tidwall/sjson/.travis.yml
+++ /dev/null
@@ -1 +0,0 @@
-language: go
diff --git a/cmd/ponzu/vendor/github.com/tidwall/sjson/LICENSE b/cmd/ponzu/vendor/github.com/tidwall/sjson/LICENSE
deleted file mode 100644
index 89593c7..0000000
--- a/cmd/ponzu/vendor/github.com/tidwall/sjson/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2016 Josh Baker
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/cmd/ponzu/vendor/github.com/tidwall/sjson/README.md b/cmd/ponzu/vendor/github.com/tidwall/sjson/README.md
deleted file mode 100644
index 1a7c5c4..0000000
--- a/cmd/ponzu/vendor/github.com/tidwall/sjson/README.md
+++ /dev/null
@@ -1,278 +0,0 @@
-<p align="center">
-<img
- src="logo.png"
- width="240" height="78" border="0" alt="SJSON">
-<br>
-<a href="https://travis-ci.org/tidwall/sjson"><img src="https://img.shields.io/travis/tidwall/sjson.svg?style=flat-square" alt="Build Status"></a>
-<a href="https://godoc.org/github.com/tidwall/sjson"><img src="https://img.shields.io/badge/api-reference-blue.svg?style=flat-square" alt="GoDoc"></a>
-</p>
-
-<p align="center">set a json value quickly</a></p>
-
-SJSON is a Go package that provides a [very fast](#performance) and simple way to set a value in a json document. The purpose for this library is to provide efficient json updating for the [SummitDB](https://github.com/tidwall/summitdb) project.
-For quickly retrieving json values check out [GJSON](https://github.com/tidwall/gjson).
-
-For a command line interface check out [JSONed](https://github.com/tidwall/jsoned).
-
-Getting Started
-===============
-
-Installing
-----------
-
-To start using SJSON, install Go and run `go get`:
-
-```sh
-$ go get -u github.com/tidwall/sjson
-```
-
-This will retrieve the library.
-
-Set a value
------------
-Set sets the value for the specified path.
-A path is in dot syntax, such as "name.last" or "age".
-This function expects that the json is well-formed and validated.
-Invalid json will not panic, but it may return back unexpected results.
-Invalid paths may return an error.
-
-```go
-package main
-
-import "github.com/tidwall/sjson"
-
-const json = `{"name":{"first":"Janet","last":"Prichard"},"age":47}`
-
-func main() {
- value, _ := sjson.Set(json, "name.last", "Anderson")
- println(value)
-}
-```
-
-This will print:
-
-```json
-{"name":{"first":"Janet","last":"Anderson"},"age":47}
-```
-
-Path syntax
------------
-
-A path is a series of keys separated by a dot.
-The dot and colon characters can be escaped with '\'.
-
-```json
-{
- "name": {"first": "Tom", "last": "Anderson"},
- "age":37,
- "children": ["Sara","Alex","Jack"],
- "fav.movie": "Deer Hunter",
- "friends": [
- {"first": "James", "last": "Murphy"},
- {"first": "Roger", "last": "Craig"}
- ]
-}
-```
-```
-"name.last" >> "Anderson"
-"age" >> 37
-"children.1" >> "Alex"
-"friends.1.last" >> "Craig"
-```
-
-The `-1` key can be used to append a value to an existing array:
-
-```
-"children.-1" >> appends a new value to the end of the children array
-```
-
-Normally number keys are used to modify arrays, but it's possible to force a numeric object key by using the colon character:
-
-```json
-{
- "users":{
- "2313":{"name":"Sara"},
- "7839":{"name":"Andy"}
- }
-}
-```
-
-A colon path would look like:
-
-```
-"users.:2313.name" >> "Sara"
-```
-
-Supported types
----------------
-
-Pretty much any type is supported:
-
-```go
-sjson.Set(`{"key":true}`, "key", nil)
-sjson.Set(`{"key":true}`, "key", false)
-sjson.Set(`{"key":true}`, "key", 1)
-sjson.Set(`{"key":true}`, "key", 10.5)
-sjson.Set(`{"key":true}`, "key", "hello")
-sjson.Set(`{"key":true}`, "key", map[string]interface{}{"hello":"world"})
-```
-
-When a type is not recognized, SJSON will fallback to the `encoding/json` Marshaller.
-
-
-Examples
---------
-
-Set a value from empty document:
-```go
-value, _ := sjson.Set("", "name", "Tom")
-println(value)
-
-// Output:
-// {"name":"Tom"}
-```
-
-Set a nested value from empty document:
-```go
-value, _ := sjson.Set("", "name.last", "Anderson")
-println(value)
-
-// Output:
-// {"name":{"last":"Anderson"}}
-```
-
-Set a new value:
-```go
-value, _ := sjson.Set(`{"name":{"last":"Anderson"}}`, "name.first", "Sara")
-println(value)
-
-// Output:
-// {"name":{"first":"Sara","last":"Anderson"}}
-```
-
-Update an existing value:
-```go
-value, _ := sjson.Set(`{"name":{"last":"Anderson"}}`, "name.last", "Smith")
-println(value)
-
-// Output:
-// {"name":{"last":"Smith"}}
-```
-
-Set a new array value:
-```go
-value, _ := sjson.Set(`{"friends":["Andy","Carol"]}`, "friends.2", "Sara")
-println(value)
-
-// Output:
-// {"friends":["Andy","Carol","Sara"]
-```
-
-Append an array value by using the `-1` key in a path:
-```go
-value, _ := sjson.Set(`{"friends":["Andy","Carol"]}`, "friends.-1", "Sara")
-println(value)
-
-// Output:
-// {"friends":["Andy","Carol","Sara"]
-```
-
-Append an array value that is past the end:
-```go
-value, _ := sjson.Set(`{"friends":["Andy","Carol"]}`, "friends.4", "Sara")
-println(value)
-
-// Output:
-// {"friends":["Andy","Carol",null,null,"Sara"]
-```
-
-Delete a value:
-```go
-value, _ := sjson.Delete(`{"name":{"first":"Sara","last":"Anderson"}}`, "name.first")
-println(value)
-
-// Output:
-// {"name":{"last":"Anderson"}}
-```
-
-Delete an array value:
-```go
-value, _ := sjson.Delete(`{"friends":["Andy","Carol"]}`, "friends.1")
-println(value)
-
-// Output:
-// {"friends":["Andy"]}
-```
-
-Delete the last array value:
-```go
-value, _ := sjson.Delete(`{"friends":["Andy","Carol"]}`, "friends.-1")
-println(value)
-
-// Output:
-// {"friends":["Andy"]}
-```
-
-## Performance
-
-Benchmarks of SJSON alongside [encoding/json](https://golang.org/pkg/encoding/json/),
-[ffjson](https://github.com/pquerna/ffjson),
-[EasyJSON](https://github.com/mailru/easyjson),
-and [Gabs](https://github.com/Jeffail/gabs)
-
-```
-Benchmark_SJSON-8 3000000 805 ns/op 1077 B/op 3 allocs/op
-Benchmark_SJSON_ReplaceInPlace-8 3000000 449 ns/op 0 B/op 0 allocs/op
-Benchmark_JSON_Map-8 300000 21236 ns/op 6392 B/op 150 allocs/op
-Benchmark_JSON_Struct-8 300000 14691 ns/op 1789 B/op 24 allocs/op
-Benchmark_Gabs-8 300000 21311 ns/op 6752 B/op 150 allocs/op
-Benchmark_FFJSON-8 300000 17673 ns/op 3589 B/op 47 allocs/op
-Benchmark_EasyJSON-8 1500000 3119 ns/op 1061 B/op 13 allocs/op
-```
-
-JSON document used:
-
-```json
-{
- "widget": {
- "debug": "on",
- "window": {
- "title": "Sample Konfabulator Widget",
- "name": "main_window",
- "width": 500,
- "height": 500
- },
- "image": {
- "src": "Images/Sun.png",
- "hOffset": 250,
- "vOffset": 250,
- "alignment": "center"
- },
- "text": {
- "data": "Click Here",
- "size": 36,
- "style": "bold",
- "vOffset": 100,
- "alignment": "center",
- "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
- }
- }
-}
-```
-
-Each operation was rotated though one of the following search paths:
-
-```
-widget.window.name
-widget.image.hOffset
-widget.text.onMouseUp
-```
-
-*These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.7.*
-
-## Contact
-Josh Baker [@tidwall](http://twitter.com/tidwall)
-
-## License
-
-SJSON source code is available under the MIT [License](/LICENSE).
diff --git a/cmd/ponzu/vendor/github.com/tidwall/sjson/logo.png b/cmd/ponzu/vendor/github.com/tidwall/sjson/logo.png
deleted file mode 100644
index b5aa257..0000000
--- a/cmd/ponzu/vendor/github.com/tidwall/sjson/logo.png
+++ /dev/null
Binary files differ
diff --git a/cmd/ponzu/vendor/github.com/tidwall/sjson/sjson.go b/cmd/ponzu/vendor/github.com/tidwall/sjson/sjson.go
deleted file mode 100644
index 7f1d358..0000000
--- a/cmd/ponzu/vendor/github.com/tidwall/sjson/sjson.go
+++ /dev/null
@@ -1,653 +0,0 @@
-// Package sjson provides setting json values.
-package sjson
-
-import (
- jsongo "encoding/json"
- "reflect"
- "strconv"
- "unsafe"
-
- "github.com/tidwall/gjson"
-)
-
-type errorType struct {
- msg string
-}
-
-func (err *errorType) Error() string {
- return err.msg
-}
-
-// Options represents additional options for the Set and Delete functions.
-type Options struct {
- // Optimistic is a hint that the value likely exists which
- // allows for the sjson to perform a fast-track search and replace.
- Optimistic bool
- // ReplaceInPlace is a hint to replace the input json rather than
- // allocate a new json byte slice. When this field is specified
- // the input json will not longer be valid and it should not be used
- // In the case when the destination slice doesn't have enough free
- // bytes to replace the data in place, a new bytes slice will be
- // created under the hood.
- // The Optimistic flag must be set to true and the input must be a
- // byte slice in order to use this field.
- ReplaceInPlace bool
-}
-
-type pathResult struct {
- part string // current key part
- path string // remaining path
- force bool // force a string key
- more bool // there is more path to parse
-}
-
-func parsePath(path string) (pathResult, error) {
- var r pathResult
- if len(path) > 0 && path[0] == ':' {
- r.force = true
- path = path[1:]
- }
- for i := 0; i < len(path); i++ {
- if path[i] == '.' {
- r.part = path[:i]
- r.path = path[i+1:]
- r.more = true
- return r, nil
- }
- if path[i] == '*' || path[i] == '?' {
- return r, &errorType{"wildcard characters not allowed in path"}
- } else if path[i] == '#' {
- return r, &errorType{"array access character not allowed in path"}
- }
- if path[i] == '\\' {
- // go into escape mode. this is a slower path that
- // strips off the escape character from the part.
- epart := []byte(path[:i])
- i++
- if i < len(path) {
- epart = append(epart, path[i])
- i++
- for ; i < len(path); i++ {
- if path[i] == '\\' {
- i++
- if i < len(path) {
- epart = append(epart, path[i])
- }
- continue
- } else if path[i] == '.' {
- r.part = string(epart)
- r.path = path[i+1:]
- r.more = true
- return r, nil
- } else if path[i] == '*' || path[i] == '?' {
- return r, &errorType{
- "wildcard characters not allowed in path"}
- } else if path[i] == '#' {
- return r, &errorType{
- "array access character not allowed in path"}
- }
- epart = append(epart, path[i])
- }
- }
- // append the last part
- r.part = string(epart)
- return r, nil
- }
- }
- r.part = path
- return r, nil
-}
-
-func mustMarshalString(s string) bool {
- for i := 0; i < len(s); i++ {
- if s[i] < ' ' || s[i] > 0x7f || s[i] == '"' {
- return true
- }
- }
- return false
-}
-
-// appendStringify makes a json string and appends to buf.
-func appendStringify(buf []byte, s string) []byte {
- if mustMarshalString(s) {
- b, _ := jsongo.Marshal(s)
- return append(buf, b...)
- }
- buf = append(buf, '"')
- buf = append(buf, s...)
- buf = append(buf, '"')
- return buf
-}
-
-// appendBuild builds a json block from a json path.
-func appendBuild(buf []byte, array bool, paths []pathResult, raw string,
- stringify bool) []byte {
- if !array {
- buf = appendStringify(buf, paths[0].part)
- buf = append(buf, ':')
- }
- if len(paths) > 1 {
- n, numeric := atoui(paths[1])
- if numeric || (!paths[1].force && paths[1].part == "-1") {
- buf = append(buf, '[')
- buf = appendRepeat(buf, "null,", n)
- buf = appendBuild(buf, true, paths[1:], raw, stringify)
- buf = append(buf, ']')
- } else {
- buf = append(buf, '{')
- buf = appendBuild(buf, false, paths[1:], raw, stringify)
- buf = append(buf, '}')
- }
- } else {
- if stringify {
- buf = appendStringify(buf, raw)
- } else {
- buf = append(buf, raw...)
- }
- }
- return buf
-}
-
-// atoui does a rip conversion of string -> unigned int.
-func atoui(r pathResult) (n int, ok bool) {
- if r.force {
- return 0, false
- }
- for i := 0; i < len(r.part); i++ {
- if r.part[i] < '0' || r.part[i] > '9' {
- return 0, false
- }
- n = n*10 + int(r.part[i]-'0')
- }
- return n, true
-}
-
-// appendRepeat repeats string "n" times and appends to buf.
-func appendRepeat(buf []byte, s string, n int) []byte {
- for i := 0; i < n; i++ {
- buf = append(buf, s...)
- }
- return buf
-}
-
-// trim does a rip trim
-func trim(s string) string {
- for len(s) > 0 {
- if s[0] <= ' ' {
- s = s[1:]
- continue
- }
- break
- }
- for len(s) > 0 {
- if s[len(s)-1] <= ' ' {
- s = s[:len(s)-1]
- continue
- }
- break
- }
- return s
-}
-
-// deleteTailItem deletes the previous key or comma.
-func deleteTailItem(buf []byte) ([]byte, bool) {
-loop:
- for i := len(buf) - 1; i >= 0; i-- {
- // look for either a ',',':','['
- switch buf[i] {
- case '[':
- return buf, true
- case ',':
- return buf[:i], false
- case ':':
- // delete tail string
- i--
- for ; i >= 0; i-- {
- if buf[i] == '"' {
- i--
- for ; i >= 0; i-- {
- if buf[i] == '"' {
- i--
- if i >= 0 && i == '\\' {
- i--
- continue
- }
- for ; i >= 0; i-- {
- // look for either a ',','{'
- switch buf[i] {
- case '{':
- return buf[:i+1], true
- case ',':
- return buf[:i], false
- }
- }
- }
- }
- break
- }
- }
- break loop
- }
- }
- return buf, false
-}
-
-var errNoChange = &errorType{"no change"}
-
-func appendRawPaths(buf []byte, jstr string, paths []pathResult, raw string,
- stringify, del bool) ([]byte, error) {
- var err error
- var res gjson.Result
- var found bool
- if del {
- if paths[0].part == "-1" && !paths[0].force {
- res = gjson.Get(jstr, "#")
- if res.Int() > 0 {
- res = gjson.Get(jstr, strconv.FormatInt(int64(res.Int()-1), 10))
- found = true
- }
- }
- }
- if !found {
- res = gjson.Get(jstr, paths[0].part)
- }
- if res.Index > 0 {
- if len(paths) > 1 {
- buf = append(buf, jstr[:res.Index]...)
- buf, err = appendRawPaths(buf, res.Raw, paths[1:], raw,
- stringify, del)
- if err != nil {
- return nil, err
- }
- buf = append(buf, jstr[res.Index+len(res.Raw):]...)
- return buf, nil
- }
- buf = append(buf, jstr[:res.Index]...)
- var exidx int // additional forward stripping
- if del {
- var delNextComma bool
- buf, delNextComma = deleteTailItem(buf)
- if delNextComma {
- i, j := res.Index+len(res.Raw), 0
- for ; i < len(jstr); i, j = i+1, j+1 {
- if jstr[i] <= ' ' {
- continue
- }
- if jstr[i] == ',' {
- exidx = j + 1
- }
- break
- }
- }
- } else {
- if stringify {
- buf = appendStringify(buf, raw)
- } else {
- buf = append(buf, raw...)
- }
- }
- buf = append(buf, jstr[res.Index+len(res.Raw)+exidx:]...)
- return buf, nil
- }
- if del {
- return nil, errNoChange
- }
- n, numeric := atoui(paths[0])
- isempty := true
- for i := 0; i < len(jstr); i++ {
- if jstr[i] > ' ' {
- isempty = false
- break
- }
- }
- if isempty {
- if numeric {
- jstr = "[]"
- } else {
- jstr = "{}"
- }
- }
- jsres := gjson.Parse(jstr)
- if jsres.Type != gjson.JSON {
- if numeric {
- jstr = "[]"
- } else {
- jstr = "{}"
- }
- jsres = gjson.Parse(jstr)
- }
- var comma bool
- for i := 1; i < len(jsres.Raw); i++ {
- if jsres.Raw[i] <= ' ' {
- continue
- }
- if jsres.Raw[i] == '}' || jsres.Raw[i] == ']' {
- break
- }
- comma = true
- break
- }
- switch jsres.Raw[0] {
- default:
- return nil, &errorType{"json must be an object or array"}
- case '{':
- buf = append(buf, '{')
- buf = appendBuild(buf, false, paths, raw, stringify)
- if comma {
- buf = append(buf, ',')
- }
- buf = append(buf, jsres.Raw[1:]...)
- return buf, nil
- case '[':
- var appendit bool
- if !numeric {
- if paths[0].part == "-1" && !paths[0].force {
- appendit = true
- } else {
- return nil, &errorType{
- "cannot set array element for non-numeric key '" +
- paths[0].part + "'"}
- }
- }
- if appendit {
- njson := trim(jsres.Raw)
- if njson[len(njson)-1] == ']' {
- njson = njson[:len(njson)-1]
- }
- buf = append(buf, njson...)
- if comma {
- buf = append(buf, ',')
- }
-
- buf = appendBuild(buf, true, paths, raw, stringify)
- buf = append(buf, ']')
- return buf, nil
- }
- buf = append(buf, '[')
- ress := jsres.Array()
- for i := 0; i < len(ress); i++ {
- if i > 0 {
- buf = append(buf, ',')
- }
- buf = append(buf, ress[i].Raw...)
- }
- if len(ress) == 0 {
- buf = appendRepeat(buf, "null,", n-len(ress))
- } else {
- buf = appendRepeat(buf, ",null", n-len(ress))
- if comma {
- buf = append(buf, ',')
- }
- }
- buf = appendBuild(buf, true, paths, raw, stringify)
- buf = append(buf, ']')
- return buf, nil
- }
-}
-
-func isOptimisticPath(path string) bool {
- for i := 0; i < len(path); i++ {
- if path[i] < '.' || path[i] > 'z' {
- return false
- }
- if path[i] > '9' && path[i] < 'A' {
- return false
- }
- if path[i] > 'z' {
- return false
- }
- }
- return true
-}
-
-func set(jstr, path, raw string,
- stringify, del, optimistic, inplace bool) ([]byte, error) {
- if path == "" {
- return nil, &errorType{"path cannot be empty"}
- }
- if !del && optimistic && isOptimisticPath(path) {
- res := gjson.Get(jstr, path)
- if res.Exists() && res.Index > 0 {
- sz := len(jstr) - len(res.Raw) + len(raw)
- if stringify {
- sz += 2
- }
- if inplace && sz <= len(jstr) {
- if !stringify || !mustMarshalString(raw) {
- jsonh := *(*reflect.StringHeader)(unsafe.Pointer(&jstr))
- jsonbh := reflect.SliceHeader{
- Data: jsonh.Data, Len: jsonh.Len, Cap: jsonh.Len}
- jbytes := *(*[]byte)(unsafe.Pointer(&jsonbh))
- if stringify {
- jbytes[res.Index] = '"'
- copy(jbytes[res.Index+1:], []byte(raw))
- jbytes[res.Index+1+len(raw)] = '"'
- copy(jbytes[res.Index+1+len(raw)+1:],
- jbytes[res.Index+len(res.Raw):])
- } else {
- copy(jbytes[res.Index:], []byte(raw))
- copy(jbytes[res.Index+len(raw):],
- jbytes[res.Index+len(res.Raw):])
- }
- return jbytes[:sz], nil
- }
- return nil, nil
- }
- buf := make([]byte, 0, sz)
- buf = append(buf, jstr[:res.Index]...)
- if stringify {
- buf = appendStringify(buf, raw)
- } else {
- buf = append(buf, raw...)
- }
- buf = append(buf, jstr[res.Index+len(res.Raw):]...)
- return buf, nil
- }
- }
- // parse the path, make sure that it does not contain invalid characters
- // such as '#', '?', '*'
- paths := make([]pathResult, 0, 4)
- r, err := parsePath(path)
- if err != nil {
- return nil, err
- }
- paths = append(paths, r)
- for r.more {
- if r, err = parsePath(r.path); err != nil {
- return nil, err
- }
- paths = append(paths, r)
- }
-
- njson, err := appendRawPaths(nil, jstr, paths, raw, stringify, del)
- if err != nil {
- return nil, err
- }
- return njson, nil
-}
-
-// Set sets a json value for the specified path.
-// A path is in dot syntax, such as "name.last" or "age".
-// This function expects that the json is well-formed, and does not validate.
-// Invalid json will not panic, but it may return back unexpected results.
-// An error is returned if the path is not valid.
-//
-// A path is a series of keys separated by a dot.
-//
-// {
-// "name": {"first": "Tom", "last": "Anderson"},
-// "age":37,
-// "children": ["Sara","Alex","Jack"],
-// "friends": [
-// {"first": "James", "last": "Murphy"},
-// {"first": "Roger", "last": "Craig"}
-// ]
-// }
-// "name.last" >> "Anderson"
-// "age" >> 37
-// "children.1" >> "Alex"
-//
-func Set(json, path string, value interface{}) (string, error) {
- return SetOptions(json, path, value, nil)
-}
-
-// SetOptions sets a json value for the specified path with options.
-// A path is in dot syntax, such as "name.last" or "age".
-// This function expects that the json is well-formed, and does not validate.
-// Invalid json will not panic, but it may return back unexpected results.
-// An error is returned if the path is not valid.
-func SetOptions(json, path string, value interface{},
- opts *Options) (string, error) {
- if opts != nil {
- if opts.ReplaceInPlace {
- // it's not safe to replace bytes in-place for strings
- // copy the Options and set options.ReplaceInPlace to false.
- nopts := *opts
- opts = &nopts
- opts.ReplaceInPlace = false
- }
- }
- jsonh := *(*reflect.StringHeader)(unsafe.Pointer(&json))
- jsonbh := reflect.SliceHeader{Data: jsonh.Data, Len: jsonh.Len}
- jsonb := *(*[]byte)(unsafe.Pointer(&jsonbh))
- res, err := SetBytesOptions(jsonb, path, value, opts)
- return string(res), err
-}
-
-// SetBytes sets a json value for the specified path.
-// If working with bytes, this method preferred over
-// Set(string(data), path, value)
-func SetBytes(json []byte, path string, value interface{}) ([]byte, error) {
- return SetBytesOptions(json, path, value, nil)
-}
-
-// SetBytesOptions sets a json value for the specified path with options.
-// If working with bytes, this method preferred over
-// SetOptions(string(data), path, value)
-func SetBytesOptions(json []byte, path string, value interface{},
- opts *Options) ([]byte, error) {
- var optimistic, inplace bool
- if opts != nil {
- optimistic = opts.Optimistic
- inplace = opts.ReplaceInPlace
- }
- jstr := *(*string)(unsafe.Pointer(&json))
- var res []byte
- var err error
- switch v := value.(type) {
- default:
- b, err := jsongo.Marshal(value)
- if err != nil {
- return nil, err
- }
- raw := *(*string)(unsafe.Pointer(&b))
- res, err = set(jstr, path, raw, false, false, optimistic, inplace)
- case dtype:
- res, err = set(jstr, path, "", false, true, optimistic, inplace)
- case string:
- res, err = set(jstr, path, v, true, false, optimistic, inplace)
- case []byte:
- raw := *(*string)(unsafe.Pointer(&v))
- res, err = set(jstr, path, raw, true, false, optimistic, inplace)
- case bool:
- if v {
- res, err = set(jstr, path, "true", false, false, optimistic, inplace)
- } else {
- res, err = set(jstr, path, "false", false, false, optimistic, inplace)
- }
- case int8:
- res, err = set(jstr, path, strconv.FormatInt(int64(v), 10),
- false, false, optimistic, inplace)
- case int16:
- res, err = set(jstr, path, strconv.FormatInt(int64(v), 10),
- false, false, optimistic, inplace)
- case int32:
- res, err = set(jstr, path, strconv.FormatInt(int64(v), 10),
- false, false, optimistic, inplace)
- case int64:
- res, err = set(jstr, path, strconv.FormatInt(int64(v), 10),
- false, false, optimistic, inplace)
- case uint8:
- res, err = set(jstr, path, strconv.FormatUint(uint64(v), 10),
- false, false, optimistic, inplace)
- case uint16:
- res, err = set(jstr, path, strconv.FormatUint(uint64(v), 10),
- false, false, optimistic, inplace)
- case uint32:
- res, err = set(jstr, path, strconv.FormatUint(uint64(v), 10),
- false, false, optimistic, inplace)
- case uint64:
- res, err = set(jstr, path, strconv.FormatUint(uint64(v), 10),
- false, false, optimistic, inplace)
- case float32:
- res, err = set(jstr, path, strconv.FormatFloat(float64(v), 'f', -1, 64),
- false, false, optimistic, inplace)
- case float64:
- res, err = set(jstr, path, strconv.FormatFloat(float64(v), 'f', -1, 64),
- false, false, optimistic, inplace)
- }
- if err == errNoChange {
- return json, nil
- }
- return res, err
-}
-
-// SetRaw sets a raw json value for the specified path.
-// This function works the same as Set except that the value is set as a
-// raw block of json. This allows for setting premarshalled json objects.
-func SetRaw(json, path, value string) (string, error) {
- return SetRawOptions(json, path, value, nil)
-}
-
-// SetRawOptions sets a raw json value for the specified path with options.
-// This furnction works the same as SetOptions except that the value is set
-// as a raw block of json. This allows for setting premarshalled json objects.
-func SetRawOptions(json, path, value string, opts *Options) (string, error) {
- var optimistic bool
- if opts != nil {
- optimistic = opts.Optimistic
- }
- res, err := set(json, path, value, false, false, optimistic, false)
- if err == errNoChange {
- return json, nil
- }
- return string(res), err
-}
-
-// SetRawBytes sets a raw json value for the specified path.
-// If working with bytes, this method preferred over
-// SetRaw(string(data), path, value)
-func SetRawBytes(json []byte, path string, value []byte) ([]byte, error) {
- return SetRawBytesOptions(json, path, value, nil)
-}
-
-// SetRawBytesOptions sets a raw json value for the specified path with options.
-// If working with bytes, this method preferred over
-// SetRawOptions(string(data), path, value, opts)
-func SetRawBytesOptions(json []byte, path string, value []byte,
- opts *Options) ([]byte, error) {
- jstr := *(*string)(unsafe.Pointer(&json))
- vstr := *(*string)(unsafe.Pointer(&value))
- var optimistic, inplace bool
- if opts != nil {
- optimistic = opts.Optimistic
- inplace = opts.ReplaceInPlace
- }
- res, err := set(jstr, path, vstr, false, false, optimistic, inplace)
- if err == errNoChange {
- return json, nil
- }
- return res, err
-}
-
-type dtype struct{}
-
-// Delete deletes a value from json for the specified path.
-func Delete(json, path string) (string, error) {
- return Set(json, path, dtype{})
-}
-
-// DeleteBytes deletes a value from json for the specified path.
-func DeleteBytes(json []byte, path string) ([]byte, error) {
- return SetBytes(json, path, dtype{})
-}