Electroneum
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());
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());
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());
389  EXPECT_EQ(2u, p.GetParseErrorOffset());
390  }
391 
392  {
393  // kPointerParseErrorCharacterMustPercentEncode
394  Pointer p("#/\n");
395  EXPECT_FALSE(p.IsValid());
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  CrtAllocator allocator;
466  Pointer p("/foo/0", &allocator);
467  Pointer q(p);
468  EXPECT_TRUE(q.IsValid());
469  EXPECT_EQ(2u, q.GetTokenCount());
470  EXPECT_EQ(3u, q.GetTokens()[0].length);
471  EXPECT_STREQ("foo", q.GetTokens()[0].name);
472  EXPECT_EQ(1u, q.GetTokens()[1].length);
473  EXPECT_STREQ("0", q.GetTokens()[1].name);
474  EXPECT_EQ(0u, q.GetTokens()[1].index);
475  EXPECT_EQ(&p.GetAllocator(), &q.GetAllocator());
476  }
477 
478  // Static tokens
479  {
480  Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
481  Pointer q(p);
482  EXPECT_TRUE(q.IsValid());
483  EXPECT_EQ(2u, q.GetTokenCount());
484  EXPECT_EQ(3u, q.GetTokens()[0].length);
485  EXPECT_STREQ("foo", q.GetTokens()[0].name);
486  EXPECT_EQ(1u, q.GetTokens()[1].length);
487  EXPECT_STREQ("0", q.GetTokens()[1].name);
488  EXPECT_EQ(0u, q.GetTokens()[1].index);
489  }
490 }
491 
492 TEST(Pointer, Assignment) {
493  {
494  CrtAllocator allocator;
495  Pointer p("/foo/0", &allocator);
496  Pointer q;
497  q = p;
498  EXPECT_TRUE(q.IsValid());
499  EXPECT_EQ(2u, q.GetTokenCount());
500  EXPECT_EQ(3u, q.GetTokens()[0].length);
501  EXPECT_STREQ("foo", q.GetTokens()[0].name);
502  EXPECT_EQ(1u, q.GetTokens()[1].length);
503  EXPECT_STREQ("0", q.GetTokens()[1].name);
504  EXPECT_EQ(0u, q.GetTokens()[1].index);
505  EXPECT_NE(&p.GetAllocator(), &q.GetAllocator());
506  q = q;
507  EXPECT_TRUE(q.IsValid());
508  EXPECT_EQ(2u, q.GetTokenCount());
509  EXPECT_EQ(3u, q.GetTokens()[0].length);
510  EXPECT_STREQ("foo", q.GetTokens()[0].name);
511  EXPECT_EQ(1u, q.GetTokens()[1].length);
512  EXPECT_STREQ("0", q.GetTokens()[1].name);
513  EXPECT_EQ(0u, q.GetTokens()[1].index);
514  EXPECT_NE(&p.GetAllocator(), &q.GetAllocator());
515  }
516 
517  // Static tokens
518  {
519  Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
520  Pointer q;
521  q = p;
522  EXPECT_TRUE(q.IsValid());
523  EXPECT_EQ(2u, q.GetTokenCount());
524  EXPECT_EQ(3u, q.GetTokens()[0].length);
525  EXPECT_STREQ("foo", q.GetTokens()[0].name);
526  EXPECT_EQ(1u, q.GetTokens()[1].length);
527  EXPECT_STREQ("0", q.GetTokens()[1].name);
528  EXPECT_EQ(0u, q.GetTokens()[1].index);
529  }
530 }
531 
532 TEST(Pointer, Append) {
533  {
534  Pointer p;
535  Pointer q = p.Append("foo");
536  EXPECT_TRUE(Pointer("/foo") == q);
537  q = q.Append(1234);
538  EXPECT_TRUE(Pointer("/foo/1234") == q);
539  q = q.Append("");
540  EXPECT_TRUE(Pointer("/foo/1234/") == q);
541  }
542 
543  {
544  Pointer p;
545  Pointer q = p.Append(Value("foo").Move());
546  EXPECT_TRUE(Pointer("/foo") == q);
547  q = q.Append(Value(1234).Move());
548  EXPECT_TRUE(Pointer("/foo/1234") == q);
549  q = q.Append(Value(kStringType).Move());
550  EXPECT_TRUE(Pointer("/foo/1234/") == q);
551  }
552 
553 #if RAPIDJSON_HAS_STDSTRING
554  {
555  Pointer p;
556  Pointer q = p.Append(std::string("foo"));
557  EXPECT_TRUE(Pointer("/foo") == q);
558  }
559 #endif
560 }
561 
562 TEST(Pointer, Equality) {
563  EXPECT_TRUE(Pointer("/foo/0") == Pointer("/foo/0"));
564  EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/1"));
565  EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/0/1"));
566  EXPECT_FALSE(Pointer("/foo/0") == Pointer("a"));
567  EXPECT_FALSE(Pointer("a") == Pointer("a")); // Invalid always not equal
568 }
569 
570 TEST(Pointer, Inequality) {
571  EXPECT_FALSE(Pointer("/foo/0") != Pointer("/foo/0"));
572  EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/1"));
573  EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/0/1"));
574  EXPECT_TRUE(Pointer("/foo/0") != Pointer("a"));
575  EXPECT_TRUE(Pointer("a") != Pointer("a")); // Invalid always not equal
576 }
577 
578 TEST(Pointer, Create) {
579  Document d;
580  {
581  Value* v = &Pointer("").Create(d, d.GetAllocator());
582  EXPECT_EQ(&d, v);
583  }
584  {
585  Value* v = &Pointer("/foo").Create(d, d.GetAllocator());
586  EXPECT_EQ(&d["foo"], v);
587  }
588  {
589  Value* v = &Pointer("/foo/0").Create(d, d.GetAllocator());
590  EXPECT_EQ(&d["foo"][0], v);
591  }
592  {
593  Value* v = &Pointer("/foo/-").Create(d, d.GetAllocator());
594  EXPECT_EQ(&d["foo"][1], v);
595  }
596 
597  {
598  Value* v = &Pointer("/foo/-/-").Create(d, d.GetAllocator());
599  // "foo/-" is a newly created null value x.
600  // "foo/-/-" finds that x is not an array, it converts x to empty object
601  // and treats - as "-" member name
602  EXPECT_EQ(&d["foo"][2]["-"], v);
603  }
604 
605  {
606  // Document with no allocator
607  Value* v = &Pointer("/foo/-").Create(d);
608  EXPECT_EQ(&d["foo"][3], v);
609  }
610 
611  {
612  // Value (not document) must give allocator
613  Value* v = &Pointer("/-").Create(d["foo"], d.GetAllocator());
614  EXPECT_EQ(&d["foo"][4], v);
615  }
616 }
617 
618 TEST(Pointer, Get) {
619  Document d;
620  d.Parse(kJson);
621 
622  EXPECT_EQ(&d, Pointer("").Get(d));
623  EXPECT_EQ(&d["foo"], Pointer("/foo").Get(d));
624  EXPECT_EQ(&d["foo"][0], Pointer("/foo/0").Get(d));
625  EXPECT_EQ(&d[""], Pointer("/").Get(d));
626  EXPECT_EQ(&d["a/b"], Pointer("/a~1b").Get(d));
627  EXPECT_EQ(&d["c%d"], Pointer("/c%d").Get(d));
628  EXPECT_EQ(&d["e^f"], Pointer("/e^f").Get(d));
629  EXPECT_EQ(&d["g|h"], Pointer("/g|h").Get(d));
630  EXPECT_EQ(&d["i\\j"], Pointer("/i\\j").Get(d));
631  EXPECT_EQ(&d["k\"l"], Pointer("/k\"l").Get(d));
632  EXPECT_EQ(&d[" "], Pointer("/ ").Get(d));
633  EXPECT_EQ(&d["m~n"], Pointer("/m~0n").Get(d));
634  EXPECT_TRUE(Pointer("/abc").Get(d) == 0);
635  size_t unresolvedTokenIndex;
636  EXPECT_TRUE(Pointer("/foo/2").Get(d, &unresolvedTokenIndex) == 0); // Out of boundary
637  EXPECT_EQ(1, unresolvedTokenIndex);
638  EXPECT_TRUE(Pointer("/foo/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
639  EXPECT_EQ(1, unresolvedTokenIndex);
640  EXPECT_TRUE(Pointer("/foo/0/0").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
641  EXPECT_EQ(2, unresolvedTokenIndex);
642  EXPECT_TRUE(Pointer("/foo/0/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
643  EXPECT_EQ(2, unresolvedTokenIndex);
644 }
645 
646 TEST(Pointer, GetWithDefault) {
647  Document d;
648  d.Parse(kJson);
649 
650  // Value version
652  const Value v("qux");
653  EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v, a));
654  EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v, a));
655  EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v, a));
656  EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move(), a));
657  EXPECT_STREQ("last", d["foo"][3].GetString());
658 
659  EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, Value().Move(), a).IsNull());
660  EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, "x", a).IsNull());
661 
662  // Generic version
663  EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -1, a).GetInt());
664  EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -2, a).GetInt());
665  EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x87654321, a).GetUint());
666  EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x12345678, a).GetUint());
667 
668  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
669  EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64, a).GetInt64());
670  EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64 + 1, a).GetInt64());
671 
672  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
673  EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64, a).GetUint64());
674  EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64 - 1, a).GetUint64());
675 
676  EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, true, a).IsTrue());
677  EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, false, a).IsTrue());
678 
679  EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, false, a).IsFalse());
680  EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, true, a).IsFalse());
681 
682  // StringRef version
683  EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d, "Hello", a).GetString());
684 
685  // Copy string version
686  {
687  char buffer[256];
688  strcpy(buffer, "World");
689  EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d, buffer, a).GetString());
690  memset(buffer, 0, sizeof(buffer));
691  }
692  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
693 
694 #if RAPIDJSON_HAS_STDSTRING
695  EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d, std::string("C++"), a).GetString());
696 #endif
697 }
698 
699 TEST(Pointer, GetWithDefault_NoAllocator) {
700  Document d;
701  d.Parse(kJson);
702 
703  // Value version
704  const Value v("qux");
705  EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v));
706  EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v));
707  EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v));
708  EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move()));
709  EXPECT_STREQ("last", d["foo"][3].GetString());
710 
711  EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, Value().Move()).IsNull());
712  EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, "x").IsNull());
713 
714  // Generic version
715  EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -1).GetInt());
716  EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -2).GetInt());
717  EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x87654321).GetUint());
718  EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x12345678).GetUint());
719 
720  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
721  EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64).GetInt64());
722  EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64 + 1).GetInt64());
723 
724  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
725  EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64).GetUint64());
726  EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64 - 1).GetUint64());
727 
728  EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, true).IsTrue());
729  EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, false).IsTrue());
730 
731  EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, false).IsFalse());
732  EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, true).IsFalse());
733 
734  // StringRef version
735  EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d, "Hello").GetString());
736 
737  // Copy string version
738  {
739  char buffer[256];
740  strcpy(buffer, "World");
741  EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d, buffer).GetString());
742  memset(buffer, 0, sizeof(buffer));
743  }
744  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
745 
746 #if RAPIDJSON_HAS_STDSTRING
747  EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d, std::string("C++")).GetString());
748 #endif
749 }
750 
751 TEST(Pointer, Set) {
752  Document d;
753  d.Parse(kJson);
755 
756  // Value version
757  Pointer("/foo/0").Set(d, Value(123).Move(), a);
758  EXPECT_EQ(123, d["foo"][0].GetInt());
759 
760  Pointer("/foo/-").Set(d, Value(456).Move(), a);
761  EXPECT_EQ(456, d["foo"][2].GetInt());
762 
763  Pointer("/foo/null").Set(d, Value().Move(), a);
764  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
765 
766  // Const Value version
767  const Value foo(d["foo"], a);
768  Pointer("/clone").Set(d, foo, a);
769  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
770 
771  // Generic version
772  Pointer("/foo/int").Set(d, -1, a);
773  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
774 
775  Pointer("/foo/uint").Set(d, 0x87654321, a);
776  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
777 
778  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
779  Pointer("/foo/int64").Set(d, i64, a);
780  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
781 
782  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
783  Pointer("/foo/uint64").Set(d, u64, a);
784  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
785 
786  Pointer("/foo/true").Set(d, true, a);
787  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
788 
789  Pointer("/foo/false").Set(d, false, a);
790  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
791 
792  // StringRef version
793  Pointer("/foo/hello").Set(d, "Hello", a);
794  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
795 
796  // Copy string version
797  {
798  char buffer[256];
799  strcpy(buffer, "World");
800  Pointer("/foo/world").Set(d, buffer, a);
801  memset(buffer, 0, sizeof(buffer));
802  }
803  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
804 
805 #if RAPIDJSON_HAS_STDSTRING
806  Pointer("/foo/c++").Set(d, std::string("C++"), a);
807  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
808 #endif
809 }
810 
811 TEST(Pointer, Set_NoAllocator) {
812  Document d;
813  d.Parse(kJson);
814 
815  // Value version
816  Pointer("/foo/0").Set(d, Value(123).Move());
817  EXPECT_EQ(123, d["foo"][0].GetInt());
818 
819  Pointer("/foo/-").Set(d, Value(456).Move());
820  EXPECT_EQ(456, d["foo"][2].GetInt());
821 
822  Pointer("/foo/null").Set(d, Value().Move());
823  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
824 
825  // Const Value version
826  const Value foo(d["foo"], d.GetAllocator());
827  Pointer("/clone").Set(d, foo);
828  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
829 
830  // Generic version
831  Pointer("/foo/int").Set(d, -1);
832  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
833 
834  Pointer("/foo/uint").Set(d, 0x87654321);
835  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
836 
837  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
838  Pointer("/foo/int64").Set(d, i64);
839  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
840 
841  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
842  Pointer("/foo/uint64").Set(d, u64);
843  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
844 
845  Pointer("/foo/true").Set(d, true);
846  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
847 
848  Pointer("/foo/false").Set(d, false);
849  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
850 
851  // StringRef version
852  Pointer("/foo/hello").Set(d, "Hello");
853  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
854 
855  // Copy string version
856  {
857  char buffer[256];
858  strcpy(buffer, "World");
859  Pointer("/foo/world").Set(d, buffer);
860  memset(buffer, 0, sizeof(buffer));
861  }
862  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
863 
864 #if RAPIDJSON_HAS_STDSTRING
865  Pointer("/foo/c++").Set(d, std::string("C++"));
866  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
867 #endif
868 }
869 
871  Document d;
872  d.Parse(kJson);
874  Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d), a);
875  EXPECT_STREQ("baz", d["foo"][0].GetString());
876  EXPECT_STREQ("bar", d["foo"][1].GetString());
877 }
878 
879 TEST(Pointer, Swap_NoAllocator) {
880  Document d;
881  d.Parse(kJson);
882  Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d));
883  EXPECT_STREQ("baz", d["foo"][0].GetString());
884  EXPECT_STREQ("bar", d["foo"][1].GetString());
885 }
886 
887 TEST(Pointer, Erase) {
888  Document d;
889  d.Parse(kJson);
890 
891  EXPECT_FALSE(Pointer("").Erase(d));
892  EXPECT_FALSE(Pointer("/nonexist").Erase(d));
893  EXPECT_FALSE(Pointer("/nonexist/nonexist").Erase(d));
894  EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
895  EXPECT_FALSE(Pointer("/foo/nonexist/nonexist").Erase(d));
896  EXPECT_FALSE(Pointer("/foo/0/nonexist").Erase(d));
897  EXPECT_FALSE(Pointer("/foo/0/nonexist/nonexist").Erase(d));
898  EXPECT_FALSE(Pointer("/foo/2/nonexist").Erase(d));
899  EXPECT_TRUE(Pointer("/foo/0").Erase(d));
900  EXPECT_EQ(1u, d["foo"].Size());
901  EXPECT_STREQ("baz", d["foo"][0].GetString());
902  EXPECT_TRUE(Pointer("/foo/0").Erase(d));
903  EXPECT_TRUE(d["foo"].Empty());
904  EXPECT_TRUE(Pointer("/foo").Erase(d));
905  EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
906 
907  Pointer("/a/0/b/0").Create(d);
908 
909  EXPECT_TRUE(Pointer("/a/0/b/0").Get(d) != 0);
910  EXPECT_TRUE(Pointer("/a/0/b/0").Erase(d));
911  EXPECT_TRUE(Pointer("/a/0/b/0").Get(d) == 0);
912 
913  EXPECT_TRUE(Pointer("/a/0/b").Get(d) != 0);
914  EXPECT_TRUE(Pointer("/a/0/b").Erase(d));
915  EXPECT_TRUE(Pointer("/a/0/b").Get(d) == 0);
916 
917  EXPECT_TRUE(Pointer("/a/0").Get(d) != 0);
918  EXPECT_TRUE(Pointer("/a/0").Erase(d));
919  EXPECT_TRUE(Pointer("/a/0").Get(d) == 0);
920 
921  EXPECT_TRUE(Pointer("/a").Get(d) != 0);
922  EXPECT_TRUE(Pointer("/a").Erase(d));
923  EXPECT_TRUE(Pointer("/a").Get(d) == 0);
924 }
925 
927  Document d;
929 
930  {
931  Value& v = CreateValueByPointer(d, Pointer("/foo/0"), a);
932  EXPECT_EQ(&d["foo"][0], &v);
933  }
934  {
935  Value& v = CreateValueByPointer(d, "/foo/1", a);
936  EXPECT_EQ(&d["foo"][1], &v);
937  }
938 }
939 
940 TEST(Pointer, CreateValueByPointer_NoAllocator) {
941  Document d;
942 
943  {
944  Value& v = CreateValueByPointer(d, Pointer("/foo/0"));
945  EXPECT_EQ(&d["foo"][0], &v);
946  }
947  {
948  Value& v = CreateValueByPointer(d, "/foo/1");
949  EXPECT_EQ(&d["foo"][1], &v);
950  }
951 }
952 
954  Document d;
955  d.Parse(kJson);
956 
957  EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, Pointer("/foo/0")));
958  EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, "/foo/0"));
959 
960  size_t unresolvedTokenIndex;
961  EXPECT_TRUE(GetValueByPointer(d, "/foo/2", &unresolvedTokenIndex) == 0); // Out of boundary
962  EXPECT_EQ(1, unresolvedTokenIndex);
963  EXPECT_TRUE(GetValueByPointer(d, "/foo/a", &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
964  EXPECT_EQ(1, unresolvedTokenIndex);
965  EXPECT_TRUE(GetValueByPointer(d, "/foo/0/0", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
966  EXPECT_EQ(2, unresolvedTokenIndex);
967  EXPECT_TRUE(GetValueByPointer(d, "/foo/0/a", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
968  EXPECT_EQ(2, unresolvedTokenIndex);
969 
970  // const version
971  const Value& v = d;
972  EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, Pointer("/foo/0")));
973  EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, "/foo/0"));
974 
975  EXPECT_TRUE(GetValueByPointer(v, "/foo/2", &unresolvedTokenIndex) == 0); // Out of boundary
976  EXPECT_EQ(1, unresolvedTokenIndex);
977  EXPECT_TRUE(GetValueByPointer(v, "/foo/a", &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
978  EXPECT_EQ(1, unresolvedTokenIndex);
979  EXPECT_TRUE(GetValueByPointer(v, "/foo/0/0", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
980  EXPECT_EQ(2, unresolvedTokenIndex);
981  EXPECT_TRUE(GetValueByPointer(v, "/foo/0/a", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
982  EXPECT_EQ(2, unresolvedTokenIndex);
983 
984 }
985 
986 TEST(Pointer, GetValueByPointerWithDefault_Pointer) {
987  Document d;
988  d.Parse(kJson);
989 
991  const Value v("qux");
992  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
993  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
994  EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, Pointer("/foo/1"), v, a));
995  EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, Pointer("/foo/2"), v, a));
996  EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, Pointer("/foo/-"), Value("last").Move(), a));
997  EXPECT_STREQ("last", d["foo"][3].GetString());
998 
999  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), Value().Move(), a).IsNull());
1000  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), "x", a).IsNull());
1001 
1002  // Generic version
1003  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -1, a).GetInt());
1004  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -2, a).GetInt());
1005  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x87654321, a).GetUint());
1006  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x12345678, a).GetUint());
1007 
1008  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1009  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64, a).GetInt64());
1010  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64 + 1, a).GetInt64());
1011 
1012  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1013  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64, a).GetUint64());
1014  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64 - 1, a).GetUint64());
1015 
1016  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), true, a).IsTrue());
1017  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), false, a).IsTrue());
1018 
1019  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), false, a).IsFalse());
1020  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), true, a).IsFalse());
1021 
1022  // StringRef version
1023  EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, Pointer("/foo/hello"), "Hello", a).GetString());
1024 
1025  // Copy string version
1026  {
1027  char buffer[256];
1028  strcpy(buffer, "World");
1029  EXPECT_STREQ("World", GetValueByPointerWithDefault(d, Pointer("/foo/world"), buffer, a).GetString());
1030  memset(buffer, 0, sizeof(buffer));
1031  }
1032  EXPECT_STREQ("World", GetValueByPointer(d, Pointer("/foo/world"))->GetString());
1033 
1034 #if RAPIDJSON_HAS_STDSTRING
1035  EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++"), a).GetString());
1036 #endif
1037 }
1038 
1039 TEST(Pointer, GetValueByPointerWithDefault_String) {
1040  Document d;
1041  d.Parse(kJson);
1042 
1044  const Value v("qux");
1045  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v, a));
1046  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v, a));
1047  EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v, a));
1048  EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, "/foo/2", v, a));
1049  EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, "/foo/-", Value("last").Move(), a));
1050  EXPECT_STREQ("last", d["foo"][3].GetString());
1051 
1052  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", Value().Move(), a).IsNull());
1053  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", "x", a).IsNull());
1054 
1055  // Generic version
1056  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -1, a).GetInt());
1057  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -2, a).GetInt());
1058  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x87654321, a).GetUint());
1059  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x12345678, a).GetUint());
1060 
1061  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1062  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64, a).GetInt64());
1063  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64 + 1, a).GetInt64());
1064 
1065  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1066  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64, a).GetUint64());
1067  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64 - 1, a).GetUint64());
1068 
1069  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", true, a).IsTrue());
1070  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", false, a).IsTrue());
1071 
1072  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", false, a).IsFalse());
1073  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", true, a).IsFalse());
1074 
1075  // StringRef version
1076  EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, "/foo/hello", "Hello", a).GetString());
1077 
1078  // Copy string version
1079  {
1080  char buffer[256];
1081  strcpy(buffer, "World");
1082  EXPECT_STREQ("World", GetValueByPointerWithDefault(d, "/foo/world", buffer, a).GetString());
1083  memset(buffer, 0, sizeof(buffer));
1084  }
1085  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1086 
1087 #if RAPIDJSON_HAS_STDSTRING
1088  EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, "/foo/C++", std::string("C++"), a).GetString());
1089 #endif
1090 }
1091 
1092 TEST(Pointer, GetValueByPointerWithDefault_Pointer_NoAllocator) {
1093  Document d;
1094  d.Parse(kJson);
1095 
1096  const Value v("qux");
1097  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v));
1098  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v));
1099  EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, Pointer("/foo/1"), v));
1100  EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, Pointer("/foo/2"), v));
1101  EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, Pointer("/foo/-"), Value("last").Move()));
1102  EXPECT_STREQ("last", d["foo"][3].GetString());
1103 
1104  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), Value().Move()).IsNull());
1105  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), "x").IsNull());
1106 
1107  // Generic version
1108  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -1).GetInt());
1109  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -2).GetInt());
1110  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x87654321).GetUint());
1111  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x12345678).GetUint());
1112 
1113  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1114  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64).GetInt64());
1115  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64 + 1).GetInt64());
1116 
1117  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1118  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64).GetUint64());
1119  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64 - 1).GetUint64());
1120 
1121  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), true).IsTrue());
1122  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), false).IsTrue());
1123 
1124  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), false).IsFalse());
1125  EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), true).IsFalse());
1126 
1127  // StringRef version
1128  EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, Pointer("/foo/hello"), "Hello").GetString());
1129 
1130  // Copy string version
1131  {
1132  char buffer[256];
1133  strcpy(buffer, "World");
1134  EXPECT_STREQ("World", GetValueByPointerWithDefault(d, Pointer("/foo/world"), buffer).GetString());
1135  memset(buffer, 0, sizeof(buffer));
1136  }
1137  EXPECT_STREQ("World", GetValueByPointer(d, Pointer("/foo/world"))->GetString());
1138 
1139 #if RAPIDJSON_HAS_STDSTRING
1140  EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++")).GetString());
1141 #endif
1142 }
1143 
1144 TEST(Pointer, GetValueByPointerWithDefault_String_NoAllocator) {
1145  Document d;
1146  d.Parse(kJson);
1147 
1148  const Value v("qux");
1149  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v));
1150  EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v));
1151  EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v));
1152  EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, "/foo/2", v));
1153  EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, "/foo/-", Value("last").Move()));
1154  EXPECT_STREQ("last", d["foo"][3].GetString());
1155 
1156  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", Value().Move()).IsNull());
1157  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", "x").IsNull());
1158 
1159  // Generic version
1160  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -1).GetInt());
1161  EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -2).GetInt());
1162  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x87654321).GetUint());
1163  EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x12345678).GetUint());
1164 
1165  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1166  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64).GetInt64());
1167  EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64 + 1).GetInt64());
1168 
1169  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1170  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64).GetUint64());
1171  EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64 - 1).GetUint64());
1172 
1173  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", true).IsTrue());
1174  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", false).IsTrue());
1175 
1176  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", false).IsFalse());
1177  EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", true).IsFalse());
1178 
1179  // StringRef version
1180  EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, "/foo/hello", "Hello").GetString());
1181 
1182  // Copy string version
1183  {
1184  char buffer[256];
1185  strcpy(buffer, "World");
1186  EXPECT_STREQ("World", GetValueByPointerWithDefault(d, "/foo/world", buffer).GetString());
1187  memset(buffer, 0, sizeof(buffer));
1188  }
1189  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1190 
1191 #if RAPIDJSON_HAS_STDSTRING
1192  EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++")).GetString());
1193 #endif
1194 }
1195 
1196 TEST(Pointer, SetValueByPointer_Pointer) {
1197  Document d;
1198  d.Parse(kJson);
1200 
1201  // Value version
1202  SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move(), a);
1203  EXPECT_EQ(123, d["foo"][0].GetInt());
1204 
1205  SetValueByPointer(d, Pointer("/foo/null"), Value().Move(), a);
1206  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1207 
1208  // Const Value version
1209  const Value foo(d["foo"], d.GetAllocator());
1210  SetValueByPointer(d, Pointer("/clone"), foo, a);
1211  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1212 
1213  // Generic version
1214  SetValueByPointer(d, Pointer("/foo/int"), -1, a);
1215  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1216 
1217  SetValueByPointer(d, Pointer("/foo/uint"), 0x87654321, a);
1218  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1219 
1220  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1221  SetValueByPointer(d, Pointer("/foo/int64"), i64, a);
1222  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1223 
1224  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1225  SetValueByPointer(d, Pointer("/foo/uint64"), u64, a);
1226  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1227 
1228  SetValueByPointer(d, Pointer("/foo/true"), true, a);
1229  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1230 
1231  SetValueByPointer(d, Pointer("/foo/false"), false, a);
1232  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1233 
1234  // StringRef version
1235  SetValueByPointer(d, Pointer("/foo/hello"), "Hello", a);
1236  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1237 
1238  // Copy string version
1239  {
1240  char buffer[256];
1241  strcpy(buffer, "World");
1242  SetValueByPointer(d, Pointer("/foo/world"), buffer, a);
1243  memset(buffer, 0, sizeof(buffer));
1244  }
1245  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1246 
1247 #if RAPIDJSON_HAS_STDSTRING
1248  SetValueByPointer(d, Pointer("/foo/c++"), std::string("C++"), a);
1249  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1250 #endif
1251 }
1252 
1253 TEST(Pointer, SetValueByPointer_String) {
1254  Document d;
1255  d.Parse(kJson);
1257 
1258  // Value version
1259  SetValueByPointer(d, "/foo/0", Value(123).Move(), a);
1260  EXPECT_EQ(123, d["foo"][0].GetInt());
1261 
1262  SetValueByPointer(d, "/foo/null", Value().Move(), a);
1263  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1264 
1265  // Const Value version
1266  const Value foo(d["foo"], d.GetAllocator());
1267  SetValueByPointer(d, "/clone", foo, a);
1268  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1269 
1270  // Generic version
1271  SetValueByPointer(d, "/foo/int", -1, a);
1272  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1273 
1274  SetValueByPointer(d, "/foo/uint", 0x87654321, a);
1275  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1276 
1277  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1278  SetValueByPointer(d, "/foo/int64", i64, a);
1279  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1280 
1281  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1282  SetValueByPointer(d, "/foo/uint64", u64, a);
1283  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1284 
1285  SetValueByPointer(d, "/foo/true", true, a);
1286  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1287 
1288  SetValueByPointer(d, "/foo/false", false, a);
1289  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1290 
1291  // StringRef version
1292  SetValueByPointer(d, "/foo/hello", "Hello", a);
1293  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1294 
1295  // Copy string version
1296  {
1297  char buffer[256];
1298  strcpy(buffer, "World");
1299  SetValueByPointer(d, "/foo/world", buffer, a);
1300  memset(buffer, 0, sizeof(buffer));
1301  }
1302  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1303 
1304 #if RAPIDJSON_HAS_STDSTRING
1305  SetValueByPointer(d, "/foo/c++", std::string("C++"), a);
1306  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1307 #endif
1308 }
1309 
1310 TEST(Pointer, SetValueByPointer_Pointer_NoAllocator) {
1311  Document d;
1312  d.Parse(kJson);
1313 
1314  // Value version
1315  SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move());
1316  EXPECT_EQ(123, d["foo"][0].GetInt());
1317 
1318  SetValueByPointer(d, Pointer("/foo/null"), Value().Move());
1319  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1320 
1321  // Const Value version
1322  const Value foo(d["foo"], d.GetAllocator());
1323  SetValueByPointer(d, Pointer("/clone"), foo);
1324  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1325 
1326  // Generic version
1327  SetValueByPointer(d, Pointer("/foo/int"), -1);
1328  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1329 
1330  SetValueByPointer(d, Pointer("/foo/uint"), 0x87654321);
1331  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1332 
1333  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1334  SetValueByPointer(d, Pointer("/foo/int64"), i64);
1335  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1336 
1337  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1338  SetValueByPointer(d, Pointer("/foo/uint64"), u64);
1339  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1340 
1341  SetValueByPointer(d, Pointer("/foo/true"), true);
1342  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1343 
1344  SetValueByPointer(d, Pointer("/foo/false"), false);
1345  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1346 
1347  // StringRef version
1348  SetValueByPointer(d, Pointer("/foo/hello"), "Hello");
1349  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1350 
1351  // Copy string version
1352  {
1353  char buffer[256];
1354  strcpy(buffer, "World");
1355  SetValueByPointer(d, Pointer("/foo/world"), buffer);
1356  memset(buffer, 0, sizeof(buffer));
1357  }
1358  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1359 
1360 #if RAPIDJSON_HAS_STDSTRING
1361  SetValueByPointer(d, Pointer("/foo/c++"), std::string("C++"));
1362  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1363 #endif
1364 }
1365 
1366 TEST(Pointer, SetValueByPointer_String_NoAllocator) {
1367  Document d;
1368  d.Parse(kJson);
1369 
1370  // Value version
1371  SetValueByPointer(d, "/foo/0", Value(123).Move());
1372  EXPECT_EQ(123, d["foo"][0].GetInt());
1373 
1374  SetValueByPointer(d, "/foo/null", Value().Move());
1375  EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1376 
1377  // Const Value version
1378  const Value foo(d["foo"], d.GetAllocator());
1379  SetValueByPointer(d, "/clone", foo);
1380  EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1381 
1382  // Generic version
1383  SetValueByPointer(d, "/foo/int", -1);
1384  EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1385 
1386  SetValueByPointer(d, "/foo/uint", 0x87654321);
1387  EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1388 
1389  const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1390  SetValueByPointer(d, "/foo/int64", i64);
1391  EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1392 
1393  const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1394  SetValueByPointer(d, "/foo/uint64", u64);
1395  EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1396 
1397  SetValueByPointer(d, "/foo/true", true);
1398  EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1399 
1400  SetValueByPointer(d, "/foo/false", false);
1401  EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1402 
1403  // StringRef version
1404  SetValueByPointer(d, "/foo/hello", "Hello");
1405  EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1406 
1407  // Copy string version
1408  {
1409  char buffer[256];
1410  strcpy(buffer, "World");
1411  SetValueByPointer(d, "/foo/world", buffer);
1412  memset(buffer, 0, sizeof(buffer));
1413  }
1414  EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1415 
1416 #if RAPIDJSON_HAS_STDSTRING
1417  SetValueByPointer(d, "/foo/c++", std::string("C++"));
1418  EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1419 #endif
1420 }
1421 
1423  Document d;
1424  d.Parse(kJson);
1426  SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"), a);
1427  EXPECT_STREQ("baz", d["foo"][0].GetString());
1428  EXPECT_STREQ("bar", d["foo"][1].GetString());
1429 
1430  SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"), a);
1431  EXPECT_STREQ("bar", d["foo"][0].GetString());
1432  EXPECT_STREQ("baz", d["foo"][1].GetString());
1433 }
1434 
1435 TEST(Pointer, SwapValueByPointer_NoAllocator) {
1436  Document d;
1437  d.Parse(kJson);
1438  SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"));
1439  EXPECT_STREQ("baz", d["foo"][0].GetString());
1440  EXPECT_STREQ("bar", d["foo"][1].GetString());
1441 
1442  SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"));
1443  EXPECT_STREQ("bar", d["foo"][0].GetString());
1444  EXPECT_STREQ("baz", d["foo"][1].GetString());
1445 }
1446 
1447 TEST(Pointer, EraseValueByPointer_Pointer) {
1448  Document d;
1449  d.Parse(kJson);
1450 
1452  EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
1453  EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo/0")));
1454  EXPECT_EQ(1u, d["foo"].Size());
1455  EXPECT_STREQ("baz", d["foo"][0].GetString());
1456  EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo/0")));
1457  EXPECT_TRUE(d["foo"].Empty());
1459  EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
1460 }
1461 
1462 TEST(Pointer, EraseValueByPointer_String) {
1463  Document d;
1464  d.Parse(kJson);
1465 
1467  EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
1468  EXPECT_TRUE(EraseValueByPointer(d, "/foo/0"));
1469  EXPECT_EQ(1u, d["foo"].Size());
1470  EXPECT_STREQ("baz", d["foo"][0].GetString());
1471  EXPECT_TRUE(EraseValueByPointer(d, "/foo/0"));
1472  EXPECT_TRUE(d["foo"].Empty());
1473  EXPECT_TRUE(EraseValueByPointer(d, "/foo"));
1474  EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
1475 }
1476 
1477 TEST(Pointer, Ambiguity) {
1478  {
1479  Document d;
1480  d.Parse("{\"0\" : [123]}");
1481  EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
1482  Pointer("/0/a").Set(d, 456); // Change array [123] to object {456}
1483  EXPECT_EQ(456, Pointer("/0/a").Get(d)->GetInt());
1484  }
1485 
1486  {
1487  Document d;
1488  EXPECT_FALSE(d.Parse("[{\"0\": 123}]").HasParseError());
1489  EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
1490  Pointer("/0/1").Set(d, 456); // 1 is treated as "1" to index object
1491  EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
1492  EXPECT_EQ(456, Pointer("/0/1").Get(d)->GetInt());
1493  }
1494 }
1495 
1496 // https://github.com/Tencent/rapidjson/issues/483
1497 namespace myjson {
1498 
1500 {
1501 public:
1502  static const bool kNeedFree = true;
1503  void * Malloc(size_t _size) { return malloc(_size); }
1504  void * Realloc(void *_org_p, size_t _org_size, size_t _new_size) { (void)_org_size; return realloc(_org_p, _new_size); }
1505  static void Free(void *_p) { return free(_p); }
1506 };
1507 
1508 typedef rapidjson::GenericDocument<
1509  rapidjson::UTF8<>,
1510  rapidjson::MemoryPoolAllocator< MyAllocator >,
1511  MyAllocator
1513 
1514 typedef rapidjson::GenericPointer<
1515  ::myjson::Document::ValueType,
1516  MyAllocator
1518 
1519 typedef ::myjson::Document::ValueType Value;
1520 
1521 }
1522 
1523 TEST(Pointer, Issue483) {
1524  std::string mystr, path;
1525  myjson::Document document;
1527  value.SetString(mystr.c_str(), static_cast<SizeType>(mystr.length()), document.GetAllocator());
1528  myjson::Pointer(path.c_str()).Set(document, value, document.GetAllocator());
1529 }
TEST(Pointer, DefaultConstructor)
Definition: pointertest.cpp:35
void * Malloc(size_t _size)
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition: pointer.h:1106
::myjson::Document::ValueType Value
A token is the basic units of internal representation.
Definition: pointer.h:97
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_STREQ(s1, s2)
Definition: gtest.h:1995
#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
void * Realloc(void *_org_p, size_t _org_size, size_t _new_size)
Invalid percent encoding in URI fragment.
Definition: pointer.h:42
::std::string string
Definition: gtest-port.h:1097
GTEST_API_ bool IsTrue(bool condition)
C-runtime library allocator.
Definition: allocators.h:75
#define NAME(s)
const char * name
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1318
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2418
string
Definition: rapidjson.h:626
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition: document.h:2394
rapidjson::GenericDocument< rapidjson::UTF8<>, rapidjson::MemoryPoolAllocator< MyAllocator >, MyAllocator > Document
unsigned __int64 uint64_t
Definition: stdint.h:136
rapidjson::GenericPointer< ::myjson::Document::ValueType, MyAllocator > Pointer
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: fwd.h:126
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:33
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
main RapidJSON namespace
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
Definition: pointer.h:1060
PolymorphicMatcher< internal::IsNullMatcher > IsNull()
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
static void Free(void *_p)
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2331
A character must percent encoded in URI fragment.
Definition: pointer.h:43
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:214
A token must begin with a &#39;/&#39;.
Definition: pointer.h:40
CharType Ch
Definition: encodings.h:270
signed __int64 int64_t
Definition: stdint.h:135
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition: pointer.h:1340
const Ch * GetString() const
Definition: stringbuffer.h:73
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1202
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition: pointer.h:1084