Compare commits
10 commits
6f969b6d5f
...
60d2daca40
Author | SHA1 | Date | |
---|---|---|---|
DataHoarder | 60d2daca40 | ||
DataHoarder | 2410a4c5e9 | ||
df897aec9d | |||
3d5ab28ab3 | |||
9b91208837 | |||
8e8cdeacf2 | |||
5e6fe10846 | |||
4d199a4b2c | |||
098041a708 | |||
fbd4feeb60 |
44
.github/workflows/go.yml
vendored
44
.github/workflows/go.yml
vendored
|
@ -10,23 +10,24 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: build
|
||||
run: docker-compose run go-json
|
||||
|
||||
test:
|
||||
name: Test
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ "ubuntu-latest", "macos-latest", "windows-latest" ]
|
||||
go-version: [ "1.16", "1.17", "1.18" ]
|
||||
go-version: [ "1.19", "1.20", "1.21" ]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: setup Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: simple test
|
||||
run: go test -v ./... -count=1
|
||||
- name: test with GC pressure
|
||||
|
@ -35,41 +36,56 @@ jobs:
|
|||
GOGC: 1
|
||||
- name: test with race detector
|
||||
run: go test -v -race ./... -count=1
|
||||
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: setup Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.21'
|
||||
- name: lint
|
||||
run: |
|
||||
make lint
|
||||
bench:
|
||||
name: Benchmark
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: setup Go
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.18
|
||||
go-version: '1.21'
|
||||
- name: checkout ( feature )
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: run benchmark ( feature )
|
||||
run: cd benchmarks && go test -bench GoJson | tee $HOME/new.txt
|
||||
- name: install benchstat
|
||||
run: go install golang.org/x/perf/cmd/benchstat@latest
|
||||
- name: checkout ( master )
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: master
|
||||
- name: run benchmark ( master )
|
||||
run: cd benchmarks && go test -bench GoJson | tee $HOME/old.txt
|
||||
- name: compare benchmark results
|
||||
run: benchstat $HOME/old.txt $HOME/new.txt
|
||||
|
||||
coverage:
|
||||
name: Coverage
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.18
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: setup Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.21'
|
||||
- name: measure coverage
|
||||
run: make cover
|
||||
- uses: codecov/codecov-action@v2
|
||||
- uses: codecov/codecov-action@v3
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
||||
|
|
16
.github/workflows/lint.yml
vendored
16
.github/workflows/lint.yml
vendored
|
@ -1,16 +0,0 @@
|
|||
name: lint
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
jobs:
|
||||
golangci:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: v1.45.2
|
||||
args: --timeout=5m
|
|
@ -56,6 +56,9 @@ linters:
|
|||
- cyclop
|
||||
- containedctx
|
||||
- revive
|
||||
- nosnakecase
|
||||
- exhaustruct
|
||||
- depguard
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
|
|
22
CHANGELOG.md
22
CHANGELOG.md
|
@ -1,3 +1,25 @@
|
|||
# v0.10.2 - 2023/03/20
|
||||
|
||||
### New features
|
||||
|
||||
* Support DebugDOT option for debugging encoder ( #440 )
|
||||
|
||||
### Fix bugs
|
||||
|
||||
* Fix combination of embedding structure and omitempty option ( #442 )
|
||||
|
||||
# v0.10.1 - 2023/03/13
|
||||
|
||||
### Fix bugs
|
||||
|
||||
* Fix checkptr error for array decoder ( #415 )
|
||||
* Fix added buffer size check when decoding key ( #430 )
|
||||
* Fix handling of anonymous fields other than struct ( #431 )
|
||||
* Fix to not optimize when lower conversion can't handle byte-by-byte ( #432 )
|
||||
* Fix a problem that MarshalIndent does not work when UnorderedMap is specified ( #435 )
|
||||
* Fix mapDecoder.DecodeStream() for empty objects containing whitespace ( #425 )
|
||||
* Fix an issue that could not set the correct NextField for fields in the embedded structure ( #438 )
|
||||
|
||||
# v0.10.0 - 2022/11/29
|
||||
|
||||
### New features
|
||||
|
|
4
Makefile
4
Makefile
|
@ -1,4 +1,4 @@
|
|||
PKG := github.com/goccy/go-json
|
||||
PKG := git.gammaspectra.live/P2Pool/go-json
|
||||
|
||||
BIN_DIR := $(CURDIR)/bin
|
||||
PKGS := $(shell go list ./... | grep -v internal/cmd|grep -v test)
|
||||
|
@ -30,7 +30,7 @@ golangci-lint: | $(BIN_DIR)
|
|||
GOLANGCI_LINT_TMP_DIR=$$(mktemp -d); \
|
||||
cd $$GOLANGCI_LINT_TMP_DIR; \
|
||||
go mod init tmp; \
|
||||
GOBIN=$(BIN_DIR) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.48.0; \
|
||||
GOBIN=$(BIN_DIR) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.2; \
|
||||
rm -rf $$GOLANGCI_LINT_TMP_DIR; \
|
||||
}
|
||||
|
||||
|
|
22
README.md
22
README.md
|
@ -1,7 +1,7 @@
|
|||
# go-json
|
||||
|
||||
![Go](https://github.com/goccy/go-json/workflows/Go/badge.svg)
|
||||
[![GoDoc](https://godoc.org/github.com/goccy/go-json?status.svg)](https://pkg.go.dev/github.com/goccy/go-json?tab=doc)
|
||||
![Go](https://git.gammaspectra.live/P2Pool/go-json/workflows/Go/badge.svg)
|
||||
[![GoDoc](https://godoc.org/git.gammaspectra.live/P2Pool/go-json?status.svg)](https://pkg.go.dev/git.gammaspectra.live/P2Pool/go-json?tab=doc)
|
||||
[![codecov](https://codecov.io/gh/goccy/go-json/branch/master/graph/badge.svg)](https://codecov.io/gh/goccy/go-json)
|
||||
|
||||
Fast JSON encoder/decoder compatible with encoding/json for Go
|
||||
|
@ -22,12 +22,12 @@ Fast JSON encoder/decoder compatible with encoding/json for Go
|
|||
```
|
||||
|
||||
We are accepting requests for features that will be implemented between v0.9.0 and v.1.0.0.
|
||||
If you have the API you need, please submit your issue [here](https://github.com/goccy/go-json/issues).
|
||||
If you have the API you need, please submit your issue [here](https://git.gammaspectra.live/P2Pool/go-json/issues).
|
||||
|
||||
# Features
|
||||
|
||||
- Drop-in replacement of `encoding/json`
|
||||
- Fast ( See [Benchmark section](https://github.com/goccy/go-json#benchmarks) )
|
||||
- Fast ( See [Benchmark section](https://git.gammaspectra.live/P2Pool/go-json#benchmarks) )
|
||||
- Flexible customization with options
|
||||
- Coloring the encoded string
|
||||
- Can propagate context.Context to `MarshalJSON` or `UnmarshalJSON`
|
||||
|
@ -36,16 +36,16 @@ If you have the API you need, please submit your issue [here](https://github.com
|
|||
# Installation
|
||||
|
||||
```
|
||||
go get github.com/goccy/go-json
|
||||
go get git.gammaspectra.live/P2Pool/go-json
|
||||
```
|
||||
|
||||
# How to use
|
||||
|
||||
Replace import statement from `encoding/json` to `github.com/goccy/go-json`
|
||||
Replace import statement from `encoding/json` to `git.gammaspectra.live/P2Pool/go-json`
|
||||
|
||||
```
|
||||
-import "encoding/json"
|
||||
+import "github.com/goccy/go-json"
|
||||
+import "git.gammaspectra.live/P2Pool/go-json"
|
||||
```
|
||||
|
||||
# JSON library comparison
|
||||
|
@ -98,8 +98,8 @@ $ go test -bench .
|
|||
|
||||
# Fuzzing
|
||||
|
||||
[go-json-fuzz](https://github.com/goccy/go-json-fuzz) is the repository for fuzzing tests.
|
||||
If you run the test in this repository and find a bug, please commit to corpus to go-json-fuzz and report the issue to [go-json](https://github.com/goccy/go-json/issues).
|
||||
[go-json-fuzz](https://git.gammaspectra.live/P2Pool/go-json-fuzz) is the repository for fuzzing tests.
|
||||
If you run the test in this repository and find a bug, please commit to corpus to go-json-fuzz and report the issue to [go-json](https://git.gammaspectra.live/P2Pool/go-json/issues).
|
||||
|
||||
# How it works
|
||||
|
||||
|
@ -192,7 +192,7 @@ For this reason, to date `reflect.Type` is the same as `*reflect.rtype`.
|
|||
|
||||
Therefore, by directly handling `*reflect.rtype`, which is an implementation of `reflect.Type`, it is possible to avoid escaping because it changes from `interface` to using `struct`.
|
||||
|
||||
The technique for working with `*reflect.rtype` directly from `go-json` is implemented at [rtype.go](https://github.com/goccy/go-json/blob/master/internal/runtime/rtype.go)
|
||||
The technique for working with `*reflect.rtype` directly from `go-json` is implemented at [rtype.go](https://git.gammaspectra.live/P2Pool/go-json/blob/master/internal/runtime/rtype.go)
|
||||
|
||||
Also, the same technique is cut out as a library ( https://github.com/goccy/go-reflect )
|
||||
|
||||
|
@ -353,7 +353,7 @@ However, if there is too much type information, it will use a lot of memory, so
|
|||
|
||||
If this approach is not available, it will fall back to the `atomic` based process described above.
|
||||
|
||||
If you want to know more, please refer to the implementation [here](https://github.com/goccy/go-json/blob/master/internal/runtime/type.go#L36-L100)
|
||||
If you want to know more, please refer to the implementation [here](https://git.gammaspectra.live/P2Pool/go-json/blob/master/internal/runtime/type.go#L36-L100)
|
||||
|
||||
## Decoder
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
stdjson "encoding/json"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
segmentiojson "github.com/segmentio/encoding/json"
|
||||
"github.com/wI2L/jettison"
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
gojson "git.gammaspectra.live/P2Pool/go-json"
|
||||
gojay "github.com/francoispqt/gojay"
|
||||
gojson "github.com/goccy/go-json"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
segmentiojson "github.com/segmentio/encoding/json"
|
||||
fastjson "github.com/valyala/fastjson"
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
gojson "git.gammaspectra.live/P2Pool/go-json"
|
||||
gojay "github.com/francoispqt/gojay"
|
||||
gojson "github.com/goccy/go-json"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/pquerna/ffjson/ffjson"
|
||||
segmentiojson "github.com/segmentio/encoding/json"
|
||||
|
|
|
@ -4,7 +4,7 @@ go 1.12
|
|||
|
||||
require (
|
||||
github.com/francoispqt/gojay v1.2.13
|
||||
github.com/goccy/go-json v0.0.0-00010101000000-000000000000
|
||||
git.gammaspectra.live/P2Pool/go-json v0.0.0-00010101000000-000000000000
|
||||
github.com/json-iterator/go v1.1.10
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe
|
||||
github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7
|
||||
|
@ -14,4 +14,4 @@ require (
|
|||
github.com/wI2L/jettison v0.7.1
|
||||
)
|
||||
|
||||
replace github.com/goccy/go-json => ../
|
||||
replace git.gammaspectra.live/P2Pool/go-json => ../
|
||||
|
|
|
@ -3,7 +3,7 @@ package benchmark
|
|||
import (
|
||||
"testing"
|
||||
|
||||
gojson "github.com/goccy/go-json"
|
||||
gojson "git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func Benchmark_Decode_SmallStruct_UnmarshalPath_GoJson(b *testing.B) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
gojson "github.com/goccy/go-json"
|
||||
gojson "git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
// Benchmark decoding from a slow io.Reader that never fills the buffer completely
|
||||
|
|
2
color.go
2
color.go
|
@ -3,7 +3,7 @@ package json
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
)
|
||||
|
||||
type (
|
||||
|
|
|
@ -3,7 +3,7 @@ package json_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestColorize(t *testing.T) {
|
||||
|
|
|
@ -7,9 +7,9 @@ import (
|
|||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/decoder"
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/decoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type Decoder struct {
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func Test_Decoder(t *testing.T) {
|
||||
|
@ -123,7 +123,7 @@ func Test_Decoder(t *testing.T) {
|
|||
assertEq(t, "map.c", v["c"], 3)
|
||||
assertEq(t, "map.d", v["d"], 4)
|
||||
t.Run("nested map", func(t *testing.T) {
|
||||
// https://github.com/goccy/go-json/issues/8
|
||||
// https://git.gammaspectra.live/P2Pool/go-json/issues/8
|
||||
content := `
|
||||
{
|
||||
"a": {
|
||||
|
@ -197,6 +197,13 @@ func Test_Decoder(t *testing.T) {
|
|||
assertEq(t, "interface{}", v.F, nil)
|
||||
assertEq(t, "nilfunc", true, v.G == nil)
|
||||
})
|
||||
t.Run("struct.pointer must be nil", func(t *testing.T) {
|
||||
var v struct {
|
||||
A *int
|
||||
}
|
||||
json.Unmarshal([]byte(`{"a": "alpha"}`), &v)
|
||||
assertEq(t, "struct.A", v.A, (*int)(nil))
|
||||
})
|
||||
})
|
||||
t.Run("interface", func(t *testing.T) {
|
||||
t.Run("number", func(t *testing.T) {
|
||||
|
|
14
encode.go
14
encode.go
|
@ -6,11 +6,11 @@ import (
|
|||
"os"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"github.com/goccy/go-json/internal/encoder/vm"
|
||||
"github.com/goccy/go-json/internal/encoder/vm_color"
|
||||
"github.com/goccy/go-json/internal/encoder/vm_color_indent"
|
||||
"github.com/goccy/go-json/internal/encoder/vm_indent"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder/vm"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder/vm_color"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder/vm_color_indent"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder/vm_indent"
|
||||
)
|
||||
|
||||
// An Encoder writes JSON values to an output stream.
|
||||
|
@ -52,7 +52,7 @@ func (e *Encoder) EncodeContext(ctx context.Context, v interface{}, optFuncs ...
|
|||
rctx.Option.Flag |= encoder.ContextOption
|
||||
rctx.Option.Context = ctx
|
||||
|
||||
err := e.encodeWithOption(rctx, v, optFuncs...)
|
||||
err := e.encodeWithOption(rctx, v, optFuncs...) //nolint: contextcheck
|
||||
|
||||
encoder.ReleaseRuntimeContext(rctx)
|
||||
return err
|
||||
|
@ -120,7 +120,7 @@ func marshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOption
|
|||
optFunc(rctx.Option)
|
||||
}
|
||||
|
||||
buf, err := encode(rctx, v)
|
||||
buf, err := encode(rctx, v) //nolint: contextcheck
|
||||
if err != nil {
|
||||
encoder.ReleaseRuntimeContext(rctx)
|
||||
return nil, err
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
type recursiveT struct {
|
||||
|
@ -2694,3 +2694,19 @@ func TestIssue426(t *testing.T) {
|
|||
b, _ := json.Marshal(s)
|
||||
assertEq(t, "unexpected result", `{"I":null,"Val":"456"}`, string(b))
|
||||
}
|
||||
|
||||
func TestIssue441(t *testing.T) {
|
||||
type A struct {
|
||||
Y string `json:"y,omitempty"`
|
||||
}
|
||||
|
||||
type B struct {
|
||||
X *int `json:"x,omitempty"`
|
||||
A
|
||||
Z int `json:"z,omitempty"`
|
||||
}
|
||||
|
||||
b, err := json.Marshal(B{})
|
||||
assertErr(t, err)
|
||||
assertEq(t, "unexpected result", "{}", string(b))
|
||||
}
|
||||
|
|
2
error.go
2
error.go
|
@ -1,7 +1,7 @@
|
|||
package json
|
||||
|
||||
import (
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package json
|
||||
|
||||
import (
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
4
go.mod
4
go.mod
|
@ -1,3 +1,3 @@
|
|||
module github.com/goccy/go-json
|
||||
module git.gammaspectra.live/P2Pool/go-json
|
||||
|
||||
go 1.12
|
||||
go 1.19
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
@ -273,11 +273,11 @@ func (t OpType) FieldToOmitEmptyField() OpType {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(path, buf, 0644)
|
||||
return os.WriteFile(path, buf, 0644)
|
||||
}
|
||||
|
||||
func generateVM() error {
|
||||
file, err := ioutil.ReadFile("vm.go.tmpl")
|
||||
file, err := os.ReadFile("vm.go.tmpl")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ func generateVM() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(path, source, 0644); err != nil {
|
||||
if err := os.WriteFile(path, source, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"sort"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
|
|
|
@ -3,7 +3,7 @@ package decoder
|
|||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type anonymousFieldDecoder struct {
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type arrayDecoder struct {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
type boolDecoder struct {
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type bytesDecoder struct {
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"unicode"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -6,7 +6,7 @@ package decoder
|
|||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
func CompileToGetDecoder(typ *runtime.Type) (Decoder, error) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
var decMu sync.RWMutex
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
type RuntimeContext struct {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
type floatDecoder struct {
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type funcDecoder struct {
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type intDecoder struct {
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type interfaceDecoder struct {
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type invalidDecoder struct {
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type mapDecoder struct {
|
||||
|
@ -36,7 +36,7 @@ const (
|
|||
mapMaxElemSize = 128
|
||||
)
|
||||
|
||||
// See detail: https://github.com/goccy/go-json/pull/283
|
||||
// See detail: https://git.gammaspectra.live/P2Pool/go-json/pull/283
|
||||
func canUseAssignFaststrType(key *runtime.Type, value *runtime.Type) bool {
|
||||
indirectElem := value.Size() > mapMaxElemSize
|
||||
if indirectElem {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
type numberDecoder struct {
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type PathString string
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type ptrDecoder struct {
|
||||
|
@ -85,6 +85,7 @@ func (d *ptrDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.P
|
|||
}
|
||||
c, err := d.dec.Decode(ctx, cursor, depth, newptr)
|
||||
if err != nil {
|
||||
*(*unsafe.Pointer)(p) = nil
|
||||
return 0, err
|
||||
}
|
||||
cursor = c
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"unicode/utf8"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
type stringDecoder struct {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
type structFieldSet struct {
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type uintDecoder struct {
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type unmarshalJSONDecoder struct {
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"unicode/utf8"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type unmarshalTextDecoder struct {
|
||||
|
@ -147,7 +147,7 @@ func (d *unmarshalTextDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int
|
|||
return nil, 0, fmt.Errorf("json: unmarshal text decoder does not support decode path")
|
||||
}
|
||||
|
||||
func unquoteBytes(s []byte) (t []byte, ok bool) {
|
||||
func unquoteBytes(s []byte) (t []byte, ok bool) { //nolint: nonamedreturns
|
||||
length := len(s)
|
||||
if length < 2 || s[0] != '"' || s[length-1] != '"' {
|
||||
return
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type wrappedStringDecoder struct {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type Code interface {
|
||||
|
@ -397,7 +397,7 @@ func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *
|
|||
func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
|
||||
// firstField is special StructHead operation for anonymous structure.
|
||||
// So, StructHead's next operation is truly struct head operation.
|
||||
for firstField.Op == OpStructHead {
|
||||
for firstField.Op == OpStructHead || firstField.Op == OpStructField {
|
||||
firstField = firstField.Next
|
||||
}
|
||||
lastField := firstField
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"sync/atomic"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type marshalerContext interface {
|
||||
|
@ -489,7 +489,7 @@ func (c *Compiler) listElemCode(typ *runtime.Type) (Code, error) {
|
|||
default:
|
||||
// isPtr was originally used to indicate whether the type of top level is pointer.
|
||||
// However, since the slice/array element is a specification that can get the pointer address, explicitly set isPtr to true.
|
||||
// See here for related issues: https://github.com/goccy/go-json/issues/370
|
||||
// See here for related issues: https://git.gammaspectra.live/P2Pool/go-json/issues/370
|
||||
code, err := c.typeToCodeWithPtr(typ, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
type compileContext struct {
|
||||
|
|
|
@ -13,8 +13,8 @@ import (
|
|||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
func (t OpType) IsMultipleOpHead() bool {
|
||||
|
@ -589,6 +589,8 @@ func IsNilForMarshaler(v interface{}) bool {
|
|||
return rv.IsNil()
|
||||
case reflect.Slice:
|
||||
return rv.IsNil() || rv.Len() == 0
|
||||
case reflect.Array:
|
||||
return rv.IsZero()
|
||||
case reflect.String:
|
||||
return rv.Len() == 0
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/errors"
|
||||
)
|
||||
|
||||
func takeIndentSrcRuntimeContext(src []byte) (*RuntimeContext, []byte) {
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
// This files's processing codes are inspired by https://github.com/segmentio/encoding.
|
||||
// The license notation is as follows.
|
||||
//
|
||||
// # MIT License
|
||||
//
|
||||
// Copyright (c) 2019 Segment.io, Inc.
|
||||
//
|
||||
// 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.
|
||||
package encoder
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package encoder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
const uintptrSize = 4 << (^uintptr(0) >> 63)
|
||||
|
@ -555,6 +557,87 @@ func (c *Opcode) Dump() string {
|
|||
return strings.Join(codes, "\n")
|
||||
}
|
||||
|
||||
func (c *Opcode) DumpDOT() string {
|
||||
type edge struct {
|
||||
from, to *Opcode
|
||||
label string
|
||||
weight int
|
||||
}
|
||||
var edges []edge
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "digraph \"%p\" {\n", c.Type)
|
||||
fmt.Fprintln(b, "mclimit=1.5;\nrankdir=TD;\nordering=out;\nnode[shape=box];")
|
||||
for code := c; !code.IsEnd(); {
|
||||
label := code.Op.String()
|
||||
fmt.Fprintf(b, "\"%p\" [label=%q];\n", code, label)
|
||||
if p := code.Next; p != nil {
|
||||
edges = append(edges, edge{
|
||||
from: code,
|
||||
to: p,
|
||||
label: "Next",
|
||||
weight: 10,
|
||||
})
|
||||
}
|
||||
if p := code.NextField; p != nil {
|
||||
edges = append(edges, edge{
|
||||
from: code,
|
||||
to: p,
|
||||
label: "NextField",
|
||||
weight: 2,
|
||||
})
|
||||
}
|
||||
if p := code.End; p != nil {
|
||||
edges = append(edges, edge{
|
||||
from: code,
|
||||
to: p,
|
||||
label: "End",
|
||||
weight: 1,
|
||||
})
|
||||
}
|
||||
if p := code.Jmp; p != nil {
|
||||
edges = append(edges, edge{
|
||||
from: code,
|
||||
to: p.Code,
|
||||
label: "Jmp",
|
||||
weight: 1,
|
||||
})
|
||||
}
|
||||
|
||||
switch code.Op.CodeType() {
|
||||
case CodeSliceHead:
|
||||
code = code.Next
|
||||
case CodeMapHead:
|
||||
code = code.Next
|
||||
case CodeArrayElem, CodeSliceElem:
|
||||
code = code.End
|
||||
case CodeMapKey:
|
||||
code = code.End
|
||||
case CodeMapValue:
|
||||
code = code.Next
|
||||
case CodeMapEnd:
|
||||
code = code.Next
|
||||
case CodeStructField:
|
||||
code = code.Next
|
||||
case CodeStructEnd:
|
||||
code = code.Next
|
||||
default:
|
||||
code = code.Next
|
||||
}
|
||||
if code.IsEnd() {
|
||||
fmt.Fprintf(b, "\"%p\" [label=%q];\n", code, code.Op.String())
|
||||
}
|
||||
}
|
||||
sort.Slice(edges, func(i, j int) bool {
|
||||
return edges[i].to.DisplayIdx < edges[j].to.DisplayIdx
|
||||
})
|
||||
for _, e := range edges {
|
||||
fmt.Fprintf(b, "\"%p\" -> \"%p\" [label=%q][weight=%d];\n", e.from, e.to, e.label, e.weight)
|
||||
}
|
||||
fmt.Fprint(b, "}")
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func newSliceHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode {
|
||||
idx := opcodeOffset(ctx.ptrIndex)
|
||||
ctx.incPtrIndex()
|
||||
|
|
|
@ -23,6 +23,7 @@ type Option struct {
|
|||
ColorScheme *ColorScheme
|
||||
Context context.Context
|
||||
DebugOut io.Writer
|
||||
DebugDOTOut io.WriteCloser
|
||||
}
|
||||
|
||||
type EncodeFormat struct {
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
// This files's string processing codes are inspired by https://github.com/segmentio/encoding.
|
||||
// The license notation is as follows.
|
||||
//
|
||||
// # MIT License
|
||||
//
|
||||
// Copyright (c) 2019 Segment.io, Inc.
|
||||
//
|
||||
// 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.
|
||||
package encoder
|
||||
|
||||
import (
|
||||
|
|
|
@ -2,8 +2,9 @@ package vm
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
)
|
||||
|
||||
func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
|
@ -14,6 +15,11 @@ func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet)
|
|||
} else {
|
||||
code = codeSet.NoescapeKeyCode
|
||||
}
|
||||
if wc := ctx.Option.DebugDOTOut; wc != nil {
|
||||
_, _ = io.WriteString(wc, code.DumpDOT())
|
||||
wc.Close()
|
||||
ctx.Option.DebugDOTOut = nil
|
||||
}
|
||||
|
||||
if err := recover(); err != nil {
|
||||
w := ctx.Option.DebugOut
|
||||
|
|
|
@ -5,5 +5,5 @@ import (
|
|||
// `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile,
|
||||
// so forcibly make dependencies and avoid compiling in concurrent.
|
||||
// dependency order: vm => vm_indent => vm_color => vm_color_indent
|
||||
_ "github.com/goccy/go-json/internal/encoder/vm_indent"
|
||||
_ "git.gammaspectra.live/P2Pool/go-json/internal/encoder/vm_indent"
|
||||
)
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
const uintptrSize = 4 << (^uintptr(0) >> 63)
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"sort"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
|
|
|
@ -3,7 +3,7 @@ package vm_color
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
)
|
||||
|
||||
func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
|
|
|
@ -5,5 +5,5 @@ import (
|
|||
// `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile,
|
||||
// so forcibly make dependencies and avoid compiling in concurrent.
|
||||
// dependency order: vm => vm_indent => vm_color => vm_color_indent
|
||||
_ "github.com/goccy/go-json/internal/encoder/vm_color_indent"
|
||||
_ "git.gammaspectra.live/P2Pool/go-json/internal/encoder/vm_color_indent"
|
||||
)
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
const uintptrSize = 4 << (^uintptr(0) >> 63)
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"sort"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
|
|
|
@ -3,7 +3,7 @@ package vm_color_indent
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
)
|
||||
|
||||
func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
const uintptrSize = 4 << (^uintptr(0) >> 63)
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"sort"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
|
|
|
@ -3,7 +3,7 @@ package vm_indent
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
)
|
||||
|
||||
func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
|
|
|
@ -5,5 +5,5 @@ import (
|
|||
// `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile,
|
||||
// so forcibly make dependencies and avoid compiling in concurrent.
|
||||
// dependency order: vm => vm_indent => vm_color => vm_color_indent
|
||||
_ "github.com/goccy/go-json/internal/encoder/vm_color"
|
||||
_ "git.gammaspectra.live/P2Pool/go-json/internal/encoder/vm_color"
|
||||
)
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
const uintptrSize = 4 << (^uintptr(0) >> 63)
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"sort"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"github.com/goccy/go-json/internal/runtime"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/runtime"
|
||||
)
|
||||
|
||||
func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
|
|
|
@ -252,7 +252,6 @@ func IfaceIndir(*Type) bool
|
|||
//go:noescape
|
||||
func RType2Type(t *Type) reflect.Type
|
||||
|
||||
//go:nolint structcheck
|
||||
type emptyInterface struct {
|
||||
_ *Type
|
||||
ptr unsafe.Pointer
|
||||
|
|
37
json.go
37
json.go
|
@ -5,7 +5,7 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
)
|
||||
|
||||
// Marshaler is the interface implemented by types that
|
||||
|
@ -89,31 +89,31 @@ type UnmarshalerContext interface {
|
|||
//
|
||||
// Examples of struct field tags and their meanings:
|
||||
//
|
||||
// // Field appears in JSON as key "myName".
|
||||
// Field int `json:"myName"`
|
||||
// // Field appears in JSON as key "myName".
|
||||
// Field int `json:"myName"`
|
||||
//
|
||||
// // Field appears in JSON as key "myName" and
|
||||
// // the field is omitted from the object if its value is empty,
|
||||
// // as defined above.
|
||||
// Field int `json:"myName,omitempty"`
|
||||
// // Field appears in JSON as key "myName" and
|
||||
// // the field is omitted from the object if its value is empty,
|
||||
// // as defined above.
|
||||
// Field int `json:"myName,omitempty"`
|
||||
//
|
||||
// // Field appears in JSON as key "Field" (the default), but
|
||||
// // the field is skipped if empty.
|
||||
// // Note the leading comma.
|
||||
// Field int `json:",omitempty"`
|
||||
// // Field appears in JSON as key "Field" (the default), but
|
||||
// // the field is skipped if empty.
|
||||
// // Note the leading comma.
|
||||
// Field int `json:",omitempty"`
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field int `json:"-"`
|
||||
// // Field is ignored by this package.
|
||||
// Field int `json:"-"`
|
||||
//
|
||||
// // Field appears in JSON as key "-".
|
||||
// Field int `json:"-,"`
|
||||
// // Field appears in JSON as key "-".
|
||||
// Field int `json:"-,"`
|
||||
//
|
||||
// The "string" option signals that a field is stored as JSON inside a
|
||||
// JSON-encoded string. It applies only to fields of string, floating point,
|
||||
// integer, or boolean types. This extra level of encoding is sometimes used
|
||||
// when communicating with JavaScript programs:
|
||||
//
|
||||
// Int64String int64 `json:",string"`
|
||||
// Int64String int64 `json:",string"`
|
||||
//
|
||||
// The key name will be used if it's a non-empty string consisting of
|
||||
// only Unicode letters, digits, and ASCII punctuation except quotation
|
||||
|
@ -166,7 +166,6 @@ type UnmarshalerContext interface {
|
|||
// JSON cannot represent cyclic data structures and Marshal does not
|
||||
// handle them. Passing cyclic structures to Marshal will result in
|
||||
// an infinite recursion.
|
||||
//
|
||||
func Marshal(v interface{}) ([]byte, error) {
|
||||
return MarshalWithOption(v)
|
||||
}
|
||||
|
@ -264,14 +263,13 @@ func MarshalIndentWithOption(v interface{}, prefix, indent string, optFuncs ...E
|
|||
//
|
||||
// The JSON null value unmarshals into an interface, map, pointer, or slice
|
||||
// by setting that Go value to nil. Because null is often used in JSON to mean
|
||||
// ``not present,'' unmarshaling a JSON null into any other Go type has no effect
|
||||
// “not present,” unmarshaling a JSON null into any other Go type has no effect
|
||||
// on the value and produces no error.
|
||||
//
|
||||
// When unmarshaling quoted strings, invalid UTF-8 or
|
||||
// invalid UTF-16 surrogate pairs are not treated as an error.
|
||||
// Instead, they are replaced by the Unicode replacement
|
||||
// character U+FFFD.
|
||||
//
|
||||
func Unmarshal(data []byte, v interface{}) error {
|
||||
return unmarshal(data, v)
|
||||
}
|
||||
|
@ -299,7 +297,6 @@ func UnmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc)
|
|||
// Number, for JSON numbers
|
||||
// string, for JSON string literals
|
||||
// nil, for JSON null
|
||||
//
|
||||
type Token = json.Token
|
||||
|
||||
// A Number represents a JSON number literal.
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
var validTests = []struct {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestNumberIsValid(t *testing.T) {
|
||||
|
|
11
option.go
11
option.go
|
@ -3,8 +3,8 @@ package json
|
|||
import (
|
||||
"io"
|
||||
|
||||
"github.com/goccy/go-json/internal/decoder"
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/decoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
)
|
||||
|
||||
type EncodeOption = encoder.Option
|
||||
|
@ -48,6 +48,13 @@ func DebugWith(w io.Writer) EncodeOptionFunc {
|
|||
}
|
||||
}
|
||||
|
||||
// DebugDOT sets the destination to write opcodes graph.
|
||||
func DebugDOT(w io.WriteCloser) EncodeOptionFunc {
|
||||
return func(opt *EncodeOption) {
|
||||
opt.DebugDOTOut = w
|
||||
}
|
||||
}
|
||||
|
||||
// Colorize add an identifier for coloring to the string of the encoded result.
|
||||
func Colorize(scheme *ColorScheme) EncodeOptionFunc {
|
||||
return func(opt *EncodeOption) {
|
||||
|
|
2
path.go
2
path.go
|
@ -3,7 +3,7 @@ package json
|
|||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/goccy/go-json/internal/decoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/decoder"
|
||||
)
|
||||
|
||||
// CreatePath creates JSON Path.
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestExtractPath(t *testing.T) {
|
||||
|
|
2
query.go
2
query.go
|
@ -1,7 +1,7 @@
|
|||
package json
|
||||
|
||||
import (
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
)
|
||||
|
||||
type (
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
type queryTestX struct {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/encoder"
|
||||
"git.gammaspectra.live/P2Pool/go-json/internal/encoder"
|
||||
)
|
||||
|
||||
func TestOpcodeSize(t *testing.T) {
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
// Test values for the stream test.
|
||||
|
|
|
@ -7,7 +7,7 @@ package json_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
type basicLatin2xTag struct {
|
||||
|
|
|
@ -5,9 +5,17 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
type customArray [2]int
|
||||
|
||||
type customArrayWithMarshaler [2]int
|
||||
|
||||
func (b customArrayWithMarshaler) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal([2]int(b))
|
||||
}
|
||||
|
||||
func TestCoverArray(t *testing.T) {
|
||||
type structArray struct {
|
||||
A [2]int `json:"a"`
|
||||
|
@ -47,6 +55,24 @@ func TestCoverArray(t *testing.T) {
|
|||
A *[2]*int `json:"a,string"`
|
||||
}
|
||||
|
||||
type structCustomArrayOmitEmpty struct {
|
||||
A customArray `json:"a,omitempty"`
|
||||
}
|
||||
|
||||
type structSecondFieldCustomArrayOmitEmpty struct {
|
||||
C [2]int `json:"c"`
|
||||
A customArray `json:"a,omitempty"`
|
||||
}
|
||||
|
||||
type structCustomArrayWithMarshalerOmitEmpty struct {
|
||||
A customArrayWithMarshaler `json:"a,omitempty"`
|
||||
}
|
||||
|
||||
type structSecondFieldCustomArrayWithMarshalerOmitEmpty struct {
|
||||
C [2]int `json:"c"`
|
||||
A customArrayWithMarshaler `json:"a,omitempty"`
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
data interface{}
|
||||
|
@ -1421,6 +1447,46 @@ func TestCoverArray(t *testing.T) {
|
|||
B: [2]int{1},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "AnonymousHeadCustomArrayOmitEmpty",
|
||||
data: struct {
|
||||
structCustomArrayOmitEmpty
|
||||
B customArray `json:"b,omitempty"`
|
||||
}{
|
||||
structCustomArrayOmitEmpty: structCustomArrayOmitEmpty{A: customArray{-1}},
|
||||
B: [2]int{1},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "AnonymousHeadCustomArrayOmitEmpty",
|
||||
data: struct {
|
||||
structCustomArrayOmitEmpty
|
||||
B customArray `json:"b,omitempty"`
|
||||
}{
|
||||
structCustomArrayOmitEmpty: structCustomArrayOmitEmpty{A: customArray{-1}},
|
||||
B: [2]int{1},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "AnonymousHeadCustomArrayWithMarshalerOmitEmpty",
|
||||
data: struct {
|
||||
structCustomArrayWithMarshalerOmitEmpty
|
||||
B customArrayWithMarshaler `json:"b,omitempty"`
|
||||
}{
|
||||
structCustomArrayWithMarshalerOmitEmpty: structCustomArrayWithMarshalerOmitEmpty{A: customArrayWithMarshaler{-1}},
|
||||
B: [2]int{1},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "AnonymousHeadCustomArrayWithMarshalerOmitEmpty",
|
||||
data: struct {
|
||||
structCustomArrayWithMarshalerOmitEmpty
|
||||
B customArrayWithMarshaler `json:"b,omitempty"`
|
||||
}{
|
||||
structCustomArrayWithMarshalerOmitEmpty: structCustomArrayWithMarshalerOmitEmpty{A: customArrayWithMarshaler{-1}},
|
||||
B: [2]int{1},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "AnonymousHeadArrayString",
|
||||
data: struct {
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
type customBool bool
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestCoverBytes(t *testing.T) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestCoverFloat32(t *testing.T) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestCoverFloat64(t *testing.T) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"bytes"
|
||||
stdjson "encoding/json"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func intptr(v int) *int { return &v }
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestCoverInt16(t *testing.T) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestCoverInt32(t *testing.T) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestCoverInt64(t *testing.T) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestCoverInt8(t *testing.T) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestCoverInt(t *testing.T) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
type recursiveMap struct {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
type coverMarshalJSON struct {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
type coverMarshalText struct {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"git.gammaspectra.live/P2Pool/go-json"
|
||||
)
|
||||
|
||||
func TestCoverNumber(t *testing.T) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue