Electroneum
Loading...
Searching...
No Matches
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"
18#include <sstream>
19
20using namespace rapidjson;
21
22static 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
35TEST(Pointer, DefaultConstructor) {
36 Pointer p;
37 EXPECT_TRUE(p.IsValid());
38 EXPECT_EQ(0u, p.GetTokenCount());
39}
40
41TEST(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
190TEST(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());
357 EXPECT_EQ(2u, p.GetParseErrorOffset());
358 }
359
360 {
361 // kPointerParseErrorInvalidPercentEncoding (invalid hex)
362 Pointer p("#/%g0");
363 EXPECT_FALSE(p.IsValid());
365 EXPECT_EQ(2u, p.GetParseErrorOffset());
366 }
367
368 {
369 // kPointerParseErrorInvalidPercentEncoding (invalid hex)
370 Pointer p("#/%0g");
371 EXPECT_FALSE(p.IsValid());
373 EXPECT_EQ(2u, p.GetParseErrorOffset());
374 }
375
376 {
377 // kPointerParseErrorInvalidPercentEncoding (incomplete UTF-8 sequence)
378 Pointer p("#/%C2");
379 EXPECT_FALSE(p.IsValid());
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
401TEST(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
447static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(0) }; // equivalent to "/foo/0"
448
449#undef NAME
450#undef INDEX
451
452TEST(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
463TEST(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
492TEST(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
532TEST(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
562TEST(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
570TEST(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
578TEST(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
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
646TEST(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
699TEST(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
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
811TEST(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
870TEST(Pointer, Swap) {
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
879TEST(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
887TEST(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
940TEST(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
986TEST(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
1039TEST(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
1092TEST(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
1144TEST(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
1196TEST(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
1253TEST(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
1310TEST(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
1366TEST(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
1435TEST(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
1447TEST(Pointer, EraseValueByPointer_Pointer) {
1448 Document d;
1449 d.Parse(kJson);
1450
1452 EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
1454 EXPECT_EQ(1u, d["foo"].Size());
1455 EXPECT_STREQ("baz", d["foo"][0].GetString());
1457 EXPECT_TRUE(d["foo"].Empty());
1459 EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
1460}
1461
1462TEST(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
1477TEST(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
1497namespace myjson {
1498
1500{
1501public:
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
1508typedef rapidjson::GenericDocument<
1509 rapidjson::UTF8<>,
1510 rapidjson::MemoryPoolAllocator< MyAllocator >,
1511 MyAllocator
1513
1514typedef rapidjson::GenericPointer<
1515 ::myjson::Document::ValueType,
1518
1519typedef ::myjson::Document::ValueType Value;
1520
1521}
1522
1523TEST(Pointer, Issue483) {
1524 std::string mystr, path;
1525 myjson::Document document;
1526 myjson::Value value(rapidjson::kStringType);
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}
C-runtime library allocator.
Definition allocators.h:75
Allocator & GetAllocator()
Get the allocator of this document.
Definition document.h:2418
MemoryPoolAllocator<> AllocatorType
Definition document.h:2134
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition document.h:2394
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion).
Definition document.h:2331
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition pointer.h:79
ValueType & Swap(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Swap a value with a value in a subtree.
Definition pointer.h:695
ValueType & Set(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with move semantics.
Definition pointer.h:613
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition pointer.h:214
const Ch * GetString() const
size_t GetSize() const
Get the size of string in bytes in the string buffer.
static void Free(void *_p)
void * Realloc(void *_org_p, size_t _org_size, size_t _new_size)
static const bool kNeedFree
void * Malloc(size_t _size)
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition document.h:2116
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition document.h:2512
GenericPointer< Value, CrtAllocator > Pointer
Definition fwd.h:128
GenericStringBuffer< UTF8< char >, CrtAllocator > StringBuffer
Definition fwd.h:61
#define EXPECT_EQ(val1, val2)
Definition gtest.h:1922
#define EXPECT_NE(val1, val2)
Definition gtest.h:1926
#define EXPECT_TRUE(condition)
Definition gtest.h:1859
#define EXPECT_STREQ(s1, s2)
Definition gtest.h:1995
#define TEST(test_case_name, test_name)
Definition gtest.h:2187
#define EXPECT_FALSE(condition)
Definition gtest.h:1862
@ kPointerParseErrorInvalidEscape
Invalid escape.
Definition pointer.h:41
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
Definition pointer.h:40
@ kPointerParseErrorCharacterMustPercentEncode
A character must percent encoded in URI fragment.
Definition pointer.h:43
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
Definition pointer.h:42
rapidjson::GenericPointer< ::myjson::Document::ValueType, MyAllocator > Pointer
::myjson::Document::ValueType Value
rapidjson::GenericDocument< rapidjson::UTF8<>, rapidjson::MemoryPoolAllocator< MyAllocator >, MyAllocator > Document
main RapidJSON namespace
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1225
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition pointer.h:1318
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition pointer.h:1202
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition pointer.h:1084
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition pointer.h:1340
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
Definition pointer.h:1060
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition pointer.h:1106
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
#define NAME(s)
#define INDEX(i)
@ kStringType
string
Definition rapidjson.h:626
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.).
Definition rapidjson.h:389
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition rapidjson.h:294
signed __int64 int64_t
Definition stdint.h:135
unsigned __int64 uint64_t
Definition stdint.h:136
CharType Ch
Definition encodings.h:270