github.com/minio/simdjson-go@v0.4.6-0.20231116094823-04d21cddf993/parsed_json_test.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2020 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package simdjson
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/json"
    22  	"fmt"
    23  	"io/ioutil"
    24  	"log"
    25  	"path/filepath"
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/klauspost/compress/zstd"
    30  )
    31  
    32  const demo_json = `{"Image":{"Width":800,"Height":600,"Title":"View from 15th Floor","Thumbnail":{"Url":"http://www.example.com/image/481989943","Height":125,"Width":100},"Animated":false,"IDs":[116,943,234,38793]}}`
    33  
    34  type tester interface {
    35  	Fatal(args ...interface{})
    36  }
    37  
    38  func loadCompressed(t tester, file string) (ref []byte) {
    39  	dec, err := zstd.NewReader(nil)
    40  	if err != nil {
    41  		t.Fatal(err)
    42  	}
    43  	ref, err = ioutil.ReadFile(filepath.Join("testdata", file+".json.zst"))
    44  	if err != nil {
    45  		t.Fatal(err)
    46  	}
    47  	ref, err = dec.DecodeAll(ref, nil)
    48  	if err != nil {
    49  		t.Fatal(err)
    50  	}
    51  
    52  	return ref
    53  }
    54  
    55  var testCases = []struct {
    56  	name  string
    57  	array bool
    58  }{
    59  	{
    60  		name: "apache_builds",
    61  	},
    62  	{
    63  		name: "canada",
    64  	},
    65  	{
    66  		name: "citm_catalog",
    67  	},
    68  	{
    69  		name:  "github_events",
    70  		array: true,
    71  	},
    72  	{
    73  		name: "gsoc-2018",
    74  	},
    75  	{
    76  		name: "instruments",
    77  	},
    78  	{
    79  		name:  "numbers",
    80  		array: true,
    81  	},
    82  	{
    83  		name: "marine_ik",
    84  	},
    85  	{
    86  		name: "mesh",
    87  	},
    88  	{
    89  		name: "mesh.pretty",
    90  	},
    91  	{
    92  		name: "twitterescaped",
    93  	},
    94  	{
    95  		name: "twitter",
    96  	},
    97  	{
    98  		name: "random",
    99  	},
   100  	{
   101  		name: "update-center",
   102  	},
   103  }
   104  
   105  func BenchmarkIter_MarshalJSONBuffer(b *testing.B) {
   106  	if !SupportedCPU() {
   107  		b.SkipNow()
   108  	}
   109  	for _, tt := range testCases {
   110  		b.Run(tt.name, func(b *testing.B) {
   111  			ref := loadCompressed(b, tt.name)
   112  			pj, err := Parse(ref, nil)
   113  			if err != nil {
   114  				b.Fatal(err)
   115  			}
   116  			iter := pj.Iter()
   117  			cpy := iter
   118  			output, err := cpy.MarshalJSON()
   119  			if err != nil {
   120  				b.Fatal(err)
   121  			}
   122  			b.SetBytes(int64(len(output)))
   123  			b.ReportAllocs()
   124  			b.ResetTimer()
   125  			for i := 0; i < b.N; i++ {
   126  				cpy := iter
   127  				output, err = cpy.MarshalJSONBuffer(output[:0])
   128  				if err != nil {
   129  					b.Fatal(err)
   130  				}
   131  			}
   132  		})
   133  	}
   134  }
   135  
   136  func BenchmarkGoMarshalJSON(b *testing.B) {
   137  	for _, tt := range testCases {
   138  		b.Run(tt.name, func(b *testing.B) {
   139  			ref := loadCompressed(b, tt.name)
   140  			var m interface{}
   141  			m = map[string]interface{}{}
   142  			if tt.array {
   143  				m = []interface{}{}
   144  			}
   145  			err := json.Unmarshal(ref, &m)
   146  			if err != nil {
   147  				b.Fatal(err)
   148  			}
   149  			output, err := json.Marshal(m)
   150  			if err != nil {
   151  				b.Fatal(err)
   152  			}
   153  			b.SetBytes(int64(len(output)))
   154  			b.ReportAllocs()
   155  			b.ResetTimer()
   156  			for i := 0; i < b.N; i++ {
   157  				output, err = json.Marshal(m)
   158  				if err != nil {
   159  					b.Fatal(err)
   160  				}
   161  			}
   162  		})
   163  	}
   164  }
   165  
   166  func TestPrintJson(t *testing.T) {
   167  	if !SupportedCPU() {
   168  		t.SkipNow()
   169  	}
   170  	msg := []byte(demo_json)
   171  	expected := `{"Image":{"Width":800,"Height":600,"Title":"View from 15th Floor","Thumbnail":{"Url":"http://www.example.com/image/481989943","Height":125,"Width":100},"Animated":false,"IDs":[116,943,234,38793]}}`
   172  
   173  	pj, err := Parse(msg, nil)
   174  
   175  	if err != nil {
   176  		t.Errorf("parseMessage failed\n")
   177  	}
   178  
   179  	iter := pj.Iter()
   180  	out, err := iter.MarshalJSON()
   181  	if err != nil {
   182  		t.Fatal(err)
   183  	}
   184  
   185  	if string(out) != expected {
   186  		t.Errorf("TestPrintJson: got: %s want: %s", out, expected)
   187  	}
   188  }
   189  
   190  func TestExchange(t *testing.T) {
   191  	if !SupportedCPU() {
   192  		t.SkipNow()
   193  	}
   194  	input := `{"value": -20}`
   195  	pj, err := Parse([]byte(input), nil)
   196  	if err != nil {
   197  		t.Errorf("Parse failed: %v", err)
   198  		return
   199  	}
   200  	for i := 0; i < 200; i++ {
   201  		i := i
   202  		t.Run(fmt.Sprint(i), func(t *testing.T) {
   203  			t.Parallel()
   204  			var cl *ParsedJson
   205  			var o *Object
   206  			for j := 0; j < 10; j++ {
   207  				cl = pj.Clone(cl)
   208  				iter := cl.Iter()
   209  				iter.Advance()
   210  				_, r, err := iter.Root(&iter)
   211  				if err != nil {
   212  					t.Fatalf("Root failed: %v", err)
   213  				}
   214  				o, err = r.Object(o)
   215  				if err != nil {
   216  					t.Fatalf("Object failed: %v", err)
   217  				}
   218  				_, _, err = o.NextElementBytes(r)
   219  				if err != nil {
   220  					t.Fatalf("NextElementBytes failed: %v", err)
   221  				}
   222  				want := uint64(i + j*100)
   223  				err = r.SetUInt(want)
   224  				if err != nil {
   225  					t.Fatalf("SetUInt failed: %v", err)
   226  					return
   227  				}
   228  				time.Sleep(10 * time.Millisecond)
   229  				v, err := r.Uint()
   230  				if err != nil {
   231  					t.Fatalf("Uint failed: %v", err)
   232  					return
   233  				}
   234  				if v != want {
   235  					t.Errorf("want %d, got %d", want, v)
   236  				}
   237  			}
   238  		})
   239  	}
   240  }
   241  
   242  func TestIter_SetNull(t *testing.T) {
   243  	if !SupportedCPU() {
   244  		t.SkipNow()
   245  	}
   246  	input := `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":12.3456,"int":-42,"uint":9223372036854775808},"stringval":"initial value","array":[null,true,false,"astring",-42,9223372036854775808,1.23455]}`
   247  	tests := []struct {
   248  		want string
   249  	}{
   250  		{
   251  			want: `{"0val":{"true":null,"false":null,"nullval":null},"1val":{"float":null,"int":null,"uint":null},"stringval":null,"array":[null,null,null,null,null,null,null]}`,
   252  		},
   253  	}
   254  
   255  	for _, test := range tests {
   256  		t.Run("null", func(t *testing.T) {
   257  			pj, err := Parse([]byte(input), nil)
   258  			if err != nil {
   259  				t.Errorf("parseMessage failed\n")
   260  				return
   261  			}
   262  			root := pj.Iter()
   263  			// Queue root
   264  			root.AdvanceInto()
   265  			if err != nil {
   266  				t.Errorf("root failed: %v", err)
   267  				return
   268  			}
   269  			iter := root
   270  			for {
   271  				typ := iter.Type()
   272  				switch typ {
   273  				case TypeBool, TypeNull:
   274  					//t.Logf("setting to %v", test.setTo)
   275  					err := iter.SetNull()
   276  					if err != nil {
   277  						t.Errorf("Unable to set value: %v", err)
   278  					}
   279  
   280  					if iter.Type() != TypeNull {
   281  						t.Errorf("Want type %v, got %v", TypeNull, iter.Type())
   282  					}
   283  				case TypeFloat, TypeUint, TypeInt:
   284  					err := iter.SetNull()
   285  					if err != nil {
   286  						t.Errorf("Unable to set value: %v", err)
   287  					}
   288  
   289  					if iter.Type() != TypeNull {
   290  						t.Errorf("Want type %v, got %v", TypeNull, iter.Type())
   291  					}
   292  				case TypeString:
   293  					// Most are keys so cannot be nulled.
   294  					s, _ := iter.String()
   295  					switch s {
   296  					case "astring", "initial value":
   297  						err := iter.SetNull()
   298  						if err != nil {
   299  							t.Errorf("Unable to set value: %v", err)
   300  						}
   301  
   302  						if iter.Type() != TypeNull {
   303  							t.Errorf("Want type %v, got %v", TypeNull, iter.Type())
   304  						}
   305  					}
   306  				case TypeRoot, TypeObject, TypeArray:
   307  				default:
   308  					err := iter.SetNull()
   309  					if err == nil {
   310  						t.Errorf("Value should not be settable for type %v", typ)
   311  					}
   312  				}
   313  				if iter.PeekNextTag() == TagEnd {
   314  					break
   315  				}
   316  				iter.AdvanceInto()
   317  			}
   318  			out, err := root.MarshalJSON()
   319  			if err != nil {
   320  				t.Fatal(err)
   321  			}
   322  			if string(out) != test.want {
   323  				t.Errorf("want: %s\n got: %s", test.want, string(out))
   324  			}
   325  			ser := NewSerializer()
   326  			pj2, err := ser.Deserialize(ser.Serialize(nil, *pj), nil)
   327  			if err != nil {
   328  				t.Fatal(err)
   329  			}
   330  			iter2 := pj2.Iter()
   331  			out2, err := iter2.MarshalJSON()
   332  			if err != nil {
   333  				t.Fatal(err)
   334  			}
   335  			if !bytes.Equal(out, out2) {
   336  				t.Errorf("roundtrip mismatch: %s != %s", out, out2)
   337  			}
   338  		})
   339  	}
   340  }
   341  
   342  func TestIter_SetNull_ObjArr(t *testing.T) {
   343  	if !SupportedCPU() {
   344  		t.SkipNow()
   345  	}
   346  
   347  	tests := []struct {
   348  		input    string
   349  		skipN    int
   350  		want     string
   351  		nullRoot bool
   352  	}{
   353  		{
   354  			input: `{"0val":{"true":true}}`,
   355  			skipN: 1,
   356  			want:  `{"0val":null}`,
   357  		},
   358  		{
   359  			input: `{"0val":[1,2,334,5,454,6,5,true,5,6,78]}`,
   360  			skipN: 1,
   361  			want:  `{"0val":null}`,
   362  		},
   363  		{
   364  			input: `[{"0val":[1,2,334,5,454,6,5,true,5,6,78]}, {"2val":{"true":true}}]`,
   365  			skipN: 1,
   366  			want:  `[null,null]`,
   367  		},
   368  		{
   369  			input:    `[{"0val":[1,2,334,5,454,6,5,true,5,6,78]}, {"2val":{"true":true}}]`,
   370  			nullRoot: true,
   371  			want:     `null`,
   372  		},
   373  	}
   374  
   375  	for i, test := range tests {
   376  		t.Run(fmt.Sprint(i), func(t *testing.T) {
   377  			skip := test.skipN
   378  			pj, err := ParseND([]byte(test.input), nil)
   379  			if err != nil {
   380  				t.Errorf("parseMessage failed\n")
   381  				return
   382  			}
   383  			root := pj.Iter()
   384  			// Queue root
   385  			root.AdvanceInto()
   386  			if err != nil {
   387  				t.Errorf("root failed: %v", err)
   388  				return
   389  			}
   390  			iter := root
   391  			for {
   392  				typ := iter.Type()
   393  				switch typ {
   394  				case TypeObject, TypeArray:
   395  					if skip > 0 {
   396  						skip--
   397  						break
   398  					}
   399  					//t.Logf("setting to %v", test.setTo)
   400  					err := iter.SetNull()
   401  					if err != nil {
   402  						t.Errorf("Unable to set value: %v", err)
   403  					}
   404  
   405  					if iter.Type() != TypeNull {
   406  						t.Errorf("Want type %v, got %v", TypeNull, iter.Type())
   407  					}
   408  				case TypeRoot:
   409  					if test.nullRoot {
   410  						err := iter.SetNull()
   411  						if err != nil {
   412  							t.Errorf("Unable to set value: %v", err)
   413  						}
   414  
   415  						if iter.Type() != TypeNull {
   416  							t.Errorf("Want type %v, got %v", TypeNull, iter.Type())
   417  						}
   418  					}
   419  				default:
   420  				}
   421  				if iter.PeekNextTag() == TagEnd {
   422  					break
   423  				}
   424  				iter.AdvanceInto()
   425  			}
   426  			root = pj.Iter()
   427  			out, err := root.MarshalJSON()
   428  			if err != nil {
   429  				t.Fatal(err)
   430  			}
   431  			if string(out) != test.want {
   432  				t.Errorf("want: %s\n got: %s", test.want, string(out))
   433  			}
   434  			ser := NewSerializer()
   435  			pj2, err := ser.Deserialize(ser.Serialize(nil, *pj), nil)
   436  			if err != nil {
   437  				t.Fatal(err)
   438  			}
   439  			iter2 := pj2.Iter()
   440  			out2, err := iter2.MarshalJSON()
   441  			if err != nil {
   442  				t.Fatal(err)
   443  			}
   444  			if !bytes.Equal(out, out2) {
   445  				t.Errorf("roundtrip mismatch: %s != %s", out, out2)
   446  			}
   447  		})
   448  	}
   449  }
   450  
   451  func TestObject_DeleteElems(t *testing.T) {
   452  	if !SupportedCPU() {
   453  		t.SkipNow()
   454  	}
   455  	input := `{"one": 1, "two": 2.02, "three": "33333", "four": 0, "five": false, "six": true, "seven": {"key": "value"}, "eight": [1,2,2,3]}`
   456  	tests := []struct {
   457  		want string
   458  		fn   func(key string) bool
   459  	}{
   460  		{
   461  			want: `{}`,
   462  			fn: func(key string) bool {
   463  				return true
   464  			},
   465  		},
   466  		{
   467  			want: `{"two":2.02,"three":"33333","four":0,"five":false,"six":true,"seven":{"key":"value"},"eight":[1,2,2,3]}`,
   468  			fn: func(key string) bool {
   469  				return key == "one"
   470  			},
   471  		},
   472  		{
   473  			want: `{"one":1,"three":"33333","four":0,"five":false,"six":true,"seven":{"key":"value"},"eight":[1,2,2,3]}`,
   474  			fn: func(key string) bool {
   475  				return key == "two"
   476  			},
   477  		},
   478  		{
   479  			want: `{"one":1,"two":2.02,"four":0,"five":false,"six":true,"seven":{"key":"value"},"eight":[1,2,2,3]}`,
   480  			fn: func(key string) bool {
   481  				return key == "three"
   482  			},
   483  		},
   484  		{
   485  			want: `{"one":1,"two":2.02,"three":"33333","five":false,"six":true,"seven":{"key":"value"},"eight":[1,2,2,3]}`,
   486  			fn: func(key string) bool {
   487  				return key == "four"
   488  			},
   489  		},
   490  		{
   491  			want: `{"one":1,"two":2.02,"three":"33333","four":0,"six":true,"seven":{"key":"value"},"eight":[1,2,2,3]}`,
   492  			fn: func(key string) bool {
   493  				return key == "five"
   494  			},
   495  		},
   496  		{
   497  			want: `{"one":1,"two":2.02,"three":"33333","four":0,"five":false,"seven":{"key":"value"},"eight":[1,2,2,3]}`,
   498  			fn: func(key string) bool {
   499  				return key == "six"
   500  			},
   501  		},
   502  		{
   503  			want: `{"one":1,"two":2.02,"three":"33333","four":0,"five":false,"six":true,"eight":[1,2,2,3]}`,
   504  			fn: func(key string) bool {
   505  				return key == "seven"
   506  			},
   507  		},
   508  		{
   509  			want: `{"one":1,"two":2.02,"three":"33333","four":0,"five":false,"six":true,"seven":{"key":"value"}}`,
   510  			fn: func(key string) bool {
   511  				return key == "eight"
   512  			},
   513  		},
   514  		{
   515  			want: `{"one":1,"two":2.02,"three":"33333","four":0,"five":false,"six":true,"seven":{"key":"value"},"eight":[1,2,2,3]}`,
   516  			fn: func(key string) bool {
   517  				return false
   518  			},
   519  		},
   520  	}
   521  
   522  	for i, test := range tests {
   523  		t.Run(fmt.Sprint(i), func(t *testing.T) {
   524  			pj, err := Parse([]byte(input), nil)
   525  			if err != nil {
   526  				t.Errorf("parseMessage failed\n")
   527  				return
   528  			}
   529  
   530  			// Queue root
   531  			iter := pj.Iter()
   532  			iter.AdvanceInto()
   533  
   534  			_, root, err := iter.Root(nil)
   535  			if err != nil {
   536  				t.Fatalf("root failed: %v", err)
   537  				return
   538  			}
   539  			obj, err := root.Object(nil)
   540  			if err != nil {
   541  				t.Fatalf("obj failed: %v", err)
   542  				return
   543  			}
   544  
   545  			err = obj.DeleteElems(func(key []byte, i Iter) bool {
   546  				return test.fn(string(key))
   547  			}, nil)
   548  			if err != nil {
   549  				t.Fatal(err)
   550  			}
   551  
   552  			// Test we don't delete more than we should
   553  			err = obj.DeleteElems(nil, map[string]struct{}{"unwanted": {}})
   554  			if err != nil {
   555  				t.Fatal(err)
   556  			}
   557  			out, err := root.MarshalJSON()
   558  			if err != nil {
   559  				t.Fatal(err)
   560  			}
   561  			if string(out) != test.want {
   562  				t.Errorf("want: %s\n got: %s", test.want, string(out))
   563  			}
   564  			ser := NewSerializer()
   565  			b := ser.Serialize(nil, *pj)
   566  			if err != nil {
   567  				t.Fatal(err)
   568  			}
   569  			pj2, err := ser.Deserialize(b, nil)
   570  			if err != nil {
   571  				t.Fatal(err)
   572  			}
   573  			iter = pj2.Iter()
   574  			iter.AdvanceInto()
   575  
   576  			_, root, err = iter.Root(nil)
   577  			if err != nil {
   578  				t.Fatalf("root failed: %v", err)
   579  				return
   580  			}
   581  			out, err = root.MarshalJSON()
   582  			if err != nil {
   583  				t.Fatal(err)
   584  			}
   585  			if string(out) != test.want {
   586  				t.Errorf("want: %s\n got: %s", test.want, string(out))
   587  			}
   588  		})
   589  	}
   590  }
   591  
   592  func TestArray_DeleteElements(t *testing.T) {
   593  	if !SupportedCPU() {
   594  		t.SkipNow()
   595  	}
   596  	input := `[1, 2.02, "33333", false, true, {"key": "value"}, [1,2,2,3], null, -42]`
   597  	tests := []struct {
   598  		want string
   599  		del  int
   600  	}{
   601  		{
   602  			want: `[]`,
   603  			del:  -1,
   604  		},
   605  		{
   606  			want: `[1,2.02,"33333",false,true,{"key":"value"},[1,2,2,3],null,-42]`,
   607  			del:  100,
   608  		},
   609  		{
   610  			want: `[2.02,"33333",false,true,{"key":"value"},[1,2,2,3],null,-42]`,
   611  			del:  0,
   612  		},
   613  		{
   614  			want: `[1,"33333",false,true,{"key":"value"},[1,2,2,3],null,-42]`,
   615  			del:  1,
   616  		}, {
   617  			want: `[1,2.02,false,true,{"key":"value"},[1,2,2,3],null,-42]`,
   618  			del:  2,
   619  		}, {
   620  			want: `[1,2.02,"33333",true,{"key":"value"},[1,2,2,3],null,-42]`,
   621  			del:  3,
   622  		}, {
   623  			want: `[1,2.02,"33333",false,{"key":"value"},[1,2,2,3],null,-42]`,
   624  			del:  4,
   625  		}, {
   626  			want: `[1,2.02,"33333",false,true,[1,2,2,3],null,-42]`,
   627  			del:  5,
   628  		}, {
   629  			want: `[1,2.02,"33333",false,true,{"key":"value"},null,-42]`,
   630  			del:  6,
   631  		}, {
   632  			want: `[1,2.02,"33333",false,true,{"key":"value"},[1,2,2,3],-42]`,
   633  			del:  7,
   634  		}, {
   635  			want: `[1,2.02,"33333",false,true,{"key":"value"},[1,2,2,3],null]`,
   636  			del:  8,
   637  		},
   638  	}
   639  
   640  	for i, test := range tests {
   641  		t.Run(fmt.Sprint(i), func(t *testing.T) {
   642  			pj, err := Parse([]byte(input), nil)
   643  			if err != nil {
   644  				t.Errorf("parseMessage failed\n")
   645  				return
   646  			}
   647  
   648  			// Queue root
   649  			iter := pj.Iter()
   650  			iter.AdvanceInto()
   651  
   652  			_, root, err := iter.Root(nil)
   653  			if err != nil {
   654  				t.Fatalf("root failed: %v", err)
   655  				return
   656  			}
   657  			arr, err := root.Array(nil)
   658  			if err != nil {
   659  				t.Fatalf("obj failed: %v", err)
   660  				return
   661  			}
   662  			var idx int
   663  			arr.DeleteElems(func(i Iter) bool {
   664  				del := test.del < 0 || idx == test.del
   665  				idx++
   666  				return del
   667  			})
   668  
   669  			out, err := root.MarshalJSON()
   670  			if err != nil {
   671  				t.Fatal(err)
   672  			}
   673  			if string(out) != test.want {
   674  				t.Errorf("want: %s\n got: %s", test.want, string(out))
   675  			}
   676  			ser := NewSerializer()
   677  			b := ser.Serialize(nil, *pj)
   678  			if err != nil {
   679  				t.Fatal(err)
   680  			}
   681  			pj2, err := ser.Deserialize(b, nil)
   682  			if err != nil {
   683  				t.Fatal(err)
   684  			}
   685  			iter = pj2.Iter()
   686  			iter.AdvanceInto()
   687  
   688  			_, root, err = iter.Root(nil)
   689  			if err != nil {
   690  				t.Fatalf("root failed: %v", err)
   691  				return
   692  			}
   693  			out, err = root.MarshalJSON()
   694  			if err != nil {
   695  				t.Fatal(err)
   696  			}
   697  			if string(out) != test.want {
   698  				t.Errorf("want: %s\n got: %s", test.want, string(out))
   699  			}
   700  		})
   701  	}
   702  }
   703  
   704  func TestIter_SetBool(t *testing.T) {
   705  	if !SupportedCPU() {
   706  		t.SkipNow()
   707  	}
   708  	input := `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":12.3456,"int":-42,"uint":9223372036854775808},"stringval":"initial value","array":[null,true,false,"astring",-42,9223372036854775808,1.23455]}`
   709  	tests := []struct {
   710  		setTo bool
   711  		want  string
   712  	}{
   713  		{
   714  			setTo: true,
   715  			want:  `{"0val":{"true":true,"false":true,"nullval":true},"1val":{"float":12.3456,"int":-42,"uint":9223372036854775808},"stringval":"initial value","array":[true,true,true,"astring",-42,9223372036854775808,1.23455]}`,
   716  		},
   717  		{
   718  			setTo: false,
   719  			want:  `{"0val":{"true":false,"false":false,"nullval":false},"1val":{"float":12.3456,"int":-42,"uint":9223372036854775808},"stringval":"initial value","array":[false,false,false,"astring",-42,9223372036854775808,1.23455]}`,
   720  		},
   721  	}
   722  
   723  	for _, test := range tests {
   724  		t.Run(fmt.Sprint(test.setTo), func(t *testing.T) {
   725  			pj, err := Parse([]byte(input), nil)
   726  			if err != nil {
   727  				t.Errorf("parseMessage failed\n")
   728  				return
   729  			}
   730  			root := pj.Iter()
   731  			// Queue root
   732  			root.AdvanceInto()
   733  			if err != nil {
   734  				t.Errorf("root failed: %v", err)
   735  				return
   736  			}
   737  			iter := root
   738  			for {
   739  				typ := iter.Type()
   740  				switch typ {
   741  				case TypeBool, TypeNull:
   742  					//t.Logf("setting to %v", test.setTo)
   743  					err := iter.SetBool(test.setTo)
   744  					if err != nil {
   745  						t.Errorf("Unable to set value: %v", err)
   746  					}
   747  					val, err := iter.Bool()
   748  					if err != nil {
   749  						t.Errorf("Unable to retrieve value: %v", err)
   750  					}
   751  
   752  					if val != test.setTo {
   753  						t.Errorf("Want value %v, got %v", test.setTo, val)
   754  					}
   755  				default:
   756  					err := iter.SetBool(test.setTo)
   757  					if err == nil {
   758  						t.Errorf("Value should not be settable for type %v", typ)
   759  					}
   760  				}
   761  				if iter.PeekNextTag() == TagEnd {
   762  					break
   763  				}
   764  				iter.AdvanceInto()
   765  			}
   766  			out, err := root.MarshalJSON()
   767  			if err != nil {
   768  				t.Fatal(err)
   769  			}
   770  			if string(out) != test.want {
   771  				t.Errorf("want: %s\n got: %s", test.want, string(out))
   772  			}
   773  			ser := NewSerializer()
   774  			pj2, err := ser.Deserialize(ser.Serialize(nil, *pj), nil)
   775  			if err != nil {
   776  				t.Fatal(err)
   777  			}
   778  			iter2 := pj2.Iter()
   779  			out2, err := iter2.MarshalJSON()
   780  			if err != nil {
   781  				t.Fatal(err)
   782  			}
   783  			if !bytes.Equal(out, out2) {
   784  				t.Errorf("roundtrip mismatch: %s != %s", out, out2)
   785  			}
   786  		})
   787  	}
   788  }
   789  
   790  func TestIter_SetFloat(t *testing.T) {
   791  	if !SupportedCPU() {
   792  		t.SkipNow()
   793  	}
   794  	input := `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":12.3456,"int":-42,"uint":9223372036854775808},"stringval":"initial value","array":[null,true,false,"astring",-42,9223372036854775808,1.23455]}`
   795  	tests := []struct {
   796  		setTo float64
   797  		want  string
   798  	}{
   799  		{
   800  			setTo: 69.420,
   801  			want:  `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":69.42,"int":69.42,"uint":69.42},"stringval":"initial value","array":[null,true,false,"astring",69.42,69.42,69.42]}`,
   802  		},
   803  		{
   804  			setTo: 10e30,
   805  			want:  `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":1e+31,"int":1e+31,"uint":1e+31},"stringval":"initial value","array":[null,true,false,"astring",1e+31,1e+31,1e+31]}`,
   806  		},
   807  	}
   808  
   809  	for _, test := range tests {
   810  		t.Run(fmt.Sprint(test.setTo), func(t *testing.T) {
   811  			pj, err := Parse([]byte(input), nil)
   812  			if err != nil {
   813  				t.Errorf("parseMessage failed\n")
   814  				return
   815  			}
   816  			root := pj.Iter()
   817  			// Queue root
   818  			root.AdvanceInto()
   819  			if err != nil {
   820  				t.Errorf("root failed: %v", err)
   821  				return
   822  			}
   823  			iter := root
   824  			for {
   825  				typ := iter.Type()
   826  				switch typ {
   827  				case TypeInt, TypeFloat, TypeUint:
   828  					//t.Logf("setting to %v", test.setTo)
   829  					err := iter.SetFloat(test.setTo)
   830  					if err != nil {
   831  						t.Errorf("Unable to set value: %v", err)
   832  					}
   833  					val, err := iter.Float()
   834  					if err != nil {
   835  						t.Errorf("Unable to retrieve value: %v", err)
   836  					}
   837  
   838  					if val != test.setTo {
   839  						t.Errorf("Want value %v, got %v", test.setTo, val)
   840  					}
   841  				case TypeString:
   842  					// Do not replace strings...
   843  				default:
   844  					err := iter.SetFloat(test.setTo)
   845  					if err == nil {
   846  						t.Errorf("Value should not be settable for type %v", typ)
   847  					}
   848  				}
   849  				if iter.PeekNextTag() == TagEnd {
   850  					break
   851  				}
   852  				iter.AdvanceInto()
   853  			}
   854  			out, err := root.MarshalJSON()
   855  			if err != nil {
   856  				t.Fatal(err)
   857  			}
   858  			if string(out) != test.want {
   859  				t.Errorf("want: %s\n got: %s", test.want, string(out))
   860  			}
   861  			ser := NewSerializer()
   862  			pj2, err := ser.Deserialize(ser.Serialize(nil, *pj), nil)
   863  			if err != nil {
   864  				t.Fatal(err)
   865  			}
   866  			iter2 := pj2.Iter()
   867  			out2, err := iter2.MarshalJSON()
   868  			if err != nil {
   869  				t.Fatal(err)
   870  			}
   871  			if !bytes.Equal(out, out2) {
   872  				t.Errorf("roundtrip mismatch: %s != %s", out, out2)
   873  			}
   874  		})
   875  	}
   876  }
   877  
   878  func TestIter_SetInt(t *testing.T) {
   879  	if !SupportedCPU() {
   880  		t.SkipNow()
   881  	}
   882  	input := `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":12.3456,"int":-42,"uint":9223372036854775808},"stringval":"initial value","array":[null,true,false,"astring",-42,9223372036854775808,1.23455]}`
   883  	tests := []struct {
   884  		setTo int64
   885  		want  string
   886  	}{
   887  		{
   888  			setTo: -69,
   889  			want:  `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":-69,"int":-69,"uint":-69},"stringval":"initial value","array":[null,true,false,"astring",-69,-69,-69]}`,
   890  		},
   891  		{
   892  			setTo: 42,
   893  			want:  `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":42,"int":42,"uint":42},"stringval":"initial value","array":[null,true,false,"astring",42,42,42]}`,
   894  		},
   895  	}
   896  
   897  	for _, test := range tests {
   898  		t.Run(fmt.Sprint(test.setTo), func(t *testing.T) {
   899  			pj, err := Parse([]byte(input), nil)
   900  			if err != nil {
   901  				t.Errorf("parseMessage failed\n")
   902  				return
   903  			}
   904  			root := pj.Iter()
   905  			// Queue root
   906  			root.AdvanceInto()
   907  			if err != nil {
   908  				t.Errorf("root failed: %v", err)
   909  				return
   910  			}
   911  			iter := root
   912  			for {
   913  				typ := iter.Type()
   914  				switch typ {
   915  				case TypeInt, TypeFloat, TypeUint:
   916  					//t.Logf("setting to %v", test.setTo)
   917  					err := iter.SetInt(test.setTo)
   918  					if err != nil {
   919  						t.Errorf("Unable to set value: %v", err)
   920  					}
   921  					val, err := iter.Int()
   922  					if err != nil {
   923  						t.Errorf("Unable to retrieve value: %v", err)
   924  					}
   925  
   926  					if val != test.setTo {
   927  						t.Errorf("Want value %v, got %v", test.setTo, val)
   928  					}
   929  				case TypeString:
   930  					// Do not replace strings...
   931  
   932  				default:
   933  					err := iter.SetInt(test.setTo)
   934  					if err == nil {
   935  						t.Errorf("Value should not be settable for type %v", typ)
   936  					}
   937  				}
   938  				if iter.PeekNextTag() == TagEnd {
   939  					break
   940  				}
   941  				iter.AdvanceInto()
   942  			}
   943  			out, err := root.MarshalJSON()
   944  			if err != nil {
   945  				t.Fatal(err)
   946  			}
   947  			if string(out) != test.want {
   948  				t.Errorf("want: %s\n got: %s", test.want, string(out))
   949  			}
   950  			ser := NewSerializer()
   951  			pj2, err := ser.Deserialize(ser.Serialize(nil, *pj), nil)
   952  			if err != nil {
   953  				t.Fatal(err)
   954  			}
   955  			iter2 := pj2.Iter()
   956  			out2, err := iter2.MarshalJSON()
   957  			if err != nil {
   958  				t.Fatal(err)
   959  			}
   960  			if !bytes.Equal(out, out2) {
   961  				t.Errorf("roundtrip mismatch: %s != %s", out, out2)
   962  			}
   963  		})
   964  	}
   965  }
   966  
   967  func TestIter_SetUInt(t *testing.T) {
   968  	if !SupportedCPU() {
   969  		t.SkipNow()
   970  	}
   971  	input := `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":12.3456,"int":-42,"uint":9223372036854775808},"stringval":"initial value","array":[null,true,false,"astring",-42,9223372036854775808,1.23455]}`
   972  	tests := []struct {
   973  		setTo uint64
   974  		want  string
   975  	}{
   976  		{
   977  			setTo: 69,
   978  			want:  `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":69,"int":69,"uint":69},"stringval":"initial value","array":[null,true,false,"astring",69,69,69]}`,
   979  		},
   980  		{
   981  			setTo: 420,
   982  			want:  `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":420,"int":420,"uint":420},"stringval":"initial value","array":[null,true,false,"astring",420,420,420]}`,
   983  		},
   984  	}
   985  
   986  	for _, test := range tests {
   987  		t.Run(fmt.Sprint(test.setTo), func(t *testing.T) {
   988  			pj, err := Parse([]byte(input), nil)
   989  			if err != nil {
   990  				t.Errorf("parseMessage failed\n")
   991  				return
   992  			}
   993  			root := pj.Iter()
   994  			// Queue root
   995  			root.AdvanceInto()
   996  			if err != nil {
   997  				t.Errorf("root failed: %v", err)
   998  				return
   999  			}
  1000  			iter := root
  1001  			for {
  1002  				typ := iter.Type()
  1003  				switch typ {
  1004  				case TypeInt, TypeFloat, TypeUint:
  1005  					//t.Logf("setting to %v", test.setTo)
  1006  					err := iter.SetUInt(test.setTo)
  1007  					if err != nil {
  1008  						t.Errorf("Unable to set value: %v", err)
  1009  					}
  1010  					val, err := iter.Uint()
  1011  					if err != nil {
  1012  						t.Errorf("Unable to retrieve value: %v", err)
  1013  					}
  1014  
  1015  					if val != test.setTo {
  1016  						t.Errorf("Want value %v, got %v", test.setTo, val)
  1017  					}
  1018  				case TypeString:
  1019  					// Do not replace strings...
  1020  				default:
  1021  					err := iter.SetUInt(test.setTo)
  1022  					if err == nil {
  1023  						t.Errorf("Value should not be settable for type %v", typ)
  1024  					}
  1025  				}
  1026  				if iter.PeekNextTag() == TagEnd {
  1027  					break
  1028  				}
  1029  				iter.AdvanceInto()
  1030  			}
  1031  			out, err := root.MarshalJSON()
  1032  			if err != nil {
  1033  				t.Fatal(err)
  1034  			}
  1035  			if string(out) != test.want {
  1036  				t.Errorf("want: %s\n got: %s", test.want, string(out))
  1037  			}
  1038  			ser := NewSerializer()
  1039  			pj2, err := ser.Deserialize(ser.Serialize(nil, *pj), nil)
  1040  			if err != nil {
  1041  				t.Fatal(err)
  1042  			}
  1043  			iter2 := pj2.Iter()
  1044  			out2, err := iter2.MarshalJSON()
  1045  			if err != nil {
  1046  				t.Fatal(err)
  1047  			}
  1048  			if !bytes.Equal(out, out2) {
  1049  				t.Errorf("roundtrip mismatch: %s != %s", out, out2)
  1050  			}
  1051  		})
  1052  	}
  1053  }
  1054  
  1055  func TestIter_SetString(t *testing.T) {
  1056  	if !SupportedCPU() {
  1057  		t.SkipNow()
  1058  	}
  1059  	input := `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":12.3456,"int":-42,"uint":9223372036854775808},"stringval":"initial value","array":[null,true,false,"astring",-42,9223372036854775808,1.23455]}`
  1060  	tests := []struct {
  1061  		setTo string
  1062  		want  string
  1063  	}{
  1064  		{
  1065  			setTo: "anotherval",
  1066  			want:  `{"anotherval":{"anotherval":true,"anotherval":false,"anotherval":null},"anotherval":{"anotherval":"anotherval","anotherval":"anotherval","anotherval":"anotherval"},"anotherval":"anotherval","anotherval":[null,true,false,"anotherval","anotherval","anotherval","anotherval"]}`,
  1067  		},
  1068  		{
  1069  			setTo: "",
  1070  			want:  `{"":{"":true,"":false,"":null},"":{"":"","":"","":""},"":"","":[null,true,false,"","","",""]}`,
  1071  		},
  1072  		{
  1073  			setTo: "\t",
  1074  			want:  `{"\t":{"\t":true,"\t":false,"\t":null},"\t":{"\t":"\t","\t":"\t","\t":"\t"},"\t":"\t","\t":[null,true,false,"\t","\t","\t","\t"]}`,
  1075  		},
  1076  	}
  1077  
  1078  	for _, test := range tests {
  1079  		t.Run(fmt.Sprint(test.setTo), func(t *testing.T) {
  1080  			pj, err := Parse([]byte(input), nil)
  1081  			if err != nil {
  1082  				t.Errorf("parseMessage failed\n")
  1083  				return
  1084  			}
  1085  			root := pj.Iter()
  1086  			// Queue root
  1087  			root.AdvanceInto()
  1088  			if err != nil {
  1089  				t.Errorf("root failed: %v", err)
  1090  				return
  1091  			}
  1092  			iter := root
  1093  			for {
  1094  				typ := iter.Type()
  1095  				switch typ {
  1096  				case TypeString, TypeInt, TypeFloat, TypeUint:
  1097  					//t.Logf("setting to %v", test.setTo)
  1098  					err := iter.SetString(test.setTo)
  1099  					if err != nil {
  1100  						t.Errorf("Unable to set value: %v", err)
  1101  					}
  1102  					val, err := iter.String()
  1103  					if err != nil {
  1104  						t.Errorf("Unable to retrieve value: %v", err)
  1105  					}
  1106  
  1107  					if val != test.setTo {
  1108  						t.Errorf("Want value %v, got %v", test.setTo, val)
  1109  					}
  1110  				default:
  1111  					err := iter.SetString(test.setTo)
  1112  					if err == nil {
  1113  						t.Errorf("Value should not be settable for type %v", typ)
  1114  					}
  1115  				}
  1116  				if iter.PeekNextTag() == TagEnd {
  1117  					break
  1118  				}
  1119  				iter.AdvanceInto()
  1120  			}
  1121  			out, err := root.MarshalJSON()
  1122  			if err != nil {
  1123  				t.Fatal(err)
  1124  			}
  1125  			if string(out) != test.want {
  1126  				t.Errorf("want: %s\n got: %s", test.want, string(out))
  1127  			}
  1128  			ser := NewSerializer()
  1129  			pj2, err := ser.Deserialize(ser.Serialize(nil, *pj), nil)
  1130  			if err != nil {
  1131  				t.Fatal(err)
  1132  			}
  1133  			iter2 := pj2.Iter()
  1134  			out2, err := iter2.MarshalJSON()
  1135  			if err != nil {
  1136  				t.Fatal(err)
  1137  			}
  1138  			if !bytes.Equal(out, out2) {
  1139  				t.Errorf("roundtrip mismatch: %s != %s", out, out2)
  1140  			}
  1141  		})
  1142  	}
  1143  }
  1144  
  1145  func TestIter_SetStringBytes(t *testing.T) {
  1146  	if !SupportedCPU() {
  1147  		t.SkipNow()
  1148  	}
  1149  	input := `{"0val":{"true":true,"false":false,"nullval":null},"1val":{"float":12.3456,"int":-42,"uint":9223372036854775808},"stringval":"initial value","array":[null,true,false,"astring",-42,9223372036854775808,1.23455]}`
  1150  	tests := []struct {
  1151  		setTo []byte
  1152  		want  string
  1153  	}{
  1154  		{
  1155  			setTo: []byte("anotherval"),
  1156  			want:  `{"anotherval":{"anotherval":true,"anotherval":false,"anotherval":null},"anotherval":{"anotherval":"anotherval","anotherval":"anotherval","anotherval":"anotherval"},"anotherval":"anotherval","anotherval":[null,true,false,"anotherval","anotherval","anotherval","anotherval"]}`,
  1157  		},
  1158  		{
  1159  			setTo: []byte{},
  1160  			want:  `{"":{"":true,"":false,"":null},"":{"":"","":"","":""},"":"","":[null,true,false,"","","",""]}`,
  1161  		},
  1162  		{
  1163  			setTo: []byte(nil),
  1164  			want:  `{"":{"":true,"":false,"":null},"":{"":"","":"","":""},"":"","":[null,true,false,"","","",""]}`,
  1165  		},
  1166  	}
  1167  
  1168  	for _, test := range tests {
  1169  		t.Run(fmt.Sprint(test.setTo), func(t *testing.T) {
  1170  			pj, err := Parse([]byte(input), nil)
  1171  			if err != nil {
  1172  				t.Errorf("parseMessage failed\n")
  1173  				return
  1174  			}
  1175  			root := pj.Iter()
  1176  			// Queue root
  1177  			root.AdvanceInto()
  1178  			if err != nil {
  1179  				t.Errorf("root failed: %v", err)
  1180  				return
  1181  			}
  1182  			iter := root
  1183  			for {
  1184  				typ := iter.Type()
  1185  				switch typ {
  1186  				case TypeString, TypeInt, TypeFloat, TypeUint:
  1187  					//t.Logf("setting to %v", test.setTo)
  1188  					err := iter.SetStringBytes(test.setTo)
  1189  					if err != nil {
  1190  						t.Errorf("Unable to set value: %v", err)
  1191  					}
  1192  					val, err := iter.StringBytes()
  1193  					if err != nil {
  1194  						t.Errorf("Unable to retrieve value: %v", err)
  1195  					}
  1196  
  1197  					if !bytes.Equal(val, test.setTo) {
  1198  						t.Errorf("Want value %v, got %v", test.setTo, val)
  1199  					}
  1200  				default:
  1201  					err := iter.SetStringBytes(test.setTo)
  1202  					if err == nil {
  1203  						t.Errorf("Value should not be settable for type %v", typ)
  1204  					}
  1205  				}
  1206  				if iter.PeekNextTag() == TagEnd {
  1207  					break
  1208  				}
  1209  				iter.AdvanceInto()
  1210  			}
  1211  			out, err := root.MarshalJSON()
  1212  			if err != nil {
  1213  				t.Fatal(err)
  1214  			}
  1215  			if string(out) != test.want {
  1216  				t.Errorf("want: %s\n got: %s", test.want, string(out))
  1217  			}
  1218  			ser := NewSerializer()
  1219  			pj2, err := ser.Deserialize(ser.Serialize(nil, *pj), nil)
  1220  			if err != nil {
  1221  				t.Fatal(err)
  1222  			}
  1223  			iter2 := pj2.Iter()
  1224  			out2, err := iter2.MarshalJSON()
  1225  			if err != nil {
  1226  				t.Fatal(err)
  1227  			}
  1228  			if !bytes.Equal(out, out2) {
  1229  				t.Errorf("roundtrip mismatch: %s != %s", out, out2)
  1230  			}
  1231  		})
  1232  	}
  1233  }
  1234  
  1235  func ExampleIter_FindElement() {
  1236  	if !SupportedCPU() {
  1237  		// Fake it
  1238  		fmt.Println("int\n100 <nil>")
  1239  		return
  1240  	}
  1241  	input := `{
  1242      "Image":
  1243      {
  1244          "Animated": false,
  1245          "Height": 600,
  1246          "IDs":
  1247          [
  1248              116,
  1249              943,
  1250              234,
  1251              38793
  1252          ],
  1253          "Thumbnail":
  1254          {
  1255              "Height": 125,
  1256              "Url": "http://www.example.com/image/481989943",
  1257              "Width": 100
  1258          },
  1259          "Title": "View from 15th Floor",
  1260          "Width": 800
  1261      },
  1262  	"Alt": "Image of city" 
  1263  }`
  1264  	pj, err := Parse([]byte(input), nil)
  1265  	if err != nil {
  1266  		log.Fatal(err)
  1267  	}
  1268  	i := pj.Iter()
  1269  
  1270  	// Find element in path.
  1271  	elem, err := i.FindElement(nil, "Image", "Thumbnail", "Width")
  1272  	if err != nil {
  1273  		log.Fatal(err)
  1274  	}
  1275  
  1276  	// Print result:
  1277  	fmt.Println(elem.Type)
  1278  	fmt.Println(elem.Iter.StringCvt())
  1279  
  1280  	// Output:
  1281  	// int
  1282  	// 100 <nil>
  1283  }
  1284  
  1285  func ExampleParsedJson_ForEach() {
  1286  	if !SupportedCPU() {
  1287  		// Fake results
  1288  		fmt.Println("Got iterator for type: object\nFound element: URL Type: string Value: http://example.com/example.gif")
  1289  		return
  1290  	}
  1291  
  1292  	// Parse JSON:
  1293  	pj, err := Parse([]byte(`{"Image":{"URL":"http://example.com/example.gif"}}`), nil)
  1294  	if err != nil {
  1295  		log.Fatal(err)
  1296  	}
  1297  
  1298  	// Create an element we can reuse.
  1299  	var element *Element
  1300  	err = pj.ForEach(func(i Iter) error {
  1301  		fmt.Println("Got iterator for type:", i.Type())
  1302  		element, err = i.FindElement(element, "Image", "URL")
  1303  		if err == nil {
  1304  			value, _ := element.Iter.StringCvt()
  1305  			fmt.Println("Found element:", element.Name, "Type:", element.Type, "Value:", value)
  1306  		}
  1307  		return nil
  1308  	})
  1309  	if err != nil {
  1310  		log.Fatal(err)
  1311  	}
  1312  	// Output:
  1313  	// Got iterator for type: object
  1314  	// Found element: URL Type: string Value: http://example.com/example.gif
  1315  }