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