pointertest.cpp
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #include "unittest.h"
16 #include "rapidjson/pointer.h"
17 #include "rapidjson/stringbuffer.h"
18 #include <sstream>
19 
20 using namespace rapidjson;
21 
22 static const char kJson[] = "{\n"
23 " \"foo\":[\"bar\", \"baz\"],\n"
24 " \"\" : 0,\n"
25 " \"a/b\" : 1,\n"
26 " \"c%d\" : 2,\n"
27 " \"e^f\" : 3,\n"
28 " \"g|h\" : 4,\n"
29 " \"i\\\\j\" : 5,\n"
30 " \"k\\\"l\" : 6,\n"
31 " \" \" : 7,\n"
32 " \"m~n\" : 8\n"
33 "}";
34 
35 TEST(Pointer, DefaultConstructor) {
36  Pointer p;
37  EXPECT_TRUE(p.IsValid());
38  EXPECT_EQ(0u, p.GetTokenCount());
39 }
40 
41 TEST(Pointer, Parse) {
42  {
43  Pointer p("");
44  EXPECT_TRUE(p.IsValid());
45  EXPECT_EQ(0u, p.GetTokenCount());
46  }
47 
48  {
49  Pointer p("/");
50  EXPECT_TRUE(p.IsValid());
51  EXPECT_EQ(1u, p.GetTokenCount());
52  EXPECT_EQ(0u, p.GetTokens()[0].length);
53  EXPECT_STREQ("", p.GetTokens()[0].name);
54  EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
55  }
56 
57  {
58  Pointer p("/foo");
59  EXPECT_TRUE(p.IsValid());
60  EXPECT_EQ(1u, p.GetTokenCount());
61  EXPECT_EQ(3u, p.GetTokens()[0].length);
62  EXPECT_STREQ("foo", p.GetTokens()[0].name);
63  EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
64  }
65 
66  #if RAPIDJSON_HAS_STDSTRING
67  {
68  Pointer p(std::string("/foo"));
69  EXPECT_TRUE(p.IsValid());
70  EXPECT_EQ(1u, p.GetTokenCount());
71  EXPECT_EQ(3u, p.GetTokens()[0].length);
72  EXPECT_STREQ("foo", p.GetTokens()[0].name);
73  EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
74  }
75  #endif
76 
77  {
78  Pointer p("/foo/0");
79  EXPECT_TRUE(p.IsValid());
80  EXPECT_EQ(2u, p.GetTokenCount());
81  EXPECT_EQ(3u, p.GetTokens()[0].length);
82  EXPECT_STREQ("foo", p.GetTokens()[0].name);
83  EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
84  EXPECT_EQ(1u, p.GetTokens()[1].length);
85  EXPECT_STREQ("0", p.GetTokens()[1].name);
86  EXPECT_EQ(0u, p.GetTokens()[1].index);
87  }
88 
89  {
90  // Unescape ~1
91  Pointer p("/a~1b");
92  EXPECT_TRUE(p.IsValid());
93  EXPECT_EQ(1u, p.GetTokenCount());
94  EXPECT_EQ(3u, p.GetTokens()[0].length);
95  EXPECT_STREQ("a/b", p.GetTokens()[0].name);
96  }
97 
98  {
99  // Unescape ~0
100  Pointer p("/m~0n");
101  EXPECT_TRUE(p.IsValid());
102  EXPECT_EQ(1u, p.GetTokenCount());
103  EXPECT_EQ(3u, p.GetTokens()[0].length);
104  EXPECT_STREQ("m~n", p.GetTokens()[0].name);
105  }
106 
107  {
108  // empty name
109  Pointer p("/");
110  EXPECT_TRUE(p.IsValid());
111  EXPECT_EQ(1u, p.GetTokenCount());
112  EXPECT_EQ(0u, p.GetTokens()[0].length);
113  EXPECT_STREQ("", p.GetTokens()[0].name);
114  }
115 
116  {
117  // empty and non-empty name
118  Pointer p("//a");
119  EXPECT_TRUE(p.IsValid());
120  EXPECT_EQ(2u, p.GetTokenCount());
121  EXPECT_EQ(0u, p.GetTokens()[0].length);
122  EXPECT_STREQ("", p.GetTokens()[0].name);
123  EXPECT_EQ(1u, p.GetTokens()[1].length);
124  EXPECT_STREQ("a", p.GetTokens()[1].name);
125  }
126 
127  {
128  // Null characters
129  Pointer p("/\0\0", 3);
130  EXPECT_TRUE(p.IsValid());
131  EXPECT_EQ(1u, p.GetTokenCount());
132  EXPECT_EQ(2u, p.GetTokens()[0].length);
133  EXPECT_EQ('\0', p.GetTokens()[0].name[0]);
134  EXPECT_EQ('\0', p.GetTokens()[0].name[1]);
135  EXPECT_EQ('\0', p.GetTokens()[0].name[2]);
136  }
137 
138  {
139  // Valid index
140  Pointer p("/123");
141  EXPECT_TRUE(p.IsValid());
142  EXPECT_EQ(1u, p.GetTokenCount());
143  EXPECT_STREQ("123", p.GetTokens()[0].name);
144  EXPECT_EQ(123u, p.GetTokens()[0].index);
145  }
146 
147  {
148  // Invalid index (with leading zero)
149  Pointer p("/01");
150  EXPECT_TRUE(p.IsValid());
151  EXPECT_EQ(1u, p.GetTokenCount());
152  EXPECT_STREQ("01", p.GetTokens()[0].name);
153  EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
154  }
155 
156  if (sizeof(SizeType) == 4) {
157  // Invalid index (overflow)
158  Pointer p("/4294967296");
159  EXPECT_TRUE(p.IsValid());
160  EXPECT_EQ(1u, p.GetTokenCount());
161  EXPECT_STREQ("4294967296", p.GetTokens()[0].name);
162  EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
163  }
164 
165  {
166  // kPointerParseErrorTokenMustBeginWithSolidus
167  Pointer p(" ");
168  EXPECT_FALSE(p.IsValid());
169  EXPECT_EQ(kPointerParseErrorTokenMustBeginWithSolidus, p.GetParseErrorCode());
170  EXPECT_EQ(0u, p.GetParseErrorOffset());
171  }
172 
173  {
174  // kPointerParseErrorInvalidEscape
175  Pointer p("/~");
176  EXPECT_FALSE(p.IsValid());
177  EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
178  EXPECT_EQ(2u, p.GetParseErrorOffset());
179  }
180 
181  {
182  // kPointerParseErrorInvalidEscape
183  Pointer p("/~2");
184  EXPECT_FALSE(p.IsValid());
185  EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
186  EXPECT_EQ(2u, p.GetParseErrorOffset());
187  }
188 }
189 
190 TEST(Pointer, Parse_URIFragment) {
191  {
192  Pointer p("#");
193  EXPECT_TRUE(p.IsValid());
194  EXPECT_EQ(0u, p.GetTokenCount());
195  }
196 
197  {
198  Pointer p("#/foo");
199  EXPECT_TRUE(p.IsValid());
200  EXPECT_EQ(1u, p.GetTokenCount());
201  EXPECT_EQ(3u, p.GetTokens()[0].length);
202  EXPECT_STREQ("foo", p.GetTokens()[0].name);
203  }
204 
205  {
206  Pointer p("#/foo/0");
207  EXPECT_TRUE(p.IsValid());
208  EXPECT_EQ(2u, p.GetTokenCount());
209  EXPECT_EQ(3u, p.GetTokens()[0].length);
210  EXPECT_STREQ("foo", p.GetTokens()[0].name);
211  EXPECT_EQ(1u, p.GetTokens()[1].length);
212  EXPECT_STREQ("0", p.GetTokens()[1].name);
213  EXPECT_EQ(0u, p.GetTokens()[1].index);
214  }
215 
216  {
217  // Unescape ~1
218  Pointer p("#/a~1b");
219  EXPECT_TRUE(p.IsValid());
220  EXPECT_EQ(1u, p.GetTokenCount());
221  EXPECT_EQ(3u, p.GetTokens()[0].length);
222  EXPECT_STREQ("a/b", p.GetTokens()[0].name);
223  }
224 
225  {
226  // Unescape ~0
227  Pointer p("#/m~0n");
228  EXPECT_TRUE(p.IsValid());
229  EXPECT_EQ(1u, p.GetTokenCount());
230  EXPECT_EQ(3u, p.GetTokens()[0].length);
231  EXPECT_STREQ("m~n", p.GetTokens()[0].name);
232  }
233 
234  {
235  // empty name
236  Pointer p("#/");
237  EXPECT_TRUE(p.IsValid());
238  EXPECT_EQ(1u, p.GetTokenCount());
239  EXPECT_EQ(0u, p.GetTokens()[0].length);
240  EXPECT_STREQ("", p.GetTokens()[0].name);
241  }
242 
243  {
244  // empty and non-empty name
245  Pointer p("#//a");
246  EXPECT_TRUE(p.IsValid());
247  EXPECT_EQ(2u, p.GetTokenCount());
248  EXPECT_EQ(0u, p.GetTokens()[0].length);
249  EXPECT_STREQ("", p.GetTokens()[0].name);
250  EXPECT_EQ(1u, p.GetTokens()[1].length);
251  EXPECT_STREQ("a", p.GetTokens()[1].name);
252  }
253 
254  {
255  // Null characters
256  Pointer p("#/%00%00");
257  EXPECT_TRUE(p.IsValid());
258  EXPECT_EQ(1u, p.GetTokenCount());
259  EXPECT_EQ(2u, p.GetTokens()[0].length);
260  EXPECT_EQ('\0', p.GetTokens()[0].name[0]);
261  EXPECT_EQ('\0', p.GetTokens()[0].name[1]);
262  EXPECT_EQ('\0', p.GetTokens()[0].name[2]);
263  }
264 
265  {
266  // Percentage Escapes
267  EXPECT_STREQ("c%d", Pointer("#/c%25d").GetTokens()[0].name);
268  EXPECT_STREQ("e^f", Pointer("#/e%5Ef").GetTokens()[0].name);
269  EXPECT_STREQ("g|h", Pointer("#/g%7Ch").GetTokens()[0].name);
270  EXPECT_STREQ("i\\j", Pointer("#/i%5Cj").GetTokens()[0].name);
271  EXPECT_STREQ("k\"l", Pointer("#/k%22l").GetTokens()[0].name);
272  EXPECT_STREQ(" ", Pointer("#/%20").GetTokens()[0].name);
273  }
274 
275  {
276  // Valid index
277  Pointer p("#/123");
278  EXPECT_TRUE(p.IsValid());
279  EXPECT_EQ(1u, p.GetTokenCount());
280  EXPECT_STREQ("123", p.GetTokens()[0].name);
281  EXPECT_EQ(123u, p.GetTokens()[0].index);
282  }
283 
284  {
285  // Invalid index (with leading zero)
286  Pointer p("#/01");
287  EXPECT_TRUE(p.IsValid());
288  EXPECT_EQ(1u, p.GetTokenCount());
289  EXPECT_STREQ("01", p.GetTokens()[0].name);
290  EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
291  }
292 
293  if (sizeof(SizeType) == 4) {
294  // Invalid index (overflow)
295  Pointer p("#/4294967296");
296  EXPECT_TRUE(p.IsValid());
297  EXPECT_EQ(1u, p.GetTokenCount());
298  EXPECT_STREQ("4294967296", p.GetTokens()[0].name);
299  EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
300  }
301 
302  {
303  // Decode UTF-8 perecent encoding to UTF-8
304  Pointer p("#/%C2%A2");
305  EXPECT_TRUE(p.IsValid());
306  EXPECT_EQ(1u, p.GetTokenCount());
307  EXPECT_STREQ("\xC2\xA2", p.GetTokens()[0].name);
308  }
309 
310  {
311  // Decode UTF-8 perecent encoding to UTF-16
312  GenericPointer<GenericValue<UTF16<> > > p(L"#/%C2%A2");
313  EXPECT_TRUE(p.IsValid());
314  EXPECT_EQ(1u, p.GetTokenCount());
315  EXPECT_EQ(static_cast<UTF16<>::Ch>(0x00A2), p.GetTokens()[0].name[0]);
316  EXPECT_EQ(1u, p.GetTokens()[0].length);
317  }
318 
319  {
320  // Decode UTF-8 perecent encoding to UTF-16
321  GenericPointer<GenericValue<UTF16<> > > p(L"#/%E2%82%AC");
322  EXPECT_TRUE(p.IsValid());
323  EXPECT_EQ(1u, p.GetTokenCount());
324  EXPECT_EQ(static_cast<UTF16<>::Ch>(0x20AC), p.GetTokens()[0].name[0]);
325  EXPECT_EQ(1u, p.GetTokens()[0].length);
326  }
327 
328  {
329  // kPointerParseErrorTokenMustBeginWithSolidus
330  Pointer p("# ");
331  EXPECT_FALSE(p.IsValid());
332  EXPECT_EQ(kPointerParseErrorTokenMustBeginWithSolidus, p.GetParseErrorCode());
333  EXPECT_EQ(1u, p.GetParseErrorOffset());
334  }
335 
336  {
337  // kPointerParseErrorInvalidEscape
338  Pointer p("#/~");
339  EXPECT_FALSE(p.IsValid());
340  EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
341  EXPECT_EQ(3u, p.GetParseErrorOffset());
342  }
343 
344  {
345  // kPointerParseErrorInvalidEscape
346  Pointer p("#/~2");
347  EXPECT_FALSE(p.IsValid());
348  EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
349  EXPECT_EQ(3u, p.GetParseErrorOffset());
350  }
351 
352  {
353  // kPointerParseErrorInvalidPercentEncoding
354  Pointer p("#/%");
355  EXPECT_FALSE(p.IsValid());
356  EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
357  EXPECT_EQ(2u, p.GetParseErrorOffset());
358  }
359 
360  {
361  // kPointerParseErrorInvalidPercentEncoding (invalid hex)
362  Pointer p("#/%g0");
363  EXPECT_FALSE(p.IsValid());
364  EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
365  EXPECT_EQ(2u, p.GetParseErrorOffset());
366  }
367 
368  {
369  // kPointerParseErrorInvalidPercentEncoding (invalid hex)
370  Pointer p("#/%0g");
371  EXPECT_FALSE(p.IsValid());
372  EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
373  EXPECT_EQ(2u, p.GetParseErrorOffset());
374  }
375 
376  {
377  // kPointerParseErrorInvalidPercentEncoding (incomplete UTF-8 sequence)
378  Pointer p("#/%C2");
379  EXPECT_FALSE(p.IsValid());
380  EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
381  EXPECT_EQ(2u, p.GetParseErrorOffset());
382  }
383 
384  {
385  // kPointerParseErrorCharacterMustPercentEncode
386  Pointer p("#/ ");
387  EXPECT_FALSE(p.IsValid());
388  EXPECT_EQ(kPointerParseErrorCharacterMustPercentEncode, p.GetParseErrorCode());
389  EXPECT_EQ(2u, p.GetParseErrorOffset());
390  }
391 
392  {
393  // kPointerParseErrorCharacterMustPercentEncode
394  Pointer p("#/\n");
395  EXPECT_FALSE(p.IsValid());
396  EXPECT_EQ(kPointerParseErrorCharacterMustPercentEncode, p.GetParseErrorCode());
397  EXPECT_EQ(2u, p.GetParseErrorOffset());
398  }
399 }
400 
401 TEST(Pointer, Stringify) {
402  // Test by roundtrip
403  const char* sources[] = {
404  "",
405  "/foo",
406  "/foo/0",
407  "/",
408  "/a~1b",
409  "/c%d",
410  "/e^f",
411  "/g|h",
412  "/i\\j",
413  "/k\"l",
414  "/ ",
415  "/m~0n",
416  "/\xC2\xA2",
417  "/\xE2\x82\xAC",
418  "/\xF0\x9D\x84\x9E"
419  };
420 
421  for (size_t i = 0; i < sizeof(sources) / sizeof(sources[0]); i++) {
422  Pointer p(sources[i]);
423  StringBuffer s;
424  EXPECT_TRUE(p.Stringify(s));
425  EXPECT_STREQ(sources[i], s.GetString());
426 
427  // Stringify to URI fragment
428  StringBuffer s2;
429  EXPECT_TRUE(p.StringifyUriFragment(s2));
430  Pointer p2(s2.GetString(), s2.GetSize());
431  EXPECT_TRUE(p2.IsValid());
432  EXPECT_TRUE(p == p2);
433  }
434 
435  {
436  // Strigify to URI fragment with an invalid UTF-8 sequence
437  Pointer p("/\xC2");
438  StringBuffer s;
439  EXPECT_FALSE(p.StringifyUriFragment(s));
440  }
441 }
442 
443 // Construct a Pointer with static tokens, no dynamic allocation involved.
444 #define NAME(s) { s, static_cast<SizeType>(sizeof(s) / sizeof(s[0]) - 1), kPointerInvalidIndex }
445 #define INDEX(i) { #i, static_cast<SizeType>(sizeof(#i) - 1), i }
446 
447 static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(0) }; // equivalent to "/foo/0"
448 
449 #undef NAME
450 #undef INDEX
451 
452 TEST(Pointer, ConstructorWithToken) {
453  Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
454  EXPECT_TRUE(p.IsValid());
455  EXPECT_EQ(2u, p.GetTokenCount());
456  EXPECT_EQ(3u, p.GetTokens()[0].length);
457  EXPECT_STREQ("foo", p.GetTokens()[0].name);
458  EXPECT_EQ(1u, p.GetTokens()[1].length);
459  EXPECT_STREQ("0", p.GetTokens()[1].name);
460  EXPECT_EQ(0u, p.GetTokens()[1].index);
461 }
462 
463 TEST(Pointer, CopyConstructor) {
464  {
465  Pointer p("/foo/0");
466  Pointer q(p);
467  EXPECT_TRUE(q.IsValid());
468  EXPECT_EQ(2u, q.GetTokenCount());
469  EXPECT_EQ(3u, q.GetTokens()[0].length);
470  EXPECT_STREQ("foo", q.GetTokens()[0].name);
471  EXPECT_EQ(1u, q.GetTokens()[1].length);
472  EXPECT_STREQ("0", q.GetTokens()[1].name);
473  EXPECT_EQ(0u, q.GetTokens()[1].index);
474  }
475 
476  // Static tokens
477  {
478  Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
479  Pointer q(p);
480  EXPECT_TRUE(q.IsValid());
481  EXPECT_EQ(2u, q.GetTokenCount());
482  EXPECT_EQ(3u, q.GetTokens()[0].length);
483  EXPECT_STREQ("foo", q.GetTokens()[0].name);
484  EXPECT_EQ(1u, q.GetTokens()[1].length);
485  EXPECT_STREQ("0", q.GetTokens()[1].name);
486  EXPECT_EQ(0u, q.GetTokens()[1].index);
487  }
488 }
489 
490 TEST(Pointer, Assignment) {
491  {
492  Pointer p("/foo/0");
493  Pointer q;
494  q = p;
495  EXPECT_TRUE(q.IsValid());
496  EXPECT_EQ(2u, q.GetTokenCount());
497  EXPECT_EQ(3u, q.GetTokens()[0].length);
498  EXPECT_STREQ("foo", q.GetTokens()[0].name);
499  EXPECT_EQ(1u, q.GetTokens()[1].length);
500  EXPECT_STREQ("0", q.GetTokens()[1].name);
501  EXPECT_EQ(0u, q.GetTokens()[1].index);
502  q = q;
503  EXPECT_TRUE(q.IsValid());
504  EXPECT_EQ(2u, q.GetTokenCount());
505  EXPECT_EQ(3u, q.GetTokens()[0].length);
506  EXPECT_STREQ("foo", q.GetTokens()[0].name);
507  EXPECT_EQ(1u, q.GetTokens()[1].length);
508  EXPECT_STREQ("0", q.GetTokens()[1].name);
509  EXPECT_EQ(0u, q.GetTokens()[1].index);
510  }
511 
512  // Static tokens
513  {
514  Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
515  Pointer q;
516  q = p;
517  EXPECT_TRUE(q.IsValid());
518  EXPECT_EQ(2u, q.GetTokenCount());
519  EXPECT_EQ(3u, q.GetTokens()[0].length);
520  EXPECT_STREQ("foo", q.GetTokens()[0].name);
521  EXPECT_EQ(1u, q.GetTokens()[1].length);
522  EXPECT_STREQ("0", q.GetTokens()[1].name);
523  EXPECT_EQ(0u, q.GetTokens()[1].index);
524  }
525 }
526 
527 TEST(Pointer, Append) {
528  {
529  Pointer p;
530  Pointer q = p.Append("foo");
531  EXPECT_TRUE(Pointer("/foo") == q);
532  q = q.Append(1234);
533  EXPECT_TRUE(Pointer("/foo/1234") == q);
534  q = q.Append("");
535  EXPECT_TRUE(Pointer("/foo/1234/") == q);
536  }
537 
538  {
539  Pointer p;
540  Pointer q = p.Append(Value("foo").Move());
541  EXPECT_TRUE(Pointer("/foo") == q);
542  q = q.Append(Value(1234).Move());
543  EXPECT_TRUE(Pointer("/foo/1234") == q);
544  q = q.Append(Value(kStringType).Move());
545  EXPECT_TRUE(Pointer("/foo/1234/") == q);
546  }
547 
548 #if RAPIDJSON_HAS_STDSTRING
549  {
550  Pointer p;
551  Pointer q = p.Append(std::string("foo"));
552  EXPECT_TRUE(Pointer("/foo") == q);
553  }
554 #endif
555 }
556 
557 TEST(Pointer, Equality) {
558  EXPECT_TRUE(Pointer("/foo/0") == Pointer("/foo/0"));
559  EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/1"));
560  EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/0/1"));
561  EXPECT_FALSE(Pointer("/foo/0") == Pointer("a"));
562  EXPECT_FALSE(Pointer("a") == Pointer("a")); // Invalid always not equal
563 }
564 
565 TEST(Pointer, Inequality) {
566  EXPECT_FALSE(Pointer("/foo/0") != Pointer("/foo/0"));
567  EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/1"));
568  EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/0/1"));
569  EXPECT_TRUE(Pointer("/foo/0") != Pointer("a"));
570  EXPECT_TRUE(Pointer("a") != Pointer("a")); // Invalid always not equal
571 }
572 
573 TEST(Pointer, Create) {
574  Document d;
575  {
576  Value* v = &Pointer("").Create(d, d.GetAllocator());
577  EXPECT_EQ(&d, v);
578  }
579  {
580  Value* v = &Pointer("/foo").Create(d, d.GetAllocator());
581  EXPECT_EQ(&d["foo"], v);
582  }
583  {
584  Value* v = &Pointer("/foo/0").Create(d, d.GetAllocator());
585  EXPECT_EQ(&d["foo"][0], v);
586  }
587  {
588  Value* v = &Pointer("/foo/-").Create(d, d.GetAllocator());
589  EXPECT_EQ(&d["foo"][1], v);
590  }
591 
592  {
593  Value* v = &Pointer("/foo/-/-").Create(d, d.GetAllocator());
594  // "foo/-" is a newly created null value x.
595  // "foo/-/-" finds that x is not an array, it converts x to empty object
596  // and treats - as "-" member name
597  EXPECT_EQ(&d["foo"][2]["-"], v);
598  }
599 
600  {
601  // Document with no allocator
602  Value* v = &Pointer("/foo/-").Create(d);
603  EXPECT_EQ(&d["foo"][3], v);
604  }
605 
606  {
607  // Value (not document) must give allocator
608  Value* v = &Pointer("/-").Create(d["foo"], d.GetAllocator());
609  EXPECT_EQ(&d["foo"][4], v);
610  }
611 }
612 
613 TEST(Pointer, Get) {
614  Document d;
615  d.Parse(kJson);
616 
617  EXPECT_EQ(&d, Pointer("").Get(d));
618  EXPECT_EQ(&d["foo"], Pointer("/foo").Get(d));
619  EXPECT_EQ(&d["foo"][0], Pointer("/foo/0").Get(d));
620  EXPECT_EQ(&d[""], Pointer("/").Get(d));
621  EXPECT_EQ(&d["a/b"], Pointer("/a~1b").Get(d));
622  EXPECT_EQ(&d["c%d"], Pointer("/c%d").Get(d));
623  EXPECT_EQ(&d["e^f"], Pointer("/e^f").Get(d));
624  EXPECT_EQ(&d["g|h"], Pointer("/g|h").Get(d));
625  EXPECT_EQ(&d["i\\j"], Pointer("/i\\j").Get(d));
626  EXPECT_EQ(&d["k\"l"], Pointer("/k\"l").Get(d));
627  EXPECT_EQ(&d[" "], Pointer("/ ").Get(d));
628  EXPECT_EQ(&d["m~n"], Pointer("/m~0n").Get(d));
629  EXPECT_TRUE(Pointer("/abc").Get(d) == 0);
630  size_t unresolvedTokenIndex;
631  EXPECT_TRUE(Pointer("/foo/2").Get(d, &unresolvedTokenIndex) == 0); // Out of boundary
632  EXPECT_EQ(1, unresolvedTokenIndex);
633  EXPECT_TRUE(Pointer("/foo/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
634  EXPECT_EQ(1, unresolvedTokenIndex);
635  EXPECT_TRUE(Pointer("/foo/0/0").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
636  EXPECT_EQ(2, unresolvedTokenIndex);
637  EXPECT_TRUE(Pointer("/foo/0/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
638  EXPECT_EQ(2, unresolvedTokenIndex);
639 }
640 
641 TEST(Pointer, GetWithDefault) {
642  Document d;
643  d.Parse(kJson);
644 
645  // Value version
647  const Value v("qux");
648  EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v, a));
649  EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v, a));
650  EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v, a));
651  EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move(), a));
652  EXPECT_STREQ("last", d["foo"][3].GetString());
653 
654  EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, Value().Move(), a).IsNull());
655  EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, "x", a).IsNull());
656 
657  // Generic version
658  EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -1, a).GetInt());
659  EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -2, a).GetInt());
660  EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x87654321, a).GetUint());
661  EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x12345678, a).GetUint());
662 
663  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
664  EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64, a).GetInt64());
665  EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64 + 1, a).GetInt64());
666 
667  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
668  EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64, a).GetUint64());
669  EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64 - 1, a).GetUint64());
670 
671  EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, true, a).IsTrue());
672  EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, false, a).IsTrue());
673 
674  EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, false, a).IsFalse());
675  EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, true, a).IsFalse());
676 
677  // StringRef version
678  EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d, "Hello", a).GetString());
679 
680  // Copy string version
681  {
682  char buffer[256];
683  strcpy(buffer, "World");
684  EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d, buffer, a).GetString());
685  memset(buffer, 0, sizeof(buffer));
686  }
687  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
688 
689 #if RAPIDJSON_HAS_STDSTRING
690  EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d, std::string("C++"), a).GetString());
691 #endif
692 }
693 
694 TEST(Pointer, GetWithDefault_NoAllocator) {
695  Document d;
696  d.Parse(kJson);
697 
698  // Value version
699  const Value v("qux");
700  EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v));
701  EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v));
702  EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v));
703  EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move()));
704  EXPECT_STREQ("last", d["foo"][3].GetString());
705 
706  EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, Value().Move()).IsNull());
707  EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, "x").IsNull());
708 
709  // Generic version
710  EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -1).GetInt());
711  EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -2).GetInt());
712  EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x87654321).GetUint());
713  EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x12345678).GetUint());
714 
715  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
716  EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64).GetInt64());
717  EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64 + 1).GetInt64());
718 
719  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
720  EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64).GetUint64());
721  EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64 - 1).GetUint64());
722 
723  EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, true).IsTrue());
724  EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, false).IsTrue());
725 
726  EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, false).IsFalse());
727  EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, true).IsFalse());
728 
729  // StringRef version
730  EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d, "Hello").GetString());
731 
732  // Copy string version
733  {
734  char buffer[256];
735  strcpy(buffer, "World");
736  EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d, buffer).GetString());
737  memset(buffer, 0, sizeof(buffer));
738  }
739  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
740 
741 #if RAPIDJSON_HAS_STDSTRING
742  EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d, std::string("C++")).GetString());
743 #endif
744 }
745 
746 TEST(Pointer, Set) {
747  Document d;
748  d.Parse(kJson);
750 
751  // Value version
752  Pointer("/foo/0").Set(d, Value(123).Move(), a);
753  EXPECT_EQ(123, d["foo"][0].GetInt());
754 
755  Pointer("/foo/-").Set(d, Value(456).Move(), a);
756  EXPECT_EQ(456, d["foo"][2].GetInt());
757 
758  Pointer("/foo/null").Set(d, Value().Move(), a);
759  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
760 
761  // Const Value version
762  const Value foo(d["foo"], a);
763  Pointer("/clone").Set(d, foo, a);
764  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
765 
766  // Generic version
767  Pointer("/foo/int").Set(d, -1, a);
768  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
769 
770  Pointer("/foo/uint").Set(d, 0x87654321, a);
771  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
772 
773  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
774  Pointer("/foo/int64").Set(d, i64, a);
775  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
776 
777  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
778  Pointer("/foo/uint64").Set(d, u64, a);
779  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
780 
781  Pointer("/foo/true").Set(d, true, a);
782  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
783 
784  Pointer("/foo/false").Set(d, false, a);
785  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
786 
787  // StringRef version
788  Pointer("/foo/hello").Set(d, "Hello", a);
789  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
790 
791  // Copy string version
792  {
793  char buffer[256];
794  strcpy(buffer, "World");
795  Pointer("/foo/world").Set(d, buffer, a);
796  memset(buffer, 0, sizeof(buffer));
797  }
798  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
799 
800 #if RAPIDJSON_HAS_STDSTRING
801  Pointer("/foo/c++").Set(d, std::string("C++"), a);
802  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
803 #endif
804 }
805 
806 TEST(Pointer, Set_NoAllocator) {
807  Document d;
808  d.Parse(kJson);
809 
810  // Value version
811  Pointer("/foo/0").Set(d, Value(123).Move());
812  EXPECT_EQ(123, d["foo"][0].GetInt());
813 
814  Pointer("/foo/-").Set(d, Value(456).Move());
815  EXPECT_EQ(456, d["foo"][2].GetInt());
816 
817  Pointer("/foo/null").Set(d, Value().Move());
818  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
819 
820  // Const Value version
821  const Value foo(d["foo"], d.GetAllocator());
822  Pointer("/clone").Set(d, foo);
823  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
824 
825  // Generic version
826  Pointer("/foo/int").Set(d, -1);
827  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
828 
829  Pointer("/foo/uint").Set(d, 0x87654321);
830  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
831 
832  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
833  Pointer("/foo/int64").Set(d, i64);
834  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
835 
836  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
837  Pointer("/foo/uint64").Set(d, u64);
838  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
839 
840  Pointer("/foo/true").Set(d, true);
841  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
842 
843  Pointer("/foo/false").Set(d, false);
844  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
845 
846  // StringRef version
847  Pointer("/foo/hello").Set(d, "Hello");
848  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
849 
850  // Copy string version
851  {
852  char buffer[256];
853  strcpy(buffer, "World");
854  Pointer("/foo/world").Set(d, buffer);
855  memset(buffer, 0, sizeof(buffer));
856  }
857  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
858 
859 #if RAPIDJSON_HAS_STDSTRING
860  Pointer("/foo/c++").Set(d, std::string("C++"));
861  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
862 #endif
863 }
864 
866  Document d;
867  d.Parse(kJson);
869  Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d), a);
870  EXPECT_STREQ("baz", d["foo"][0].GetString());
871  EXPECT_STREQ("bar", d["foo"][1].GetString());
872 }
873 
874 TEST(Pointer, Swap_NoAllocator) {
875  Document d;
876  d.Parse(kJson);
877  Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d));
878  EXPECT_STREQ("baz", d["foo"][0].GetString());
879  EXPECT_STREQ("bar", d["foo"][1].GetString());
880 }
881 
882 TEST(Pointer, Erase) {
883  Document d;
884  d.Parse(kJson);
885 
886  EXPECT_FALSE(Pointer("").Erase(d));
887  EXPECT_FALSE(Pointer("/nonexist").Erase(d));
888  EXPECT_FALSE(Pointer("/nonexist/nonexist").Erase(d));
889  EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
890  EXPECT_FALSE(Pointer("/foo/nonexist/nonexist").Erase(d));
891  EXPECT_FALSE(Pointer("/foo/0/nonexist").Erase(d));
892  EXPECT_FALSE(Pointer("/foo/0/nonexist/nonexist").Erase(d));
893  EXPECT_FALSE(Pointer("/foo/2/nonexist").Erase(d));
894  EXPECT_TRUE(Pointer("/foo/0").Erase(d));
895  EXPECT_EQ(1u, d["foo"].Size());
896  EXPECT_STREQ("baz", d["foo"][0].GetString());
897  EXPECT_TRUE(Pointer("/foo/0").Erase(d));
898  EXPECT_TRUE(d["foo"].Empty());
899  EXPECT_TRUE(Pointer("/foo").Erase(d));
900  EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
901 
902  Pointer("/a/0/b/0").Create(d);
903 
904  EXPECT_TRUE(Pointer("/a/0/b/0").Get(d) != 0);
905  EXPECT_TRUE(Pointer("/a/0/b/0").Erase(d));
906  EXPECT_TRUE(Pointer("/a/0/b/0").Get(d) == 0);
907 
908  EXPECT_TRUE(Pointer("/a/0/b").Get(d) != 0);
909  EXPECT_TRUE(Pointer("/a/0/b").Erase(d));
910  EXPECT_TRUE(Pointer("/a/0/b").Get(d) == 0);
911 
912  EXPECT_TRUE(Pointer("/a/0").Get(d) != 0);
913  EXPECT_TRUE(Pointer("/a/0").Erase(d));
914  EXPECT_TRUE(Pointer("/a/0").Get(d) == 0);
915 
916  EXPECT_TRUE(Pointer("/a").Get(d) != 0);
917  EXPECT_TRUE(Pointer("/a").Erase(d));
918  EXPECT_TRUE(Pointer("/a").Get(d) == 0);
919 }
920 
922  Document d;
924 
925  {
926  Value& v = CreateValueByPointer(d, Pointer("/foo/0"), a);
927  EXPECT_EQ(&d["foo"][0], &v);
928  }
929  {
930  Value& v = CreateValueByPointer(d, "/foo/1", a);
931  EXPECT_EQ(&d["foo"][1], &v);
932  }
933 }
934 
935 TEST(Pointer, CreateValueByPointer_NoAllocator) {
936  Document d;
937 
938  {
939  Value& v = CreateValueByPointer(d, Pointer("/foo/0"));
940  EXPECT_EQ(&d["foo"][0], &v);
941  }
942  {
943  Value& v = CreateValueByPointer(d, "/foo/1");
944  EXPECT_EQ(&d["foo"][1], &v);
945  }
946 }
947 
949  Document d;
950  d.Parse(kJson);
951 
952  EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, Pointer("/foo/0")));
953  EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, "/foo/0"));
954 
955  size_t unresolvedTokenIndex;
956  EXPECT_TRUE(GetValueByPointer(d, "/foo/2", &unresolvedTokenIndex) == 0); // Out of boundary
957  EXPECT_EQ(1, unresolvedTokenIndex);
958  EXPECT_TRUE(GetValueByPointer(d, "/foo/a", &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
959  EXPECT_EQ(1, unresolvedTokenIndex);
960  EXPECT_TRUE(GetValueByPointer(d, "/foo/0/0", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
961  EXPECT_EQ(2, unresolvedTokenIndex);
962  EXPECT_TRUE(GetValueByPointer(d, "/foo/0/a", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
963  EXPECT_EQ(2, unresolvedTokenIndex);
964 
965  // const version
966  const Value& v = d;
967  EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, Pointer("/foo/0")));
968  EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, "/foo/0"));
969 
970  EXPECT_TRUE(GetValueByPointer(v, "/foo/2", &unresolvedTokenIndex) == 0); // Out of boundary
971  EXPECT_EQ(1, unresolvedTokenIndex);
972  EXPECT_TRUE(GetValueByPointer(v, "/foo/a", &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
973  EXPECT_EQ(1, unresolvedTokenIndex);
974  EXPECT_TRUE(GetValueByPointer(v, "/foo/0/0", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
975  EXPECT_EQ(2, unresolvedTokenIndex);
976  EXPECT_TRUE(GetValueByPointer(v, "/foo/0/a", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
977  EXPECT_EQ(2, unresolvedTokenIndex);
978 
979 }
980 
981 TEST(Pointer, GetValueByPointerWithDefault_Pointer) {
982  Document d;
983  d.Parse(kJson);
984 
986  const Value v("qux");
987  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
988  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
989  EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, Pointer("/foo/1"), v, a));
990  EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, Pointer("/foo/2"), v, a));
991  EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, Pointer("/foo/-"), Value("last").Move(), a));
992  EXPECT_STREQ("last", d["foo"][3].GetString());
993 
994  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), Value().Move(), a).IsNull());
995  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), "x", a).IsNull());
996 
997  // Generic version
998  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -1, a).GetInt());
999  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -2, a).GetInt());
1000  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x87654321, a).GetUint());
1001  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x12345678, a).GetUint());
1002 
1003  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1004  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64, a).GetInt64());
1005  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64 + 1, a).GetInt64());
1006 
1007  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1008  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64, a).GetUint64());
1009  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64 - 1, a).GetUint64());
1010 
1011  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), true, a).IsTrue());
1012  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), false, a).IsTrue());
1013 
1014  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), false, a).IsFalse());
1015  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), true, a).IsFalse());
1016 
1017  // StringRef version
1018  EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, Pointer("/foo/hello"), "Hello", a).GetString());
1019 
1020  // Copy string version
1021  {
1022  char buffer[256];
1023  strcpy(buffer, "World");
1024  EXPECT_STREQ("World", GetValueByPointerWithDefault(d, Pointer("/foo/world"), buffer, a).GetString());
1025  memset(buffer, 0, sizeof(buffer));
1026  }
1027  EXPECT_STREQ("World", GetValueByPointer(d, Pointer("/foo/world"))->GetString());
1028 
1029 #if RAPIDJSON_HAS_STDSTRING
1030  EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++"), a).GetString());
1031 #endif
1032 }
1033 
1034 TEST(Pointer, GetValueByPointerWithDefault_String) {
1035  Document d;
1036  d.Parse(kJson);
1037 
1039  const Value v("qux");
1040  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v, a));
1041  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v, a));
1042  EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v, a));
1043  EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, "/foo/2", v, a));
1044  EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, "/foo/-", Value("last").Move(), a));
1045  EXPECT_STREQ("last", d["foo"][3].GetString());
1046 
1047  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", Value().Move(), a).IsNull());
1048  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", "x", a).IsNull());
1049 
1050  // Generic version
1051  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -1, a).GetInt());
1052  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -2, a).GetInt());
1053  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x87654321, a).GetUint());
1054  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x12345678, a).GetUint());
1055 
1056  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1057  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64, a).GetInt64());
1058  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64 + 1, a).GetInt64());
1059 
1060  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1061  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64, a).GetUint64());
1062  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64 - 1, a).GetUint64());
1063 
1064  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", true, a).IsTrue());
1065  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", false, a).IsTrue());
1066 
1067  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", false, a).IsFalse());
1068  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", true, a).IsFalse());
1069 
1070  // StringRef version
1071  EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, "/foo/hello", "Hello", a).GetString());
1072 
1073  // Copy string version
1074  {
1075  char buffer[256];
1076  strcpy(buffer, "World");
1077  EXPECT_STREQ("World", GetValueByPointerWithDefault(d, "/foo/world", buffer, a).GetString());
1078  memset(buffer, 0, sizeof(buffer));
1079  }
1080  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1081 
1082 #if RAPIDJSON_HAS_STDSTRING
1083  EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, "/foo/C++", std::string("C++"), a).GetString());
1084 #endif
1085 }
1086 
1087 TEST(Pointer, GetValueByPointerWithDefault_Pointer_NoAllocator) {
1088  Document d;
1089  d.Parse(kJson);
1090 
1091  const Value v("qux");
1092  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v));
1093  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v));
1094  EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, Pointer("/foo/1"), v));
1095  EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, Pointer("/foo/2"), v));
1096  EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, Pointer("/foo/-"), Value("last").Move()));
1097  EXPECT_STREQ("last", d["foo"][3].GetString());
1098 
1099  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), Value().Move()).IsNull());
1100  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), "x").IsNull());
1101 
1102  // Generic version
1103  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -1).GetInt());
1104  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -2).GetInt());
1105  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x87654321).GetUint());
1106  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x12345678).GetUint());
1107 
1108  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1109  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64).GetInt64());
1110  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64 + 1).GetInt64());
1111 
1112  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1113  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64).GetUint64());
1114  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64 - 1).GetUint64());
1115 
1116  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), true).IsTrue());
1117  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), false).IsTrue());
1118 
1119  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), false).IsFalse());
1120  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), true).IsFalse());
1121 
1122  // StringRef version
1123  EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, Pointer("/foo/hello"), "Hello").GetString());
1124 
1125  // Copy string version
1126  {
1127  char buffer[256];
1128  strcpy(buffer, "World");
1129  EXPECT_STREQ("World", GetValueByPointerWithDefault(d, Pointer("/foo/world"), buffer).GetString());
1130  memset(buffer, 0, sizeof(buffer));
1131  }
1132  EXPECT_STREQ("World", GetValueByPointer(d, Pointer("/foo/world"))->GetString());
1133 
1134 #if RAPIDJSON_HAS_STDSTRING
1135  EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++")).GetString());
1136 #endif
1137 }
1138 
1139 TEST(Pointer, GetValueByPointerWithDefault_String_NoAllocator) {
1140  Document d;
1141  d.Parse(kJson);
1142 
1143  const Value v("qux");
1144  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v));
1145  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v));
1146  EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v));
1147  EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, "/foo/2", v));
1148  EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, "/foo/-", Value("last").Move()));
1149  EXPECT_STREQ("last", d["foo"][3].GetString());
1150 
1151  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", Value().Move()).IsNull());
1152  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", "x").IsNull());
1153 
1154  // Generic version
1155  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -1).GetInt());
1156  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -2).GetInt());
1157  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x87654321).GetUint());
1158  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x12345678).GetUint());
1159 
1160  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1161  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64).GetInt64());
1162  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64 + 1).GetInt64());
1163 
1164  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1165  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64).GetUint64());
1166  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64 - 1).GetUint64());
1167 
1168  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", true).IsTrue());
1169  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", false).IsTrue());
1170 
1171  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", false).IsFalse());
1172  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", true).IsFalse());
1173 
1174  // StringRef version
1175  EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, "/foo/hello", "Hello").GetString());
1176 
1177  // Copy string version
1178  {
1179  char buffer[256];
1180  strcpy(buffer, "World");
1181  EXPECT_STREQ("World", GetValueByPointerWithDefault(d, "/foo/world", buffer).GetString());
1182  memset(buffer, 0, sizeof(buffer));
1183  }
1184  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1185 
1186 #if RAPIDJSON_HAS_STDSTRING
1187  EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++")).GetString());
1188 #endif
1189 }
1190 
1191 TEST(Pointer, SetValueByPointer_Pointer) {
1192  Document d;
1193  d.Parse(kJson);
1195 
1196  // Value version
1197  SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move(), a);
1198  EXPECT_EQ(123, d["foo"][0].GetInt());
1199 
1200  SetValueByPointer(d, Pointer("/foo/null"), Value().Move(), a);
1201  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1202 
1203  // Const Value version
1204  const Value foo(d["foo"], d.GetAllocator());
1205  SetValueByPointer(d, Pointer("/clone"), foo, a);
1206  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1207 
1208  // Generic version
1209  SetValueByPointer(d, Pointer("/foo/int"), -1, a);
1210  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1211 
1212  SetValueByPointer(d, Pointer("/foo/uint"), 0x87654321, a);
1213  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1214 
1215  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1216  SetValueByPointer(d, Pointer("/foo/int64"), i64, a);
1217  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1218 
1219  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1220  SetValueByPointer(d, Pointer("/foo/uint64"), u64, a);
1221  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1222 
1223  SetValueByPointer(d, Pointer("/foo/true"), true, a);
1224  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1225 
1226  SetValueByPointer(d, Pointer("/foo/false"), false, a);
1227  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1228 
1229  // StringRef version
1230  SetValueByPointer(d, Pointer("/foo/hello"), "Hello", a);
1231  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1232 
1233  // Copy string version
1234  {
1235  char buffer[256];
1236  strcpy(buffer, "World");
1237  SetValueByPointer(d, Pointer("/foo/world"), buffer, a);
1238  memset(buffer, 0, sizeof(buffer));
1239  }
1240  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1241 
1242 #if RAPIDJSON_HAS_STDSTRING
1243  SetValueByPointer(d, Pointer("/foo/c++"), std::string("C++"), a);
1244  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1245 #endif
1246 }
1247 
1248 TEST(Pointer, SetValueByPointer_String) {
1249  Document d;
1250  d.Parse(kJson);
1252 
1253  // Value version
1254  SetValueByPointer(d, "/foo/0", Value(123).Move(), a);
1255  EXPECT_EQ(123, d["foo"][0].GetInt());
1256 
1257  SetValueByPointer(d, "/foo/null", Value().Move(), a);
1258  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1259 
1260  // Const Value version
1261  const Value foo(d["foo"], d.GetAllocator());
1262  SetValueByPointer(d, "/clone", foo, a);
1263  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1264 
1265  // Generic version
1266  SetValueByPointer(d, "/foo/int", -1, a);
1267  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1268 
1269  SetValueByPointer(d, "/foo/uint", 0x87654321, a);
1270  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1271 
1272  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1273  SetValueByPointer(d, "/foo/int64", i64, a);
1274  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1275 
1276  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1277  SetValueByPointer(d, "/foo/uint64", u64, a);
1278  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1279 
1280  SetValueByPointer(d, "/foo/true", true, a);
1281  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1282 
1283  SetValueByPointer(d, "/foo/false", false, a);
1284  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1285 
1286  // StringRef version
1287  SetValueByPointer(d, "/foo/hello", "Hello", a);
1288  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1289 
1290  // Copy string version
1291  {
1292  char buffer[256];
1293  strcpy(buffer, "World");
1294  SetValueByPointer(d, "/foo/world", buffer, a);
1295  memset(buffer, 0, sizeof(buffer));
1296  }
1297  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1298 
1299 #if RAPIDJSON_HAS_STDSTRING
1300  SetValueByPointer(d, "/foo/c++", std::string("C++"), a);
1301  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1302 #endif
1303 }
1304 
1305 TEST(Pointer, SetValueByPointer_Pointer_NoAllocator) {
1306  Document d;
1307  d.Parse(kJson);
1308 
1309  // Value version
1310  SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move());
1311  EXPECT_EQ(123, d["foo"][0].GetInt());
1312 
1313  SetValueByPointer(d, Pointer("/foo/null"), Value().Move());
1314  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1315 
1316  // Const Value version
1317  const Value foo(d["foo"], d.GetAllocator());
1318  SetValueByPointer(d, Pointer("/clone"), foo);
1319  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1320 
1321  // Generic version
1322  SetValueByPointer(d, Pointer("/foo/int"), -1);
1323  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1324 
1325  SetValueByPointer(d, Pointer("/foo/uint"), 0x87654321);
1326  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1327 
1328  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1329  SetValueByPointer(d, Pointer("/foo/int64"), i64);
1330  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1331 
1332  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1333  SetValueByPointer(d, Pointer("/foo/uint64"), u64);
1334  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1335 
1336  SetValueByPointer(d, Pointer("/foo/true"), true);
1337  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1338 
1339  SetValueByPointer(d, Pointer("/foo/false"), false);
1340  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1341 
1342  // StringRef version
1343  SetValueByPointer(d, Pointer("/foo/hello"), "Hello");
1344  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1345 
1346  // Copy string version
1347  {
1348  char buffer[256];
1349  strcpy(buffer, "World");
1350  SetValueByPointer(d, Pointer("/foo/world"), buffer);
1351  memset(buffer, 0, sizeof(buffer));
1352  }
1353  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1354 
1355 #if RAPIDJSON_HAS_STDSTRING
1356  SetValueByPointer(d, Pointer("/foo/c++"), std::string("C++"));
1357  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1358 #endif
1359 }
1360 
1361 TEST(Pointer, SetValueByPointer_String_NoAllocator) {
1362  Document d;
1363  d.Parse(kJson);
1364 
1365  // Value version
1366  SetValueByPointer(d, "/foo/0", Value(123).Move());
1367  EXPECT_EQ(123, d["foo"][0].GetInt());
1368 
1369  SetValueByPointer(d, "/foo/null", Value().Move());
1370  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1371 
1372  // Const Value version
1373  const Value foo(d["foo"], d.GetAllocator());
1374  SetValueByPointer(d, "/clone", foo);
1375  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1376 
1377  // Generic version
1378  SetValueByPointer(d, "/foo/int", -1);
1379  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1380 
1381  SetValueByPointer(d, "/foo/uint", 0x87654321);
1382  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1383 
1384  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1385  SetValueByPointer(d, "/foo/int64", i64);
1386  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1387 
1388  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1389  SetValueByPointer(d, "/foo/uint64", u64);
1390  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1391 
1392  SetValueByPointer(d, "/foo/true", true);
1393  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1394 
1395  SetValueByPointer(d, "/foo/false", false);
1396  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1397 
1398  // StringRef version
1399  SetValueByPointer(d, "/foo/hello", "Hello");
1400  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1401 
1402  // Copy string version
1403  {
1404  char buffer[256];
1405  strcpy(buffer, "World");
1406  SetValueByPointer(d, "/foo/world", buffer);
1407  memset(buffer, 0, sizeof(buffer));
1408  }
1409  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1410 
1411 #if RAPIDJSON_HAS_STDSTRING
1412  SetValueByPointer(d, "/foo/c++", std::string("C++"));
1413  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1414 #endif
1415 }
1416 
1418  Document d;
1419  d.Parse(kJson);
1421  SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"), a);
1422  EXPECT_STREQ("baz", d["foo"][0].GetString());
1423  EXPECT_STREQ("bar", d["foo"][1].GetString());
1424 
1425  SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"), a);
1426  EXPECT_STREQ("bar", d["foo"][0].GetString());
1427  EXPECT_STREQ("baz", d["foo"][1].GetString());
1428 }
1429 
1430 TEST(Pointer, SwapValueByPointer_NoAllocator) {
1431  Document d;
1432  d.Parse(kJson);
1433  SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"));
1434  EXPECT_STREQ("baz", d["foo"][0].GetString());
1435  EXPECT_STREQ("bar", d["foo"][1].GetString());
1436 
1437  SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"));
1438  EXPECT_STREQ("bar", d["foo"][0].GetString());
1439  EXPECT_STREQ("baz", d["foo"][1].GetString());
1440 }
1441 
1442 TEST(Pointer, EraseValueByPointer_Pointer) {
1443  Document d;
1444  d.Parse(kJson);
1445 
1446  EXPECT_FALSE(EraseValueByPointer(d, Pointer("")));
1447  EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
1448  EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo/0")));
1449  EXPECT_EQ(1u, d["foo"].Size());
1450  EXPECT_STREQ("baz", d["foo"][0].GetString());
1451  EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo/0")));
1452  EXPECT_TRUE(d["foo"].Empty());
1453  EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo")));
1454  EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
1455 }
1456 
1457 TEST(Pointer, EraseValueByPointer_String) {
1458  Document d;
1459  d.Parse(kJson);
1460 
1461  EXPECT_FALSE(EraseValueByPointer(d, ""));
1462  EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
1463  EXPECT_TRUE(EraseValueByPointer(d, "/foo/0"));
1464  EXPECT_EQ(1u, d["foo"].Size());
1465  EXPECT_STREQ("baz", d["foo"][0].GetString());
1466  EXPECT_TRUE(EraseValueByPointer(d, "/foo/0"));
1467  EXPECT_TRUE(d["foo"].Empty());
1468  EXPECT_TRUE(EraseValueByPointer(d, "/foo"));
1469  EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
1470 }
1471 
1472 TEST(Pointer, Ambiguity) {
1473  {
1474  Document d;
1475  d.Parse("{\"0\" : [123]}");
1476  EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
1477  Pointer("/0/a").Set(d, 456); // Change array [123] to object {456}
1478  EXPECT_EQ(456, Pointer("/0/a").Get(d)->GetInt());
1479  }
1480 
1481  {
1482  Document d;
1483  EXPECT_FALSE(d.Parse("[{\"0\": 123}]").HasParseError());
1484  EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
1485  Pointer("/0/1").Set(d, 456); // 1 is treated as "1" to index object
1486  EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
1487  EXPECT_EQ(456, Pointer("/0/1").Get(d)->GetInt());
1488  }
1489 }
1490 
1491 // https://github.com/miloyip/rapidjson/issues/483
1492 namespace myjson {
1493 
1495 {
1496 public:
1497  static const bool kNeedFree = true;
1498  void * Malloc(size_t _size) { return malloc(_size); }
1499  void * Realloc(void *_org_p, size_t _org_size, size_t _new_size) { (void)_org_size; return realloc(_org_p, _new_size); }
1500  static void Free(void *_p) { return free(_p); }
1501 };
1502 
1503 typedef rapidjson::GenericDocument<
1504  rapidjson::UTF8<>,
1505  rapidjson::MemoryPoolAllocator< MyAllocator >,
1506  MyAllocator
1508 
1509 typedef rapidjson::GenericPointer<
1510  ::myjson::Document::ValueType,
1511  MyAllocator
1513 
1514 typedef ::myjson::Document::ValueType Value;
1515 
1516 }
1517 
1518 TEST(Pointer, Issue483) {
1519  std::string mystr, path;
1520  myjson::Document document;
1522  value.SetString(mystr.c_str(), static_cast<SizeType>(mystr.length()), document.GetAllocator());
1523  myjson::Pointer(path.c_str()).Set(document, value, document.GetAllocator());
1524 }
d
TEST(Pointer, DefaultConstructor)
Definition: pointertest.cpp:35
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition: pointer.h:1103
::myjson::Document::ValueType Value
static const Pointer::Token kTokens[]
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
#define INDEX(i)
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:294
const Ch * GetString() const
Definition: stringbuffer.h:73
#define NAME(s)
Invalid percent encoding in URI fragment.
Definition: pointer.h:44
XmlRpcServer s
static void Free(void *_p)
static RAPIDJSON_NAMESPACE_BEGIN const SizeType kPointerInvalidIndex
Represents an invalid index in GenericPointer::Token.
Definition: pointer.h:33
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1315
A token is the basic units of internal representation.
Definition: pointer.h:99
A token must begin with a &#39;/&#39;.
Definition: pointer.h:42
string
Definition: rapidjson.h:622
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: fwd.h:126
void * Realloc(void *_org_p, size_t _org_size, size_t _new_size)
rapidjson::GenericDocument< rapidjson::UTF8<>, rapidjson::MemoryPoolAllocator< MyAllocator >, MyAllocator > Document
unsigned __int64 uint64_t
Definition: stdint.h:136
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2383
CharType Ch
Definition: encodings.h:270
rapidjson::GenericPointer< ::myjson::Document::ValueType, MyAllocator > Pointer
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:33
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2296
main RapidJSON namespace
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
Definition: pointer.h:1057
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1121
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1222
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:211
signed __int64 int64_t
Definition: stdint.h:135
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition: pointer.h:1337
bool Stringify(OutputStream &os) const
Stringify to string or URI fragment representation.
Definition: pointer.h:941
static const char kJson[]
Definition: pointertest.cpp:22
void * Malloc(size_t _size)
A character must percent encoded in URI fragment.
Definition: pointer.h:45
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1199
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition: pointer.h:1081
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: document.h:2359


choreo_rapidjson
Author(s):
autogenerated on Thu Jul 18 2019 03:59:09