1 // Tencent is pleased to support the open source community by making RapidJSON available.
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
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
8 // http://opensource.org/licenses/MIT
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.
16 #include "rapidjson/pointer.h"
17 #include "rapidjson/stringbuffer.h"
18 #include "rapidjson/ostreamwrapper.h"
23 using namespace rapidjson
;
25 static const char kJson
[] = "{\n"
26 " \"foo\":[\"bar\", \"baz\"],\n"
38 TEST(Pointer
, DefaultConstructor
) {
40 EXPECT_TRUE(p
.IsValid());
41 EXPECT_EQ(0u, p
.GetTokenCount());
44 TEST(Pointer
, Parse
) {
47 EXPECT_TRUE(p
.IsValid());
48 EXPECT_EQ(0u, p
.GetTokenCount());
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
);
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
);
69 #if RAPIDJSON_HAS_STDSTRING
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
);
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
);
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
);
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
);
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
);
120 // empty and non-empty name
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
);
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]);
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
);
151 // Invalid index (with leading zero)
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
);
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
);
169 // kPointerParseErrorTokenMustBeginWithSolidus
171 EXPECT_FALSE(p
.IsValid());
172 EXPECT_EQ(kPointerParseErrorTokenMustBeginWithSolidus
, p
.GetParseErrorCode());
173 EXPECT_EQ(0u, p
.GetParseErrorOffset());
177 // kPointerParseErrorInvalidEscape
179 EXPECT_FALSE(p
.IsValid());
180 EXPECT_EQ(kPointerParseErrorInvalidEscape
, p
.GetParseErrorCode());
181 EXPECT_EQ(2u, p
.GetParseErrorOffset());
185 // kPointerParseErrorInvalidEscape
187 EXPECT_FALSE(p
.IsValid());
188 EXPECT_EQ(kPointerParseErrorInvalidEscape
, p
.GetParseErrorCode());
189 EXPECT_EQ(2u, p
.GetParseErrorOffset());
193 TEST(Pointer
, Parse_URIFragment
) {
196 EXPECT_TRUE(p
.IsValid());
197 EXPECT_EQ(0u, p
.GetTokenCount());
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
);
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
);
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
);
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
);
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
);
247 // empty and non-empty name
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
);
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]);
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
);
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
);
288 // Invalid index (with leading zero)
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
);
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
);
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
);
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
);
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
);
332 // kPointerParseErrorTokenMustBeginWithSolidus
334 EXPECT_FALSE(p
.IsValid());
335 EXPECT_EQ(kPointerParseErrorTokenMustBeginWithSolidus
, p
.GetParseErrorCode());
336 EXPECT_EQ(1u, p
.GetParseErrorOffset());
340 // kPointerParseErrorInvalidEscape
342 EXPECT_FALSE(p
.IsValid());
343 EXPECT_EQ(kPointerParseErrorInvalidEscape
, p
.GetParseErrorCode());
344 EXPECT_EQ(3u, p
.GetParseErrorOffset());
348 // kPointerParseErrorInvalidEscape
350 EXPECT_FALSE(p
.IsValid());
351 EXPECT_EQ(kPointerParseErrorInvalidEscape
, p
.GetParseErrorCode());
352 EXPECT_EQ(3u, p
.GetParseErrorOffset());
356 // kPointerParseErrorInvalidPercentEncoding
358 EXPECT_FALSE(p
.IsValid());
359 EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding
, p
.GetParseErrorCode());
360 EXPECT_EQ(2u, p
.GetParseErrorOffset());
364 // kPointerParseErrorInvalidPercentEncoding (invalid hex)
366 EXPECT_FALSE(p
.IsValid());
367 EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding
, p
.GetParseErrorCode());
368 EXPECT_EQ(2u, p
.GetParseErrorOffset());
372 // kPointerParseErrorInvalidPercentEncoding (invalid hex)
374 EXPECT_FALSE(p
.IsValid());
375 EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding
, p
.GetParseErrorCode());
376 EXPECT_EQ(2u, p
.GetParseErrorOffset());
380 // kPointerParseErrorInvalidPercentEncoding (incomplete UTF-8 sequence)
382 EXPECT_FALSE(p
.IsValid());
383 EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding
, p
.GetParseErrorCode());
384 EXPECT_EQ(2u, p
.GetParseErrorOffset());
388 // kPointerParseErrorCharacterMustPercentEncode
390 EXPECT_FALSE(p
.IsValid());
391 EXPECT_EQ(kPointerParseErrorCharacterMustPercentEncode
, p
.GetParseErrorCode());
392 EXPECT_EQ(2u, p
.GetParseErrorOffset());
396 // kPointerParseErrorCharacterMustPercentEncode
398 EXPECT_FALSE(p
.IsValid());
399 EXPECT_EQ(kPointerParseErrorCharacterMustPercentEncode
, p
.GetParseErrorCode());
400 EXPECT_EQ(2u, p
.GetParseErrorOffset());
404 TEST(Pointer
, Stringify
) {
406 const char* sources
[] = {
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());
430 // Stringify to URI fragment
432 EXPECT_TRUE(p
.StringifyUriFragment(s2
));
433 Pointer
p2(s2
.GetString(), s2
.GetSize());
434 EXPECT_TRUE(p2
.IsValid());
435 EXPECT_TRUE(p
== p2
);
439 // Strigify to URI fragment with an invalid UTF-8 sequence
442 EXPECT_FALSE(p
.StringifyUriFragment(s
));
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 }
450 static const Pointer::Token kTokens
[] = { NAME("foo"), INDEX(0) }; // equivalent to "/foo/0"
455 TEST(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
);
466 TEST(Pointer
, CopyConstructor
) {
468 CrtAllocator allocator
;
469 Pointer
p("/foo/0", &allocator
);
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
);
479 // Copied pointer needs to have its own allocator
480 EXPECT_NE(&p
.GetAllocator(), &q
.GetAllocator());
485 Pointer
p(kTokens
, sizeof(kTokens
) / sizeof(kTokens
[0]));
487 EXPECT_TRUE(q
.IsValid());
488 EXPECT_EQ(2u, q
.GetTokenCount());
489 EXPECT_EQ(3u, q
.GetTokens()[0].length
);
490 EXPECT_STREQ("foo", q
.GetTokens()[0].name
);
491 EXPECT_EQ(1u, q
.GetTokens()[1].length
);
492 EXPECT_STREQ("0", q
.GetTokens()[1].name
);
493 EXPECT_EQ(0u, q
.GetTokens()[1].index
);
497 TEST(Pointer
, Assignment
) {
499 CrtAllocator allocator
;
500 Pointer
p("/foo/0", &allocator
);
503 EXPECT_TRUE(q
.IsValid());
504 EXPECT_EQ(2u, q
.GetTokenCount());
505 EXPECT_EQ(3u, q
.GetTokens()[0].length
);
506 EXPECT_STREQ("foo", q
.GetTokens()[0].name
);
507 EXPECT_EQ(1u, q
.GetTokens()[1].length
);
508 EXPECT_STREQ("0", q
.GetTokens()[1].name
);
509 EXPECT_EQ(0u, q
.GetTokens()[1].index
);
510 EXPECT_NE(&p
.GetAllocator(), &q
.GetAllocator());
511 q
= static_cast<const Pointer
&>(q
);
512 EXPECT_TRUE(q
.IsValid());
513 EXPECT_EQ(2u, q
.GetTokenCount());
514 EXPECT_EQ(3u, q
.GetTokens()[0].length
);
515 EXPECT_STREQ("foo", q
.GetTokens()[0].name
);
516 EXPECT_EQ(1u, q
.GetTokens()[1].length
);
517 EXPECT_STREQ("0", q
.GetTokens()[1].name
);
518 EXPECT_EQ(0u, q
.GetTokens()[1].index
);
519 EXPECT_NE(&p
.GetAllocator(), &q
.GetAllocator());
524 Pointer
p(kTokens
, sizeof(kTokens
) / sizeof(kTokens
[0]));
527 EXPECT_TRUE(q
.IsValid());
528 EXPECT_EQ(2u, q
.GetTokenCount());
529 EXPECT_EQ(3u, q
.GetTokens()[0].length
);
530 EXPECT_STREQ("foo", q
.GetTokens()[0].name
);
531 EXPECT_EQ(1u, q
.GetTokens()[1].length
);
532 EXPECT_STREQ("0", q
.GetTokens()[1].name
);
533 EXPECT_EQ(0u, q
.GetTokens()[1].index
);
537 TEST(Pointer
, Swap
) {
539 Pointer
q(&p
.GetAllocator());
542 EXPECT_EQ(&q
.GetAllocator(), &p
.GetAllocator());
543 EXPECT_TRUE(p
.IsValid());
544 EXPECT_TRUE(q
.IsValid());
545 EXPECT_EQ(0u, p
.GetTokenCount());
546 EXPECT_EQ(2u, q
.GetTokenCount());
547 EXPECT_EQ(3u, q
.GetTokens()[0].length
);
548 EXPECT_STREQ("foo", q
.GetTokens()[0].name
);
549 EXPECT_EQ(1u, q
.GetTokens()[1].length
);
550 EXPECT_STREQ("0", q
.GetTokens()[1].name
);
551 EXPECT_EQ(0u, q
.GetTokens()[1].index
);
553 // std::swap compatibility
555 EXPECT_EQ(&p
.GetAllocator(), &q
.GetAllocator());
556 EXPECT_TRUE(q
.IsValid());
557 EXPECT_TRUE(p
.IsValid());
558 EXPECT_EQ(0u, q
.GetTokenCount());
559 EXPECT_EQ(2u, p
.GetTokenCount());
560 EXPECT_EQ(3u, p
.GetTokens()[0].length
);
561 EXPECT_STREQ("foo", p
.GetTokens()[0].name
);
562 EXPECT_EQ(1u, p
.GetTokens()[1].length
);
563 EXPECT_STREQ("0", p
.GetTokens()[1].name
);
564 EXPECT_EQ(0u, p
.GetTokens()[1].index
);
567 TEST(Pointer
, Append
) {
570 Pointer q
= p
.Append("foo");
571 EXPECT_TRUE(Pointer("/foo") == q
);
573 EXPECT_TRUE(Pointer("/foo/1234") == q
);
575 EXPECT_TRUE(Pointer("/foo/1234/") == q
);
580 Pointer q
= p
.Append(Value("foo").Move());
581 EXPECT_TRUE(Pointer("/foo") == q
);
582 q
= q
.Append(Value(1234).Move());
583 EXPECT_TRUE(Pointer("/foo/1234") == q
);
584 q
= q
.Append(Value(kStringType
).Move());
585 EXPECT_TRUE(Pointer("/foo/1234/") == q
);
588 #if RAPIDJSON_HAS_STDSTRING
591 Pointer q
= p
.Append(std::string("foo"));
592 EXPECT_TRUE(Pointer("/foo") == q
);
597 TEST(Pointer
, Equality
) {
598 EXPECT_TRUE(Pointer("/foo/0") == Pointer("/foo/0"));
599 EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/1"));
600 EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/0/1"));
601 EXPECT_FALSE(Pointer("/foo/0") == Pointer("a"));
602 EXPECT_FALSE(Pointer("a") == Pointer("a")); // Invalid always not equal
605 TEST(Pointer
, Inequality
) {
606 EXPECT_FALSE(Pointer("/foo/0") != Pointer("/foo/0"));
607 EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/1"));
608 EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/0/1"));
609 EXPECT_TRUE(Pointer("/foo/0") != Pointer("a"));
610 EXPECT_TRUE(Pointer("a") != Pointer("a")); // Invalid always not equal
613 TEST(Pointer
, Create
) {
616 Value
* v
= &Pointer("").Create(d
, d
.GetAllocator());
620 Value
* v
= &Pointer("/foo").Create(d
, d
.GetAllocator());
621 EXPECT_EQ(&d
["foo"], v
);
624 Value
* v
= &Pointer("/foo/0").Create(d
, d
.GetAllocator());
625 EXPECT_EQ(&d
["foo"][0], v
);
628 Value
* v
= &Pointer("/foo/-").Create(d
, d
.GetAllocator());
629 EXPECT_EQ(&d
["foo"][1], v
);
633 Value
* v
= &Pointer("/foo/-/-").Create(d
, d
.GetAllocator());
634 // "foo/-" is a newly created null value x.
635 // "foo/-/-" finds that x is not an array, it converts x to empty object
636 // and treats - as "-" member name
637 EXPECT_EQ(&d
["foo"][2]["-"], v
);
641 // Document with no allocator
642 Value
* v
= &Pointer("/foo/-").Create(d
);
643 EXPECT_EQ(&d
["foo"][3], v
);
647 // Value (not document) must give allocator
648 Value
* v
= &Pointer("/-").Create(d
["foo"], d
.GetAllocator());
649 EXPECT_EQ(&d
["foo"][4], v
);
653 static const char kJsonIds
[] = "{\n"
654 " \"id\": \"/root/\","
655 " \"foo\":[\"bar\", \"baz\", {\"id\": \"inarray\", \"child\": 1}],\n"
657 " \"str\" : \"val\",\n"
658 " \"obj\": {\"id\": \"inobj\", \"child\": 3},\n"
659 " \"jbo\": {\"id\": true, \"child\": 4}\n"
663 TEST(Pointer
, GetUri
) {
664 CrtAllocator allocator
;
667 Pointer::UriType
doc("http://doc");
668 Pointer::UriType
root("http://doc/root/");
669 Pointer::UriType empty
= Pointer::UriType();
671 EXPECT_TRUE(Pointer("").GetUri(d
, doc
) == doc
);
672 EXPECT_TRUE(Pointer("/foo").GetUri(d
, doc
) == root
);
673 EXPECT_TRUE(Pointer("/foo/0").GetUri(d
, doc
) == root
);
674 EXPECT_TRUE(Pointer("/foo/2").GetUri(d
, doc
) == root
);
675 EXPECT_TRUE(Pointer("/foo/2/child").GetUri(d
, doc
) == Pointer::UriType("http://doc/root/inarray"));
676 EXPECT_TRUE(Pointer("/int").GetUri(d
, doc
) == root
);
677 EXPECT_TRUE(Pointer("/str").GetUri(d
, doc
) == root
);
678 EXPECT_TRUE(Pointer("/obj").GetUri(d
, doc
) == root
);
679 EXPECT_TRUE(Pointer("/obj/child").GetUri(d
, doc
) == Pointer::UriType("http://doc/root/inobj"));
680 EXPECT_TRUE(Pointer("/jbo").GetUri(d
, doc
) == root
);
681 EXPECT_TRUE(Pointer("/jbo/child").GetUri(d
, doc
) == root
); // id not string
683 size_t unresolvedTokenIndex
;
684 EXPECT_TRUE(Pointer("/abc").GetUri(d
, doc
, &unresolvedTokenIndex
, &allocator
) == empty
); // Out of boundary
685 EXPECT_EQ(0u, unresolvedTokenIndex
);
686 EXPECT_TRUE(Pointer("/foo/3").GetUri(d
, doc
, &unresolvedTokenIndex
, &allocator
) == empty
); // Out of boundary
687 EXPECT_EQ(1u, unresolvedTokenIndex
);
688 EXPECT_TRUE(Pointer("/foo/a").GetUri(d
, doc
, &unresolvedTokenIndex
, &allocator
) == empty
); // "/foo" is an array, cannot query by "a"
689 EXPECT_EQ(1u, unresolvedTokenIndex
);
690 EXPECT_TRUE(Pointer("/foo/0/0").GetUri(d
, doc
, &unresolvedTokenIndex
, &allocator
) == empty
); // "/foo/0" is an string, cannot further query
691 EXPECT_EQ(2u, unresolvedTokenIndex
);
692 EXPECT_TRUE(Pointer("/foo/0/a").GetUri(d
, doc
, &unresolvedTokenIndex
, &allocator
) == empty
); // "/foo/0" is an string, cannot further query
693 EXPECT_EQ(2u, unresolvedTokenIndex
);
695 Pointer::Token tokens
[] = { { "foo ...", 3, kPointerInvalidIndex
} };
696 EXPECT_TRUE(Pointer(tokens
, 1).GetUri(d
, doc
) == root
);
703 EXPECT_EQ(&d
, Pointer("").Get(d
));
704 EXPECT_EQ(&d
["foo"], Pointer("/foo").Get(d
));
705 EXPECT_EQ(&d
["foo"][0], Pointer("/foo/0").Get(d
));
706 EXPECT_EQ(&d
[""], Pointer("/").Get(d
));
707 EXPECT_EQ(&d
["a/b"], Pointer("/a~1b").Get(d
));
708 EXPECT_EQ(&d
["c%d"], Pointer("/c%d").Get(d
));
709 EXPECT_EQ(&d
["e^f"], Pointer("/e^f").Get(d
));
710 EXPECT_EQ(&d
["g|h"], Pointer("/g|h").Get(d
));
711 EXPECT_EQ(&d
["i\\j"], Pointer("/i\\j").Get(d
));
712 EXPECT_EQ(&d
["k\"l"], Pointer("/k\"l").Get(d
));
713 EXPECT_EQ(&d
[" "], Pointer("/ ").Get(d
));
714 EXPECT_EQ(&d
["m~n"], Pointer("/m~0n").Get(d
));
716 EXPECT_TRUE(Pointer("/abc").Get(d
) == 0); // Out of boundary
717 size_t unresolvedTokenIndex
;
718 EXPECT_TRUE(Pointer("/foo/2").Get(d
, &unresolvedTokenIndex
) == 0); // Out of boundary
719 EXPECT_EQ(1u, unresolvedTokenIndex
);
720 EXPECT_TRUE(Pointer("/foo/a").Get(d
, &unresolvedTokenIndex
) == 0); // "/foo" is an array, cannot query by "a"
721 EXPECT_EQ(1u, unresolvedTokenIndex
);
722 EXPECT_TRUE(Pointer("/foo/0/0").Get(d
, &unresolvedTokenIndex
) == 0); // "/foo/0" is an string, cannot further query
723 EXPECT_EQ(2u, unresolvedTokenIndex
);
724 EXPECT_TRUE(Pointer("/foo/0/a").Get(d
, &unresolvedTokenIndex
) == 0); // "/foo/0" is an string, cannot further query
725 EXPECT_EQ(2u, unresolvedTokenIndex
);
727 Pointer::Token tokens
[] = { { "foo ...", 3, kPointerInvalidIndex
} };
728 EXPECT_EQ(&d
["foo"], Pointer(tokens
, 1).Get(d
));
731 TEST(Pointer
, GetWithDefault
) {
736 Document::AllocatorType
& a
= d
.GetAllocator();
737 const Value
v("qux");
738 EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d
, v
, a
));
739 EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d
, v
, a
));
740 EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d
, v
, a
));
741 EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d
, Value("last").Move(), a
));
742 EXPECT_STREQ("last", d
["foo"][3].GetString());
744 EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d
, Value().Move(), a
).IsNull());
745 EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d
, "x", a
).IsNull());
748 EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d
, -1, a
).GetInt());
749 EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d
, -2, a
).GetInt());
750 EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d
, 0x87654321, a
).GetUint());
751 EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d
, 0x12345678, a
).GetUint());
753 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
754 EXPECT_EQ(i64
, Pointer("/foo/int64").GetWithDefault(d
, i64
, a
).GetInt64());
755 EXPECT_EQ(i64
, Pointer("/foo/int64").GetWithDefault(d
, i64
+ 1, a
).GetInt64());
757 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
758 EXPECT_EQ(u64
, Pointer("/foo/uint64").GetWithDefault(d
, u64
, a
).GetUint64());
759 EXPECT_EQ(u64
, Pointer("/foo/uint64").GetWithDefault(d
, u64
- 1, a
).GetUint64());
761 EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d
, true, a
).IsTrue());
762 EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d
, false, a
).IsTrue());
764 EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d
, false, a
).IsFalse());
765 EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d
, true, a
).IsFalse());
768 EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d
, "Hello", a
).GetString());
770 // Copy string version
773 strcpy(buffer
, "World");
774 EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d
, buffer
, a
).GetString());
775 memset(buffer
, 0, sizeof(buffer
));
777 EXPECT_STREQ("World", GetValueByPointer(d
, "/foo/world")->GetString());
779 #if RAPIDJSON_HAS_STDSTRING
780 EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d
, std::string("C++"), a
).GetString());
784 TEST(Pointer
, GetWithDefault_NoAllocator
) {
789 const Value
v("qux");
790 EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d
, v
));
791 EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d
, v
));
792 EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d
, v
));
793 EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d
, Value("last").Move()));
794 EXPECT_STREQ("last", d
["foo"][3].GetString());
796 EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d
, Value().Move()).IsNull());
797 EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d
, "x").IsNull());
800 EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d
, -1).GetInt());
801 EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d
, -2).GetInt());
802 EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d
, 0x87654321).GetUint());
803 EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d
, 0x12345678).GetUint());
805 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
806 EXPECT_EQ(i64
, Pointer("/foo/int64").GetWithDefault(d
, i64
).GetInt64());
807 EXPECT_EQ(i64
, Pointer("/foo/int64").GetWithDefault(d
, i64
+ 1).GetInt64());
809 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
810 EXPECT_EQ(u64
, Pointer("/foo/uint64").GetWithDefault(d
, u64
).GetUint64());
811 EXPECT_EQ(u64
, Pointer("/foo/uint64").GetWithDefault(d
, u64
- 1).GetUint64());
813 EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d
, true).IsTrue());
814 EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d
, false).IsTrue());
816 EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d
, false).IsFalse());
817 EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d
, true).IsFalse());
820 EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d
, "Hello").GetString());
822 // Copy string version
825 strcpy(buffer
, "World");
826 EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d
, buffer
).GetString());
827 memset(buffer
, 0, sizeof(buffer
));
829 EXPECT_STREQ("World", GetValueByPointer(d
, "/foo/world")->GetString());
831 #if RAPIDJSON_HAS_STDSTRING
832 EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d
, std::string("C++")).GetString());
839 Document::AllocatorType
& a
= d
.GetAllocator();
842 Pointer("/foo/0").Set(d
, Value(123).Move(), a
);
843 EXPECT_EQ(123, d
["foo"][0].GetInt());
845 Pointer("/foo/-").Set(d
, Value(456).Move(), a
);
846 EXPECT_EQ(456, d
["foo"][2].GetInt());
848 Pointer("/foo/null").Set(d
, Value().Move(), a
);
849 EXPECT_TRUE(GetValueByPointer(d
, "/foo/null")->IsNull());
851 // Const Value version
852 const Value
foo(d
["foo"], a
);
853 Pointer("/clone").Set(d
, foo
, a
);
854 EXPECT_EQ(foo
, *GetValueByPointer(d
, "/clone"));
857 Pointer("/foo/int").Set(d
, -1, a
);
858 EXPECT_EQ(-1, GetValueByPointer(d
, "/foo/int")->GetInt());
860 Pointer("/foo/uint").Set(d
, 0x87654321, a
);
861 EXPECT_EQ(0x87654321, GetValueByPointer(d
, "/foo/uint")->GetUint());
863 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
864 Pointer("/foo/int64").Set(d
, i64
, a
);
865 EXPECT_EQ(i64
, GetValueByPointer(d
, "/foo/int64")->GetInt64());
867 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
868 Pointer("/foo/uint64").Set(d
, u64
, a
);
869 EXPECT_EQ(u64
, GetValueByPointer(d
, "/foo/uint64")->GetUint64());
871 Pointer("/foo/true").Set(d
, true, a
);
872 EXPECT_TRUE(GetValueByPointer(d
, "/foo/true")->IsTrue());
874 Pointer("/foo/false").Set(d
, false, a
);
875 EXPECT_TRUE(GetValueByPointer(d
, "/foo/false")->IsFalse());
878 Pointer("/foo/hello").Set(d
, "Hello", a
);
879 EXPECT_STREQ("Hello", GetValueByPointer(d
, "/foo/hello")->GetString());
881 // Copy string version
884 strcpy(buffer
, "World");
885 Pointer("/foo/world").Set(d
, buffer
, a
);
886 memset(buffer
, 0, sizeof(buffer
));
888 EXPECT_STREQ("World", GetValueByPointer(d
, "/foo/world")->GetString());
890 #if RAPIDJSON_HAS_STDSTRING
891 Pointer("/foo/c++").Set(d
, std::string("C++"), a
);
892 EXPECT_STREQ("C++", GetValueByPointer(d
, "/foo/c++")->GetString());
896 TEST(Pointer
, Set_NoAllocator
) {
901 Pointer("/foo/0").Set(d
, Value(123).Move());
902 EXPECT_EQ(123, d
["foo"][0].GetInt());
904 Pointer("/foo/-").Set(d
, Value(456).Move());
905 EXPECT_EQ(456, d
["foo"][2].GetInt());
907 Pointer("/foo/null").Set(d
, Value().Move());
908 EXPECT_TRUE(GetValueByPointer(d
, "/foo/null")->IsNull());
910 // Const Value version
911 const Value
foo(d
["foo"], d
.GetAllocator());
912 Pointer("/clone").Set(d
, foo
);
913 EXPECT_EQ(foo
, *GetValueByPointer(d
, "/clone"));
916 Pointer("/foo/int").Set(d
, -1);
917 EXPECT_EQ(-1, GetValueByPointer(d
, "/foo/int")->GetInt());
919 Pointer("/foo/uint").Set(d
, 0x87654321);
920 EXPECT_EQ(0x87654321, GetValueByPointer(d
, "/foo/uint")->GetUint());
922 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
923 Pointer("/foo/int64").Set(d
, i64
);
924 EXPECT_EQ(i64
, GetValueByPointer(d
, "/foo/int64")->GetInt64());
926 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
927 Pointer("/foo/uint64").Set(d
, u64
);
928 EXPECT_EQ(u64
, GetValueByPointer(d
, "/foo/uint64")->GetUint64());
930 Pointer("/foo/true").Set(d
, true);
931 EXPECT_TRUE(GetValueByPointer(d
, "/foo/true")->IsTrue());
933 Pointer("/foo/false").Set(d
, false);
934 EXPECT_TRUE(GetValueByPointer(d
, "/foo/false")->IsFalse());
937 Pointer("/foo/hello").Set(d
, "Hello");
938 EXPECT_STREQ("Hello", GetValueByPointer(d
, "/foo/hello")->GetString());
940 // Copy string version
943 strcpy(buffer
, "World");
944 Pointer("/foo/world").Set(d
, buffer
);
945 memset(buffer
, 0, sizeof(buffer
));
947 EXPECT_STREQ("World", GetValueByPointer(d
, "/foo/world")->GetString());
949 #if RAPIDJSON_HAS_STDSTRING
950 Pointer("/foo/c++").Set(d
, std::string("C++"));
951 EXPECT_STREQ("C++", GetValueByPointer(d
, "/foo/c++")->GetString());
955 TEST(Pointer
, Swap_Value
) {
958 Document::AllocatorType
& a
= d
.GetAllocator();
959 Pointer("/foo/0").Swap(d
, *Pointer("/foo/1").Get(d
), a
);
960 EXPECT_STREQ("baz", d
["foo"][0].GetString());
961 EXPECT_STREQ("bar", d
["foo"][1].GetString());
964 TEST(Pointer
, Swap_Value_NoAllocator
) {
967 Pointer("/foo/0").Swap(d
, *Pointer("/foo/1").Get(d
));
968 EXPECT_STREQ("baz", d
["foo"][0].GetString());
969 EXPECT_STREQ("bar", d
["foo"][1].GetString());
972 TEST(Pointer
, Erase
) {
976 EXPECT_FALSE(Pointer("").Erase(d
));
977 EXPECT_FALSE(Pointer("/nonexist").Erase(d
));
978 EXPECT_FALSE(Pointer("/nonexist/nonexist").Erase(d
));
979 EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d
));
980 EXPECT_FALSE(Pointer("/foo/nonexist/nonexist").Erase(d
));
981 EXPECT_FALSE(Pointer("/foo/0/nonexist").Erase(d
));
982 EXPECT_FALSE(Pointer("/foo/0/nonexist/nonexist").Erase(d
));
983 EXPECT_FALSE(Pointer("/foo/2/nonexist").Erase(d
));
984 EXPECT_TRUE(Pointer("/foo/0").Erase(d
));
985 EXPECT_EQ(1u, d
["foo"].Size());
986 EXPECT_STREQ("baz", d
["foo"][0].GetString());
987 EXPECT_TRUE(Pointer("/foo/0").Erase(d
));
988 EXPECT_TRUE(d
["foo"].Empty());
989 EXPECT_TRUE(Pointer("/foo").Erase(d
));
990 EXPECT_TRUE(Pointer("/foo").Get(d
) == 0);
992 Pointer("/a/0/b/0").Create(d
);
994 EXPECT_TRUE(Pointer("/a/0/b/0").Get(d
) != 0);
995 EXPECT_TRUE(Pointer("/a/0/b/0").Erase(d
));
996 EXPECT_TRUE(Pointer("/a/0/b/0").Get(d
) == 0);
998 EXPECT_TRUE(Pointer("/a/0/b").Get(d
) != 0);
999 EXPECT_TRUE(Pointer("/a/0/b").Erase(d
));
1000 EXPECT_TRUE(Pointer("/a/0/b").Get(d
) == 0);
1002 EXPECT_TRUE(Pointer("/a/0").Get(d
) != 0);
1003 EXPECT_TRUE(Pointer("/a/0").Erase(d
));
1004 EXPECT_TRUE(Pointer("/a/0").Get(d
) == 0);
1006 EXPECT_TRUE(Pointer("/a").Get(d
) != 0);
1007 EXPECT_TRUE(Pointer("/a").Erase(d
));
1008 EXPECT_TRUE(Pointer("/a").Get(d
) == 0);
1011 TEST(Pointer
, CreateValueByPointer
) {
1013 Document::AllocatorType
& a
= d
.GetAllocator();
1016 Value
& v
= CreateValueByPointer(d
, Pointer("/foo/0"), a
);
1017 EXPECT_EQ(&d
["foo"][0], &v
);
1020 Value
& v
= CreateValueByPointer(d
, "/foo/1", a
);
1021 EXPECT_EQ(&d
["foo"][1], &v
);
1025 TEST(Pointer
, CreateValueByPointer_NoAllocator
) {
1029 Value
& v
= CreateValueByPointer(d
, Pointer("/foo/0"));
1030 EXPECT_EQ(&d
["foo"][0], &v
);
1033 Value
& v
= CreateValueByPointer(d
, "/foo/1");
1034 EXPECT_EQ(&d
["foo"][1], &v
);
1038 TEST(Pointer
, GetValueByPointer
) {
1042 EXPECT_EQ(&d
["foo"][0], GetValueByPointer(d
, Pointer("/foo/0")));
1043 EXPECT_EQ(&d
["foo"][0], GetValueByPointer(d
, "/foo/0"));
1045 size_t unresolvedTokenIndex
;
1046 EXPECT_TRUE(GetValueByPointer(d
, "/foo/2", &unresolvedTokenIndex
) == 0); // Out of boundary
1047 EXPECT_EQ(1u, unresolvedTokenIndex
);
1048 EXPECT_TRUE(GetValueByPointer(d
, "/foo/a", &unresolvedTokenIndex
) == 0); // "/foo" is an array, cannot query by "a"
1049 EXPECT_EQ(1u, unresolvedTokenIndex
);
1050 EXPECT_TRUE(GetValueByPointer(d
, "/foo/0/0", &unresolvedTokenIndex
) == 0); // "/foo/0" is an string, cannot further query
1051 EXPECT_EQ(2u, unresolvedTokenIndex
);
1052 EXPECT_TRUE(GetValueByPointer(d
, "/foo/0/a", &unresolvedTokenIndex
) == 0); // "/foo/0" is an string, cannot further query
1053 EXPECT_EQ(2u, unresolvedTokenIndex
);
1057 EXPECT_EQ(&d
["foo"][0], GetValueByPointer(v
, Pointer("/foo/0")));
1058 EXPECT_EQ(&d
["foo"][0], GetValueByPointer(v
, "/foo/0"));
1060 EXPECT_TRUE(GetValueByPointer(v
, "/foo/2", &unresolvedTokenIndex
) == 0); // Out of boundary
1061 EXPECT_EQ(1u, unresolvedTokenIndex
);
1062 EXPECT_TRUE(GetValueByPointer(v
, "/foo/a", &unresolvedTokenIndex
) == 0); // "/foo" is an array, cannot query by "a"
1063 EXPECT_EQ(1u, unresolvedTokenIndex
);
1064 EXPECT_TRUE(GetValueByPointer(v
, "/foo/0/0", &unresolvedTokenIndex
) == 0); // "/foo/0" is an string, cannot further query
1065 EXPECT_EQ(2u, unresolvedTokenIndex
);
1066 EXPECT_TRUE(GetValueByPointer(v
, "/foo/0/a", &unresolvedTokenIndex
) == 0); // "/foo/0" is an string, cannot further query
1067 EXPECT_EQ(2u, unresolvedTokenIndex
);
1071 TEST(Pointer
, GetValueByPointerWithDefault_Pointer
) {
1075 Document::AllocatorType
& a
= d
.GetAllocator();
1076 const Value
v("qux");
1077 EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d
, Pointer("/foo/0"), v
, a
));
1078 EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d
, Pointer("/foo/0"), v
, a
));
1079 EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d
, Pointer("/foo/1"), v
, a
));
1080 EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d
, Pointer("/foo/2"), v
, a
));
1081 EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d
, Pointer("/foo/-"), Value("last").Move(), a
));
1082 EXPECT_STREQ("last", d
["foo"][3].GetString());
1084 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/null"), Value().Move(), a
).IsNull());
1085 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/null"), "x", a
).IsNull());
1088 EXPECT_EQ(-1, GetValueByPointerWithDefault(d
, Pointer("/foo/int"), -1, a
).GetInt());
1089 EXPECT_EQ(-1, GetValueByPointerWithDefault(d
, Pointer("/foo/int"), -2, a
).GetInt());
1090 EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d
, Pointer("/foo/uint"), 0x87654321, a
).GetUint());
1091 EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d
, Pointer("/foo/uint"), 0x12345678, a
).GetUint());
1093 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1094 EXPECT_EQ(i64
, GetValueByPointerWithDefault(d
, Pointer("/foo/int64"), i64
, a
).GetInt64());
1095 EXPECT_EQ(i64
, GetValueByPointerWithDefault(d
, Pointer("/foo/int64"), i64
+ 1, a
).GetInt64());
1097 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1098 EXPECT_EQ(u64
, GetValueByPointerWithDefault(d
, Pointer("/foo/uint64"), u64
, a
).GetUint64());
1099 EXPECT_EQ(u64
, GetValueByPointerWithDefault(d
, Pointer("/foo/uint64"), u64
- 1, a
).GetUint64());
1101 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/true"), true, a
).IsTrue());
1102 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/true"), false, a
).IsTrue());
1104 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/false"), false, a
).IsFalse());
1105 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/false"), true, a
).IsFalse());
1107 // StringRef version
1108 EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d
, Pointer("/foo/hello"), "Hello", a
).GetString());
1110 // Copy string version
1113 strcpy(buffer
, "World");
1114 EXPECT_STREQ("World", GetValueByPointerWithDefault(d
, Pointer("/foo/world"), buffer
, a
).GetString());
1115 memset(buffer
, 0, sizeof(buffer
));
1117 EXPECT_STREQ("World", GetValueByPointer(d
, Pointer("/foo/world"))->GetString());
1119 #if RAPIDJSON_HAS_STDSTRING
1120 EXPECT_STREQ("C++", GetValueByPointerWithDefault(d
, Pointer("/foo/C++"), std::string("C++"), a
).GetString());
1124 TEST(Pointer
, GetValueByPointerWithDefault_String
) {
1128 Document::AllocatorType
& a
= d
.GetAllocator();
1129 const Value
v("qux");
1130 EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d
, "/foo/0", v
, a
));
1131 EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d
, "/foo/0", v
, a
));
1132 EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d
, "/foo/1", v
, a
));
1133 EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d
, "/foo/2", v
, a
));
1134 EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d
, "/foo/-", Value("last").Move(), a
));
1135 EXPECT_STREQ("last", d
["foo"][3].GetString());
1137 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/null", Value().Move(), a
).IsNull());
1138 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/null", "x", a
).IsNull());
1141 EXPECT_EQ(-1, GetValueByPointerWithDefault(d
, "/foo/int", -1, a
).GetInt());
1142 EXPECT_EQ(-1, GetValueByPointerWithDefault(d
, "/foo/int", -2, a
).GetInt());
1143 EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d
, "/foo/uint", 0x87654321, a
).GetUint());
1144 EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d
, "/foo/uint", 0x12345678, a
).GetUint());
1146 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1147 EXPECT_EQ(i64
, GetValueByPointerWithDefault(d
, "/foo/int64", i64
, a
).GetInt64());
1148 EXPECT_EQ(i64
, GetValueByPointerWithDefault(d
, "/foo/int64", i64
+ 1, a
).GetInt64());
1150 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1151 EXPECT_EQ(u64
, GetValueByPointerWithDefault(d
, "/foo/uint64", u64
, a
).GetUint64());
1152 EXPECT_EQ(u64
, GetValueByPointerWithDefault(d
, "/foo/uint64", u64
- 1, a
).GetUint64());
1154 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/true", true, a
).IsTrue());
1155 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/true", false, a
).IsTrue());
1157 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/false", false, a
).IsFalse());
1158 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/false", true, a
).IsFalse());
1160 // StringRef version
1161 EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d
, "/foo/hello", "Hello", a
).GetString());
1163 // Copy string version
1166 strcpy(buffer
, "World");
1167 EXPECT_STREQ("World", GetValueByPointerWithDefault(d
, "/foo/world", buffer
, a
).GetString());
1168 memset(buffer
, 0, sizeof(buffer
));
1170 EXPECT_STREQ("World", GetValueByPointer(d
, "/foo/world")->GetString());
1172 #if RAPIDJSON_HAS_STDSTRING
1173 EXPECT_STREQ("C++", GetValueByPointerWithDefault(d
, "/foo/C++", std::string("C++"), a
).GetString());
1177 TEST(Pointer
, GetValueByPointerWithDefault_Pointer_NoAllocator
) {
1181 const Value
v("qux");
1182 EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d
, Pointer("/foo/0"), v
));
1183 EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d
, Pointer("/foo/0"), v
));
1184 EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d
, Pointer("/foo/1"), v
));
1185 EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d
, Pointer("/foo/2"), v
));
1186 EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d
, Pointer("/foo/-"), Value("last").Move()));
1187 EXPECT_STREQ("last", d
["foo"][3].GetString());
1189 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/null"), Value().Move()).IsNull());
1190 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/null"), "x").IsNull());
1193 EXPECT_EQ(-1, GetValueByPointerWithDefault(d
, Pointer("/foo/int"), -1).GetInt());
1194 EXPECT_EQ(-1, GetValueByPointerWithDefault(d
, Pointer("/foo/int"), -2).GetInt());
1195 EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d
, Pointer("/foo/uint"), 0x87654321).GetUint());
1196 EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d
, Pointer("/foo/uint"), 0x12345678).GetUint());
1198 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1199 EXPECT_EQ(i64
, GetValueByPointerWithDefault(d
, Pointer("/foo/int64"), i64
).GetInt64());
1200 EXPECT_EQ(i64
, GetValueByPointerWithDefault(d
, Pointer("/foo/int64"), i64
+ 1).GetInt64());
1202 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1203 EXPECT_EQ(u64
, GetValueByPointerWithDefault(d
, Pointer("/foo/uint64"), u64
).GetUint64());
1204 EXPECT_EQ(u64
, GetValueByPointerWithDefault(d
, Pointer("/foo/uint64"), u64
- 1).GetUint64());
1206 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/true"), true).IsTrue());
1207 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/true"), false).IsTrue());
1209 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/false"), false).IsFalse());
1210 EXPECT_TRUE(GetValueByPointerWithDefault(d
, Pointer("/foo/false"), true).IsFalse());
1212 // StringRef version
1213 EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d
, Pointer("/foo/hello"), "Hello").GetString());
1215 // Copy string version
1218 strcpy(buffer
, "World");
1219 EXPECT_STREQ("World", GetValueByPointerWithDefault(d
, Pointer("/foo/world"), buffer
).GetString());
1220 memset(buffer
, 0, sizeof(buffer
));
1222 EXPECT_STREQ("World", GetValueByPointer(d
, Pointer("/foo/world"))->GetString());
1224 #if RAPIDJSON_HAS_STDSTRING
1225 EXPECT_STREQ("C++", GetValueByPointerWithDefault(d
, Pointer("/foo/C++"), std::string("C++")).GetString());
1229 TEST(Pointer
, GetValueByPointerWithDefault_String_NoAllocator
) {
1233 const Value
v("qux");
1234 EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d
, "/foo/0", v
));
1235 EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d
, "/foo/0", v
));
1236 EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d
, "/foo/1", v
));
1237 EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d
, "/foo/2", v
));
1238 EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d
, "/foo/-", Value("last").Move()));
1239 EXPECT_STREQ("last", d
["foo"][3].GetString());
1241 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/null", Value().Move()).IsNull());
1242 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/null", "x").IsNull());
1245 EXPECT_EQ(-1, GetValueByPointerWithDefault(d
, "/foo/int", -1).GetInt());
1246 EXPECT_EQ(-1, GetValueByPointerWithDefault(d
, "/foo/int", -2).GetInt());
1247 EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d
, "/foo/uint", 0x87654321).GetUint());
1248 EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d
, "/foo/uint", 0x12345678).GetUint());
1250 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1251 EXPECT_EQ(i64
, GetValueByPointerWithDefault(d
, "/foo/int64", i64
).GetInt64());
1252 EXPECT_EQ(i64
, GetValueByPointerWithDefault(d
, "/foo/int64", i64
+ 1).GetInt64());
1254 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1255 EXPECT_EQ(u64
, GetValueByPointerWithDefault(d
, "/foo/uint64", u64
).GetUint64());
1256 EXPECT_EQ(u64
, GetValueByPointerWithDefault(d
, "/foo/uint64", u64
- 1).GetUint64());
1258 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/true", true).IsTrue());
1259 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/true", false).IsTrue());
1261 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/false", false).IsFalse());
1262 EXPECT_TRUE(GetValueByPointerWithDefault(d
, "/foo/false", true).IsFalse());
1264 // StringRef version
1265 EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d
, "/foo/hello", "Hello").GetString());
1267 // Copy string version
1270 strcpy(buffer
, "World");
1271 EXPECT_STREQ("World", GetValueByPointerWithDefault(d
, "/foo/world", buffer
).GetString());
1272 memset(buffer
, 0, sizeof(buffer
));
1274 EXPECT_STREQ("World", GetValueByPointer(d
, "/foo/world")->GetString());
1276 #if RAPIDJSON_HAS_STDSTRING
1277 EXPECT_STREQ("C++", GetValueByPointerWithDefault(d
, Pointer("/foo/C++"), std::string("C++")).GetString());
1281 TEST(Pointer
, SetValueByPointer_Pointer
) {
1284 Document::AllocatorType
& a
= d
.GetAllocator();
1287 SetValueByPointer(d
, Pointer("/foo/0"), Value(123).Move(), a
);
1288 EXPECT_EQ(123, d
["foo"][0].GetInt());
1290 SetValueByPointer(d
, Pointer("/foo/null"), Value().Move(), a
);
1291 EXPECT_TRUE(GetValueByPointer(d
, "/foo/null")->IsNull());
1293 // Const Value version
1294 const Value
foo(d
["foo"], d
.GetAllocator());
1295 SetValueByPointer(d
, Pointer("/clone"), foo
, a
);
1296 EXPECT_EQ(foo
, *GetValueByPointer(d
, "/clone"));
1299 SetValueByPointer(d
, Pointer("/foo/int"), -1, a
);
1300 EXPECT_EQ(-1, GetValueByPointer(d
, "/foo/int")->GetInt());
1302 SetValueByPointer(d
, Pointer("/foo/uint"), 0x87654321, a
);
1303 EXPECT_EQ(0x87654321, GetValueByPointer(d
, "/foo/uint")->GetUint());
1305 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1306 SetValueByPointer(d
, Pointer("/foo/int64"), i64
, a
);
1307 EXPECT_EQ(i64
, GetValueByPointer(d
, "/foo/int64")->GetInt64());
1309 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1310 SetValueByPointer(d
, Pointer("/foo/uint64"), u64
, a
);
1311 EXPECT_EQ(u64
, GetValueByPointer(d
, "/foo/uint64")->GetUint64());
1313 SetValueByPointer(d
, Pointer("/foo/true"), true, a
);
1314 EXPECT_TRUE(GetValueByPointer(d
, "/foo/true")->IsTrue());
1316 SetValueByPointer(d
, Pointer("/foo/false"), false, a
);
1317 EXPECT_TRUE(GetValueByPointer(d
, "/foo/false")->IsFalse());
1319 // StringRef version
1320 SetValueByPointer(d
, Pointer("/foo/hello"), "Hello", a
);
1321 EXPECT_STREQ("Hello", GetValueByPointer(d
, "/foo/hello")->GetString());
1323 // Copy string version
1326 strcpy(buffer
, "World");
1327 SetValueByPointer(d
, Pointer("/foo/world"), buffer
, a
);
1328 memset(buffer
, 0, sizeof(buffer
));
1330 EXPECT_STREQ("World", GetValueByPointer(d
, "/foo/world")->GetString());
1332 #if RAPIDJSON_HAS_STDSTRING
1333 SetValueByPointer(d
, Pointer("/foo/c++"), std::string("C++"), a
);
1334 EXPECT_STREQ("C++", GetValueByPointer(d
, "/foo/c++")->GetString());
1338 TEST(Pointer
, SetValueByPointer_String
) {
1341 Document::AllocatorType
& a
= d
.GetAllocator();
1344 SetValueByPointer(d
, "/foo/0", Value(123).Move(), a
);
1345 EXPECT_EQ(123, d
["foo"][0].GetInt());
1347 SetValueByPointer(d
, "/foo/null", Value().Move(), a
);
1348 EXPECT_TRUE(GetValueByPointer(d
, "/foo/null")->IsNull());
1350 // Const Value version
1351 const Value
foo(d
["foo"], d
.GetAllocator());
1352 SetValueByPointer(d
, "/clone", foo
, a
);
1353 EXPECT_EQ(foo
, *GetValueByPointer(d
, "/clone"));
1356 SetValueByPointer(d
, "/foo/int", -1, a
);
1357 EXPECT_EQ(-1, GetValueByPointer(d
, "/foo/int")->GetInt());
1359 SetValueByPointer(d
, "/foo/uint", 0x87654321, a
);
1360 EXPECT_EQ(0x87654321, GetValueByPointer(d
, "/foo/uint")->GetUint());
1362 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1363 SetValueByPointer(d
, "/foo/int64", i64
, a
);
1364 EXPECT_EQ(i64
, GetValueByPointer(d
, "/foo/int64")->GetInt64());
1366 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1367 SetValueByPointer(d
, "/foo/uint64", u64
, a
);
1368 EXPECT_EQ(u64
, GetValueByPointer(d
, "/foo/uint64")->GetUint64());
1370 SetValueByPointer(d
, "/foo/true", true, a
);
1371 EXPECT_TRUE(GetValueByPointer(d
, "/foo/true")->IsTrue());
1373 SetValueByPointer(d
, "/foo/false", false, a
);
1374 EXPECT_TRUE(GetValueByPointer(d
, "/foo/false")->IsFalse());
1376 // StringRef version
1377 SetValueByPointer(d
, "/foo/hello", "Hello", a
);
1378 EXPECT_STREQ("Hello", GetValueByPointer(d
, "/foo/hello")->GetString());
1380 // Copy string version
1383 strcpy(buffer
, "World");
1384 SetValueByPointer(d
, "/foo/world", buffer
, a
);
1385 memset(buffer
, 0, sizeof(buffer
));
1387 EXPECT_STREQ("World", GetValueByPointer(d
, "/foo/world")->GetString());
1389 #if RAPIDJSON_HAS_STDSTRING
1390 SetValueByPointer(d
, "/foo/c++", std::string("C++"), a
);
1391 EXPECT_STREQ("C++", GetValueByPointer(d
, "/foo/c++")->GetString());
1395 TEST(Pointer
, SetValueByPointer_Pointer_NoAllocator
) {
1400 SetValueByPointer(d
, Pointer("/foo/0"), Value(123).Move());
1401 EXPECT_EQ(123, d
["foo"][0].GetInt());
1403 SetValueByPointer(d
, Pointer("/foo/null"), Value().Move());
1404 EXPECT_TRUE(GetValueByPointer(d
, "/foo/null")->IsNull());
1406 // Const Value version
1407 const Value
foo(d
["foo"], d
.GetAllocator());
1408 SetValueByPointer(d
, Pointer("/clone"), foo
);
1409 EXPECT_EQ(foo
, *GetValueByPointer(d
, "/clone"));
1412 SetValueByPointer(d
, Pointer("/foo/int"), -1);
1413 EXPECT_EQ(-1, GetValueByPointer(d
, "/foo/int")->GetInt());
1415 SetValueByPointer(d
, Pointer("/foo/uint"), 0x87654321);
1416 EXPECT_EQ(0x87654321, GetValueByPointer(d
, "/foo/uint")->GetUint());
1418 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1419 SetValueByPointer(d
, Pointer("/foo/int64"), i64
);
1420 EXPECT_EQ(i64
, GetValueByPointer(d
, "/foo/int64")->GetInt64());
1422 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1423 SetValueByPointer(d
, Pointer("/foo/uint64"), u64
);
1424 EXPECT_EQ(u64
, GetValueByPointer(d
, "/foo/uint64")->GetUint64());
1426 SetValueByPointer(d
, Pointer("/foo/true"), true);
1427 EXPECT_TRUE(GetValueByPointer(d
, "/foo/true")->IsTrue());
1429 SetValueByPointer(d
, Pointer("/foo/false"), false);
1430 EXPECT_TRUE(GetValueByPointer(d
, "/foo/false")->IsFalse());
1432 // StringRef version
1433 SetValueByPointer(d
, Pointer("/foo/hello"), "Hello");
1434 EXPECT_STREQ("Hello", GetValueByPointer(d
, "/foo/hello")->GetString());
1436 // Copy string version
1439 strcpy(buffer
, "World");
1440 SetValueByPointer(d
, Pointer("/foo/world"), buffer
);
1441 memset(buffer
, 0, sizeof(buffer
));
1443 EXPECT_STREQ("World", GetValueByPointer(d
, "/foo/world")->GetString());
1445 #if RAPIDJSON_HAS_STDSTRING
1446 SetValueByPointer(d
, Pointer("/foo/c++"), std::string("C++"));
1447 EXPECT_STREQ("C++", GetValueByPointer(d
, "/foo/c++")->GetString());
1451 TEST(Pointer
, SetValueByPointer_String_NoAllocator
) {
1456 SetValueByPointer(d
, "/foo/0", Value(123).Move());
1457 EXPECT_EQ(123, d
["foo"][0].GetInt());
1459 SetValueByPointer(d
, "/foo/null", Value().Move());
1460 EXPECT_TRUE(GetValueByPointer(d
, "/foo/null")->IsNull());
1462 // Const Value version
1463 const Value
foo(d
["foo"], d
.GetAllocator());
1464 SetValueByPointer(d
, "/clone", foo
);
1465 EXPECT_EQ(foo
, *GetValueByPointer(d
, "/clone"));
1468 SetValueByPointer(d
, "/foo/int", -1);
1469 EXPECT_EQ(-1, GetValueByPointer(d
, "/foo/int")->GetInt());
1471 SetValueByPointer(d
, "/foo/uint", 0x87654321);
1472 EXPECT_EQ(0x87654321, GetValueByPointer(d
, "/foo/uint")->GetUint());
1474 const int64_t i64
= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1475 SetValueByPointer(d
, "/foo/int64", i64
);
1476 EXPECT_EQ(i64
, GetValueByPointer(d
, "/foo/int64")->GetInt64());
1478 const uint64_t u64
= RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1479 SetValueByPointer(d
, "/foo/uint64", u64
);
1480 EXPECT_EQ(u64
, GetValueByPointer(d
, "/foo/uint64")->GetUint64());
1482 SetValueByPointer(d
, "/foo/true", true);
1483 EXPECT_TRUE(GetValueByPointer(d
, "/foo/true")->IsTrue());
1485 SetValueByPointer(d
, "/foo/false", false);
1486 EXPECT_TRUE(GetValueByPointer(d
, "/foo/false")->IsFalse());
1488 // StringRef version
1489 SetValueByPointer(d
, "/foo/hello", "Hello");
1490 EXPECT_STREQ("Hello", GetValueByPointer(d
, "/foo/hello")->GetString());
1492 // Copy string version
1495 strcpy(buffer
, "World");
1496 SetValueByPointer(d
, "/foo/world", buffer
);
1497 memset(buffer
, 0, sizeof(buffer
));
1499 EXPECT_STREQ("World", GetValueByPointer(d
, "/foo/world")->GetString());
1501 #if RAPIDJSON_HAS_STDSTRING
1502 SetValueByPointer(d
, "/foo/c++", std::string("C++"));
1503 EXPECT_STREQ("C++", GetValueByPointer(d
, "/foo/c++")->GetString());
1507 TEST(Pointer
, SwapValueByPointer
) {
1510 Document::AllocatorType
& a
= d
.GetAllocator();
1511 SwapValueByPointer(d
, Pointer("/foo/0"), *GetValueByPointer(d
, "/foo/1"), a
);
1512 EXPECT_STREQ("baz", d
["foo"][0].GetString());
1513 EXPECT_STREQ("bar", d
["foo"][1].GetString());
1515 SwapValueByPointer(d
, "/foo/0", *GetValueByPointer(d
, "/foo/1"), a
);
1516 EXPECT_STREQ("bar", d
["foo"][0].GetString());
1517 EXPECT_STREQ("baz", d
["foo"][1].GetString());
1520 TEST(Pointer
, SwapValueByPointer_NoAllocator
) {
1523 SwapValueByPointer(d
, Pointer("/foo/0"), *GetValueByPointer(d
, "/foo/1"));
1524 EXPECT_STREQ("baz", d
["foo"][0].GetString());
1525 EXPECT_STREQ("bar", d
["foo"][1].GetString());
1527 SwapValueByPointer(d
, "/foo/0", *GetValueByPointer(d
, "/foo/1"));
1528 EXPECT_STREQ("bar", d
["foo"][0].GetString());
1529 EXPECT_STREQ("baz", d
["foo"][1].GetString());
1532 TEST(Pointer
, EraseValueByPointer_Pointer
) {
1536 EXPECT_FALSE(EraseValueByPointer(d
, Pointer("")));
1537 EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d
));
1538 EXPECT_TRUE(EraseValueByPointer(d
, Pointer("/foo/0")));
1539 EXPECT_EQ(1u, d
["foo"].Size());
1540 EXPECT_STREQ("baz", d
["foo"][0].GetString());
1541 EXPECT_TRUE(EraseValueByPointer(d
, Pointer("/foo/0")));
1542 EXPECT_TRUE(d
["foo"].Empty());
1543 EXPECT_TRUE(EraseValueByPointer(d
, Pointer("/foo")));
1544 EXPECT_TRUE(Pointer("/foo").Get(d
) == 0);
1547 TEST(Pointer
, EraseValueByPointer_String
) {
1551 EXPECT_FALSE(EraseValueByPointer(d
, ""));
1552 EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d
));
1553 EXPECT_TRUE(EraseValueByPointer(d
, "/foo/0"));
1554 EXPECT_EQ(1u, d
["foo"].Size());
1555 EXPECT_STREQ("baz", d
["foo"][0].GetString());
1556 EXPECT_TRUE(EraseValueByPointer(d
, "/foo/0"));
1557 EXPECT_TRUE(d
["foo"].Empty());
1558 EXPECT_TRUE(EraseValueByPointer(d
, "/foo"));
1559 EXPECT_TRUE(Pointer("/foo").Get(d
) == 0);
1562 TEST(Pointer
, Ambiguity
) {
1565 d
.Parse("{\"0\" : [123]}");
1566 EXPECT_EQ(123, Pointer("/0/0").Get(d
)->GetInt());
1567 Pointer("/0/a").Set(d
, 456); // Change array [123] to object {456}
1568 EXPECT_EQ(456, Pointer("/0/a").Get(d
)->GetInt());
1573 EXPECT_FALSE(d
.Parse("[{\"0\": 123}]").HasParseError());
1574 EXPECT_EQ(123, Pointer("/0/0").Get(d
)->GetInt());
1575 Pointer("/0/1").Set(d
, 456); // 1 is treated as "1" to index object
1576 EXPECT_EQ(123, Pointer("/0/0").Get(d
)->GetInt());
1577 EXPECT_EQ(456, Pointer("/0/1").Get(d
)->GetInt());
1581 TEST(Pointer
, ResolveOnObject
) {
1583 EXPECT_FALSE(d
.Parse("{\"a\": 123}").HasParseError());
1586 Value::ConstObject o
= static_cast<const Document
&>(d
).GetObject();
1587 EXPECT_EQ(123, Pointer("/a").Get(o
)->GetInt());
1591 Value::Object o
= d
.GetObject();
1592 Pointer("/a").Set(o
, 456, d
.GetAllocator());
1593 EXPECT_EQ(456, Pointer("/a").Get(o
)->GetInt());
1597 TEST(Pointer
, ResolveOnArray
) {
1599 EXPECT_FALSE(d
.Parse("[1, 2, 3]").HasParseError());
1602 Value::ConstArray a
= static_cast<const Document
&>(d
).GetArray();
1603 EXPECT_EQ(2, Pointer("/1").Get(a
)->GetInt());
1607 Value::Array a
= d
.GetArray();
1608 Pointer("/1").Set(a
, 123, d
.GetAllocator());
1609 EXPECT_EQ(123, Pointer("/1").Get(a
)->GetInt());
1613 TEST(Pointer
, LessThan
) {
1614 static const struct {
1625 { "/e/f~g", false },
1626 { "/d/2/zz", true },
1629 { "/e/f~~g", false },
1630 { "/e/f~0g", true },
1631 { "/e/f~1g", true },
1635 static const char *ordered_pointers
[] = {
1650 NULL
, // was invalid "/e/f~g"
1651 NULL
// was invalid "/e/f~~g"
1653 typedef MemoryPoolAllocator
<> AllocatorType
;
1654 typedef GenericPointer
<Value
, AllocatorType
> PointerType
;
1655 typedef std::multimap
<PointerType
, size_t> PointerMap
;
1657 PointerMap::iterator it
;
1658 AllocatorType allocator
;
1661 EXPECT_EQ(sizeof(pointers
) / sizeof(pointers
[0]),
1662 sizeof(ordered_pointers
) / sizeof(ordered_pointers
[0]));
1664 for (i
= 0; i
< sizeof(pointers
) / sizeof(pointers
[0]); ++i
) {
1665 it
= map
.insert(PointerMap::value_type(PointerType(pointers
[i
].str
, &allocator
), i
));
1666 if (!it
->first
.IsValid()) {
1667 EXPECT_EQ(++it
, map
.end());
1671 for (i
= 0, it
= map
.begin(); it
!= map
.end(); ++it
, ++i
) {
1672 EXPECT_TRUE(it
->second
< sizeof(pointers
) / sizeof(pointers
[0]));
1673 EXPECT_EQ(it
->first
.IsValid(), pointers
[it
->second
].valid
);
1674 EXPECT_TRUE(i
< sizeof(ordered_pointers
) / sizeof(ordered_pointers
[0]));
1675 EXPECT_EQ(it
->first
.IsValid(), !!ordered_pointers
[i
]);
1676 if (it
->first
.IsValid()) {
1677 std::stringstream ss
;
1678 OStreamWrapper
os(ss
);
1679 EXPECT_TRUE(it
->first
.Stringify(os
));
1680 EXPECT_EQ(ss
.str(), pointers
[it
->second
].str
);
1681 EXPECT_EQ(ss
.str(), ordered_pointers
[i
]);
1686 // https://github.com/Tencent/rapidjson/issues/483
1692 static const bool kNeedFree
= true;
1693 void * Malloc(size_t _size
) { return malloc(_size
); }
1694 void * Realloc(void *_org_p
, size_t _org_size
, size_t _new_size
) { (void)_org_size
; return realloc(_org_p
, _new_size
); }
1695 static void Free(void *_p
) { return free(_p
); }
1698 typedef rapidjson::GenericDocument
<
1700 rapidjson::MemoryPoolAllocator
< MyAllocator
>,
1704 typedef rapidjson::GenericPointer
<
1705 ::myjson::Document::ValueType
,
1709 typedef ::myjson::Document::ValueType Value
;
1713 TEST(Pointer
, Issue483
) {
1714 std::string mystr
, path
;
1715 myjson::Document document
;
1716 myjson::Value
value(rapidjson::kStringType
);
1717 value
.SetString(mystr
.c_str(), static_cast<SizeType
>(mystr
.length()), document
.GetAllocator());
1718 myjson::Pointer(path
.c_str()).Set(document
, value
, document
.GetAllocator());
1721 TEST(Pointer
, Issue1899
) {
1722 typedef GenericPointer
<Value
, MemoryPoolAllocator
<> > PointerType
;
1724 PointerType q
= p
.Append("foo");
1725 EXPECT_TRUE(PointerType("/foo") == q
);
1727 EXPECT_TRUE(PointerType("/foo/1234") == q
);
1729 EXPECT_TRUE(PointerType("/foo/1234/") == q
);