pointertest.cpp 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524
  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. #include "unittest.h"
  15. #include "rapidjson/pointer.h"
  16. #include "rapidjson/stringbuffer.h"
  17. #include <sstream>
  18. using namespace rapidjson;
  19. static const char kJson[] = "{\n"
  20. " \"foo\":[\"bar\", \"baz\"],\n"
  21. " \"\" : 0,\n"
  22. " \"a/b\" : 1,\n"
  23. " \"c%d\" : 2,\n"
  24. " \"e^f\" : 3,\n"
  25. " \"g|h\" : 4,\n"
  26. " \"i\\\\j\" : 5,\n"
  27. " \"k\\\"l\" : 6,\n"
  28. " \" \" : 7,\n"
  29. " \"m~n\" : 8\n"
  30. "}";
  31. TEST(Pointer, DefaultConstructor) {
  32. Pointer p;
  33. EXPECT_TRUE(p.IsValid());
  34. EXPECT_EQ(0u, p.GetTokenCount());
  35. }
  36. TEST(Pointer, Parse) {
  37. {
  38. Pointer p("");
  39. EXPECT_TRUE(p.IsValid());
  40. EXPECT_EQ(0u, p.GetTokenCount());
  41. }
  42. {
  43. Pointer p("/");
  44. EXPECT_TRUE(p.IsValid());
  45. EXPECT_EQ(1u, p.GetTokenCount());
  46. EXPECT_EQ(0u, p.GetTokens()[0].length);
  47. EXPECT_STREQ("", p.GetTokens()[0].name);
  48. EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
  49. }
  50. {
  51. Pointer p("/foo");
  52. EXPECT_TRUE(p.IsValid());
  53. EXPECT_EQ(1u, p.GetTokenCount());
  54. EXPECT_EQ(3u, p.GetTokens()[0].length);
  55. EXPECT_STREQ("foo", p.GetTokens()[0].name);
  56. EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
  57. }
  58. #if RAPIDJSON_HAS_STDSTRING
  59. {
  60. Pointer p(std::string("/foo"));
  61. EXPECT_TRUE(p.IsValid());
  62. EXPECT_EQ(1u, p.GetTokenCount());
  63. EXPECT_EQ(3u, p.GetTokens()[0].length);
  64. EXPECT_STREQ("foo", p.GetTokens()[0].name);
  65. EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
  66. }
  67. #endif
  68. {
  69. Pointer p("/foo/0");
  70. EXPECT_TRUE(p.IsValid());
  71. EXPECT_EQ(2u, p.GetTokenCount());
  72. EXPECT_EQ(3u, p.GetTokens()[0].length);
  73. EXPECT_STREQ("foo", p.GetTokens()[0].name);
  74. EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
  75. EXPECT_EQ(1u, p.GetTokens()[1].length);
  76. EXPECT_STREQ("0", p.GetTokens()[1].name);
  77. EXPECT_EQ(0u, p.GetTokens()[1].index);
  78. }
  79. {
  80. // Unescape ~1
  81. Pointer p("/a~1b");
  82. EXPECT_TRUE(p.IsValid());
  83. EXPECT_EQ(1u, p.GetTokenCount());
  84. EXPECT_EQ(3u, p.GetTokens()[0].length);
  85. EXPECT_STREQ("a/b", p.GetTokens()[0].name);
  86. }
  87. {
  88. // Unescape ~0
  89. Pointer p("/m~0n");
  90. EXPECT_TRUE(p.IsValid());
  91. EXPECT_EQ(1u, p.GetTokenCount());
  92. EXPECT_EQ(3u, p.GetTokens()[0].length);
  93. EXPECT_STREQ("m~n", p.GetTokens()[0].name);
  94. }
  95. {
  96. // empty name
  97. Pointer p("/");
  98. EXPECT_TRUE(p.IsValid());
  99. EXPECT_EQ(1u, p.GetTokenCount());
  100. EXPECT_EQ(0u, p.GetTokens()[0].length);
  101. EXPECT_STREQ("", p.GetTokens()[0].name);
  102. }
  103. {
  104. // empty and non-empty name
  105. Pointer p("//a");
  106. EXPECT_TRUE(p.IsValid());
  107. EXPECT_EQ(2u, p.GetTokenCount());
  108. EXPECT_EQ(0u, p.GetTokens()[0].length);
  109. EXPECT_STREQ("", p.GetTokens()[0].name);
  110. EXPECT_EQ(1u, p.GetTokens()[1].length);
  111. EXPECT_STREQ("a", p.GetTokens()[1].name);
  112. }
  113. {
  114. // Null characters
  115. Pointer p("/\0\0", 3);
  116. EXPECT_TRUE(p.IsValid());
  117. EXPECT_EQ(1u, p.GetTokenCount());
  118. EXPECT_EQ(2u, p.GetTokens()[0].length);
  119. EXPECT_EQ('\0', p.GetTokens()[0].name[0]);
  120. EXPECT_EQ('\0', p.GetTokens()[0].name[1]);
  121. EXPECT_EQ('\0', p.GetTokens()[0].name[2]);
  122. }
  123. {
  124. // Valid index
  125. Pointer p("/123");
  126. EXPECT_TRUE(p.IsValid());
  127. EXPECT_EQ(1u, p.GetTokenCount());
  128. EXPECT_STREQ("123", p.GetTokens()[0].name);
  129. EXPECT_EQ(123u, p.GetTokens()[0].index);
  130. }
  131. {
  132. // Invalid index (with leading zero)
  133. Pointer p("/01");
  134. EXPECT_TRUE(p.IsValid());
  135. EXPECT_EQ(1u, p.GetTokenCount());
  136. EXPECT_STREQ("01", p.GetTokens()[0].name);
  137. EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
  138. }
  139. if (sizeof(SizeType) == 4) {
  140. // Invalid index (overflow)
  141. Pointer p("/4294967296");
  142. EXPECT_TRUE(p.IsValid());
  143. EXPECT_EQ(1u, p.GetTokenCount());
  144. EXPECT_STREQ("4294967296", p.GetTokens()[0].name);
  145. EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
  146. }
  147. {
  148. // kPointerParseErrorTokenMustBeginWithSolidus
  149. Pointer p(" ");
  150. EXPECT_FALSE(p.IsValid());
  151. EXPECT_EQ(kPointerParseErrorTokenMustBeginWithSolidus, p.GetParseErrorCode());
  152. EXPECT_EQ(0u, p.GetParseErrorOffset());
  153. }
  154. {
  155. // kPointerParseErrorInvalidEscape
  156. Pointer p("/~");
  157. EXPECT_FALSE(p.IsValid());
  158. EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
  159. EXPECT_EQ(2u, p.GetParseErrorOffset());
  160. }
  161. {
  162. // kPointerParseErrorInvalidEscape
  163. Pointer p("/~2");
  164. EXPECT_FALSE(p.IsValid());
  165. EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
  166. EXPECT_EQ(2u, p.GetParseErrorOffset());
  167. }
  168. }
  169. TEST(Pointer, Parse_URIFragment) {
  170. {
  171. Pointer p("#");
  172. EXPECT_TRUE(p.IsValid());
  173. EXPECT_EQ(0u, p.GetTokenCount());
  174. }
  175. {
  176. Pointer p("#/foo");
  177. EXPECT_TRUE(p.IsValid());
  178. EXPECT_EQ(1u, p.GetTokenCount());
  179. EXPECT_EQ(3u, p.GetTokens()[0].length);
  180. EXPECT_STREQ("foo", p.GetTokens()[0].name);
  181. }
  182. {
  183. Pointer p("#/foo/0");
  184. EXPECT_TRUE(p.IsValid());
  185. EXPECT_EQ(2u, p.GetTokenCount());
  186. EXPECT_EQ(3u, p.GetTokens()[0].length);
  187. EXPECT_STREQ("foo", p.GetTokens()[0].name);
  188. EXPECT_EQ(1u, p.GetTokens()[1].length);
  189. EXPECT_STREQ("0", p.GetTokens()[1].name);
  190. EXPECT_EQ(0u, p.GetTokens()[1].index);
  191. }
  192. {
  193. // Unescape ~1
  194. Pointer p("#/a~1b");
  195. EXPECT_TRUE(p.IsValid());
  196. EXPECT_EQ(1u, p.GetTokenCount());
  197. EXPECT_EQ(3u, p.GetTokens()[0].length);
  198. EXPECT_STREQ("a/b", p.GetTokens()[0].name);
  199. }
  200. {
  201. // Unescape ~0
  202. Pointer p("#/m~0n");
  203. EXPECT_TRUE(p.IsValid());
  204. EXPECT_EQ(1u, p.GetTokenCount());
  205. EXPECT_EQ(3u, p.GetTokens()[0].length);
  206. EXPECT_STREQ("m~n", p.GetTokens()[0].name);
  207. }
  208. {
  209. // empty name
  210. Pointer p("#/");
  211. EXPECT_TRUE(p.IsValid());
  212. EXPECT_EQ(1u, p.GetTokenCount());
  213. EXPECT_EQ(0u, p.GetTokens()[0].length);
  214. EXPECT_STREQ("", p.GetTokens()[0].name);
  215. }
  216. {
  217. // empty and non-empty name
  218. Pointer p("#//a");
  219. EXPECT_TRUE(p.IsValid());
  220. EXPECT_EQ(2u, p.GetTokenCount());
  221. EXPECT_EQ(0u, p.GetTokens()[0].length);
  222. EXPECT_STREQ("", p.GetTokens()[0].name);
  223. EXPECT_EQ(1u, p.GetTokens()[1].length);
  224. EXPECT_STREQ("a", p.GetTokens()[1].name);
  225. }
  226. {
  227. // Null characters
  228. Pointer p("#/%00%00");
  229. EXPECT_TRUE(p.IsValid());
  230. EXPECT_EQ(1u, p.GetTokenCount());
  231. EXPECT_EQ(2u, p.GetTokens()[0].length);
  232. EXPECT_EQ('\0', p.GetTokens()[0].name[0]);
  233. EXPECT_EQ('\0', p.GetTokens()[0].name[1]);
  234. EXPECT_EQ('\0', p.GetTokens()[0].name[2]);
  235. }
  236. {
  237. // Percentage Escapes
  238. EXPECT_STREQ("c%d", Pointer("#/c%25d").GetTokens()[0].name);
  239. EXPECT_STREQ("e^f", Pointer("#/e%5Ef").GetTokens()[0].name);
  240. EXPECT_STREQ("g|h", Pointer("#/g%7Ch").GetTokens()[0].name);
  241. EXPECT_STREQ("i\\j", Pointer("#/i%5Cj").GetTokens()[0].name);
  242. EXPECT_STREQ("k\"l", Pointer("#/k%22l").GetTokens()[0].name);
  243. EXPECT_STREQ(" ", Pointer("#/%20").GetTokens()[0].name);
  244. }
  245. {
  246. // Valid index
  247. Pointer p("#/123");
  248. EXPECT_TRUE(p.IsValid());
  249. EXPECT_EQ(1u, p.GetTokenCount());
  250. EXPECT_STREQ("123", p.GetTokens()[0].name);
  251. EXPECT_EQ(123u, p.GetTokens()[0].index);
  252. }
  253. {
  254. // Invalid index (with leading zero)
  255. Pointer p("#/01");
  256. EXPECT_TRUE(p.IsValid());
  257. EXPECT_EQ(1u, p.GetTokenCount());
  258. EXPECT_STREQ("01", p.GetTokens()[0].name);
  259. EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
  260. }
  261. if (sizeof(SizeType) == 4) {
  262. // Invalid index (overflow)
  263. Pointer p("#/4294967296");
  264. EXPECT_TRUE(p.IsValid());
  265. EXPECT_EQ(1u, p.GetTokenCount());
  266. EXPECT_STREQ("4294967296", p.GetTokens()[0].name);
  267. EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
  268. }
  269. {
  270. // Decode UTF-8 perecent encoding to UTF-8
  271. Pointer p("#/%C2%A2");
  272. EXPECT_TRUE(p.IsValid());
  273. EXPECT_EQ(1u, p.GetTokenCount());
  274. EXPECT_STREQ("\xC2\xA2", p.GetTokens()[0].name);
  275. }
  276. {
  277. // Decode UTF-8 perecent encoding to UTF-16
  278. GenericPointer<GenericValue<UTF16<> > > p(L"#/%C2%A2");
  279. EXPECT_TRUE(p.IsValid());
  280. EXPECT_EQ(1u, p.GetTokenCount());
  281. EXPECT_EQ(static_cast<UTF16<>::Ch>(0x00A2), p.GetTokens()[0].name[0]);
  282. EXPECT_EQ(1u, p.GetTokens()[0].length);
  283. }
  284. {
  285. // Decode UTF-8 perecent encoding to UTF-16
  286. GenericPointer<GenericValue<UTF16<> > > p(L"#/%E2%82%AC");
  287. EXPECT_TRUE(p.IsValid());
  288. EXPECT_EQ(1u, p.GetTokenCount());
  289. EXPECT_EQ(static_cast<UTF16<>::Ch>(0x20AC), p.GetTokens()[0].name[0]);
  290. EXPECT_EQ(1u, p.GetTokens()[0].length);
  291. }
  292. {
  293. // kPointerParseErrorTokenMustBeginWithSolidus
  294. Pointer p("# ");
  295. EXPECT_FALSE(p.IsValid());
  296. EXPECT_EQ(kPointerParseErrorTokenMustBeginWithSolidus, p.GetParseErrorCode());
  297. EXPECT_EQ(1u, p.GetParseErrorOffset());
  298. }
  299. {
  300. // kPointerParseErrorInvalidEscape
  301. Pointer p("#/~");
  302. EXPECT_FALSE(p.IsValid());
  303. EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
  304. EXPECT_EQ(3u, p.GetParseErrorOffset());
  305. }
  306. {
  307. // kPointerParseErrorInvalidEscape
  308. Pointer p("#/~2");
  309. EXPECT_FALSE(p.IsValid());
  310. EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
  311. EXPECT_EQ(3u, p.GetParseErrorOffset());
  312. }
  313. {
  314. // kPointerParseErrorInvalidPercentEncoding
  315. Pointer p("#/%");
  316. EXPECT_FALSE(p.IsValid());
  317. EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
  318. EXPECT_EQ(2u, p.GetParseErrorOffset());
  319. }
  320. {
  321. // kPointerParseErrorInvalidPercentEncoding (invalid hex)
  322. Pointer p("#/%g0");
  323. EXPECT_FALSE(p.IsValid());
  324. EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
  325. EXPECT_EQ(2u, p.GetParseErrorOffset());
  326. }
  327. {
  328. // kPointerParseErrorInvalidPercentEncoding (invalid hex)
  329. Pointer p("#/%0g");
  330. EXPECT_FALSE(p.IsValid());
  331. EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
  332. EXPECT_EQ(2u, p.GetParseErrorOffset());
  333. }
  334. {
  335. // kPointerParseErrorInvalidPercentEncoding (incomplete UTF-8 sequence)
  336. Pointer p("#/%C2");
  337. EXPECT_FALSE(p.IsValid());
  338. EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
  339. EXPECT_EQ(2u, p.GetParseErrorOffset());
  340. }
  341. {
  342. // kPointerParseErrorCharacterMustPercentEncode
  343. Pointer p("#/ ");
  344. EXPECT_FALSE(p.IsValid());
  345. EXPECT_EQ(kPointerParseErrorCharacterMustPercentEncode, p.GetParseErrorCode());
  346. EXPECT_EQ(2u, p.GetParseErrorOffset());
  347. }
  348. {
  349. // kPointerParseErrorCharacterMustPercentEncode
  350. Pointer p("#/\n");
  351. EXPECT_FALSE(p.IsValid());
  352. EXPECT_EQ(kPointerParseErrorCharacterMustPercentEncode, p.GetParseErrorCode());
  353. EXPECT_EQ(2u, p.GetParseErrorOffset());
  354. }
  355. }
  356. TEST(Pointer, Stringify) {
  357. // Test by roundtrip
  358. const char* sources[] = {
  359. "",
  360. "/foo",
  361. "/foo/0",
  362. "/",
  363. "/a~1b",
  364. "/c%d",
  365. "/e^f",
  366. "/g|h",
  367. "/i\\j",
  368. "/k\"l",
  369. "/ ",
  370. "/m~0n",
  371. "/\xC2\xA2",
  372. "/\xE2\x82\xAC",
  373. "/\xF0\x9D\x84\x9E"
  374. };
  375. for (size_t i = 0; i < sizeof(sources) / sizeof(sources[0]); i++) {
  376. Pointer p(sources[i]);
  377. StringBuffer s;
  378. EXPECT_TRUE(p.Stringify(s));
  379. EXPECT_STREQ(sources[i], s.GetString());
  380. // Stringify to URI fragment
  381. StringBuffer s2;
  382. EXPECT_TRUE(p.StringifyUriFragment(s2));
  383. Pointer p2(s2.GetString(), s2.GetSize());
  384. EXPECT_TRUE(p2.IsValid());
  385. EXPECT_TRUE(p == p2);
  386. }
  387. {
  388. // Strigify to URI fragment with an invalid UTF-8 sequence
  389. Pointer p("/\xC2");
  390. StringBuffer s;
  391. EXPECT_FALSE(p.StringifyUriFragment(s));
  392. }
  393. }
  394. // Construct a Pointer with static tokens, no dynamic allocation involved.
  395. #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }
  396. #define INDEX(i) { #i, sizeof(#i) - 1, i }
  397. static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(0) }; // equivalent to "/foo/0"
  398. #undef NAME
  399. #undef INDEX
  400. TEST(Pointer, ConstructorWithToken) {
  401. Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
  402. EXPECT_TRUE(p.IsValid());
  403. EXPECT_EQ(2u, p.GetTokenCount());
  404. EXPECT_EQ(3u, p.GetTokens()[0].length);
  405. EXPECT_STREQ("foo", p.GetTokens()[0].name);
  406. EXPECT_EQ(1u, p.GetTokens()[1].length);
  407. EXPECT_STREQ("0", p.GetTokens()[1].name);
  408. EXPECT_EQ(0u, p.GetTokens()[1].index);
  409. }
  410. TEST(Pointer, CopyConstructor) {
  411. {
  412. Pointer p("/foo/0");
  413. Pointer q(p);
  414. EXPECT_TRUE(q.IsValid());
  415. EXPECT_EQ(2u, q.GetTokenCount());
  416. EXPECT_EQ(3u, q.GetTokens()[0].length);
  417. EXPECT_STREQ("foo", q.GetTokens()[0].name);
  418. EXPECT_EQ(1u, q.GetTokens()[1].length);
  419. EXPECT_STREQ("0", q.GetTokens()[1].name);
  420. EXPECT_EQ(0u, q.GetTokens()[1].index);
  421. }
  422. // Static tokens
  423. {
  424. Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
  425. Pointer q(p);
  426. EXPECT_TRUE(q.IsValid());
  427. EXPECT_EQ(2u, q.GetTokenCount());
  428. EXPECT_EQ(3u, q.GetTokens()[0].length);
  429. EXPECT_STREQ("foo", q.GetTokens()[0].name);
  430. EXPECT_EQ(1u, q.GetTokens()[1].length);
  431. EXPECT_STREQ("0", q.GetTokens()[1].name);
  432. EXPECT_EQ(0u, q.GetTokens()[1].index);
  433. }
  434. }
  435. TEST(Pointer, Assignment) {
  436. {
  437. Pointer p("/foo/0");
  438. Pointer q;
  439. q = p;
  440. EXPECT_TRUE(q.IsValid());
  441. EXPECT_EQ(2u, q.GetTokenCount());
  442. EXPECT_EQ(3u, q.GetTokens()[0].length);
  443. EXPECT_STREQ("foo", q.GetTokens()[0].name);
  444. EXPECT_EQ(1u, q.GetTokens()[1].length);
  445. EXPECT_STREQ("0", q.GetTokens()[1].name);
  446. EXPECT_EQ(0u, q.GetTokens()[1].index);
  447. q = q;
  448. EXPECT_TRUE(q.IsValid());
  449. EXPECT_EQ(2u, q.GetTokenCount());
  450. EXPECT_EQ(3u, q.GetTokens()[0].length);
  451. EXPECT_STREQ("foo", q.GetTokens()[0].name);
  452. EXPECT_EQ(1u, q.GetTokens()[1].length);
  453. EXPECT_STREQ("0", q.GetTokens()[1].name);
  454. EXPECT_EQ(0u, q.GetTokens()[1].index);
  455. }
  456. // Static tokens
  457. {
  458. Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
  459. Pointer q;
  460. q = p;
  461. EXPECT_TRUE(q.IsValid());
  462. EXPECT_EQ(2u, q.GetTokenCount());
  463. EXPECT_EQ(3u, q.GetTokens()[0].length);
  464. EXPECT_STREQ("foo", q.GetTokens()[0].name);
  465. EXPECT_EQ(1u, q.GetTokens()[1].length);
  466. EXPECT_STREQ("0", q.GetTokens()[1].name);
  467. EXPECT_EQ(0u, q.GetTokens()[1].index);
  468. }
  469. }
  470. TEST(Pointer, Append) {
  471. {
  472. Pointer p;
  473. Pointer q = p.Append("foo");
  474. EXPECT_TRUE(Pointer("/foo") == q);
  475. q = q.Append(1234);
  476. EXPECT_TRUE(Pointer("/foo/1234") == q);
  477. q = q.Append("");
  478. EXPECT_TRUE(Pointer("/foo/1234/") == q);
  479. }
  480. {
  481. Pointer p;
  482. Pointer q = p.Append(Value("foo").Move());
  483. EXPECT_TRUE(Pointer("/foo") == q);
  484. q = q.Append(Value(1234).Move());
  485. EXPECT_TRUE(Pointer("/foo/1234") == q);
  486. q = q.Append(Value(kStringType).Move());
  487. EXPECT_TRUE(Pointer("/foo/1234/") == q);
  488. }
  489. #if RAPIDJSON_HAS_STDSTRING
  490. {
  491. Pointer p;
  492. Pointer q = p.Append(std::string("foo"));
  493. EXPECT_TRUE(Pointer("/foo") == q);
  494. }
  495. #endif
  496. }
  497. TEST(Pointer, Equality) {
  498. EXPECT_TRUE(Pointer("/foo/0") == Pointer("/foo/0"));
  499. EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/1"));
  500. EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/0/1"));
  501. EXPECT_FALSE(Pointer("/foo/0") == Pointer("a"));
  502. EXPECT_FALSE(Pointer("a") == Pointer("a")); // Invalid always not equal
  503. }
  504. TEST(Pointer, Inequality) {
  505. EXPECT_FALSE(Pointer("/foo/0") != Pointer("/foo/0"));
  506. EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/1"));
  507. EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/0/1"));
  508. EXPECT_TRUE(Pointer("/foo/0") != Pointer("a"));
  509. EXPECT_TRUE(Pointer("a") != Pointer("a")); // Invalid always not equal
  510. }
  511. TEST(Pointer, Create) {
  512. Document d;
  513. {
  514. Value* v = &Pointer("").Create(d, d.GetAllocator());
  515. EXPECT_EQ(&d, v);
  516. }
  517. {
  518. Value* v = &Pointer("/foo").Create(d, d.GetAllocator());
  519. EXPECT_EQ(&d["foo"], v);
  520. }
  521. {
  522. Value* v = &Pointer("/foo/0").Create(d, d.GetAllocator());
  523. EXPECT_EQ(&d["foo"][0], v);
  524. }
  525. {
  526. Value* v = &Pointer("/foo/-").Create(d, d.GetAllocator());
  527. EXPECT_EQ(&d["foo"][1], v);
  528. }
  529. {
  530. Value* v = &Pointer("/foo/-/-").Create(d, d.GetAllocator());
  531. // "foo/-" is a newly created null value x.
  532. // "foo/-/-" finds that x is not an array, it converts x to empty object
  533. // and treats - as "-" member name
  534. EXPECT_EQ(&d["foo"][2]["-"], v);
  535. }
  536. {
  537. // Document with no allocator
  538. Value* v = &Pointer("/foo/-").Create(d);
  539. EXPECT_EQ(&d["foo"][3], v);
  540. }
  541. {
  542. // Value (not document) must give allocator
  543. Value* v = &Pointer("/-").Create(d["foo"], d.GetAllocator());
  544. EXPECT_EQ(&d["foo"][4], v);
  545. }
  546. }
  547. TEST(Pointer, Get) {
  548. Document d;
  549. d.Parse(kJson);
  550. EXPECT_EQ(&d, Pointer("").Get(d));
  551. EXPECT_EQ(&d["foo"], Pointer("/foo").Get(d));
  552. EXPECT_EQ(&d["foo"][0], Pointer("/foo/0").Get(d));
  553. EXPECT_EQ(&d[""], Pointer("/").Get(d));
  554. EXPECT_EQ(&d["a/b"], Pointer("/a~1b").Get(d));
  555. EXPECT_EQ(&d["c%d"], Pointer("/c%d").Get(d));
  556. EXPECT_EQ(&d["e^f"], Pointer("/e^f").Get(d));
  557. EXPECT_EQ(&d["g|h"], Pointer("/g|h").Get(d));
  558. EXPECT_EQ(&d["i\\j"], Pointer("/i\\j").Get(d));
  559. EXPECT_EQ(&d["k\"l"], Pointer("/k\"l").Get(d));
  560. EXPECT_EQ(&d[" "], Pointer("/ ").Get(d));
  561. EXPECT_EQ(&d["m~n"], Pointer("/m~0n").Get(d));
  562. EXPECT_TRUE(Pointer("/abc").Get(d) == 0);
  563. size_t unresolvedTokenIndex;
  564. EXPECT_TRUE(Pointer("/foo/2").Get(d, &unresolvedTokenIndex) == 0); // Out of boundary
  565. EXPECT_EQ(1, unresolvedTokenIndex);
  566. EXPECT_TRUE(Pointer("/foo/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
  567. EXPECT_EQ(1, unresolvedTokenIndex);
  568. EXPECT_TRUE(Pointer("/foo/0/0").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  569. EXPECT_EQ(2, unresolvedTokenIndex);
  570. EXPECT_TRUE(Pointer("/foo/0/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  571. EXPECT_EQ(2, unresolvedTokenIndex);
  572. }
  573. TEST(Pointer, GetWithDefault) {
  574. Document d;
  575. d.Parse(kJson);
  576. // Value version
  577. Document::AllocatorType& a = d.GetAllocator();
  578. const Value v("qux");
  579. EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v, a));
  580. EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v, a));
  581. EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v, a));
  582. EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move(), a));
  583. EXPECT_STREQ("last", d["foo"][3].GetString());
  584. EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, Value().Move(), a).IsNull());
  585. EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, "x", a).IsNull());
  586. // Generic version
  587. EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -1, a).GetInt());
  588. EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -2, a).GetInt());
  589. EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x87654321, a).GetUint());
  590. EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x12345678, a).GetUint());
  591. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  592. EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64, a).GetInt64());
  593. EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64 + 1, a).GetInt64());
  594. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  595. EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64, a).GetUint64());
  596. EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64 - 1, a).GetUint64());
  597. EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, true, a).IsTrue());
  598. EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, false, a).IsTrue());
  599. EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, false, a).IsFalse());
  600. EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, true, a).IsFalse());
  601. // StringRef version
  602. EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d, "Hello", a).GetString());
  603. // Copy string version
  604. {
  605. char buffer[256];
  606. strcpy(buffer, "World");
  607. EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d, buffer, a).GetString());
  608. memset(buffer, 0, sizeof(buffer));
  609. }
  610. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  611. #if RAPIDJSON_HAS_STDSTRING
  612. EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d, std::string("C++"), a).GetString());
  613. #endif
  614. }
  615. TEST(Pointer, GetWithDefault_NoAllocator) {
  616. Document d;
  617. d.Parse(kJson);
  618. // Value version
  619. const Value v("qux");
  620. EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v));
  621. EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v));
  622. EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v));
  623. EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move()));
  624. EXPECT_STREQ("last", d["foo"][3].GetString());
  625. EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, Value().Move()).IsNull());
  626. EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, "x").IsNull());
  627. // Generic version
  628. EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -1).GetInt());
  629. EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -2).GetInt());
  630. EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x87654321).GetUint());
  631. EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x12345678).GetUint());
  632. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  633. EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64).GetInt64());
  634. EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64 + 1).GetInt64());
  635. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  636. EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64).GetUint64());
  637. EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64 - 1).GetUint64());
  638. EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, true).IsTrue());
  639. EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, false).IsTrue());
  640. EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, false).IsFalse());
  641. EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, true).IsFalse());
  642. // StringRef version
  643. EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d, "Hello").GetString());
  644. // Copy string version
  645. {
  646. char buffer[256];
  647. strcpy(buffer, "World");
  648. EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d, buffer).GetString());
  649. memset(buffer, 0, sizeof(buffer));
  650. }
  651. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  652. #if RAPIDJSON_HAS_STDSTRING
  653. EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d, std::string("C++")).GetString());
  654. #endif
  655. }
  656. TEST(Pointer, Set) {
  657. Document d;
  658. d.Parse(kJson);
  659. Document::AllocatorType& a = d.GetAllocator();
  660. // Value version
  661. Pointer("/foo/0").Set(d, Value(123).Move(), a);
  662. EXPECT_EQ(123, d["foo"][0].GetInt());
  663. Pointer("/foo/-").Set(d, Value(456).Move(), a);
  664. EXPECT_EQ(456, d["foo"][2].GetInt());
  665. Pointer("/foo/null").Set(d, Value().Move(), a);
  666. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  667. // Const Value version
  668. const Value foo(d["foo"], a);
  669. Pointer("/clone").Set(d, foo, a);
  670. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  671. // Generic version
  672. Pointer("/foo/int").Set(d, -1, a);
  673. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  674. Pointer("/foo/uint").Set(d, 0x87654321, a);
  675. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  676. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  677. Pointer("/foo/int64").Set(d, i64, a);
  678. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  679. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  680. Pointer("/foo/uint64").Set(d, u64, a);
  681. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  682. Pointer("/foo/true").Set(d, true, a);
  683. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  684. Pointer("/foo/false").Set(d, false, a);
  685. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  686. // StringRef version
  687. Pointer("/foo/hello").Set(d, "Hello", a);
  688. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  689. // Copy string version
  690. {
  691. char buffer[256];
  692. strcpy(buffer, "World");
  693. Pointer("/foo/world").Set(d, buffer, a);
  694. memset(buffer, 0, sizeof(buffer));
  695. }
  696. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  697. #if RAPIDJSON_HAS_STDSTRING
  698. Pointer("/foo/c++").Set(d, std::string("C++"), a);
  699. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  700. #endif
  701. }
  702. TEST(Pointer, Set_NoAllocator) {
  703. Document d;
  704. d.Parse(kJson);
  705. // Value version
  706. Pointer("/foo/0").Set(d, Value(123).Move());
  707. EXPECT_EQ(123, d["foo"][0].GetInt());
  708. Pointer("/foo/-").Set(d, Value(456).Move());
  709. EXPECT_EQ(456, d["foo"][2].GetInt());
  710. Pointer("/foo/null").Set(d, Value().Move());
  711. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  712. // Const Value version
  713. const Value foo(d["foo"], d.GetAllocator());
  714. Pointer("/clone").Set(d, foo);
  715. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  716. // Generic version
  717. Pointer("/foo/int").Set(d, -1);
  718. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  719. Pointer("/foo/uint").Set(d, 0x87654321);
  720. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  721. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  722. Pointer("/foo/int64").Set(d, i64);
  723. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  724. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  725. Pointer("/foo/uint64").Set(d, u64);
  726. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  727. Pointer("/foo/true").Set(d, true);
  728. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  729. Pointer("/foo/false").Set(d, false);
  730. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  731. // StringRef version
  732. Pointer("/foo/hello").Set(d, "Hello");
  733. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  734. // Copy string version
  735. {
  736. char buffer[256];
  737. strcpy(buffer, "World");
  738. Pointer("/foo/world").Set(d, buffer);
  739. memset(buffer, 0, sizeof(buffer));
  740. }
  741. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  742. #if RAPIDJSON_HAS_STDSTRING
  743. Pointer("/foo/c++").Set(d, std::string("C++"));
  744. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  745. #endif
  746. }
  747. TEST(Pointer, Swap) {
  748. Document d;
  749. d.Parse(kJson);
  750. Document::AllocatorType& a = d.GetAllocator();
  751. Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d), a);
  752. EXPECT_STREQ("baz", d["foo"][0].GetString());
  753. EXPECT_STREQ("bar", d["foo"][1].GetString());
  754. }
  755. TEST(Pointer, Swap_NoAllocator) {
  756. Document d;
  757. d.Parse(kJson);
  758. Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d));
  759. EXPECT_STREQ("baz", d["foo"][0].GetString());
  760. EXPECT_STREQ("bar", d["foo"][1].GetString());
  761. }
  762. TEST(Pointer, Erase) {
  763. Document d;
  764. d.Parse(kJson);
  765. EXPECT_FALSE(Pointer("").Erase(d));
  766. EXPECT_FALSE(Pointer("/nonexist").Erase(d));
  767. EXPECT_FALSE(Pointer("/nonexist/nonexist").Erase(d));
  768. EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
  769. EXPECT_FALSE(Pointer("/foo/nonexist/nonexist").Erase(d));
  770. EXPECT_FALSE(Pointer("/foo/0/nonexist").Erase(d));
  771. EXPECT_FALSE(Pointer("/foo/0/nonexist/nonexist").Erase(d));
  772. EXPECT_FALSE(Pointer("/foo/2/nonexist").Erase(d));
  773. EXPECT_TRUE(Pointer("/foo/0").Erase(d));
  774. EXPECT_EQ(1u, d["foo"].Size());
  775. EXPECT_STREQ("baz", d["foo"][0].GetString());
  776. EXPECT_TRUE(Pointer("/foo/0").Erase(d));
  777. EXPECT_TRUE(d["foo"].Empty());
  778. EXPECT_TRUE(Pointer("/foo").Erase(d));
  779. EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
  780. Pointer("/a/0/b/0").Create(d);
  781. EXPECT_TRUE(Pointer("/a/0/b/0").Get(d) != 0);
  782. EXPECT_TRUE(Pointer("/a/0/b/0").Erase(d));
  783. EXPECT_TRUE(Pointer("/a/0/b/0").Get(d) == 0);
  784. EXPECT_TRUE(Pointer("/a/0/b").Get(d) != 0);
  785. EXPECT_TRUE(Pointer("/a/0/b").Erase(d));
  786. EXPECT_TRUE(Pointer("/a/0/b").Get(d) == 0);
  787. EXPECT_TRUE(Pointer("/a/0").Get(d) != 0);
  788. EXPECT_TRUE(Pointer("/a/0").Erase(d));
  789. EXPECT_TRUE(Pointer("/a/0").Get(d) == 0);
  790. EXPECT_TRUE(Pointer("/a").Get(d) != 0);
  791. EXPECT_TRUE(Pointer("/a").Erase(d));
  792. EXPECT_TRUE(Pointer("/a").Get(d) == 0);
  793. }
  794. TEST(Pointer, CreateValueByPointer) {
  795. Document d;
  796. Document::AllocatorType& a = d.GetAllocator();
  797. {
  798. Value& v = CreateValueByPointer(d, Pointer("/foo/0"), a);
  799. EXPECT_EQ(&d["foo"][0], &v);
  800. }
  801. {
  802. Value& v = CreateValueByPointer(d, "/foo/1", a);
  803. EXPECT_EQ(&d["foo"][1], &v);
  804. }
  805. }
  806. TEST(Pointer, CreateValueByPointer_NoAllocator) {
  807. Document d;
  808. {
  809. Value& v = CreateValueByPointer(d, Pointer("/foo/0"));
  810. EXPECT_EQ(&d["foo"][0], &v);
  811. }
  812. {
  813. Value& v = CreateValueByPointer(d, "/foo/1");
  814. EXPECT_EQ(&d["foo"][1], &v);
  815. }
  816. }
  817. TEST(Pointer, GetValueByPointer) {
  818. Document d;
  819. d.Parse(kJson);
  820. EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, Pointer("/foo/0")));
  821. EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, "/foo/0"));
  822. size_t unresolvedTokenIndex;
  823. EXPECT_TRUE(GetValueByPointer(d, "/foo/2", &unresolvedTokenIndex) == 0); // Out of boundary
  824. EXPECT_EQ(1, unresolvedTokenIndex);
  825. EXPECT_TRUE(GetValueByPointer(d, "/foo/a", &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
  826. EXPECT_EQ(1, unresolvedTokenIndex);
  827. EXPECT_TRUE(GetValueByPointer(d, "/foo/0/0", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  828. EXPECT_EQ(2, unresolvedTokenIndex);
  829. EXPECT_TRUE(GetValueByPointer(d, "/foo/0/a", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  830. EXPECT_EQ(2, unresolvedTokenIndex);
  831. // const version
  832. const Value& v = d;
  833. EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, Pointer("/foo/0")));
  834. EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, "/foo/0"));
  835. EXPECT_TRUE(GetValueByPointer(v, "/foo/2", &unresolvedTokenIndex) == 0); // Out of boundary
  836. EXPECT_EQ(1, unresolvedTokenIndex);
  837. EXPECT_TRUE(GetValueByPointer(v, "/foo/a", &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
  838. EXPECT_EQ(1, unresolvedTokenIndex);
  839. EXPECT_TRUE(GetValueByPointer(v, "/foo/0/0", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  840. EXPECT_EQ(2, unresolvedTokenIndex);
  841. EXPECT_TRUE(GetValueByPointer(v, "/foo/0/a", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  842. EXPECT_EQ(2, unresolvedTokenIndex);
  843. }
  844. TEST(Pointer, GetValueByPointerWithDefault_Pointer) {
  845. Document d;
  846. d.Parse(kJson);
  847. Document::AllocatorType& a = d.GetAllocator();
  848. const Value v("qux");
  849. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
  850. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
  851. EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, Pointer("/foo/1"), v, a));
  852. EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, Pointer("/foo/2"), v, a));
  853. EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, Pointer("/foo/-"), Value("last").Move(), a));
  854. EXPECT_STREQ("last", d["foo"][3].GetString());
  855. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), Value().Move(), a).IsNull());
  856. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), "x", a).IsNull());
  857. // Generic version
  858. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -1, a).GetInt());
  859. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -2, a).GetInt());
  860. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x87654321, a).GetUint());
  861. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x12345678, a).GetUint());
  862. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  863. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64, a).GetInt64());
  864. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64 + 1, a).GetInt64());
  865. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  866. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64, a).GetUint64());
  867. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64 - 1, a).GetUint64());
  868. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), true, a).IsTrue());
  869. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), false, a).IsTrue());
  870. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), false, a).IsFalse());
  871. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), true, a).IsFalse());
  872. // StringRef version
  873. EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, Pointer("/foo/hello"), "Hello", a).GetString());
  874. // Copy string version
  875. {
  876. char buffer[256];
  877. strcpy(buffer, "World");
  878. EXPECT_STREQ("World", GetValueByPointerWithDefault(d, Pointer("/foo/world"), buffer, a).GetString());
  879. memset(buffer, 0, sizeof(buffer));
  880. }
  881. EXPECT_STREQ("World", GetValueByPointer(d, Pointer("/foo/world"))->GetString());
  882. #if RAPIDJSON_HAS_STDSTRING
  883. EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++"), a).GetString());
  884. #endif
  885. }
  886. TEST(Pointer, GetValueByPointerWithDefault_String) {
  887. Document d;
  888. d.Parse(kJson);
  889. Document::AllocatorType& a = d.GetAllocator();
  890. const Value v("qux");
  891. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v, a));
  892. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v, a));
  893. EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v, a));
  894. EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, "/foo/2", v, a));
  895. EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, "/foo/-", Value("last").Move(), a));
  896. EXPECT_STREQ("last", d["foo"][3].GetString());
  897. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", Value().Move(), a).IsNull());
  898. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", "x", a).IsNull());
  899. // Generic version
  900. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -1, a).GetInt());
  901. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -2, a).GetInt());
  902. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x87654321, a).GetUint());
  903. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x12345678, a).GetUint());
  904. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  905. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64, a).GetInt64());
  906. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64 + 1, a).GetInt64());
  907. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  908. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64, a).GetUint64());
  909. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64 - 1, a).GetUint64());
  910. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", true, a).IsTrue());
  911. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", false, a).IsTrue());
  912. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", false, a).IsFalse());
  913. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", true, a).IsFalse());
  914. // StringRef version
  915. EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, "/foo/hello", "Hello", a).GetString());
  916. // Copy string version
  917. {
  918. char buffer[256];
  919. strcpy(buffer, "World");
  920. EXPECT_STREQ("World", GetValueByPointerWithDefault(d, "/foo/world", buffer, a).GetString());
  921. memset(buffer, 0, sizeof(buffer));
  922. }
  923. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  924. #if RAPIDJSON_HAS_STDSTRING
  925. EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, "/foo/C++", std::string("C++"), a).GetString());
  926. #endif
  927. }
  928. TEST(Pointer, GetValueByPointerWithDefault_Pointer_NoAllocator) {
  929. Document d;
  930. d.Parse(kJson);
  931. const Value v("qux");
  932. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v));
  933. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v));
  934. EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, Pointer("/foo/1"), v));
  935. EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, Pointer("/foo/2"), v));
  936. EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, Pointer("/foo/-"), Value("last").Move()));
  937. EXPECT_STREQ("last", d["foo"][3].GetString());
  938. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), Value().Move()).IsNull());
  939. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), "x").IsNull());
  940. // Generic version
  941. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -1).GetInt());
  942. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -2).GetInt());
  943. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x87654321).GetUint());
  944. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x12345678).GetUint());
  945. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  946. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64).GetInt64());
  947. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64 + 1).GetInt64());
  948. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  949. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64).GetUint64());
  950. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64 - 1).GetUint64());
  951. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), true).IsTrue());
  952. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), false).IsTrue());
  953. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), false).IsFalse());
  954. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), true).IsFalse());
  955. // StringRef version
  956. EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, Pointer("/foo/hello"), "Hello").GetString());
  957. // Copy string version
  958. {
  959. char buffer[256];
  960. strcpy(buffer, "World");
  961. EXPECT_STREQ("World", GetValueByPointerWithDefault(d, Pointer("/foo/world"), buffer).GetString());
  962. memset(buffer, 0, sizeof(buffer));
  963. }
  964. EXPECT_STREQ("World", GetValueByPointer(d, Pointer("/foo/world"))->GetString());
  965. #if RAPIDJSON_HAS_STDSTRING
  966. EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++")).GetString());
  967. #endif
  968. }
  969. TEST(Pointer, GetValueByPointerWithDefault_String_NoAllocator) {
  970. Document d;
  971. d.Parse(kJson);
  972. const Value v("qux");
  973. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v));
  974. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v));
  975. EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v));
  976. EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, "/foo/2", v));
  977. EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, "/foo/-", Value("last").Move()));
  978. EXPECT_STREQ("last", d["foo"][3].GetString());
  979. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", Value().Move()).IsNull());
  980. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", "x").IsNull());
  981. // Generic version
  982. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -1).GetInt());
  983. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -2).GetInt());
  984. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x87654321).GetUint());
  985. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x12345678).GetUint());
  986. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  987. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64).GetInt64());
  988. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64 + 1).GetInt64());
  989. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  990. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64).GetUint64());
  991. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64 - 1).GetUint64());
  992. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", true).IsTrue());
  993. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", false).IsTrue());
  994. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", false).IsFalse());
  995. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", true).IsFalse());
  996. // StringRef version
  997. EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, "/foo/hello", "Hello").GetString());
  998. // Copy string version
  999. {
  1000. char buffer[256];
  1001. strcpy(buffer, "World");
  1002. EXPECT_STREQ("World", GetValueByPointerWithDefault(d, "/foo/world", buffer).GetString());
  1003. memset(buffer, 0, sizeof(buffer));
  1004. }
  1005. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  1006. #if RAPIDJSON_HAS_STDSTRING
  1007. EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++")).GetString());
  1008. #endif
  1009. }
  1010. TEST(Pointer, SetValueByPointer_Pointer) {
  1011. Document d;
  1012. d.Parse(kJson);
  1013. Document::AllocatorType& a = d.GetAllocator();
  1014. // Value version
  1015. SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move(), a);
  1016. EXPECT_EQ(123, d["foo"][0].GetInt());
  1017. SetValueByPointer(d, Pointer("/foo/null"), Value().Move(), a);
  1018. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  1019. // Const Value version
  1020. const Value foo(d["foo"], d.GetAllocator());
  1021. SetValueByPointer(d, Pointer("/clone"), foo, a);
  1022. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  1023. // Generic version
  1024. SetValueByPointer(d, Pointer("/foo/int"), -1, a);
  1025. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  1026. SetValueByPointer(d, Pointer("/foo/uint"), 0x87654321, a);
  1027. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  1028. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  1029. SetValueByPointer(d, Pointer("/foo/int64"), i64, a);
  1030. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  1031. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  1032. SetValueByPointer(d, Pointer("/foo/uint64"), u64, a);
  1033. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  1034. SetValueByPointer(d, Pointer("/foo/true"), true, a);
  1035. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  1036. SetValueByPointer(d, Pointer("/foo/false"), false, a);
  1037. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  1038. // StringRef version
  1039. SetValueByPointer(d, Pointer("/foo/hello"), "Hello", a);
  1040. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  1041. // Copy string version
  1042. {
  1043. char buffer[256];
  1044. strcpy(buffer, "World");
  1045. SetValueByPointer(d, Pointer("/foo/world"), buffer, a);
  1046. memset(buffer, 0, sizeof(buffer));
  1047. }
  1048. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  1049. #if RAPIDJSON_HAS_STDSTRING
  1050. SetValueByPointer(d, Pointer("/foo/c++"), std::string("C++"), a);
  1051. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  1052. #endif
  1053. }
  1054. TEST(Pointer, SetValueByPointer_String) {
  1055. Document d;
  1056. d.Parse(kJson);
  1057. Document::AllocatorType& a = d.GetAllocator();
  1058. // Value version
  1059. SetValueByPointer(d, "/foo/0", Value(123).Move(), a);
  1060. EXPECT_EQ(123, d["foo"][0].GetInt());
  1061. SetValueByPointer(d, "/foo/null", Value().Move(), a);
  1062. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  1063. // Const Value version
  1064. const Value foo(d["foo"], d.GetAllocator());
  1065. SetValueByPointer(d, "/clone", foo, a);
  1066. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  1067. // Generic version
  1068. SetValueByPointer(d, "/foo/int", -1, a);
  1069. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  1070. SetValueByPointer(d, "/foo/uint", 0x87654321, a);
  1071. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  1072. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  1073. SetValueByPointer(d, "/foo/int64", i64, a);
  1074. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  1075. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  1076. SetValueByPointer(d, "/foo/uint64", u64, a);
  1077. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  1078. SetValueByPointer(d, "/foo/true", true, a);
  1079. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  1080. SetValueByPointer(d, "/foo/false", false, a);
  1081. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  1082. // StringRef version
  1083. SetValueByPointer(d, "/foo/hello", "Hello", a);
  1084. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  1085. // Copy string version
  1086. {
  1087. char buffer[256];
  1088. strcpy(buffer, "World");
  1089. SetValueByPointer(d, "/foo/world", buffer, a);
  1090. memset(buffer, 0, sizeof(buffer));
  1091. }
  1092. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  1093. #if RAPIDJSON_HAS_STDSTRING
  1094. SetValueByPointer(d, "/foo/c++", std::string("C++"), a);
  1095. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  1096. #endif
  1097. }
  1098. TEST(Pointer, SetValueByPointer_Pointer_NoAllocator) {
  1099. Document d;
  1100. d.Parse(kJson);
  1101. // Value version
  1102. SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move());
  1103. EXPECT_EQ(123, d["foo"][0].GetInt());
  1104. SetValueByPointer(d, Pointer("/foo/null"), Value().Move());
  1105. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  1106. // Const Value version
  1107. const Value foo(d["foo"], d.GetAllocator());
  1108. SetValueByPointer(d, Pointer("/clone"), foo);
  1109. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  1110. // Generic version
  1111. SetValueByPointer(d, Pointer("/foo/int"), -1);
  1112. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  1113. SetValueByPointer(d, Pointer("/foo/uint"), 0x87654321);
  1114. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  1115. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  1116. SetValueByPointer(d, Pointer("/foo/int64"), i64);
  1117. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  1118. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  1119. SetValueByPointer(d, Pointer("/foo/uint64"), u64);
  1120. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  1121. SetValueByPointer(d, Pointer("/foo/true"), true);
  1122. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  1123. SetValueByPointer(d, Pointer("/foo/false"), false);
  1124. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  1125. // StringRef version
  1126. SetValueByPointer(d, Pointer("/foo/hello"), "Hello");
  1127. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  1128. // Copy string version
  1129. {
  1130. char buffer[256];
  1131. strcpy(buffer, "World");
  1132. SetValueByPointer(d, Pointer("/foo/world"), buffer);
  1133. memset(buffer, 0, sizeof(buffer));
  1134. }
  1135. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  1136. #if RAPIDJSON_HAS_STDSTRING
  1137. SetValueByPointer(d, Pointer("/foo/c++"), std::string("C++"));
  1138. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  1139. #endif
  1140. }
  1141. TEST(Pointer, SetValueByPointer_String_NoAllocator) {
  1142. Document d;
  1143. d.Parse(kJson);
  1144. // Value version
  1145. SetValueByPointer(d, "/foo/0", Value(123).Move());
  1146. EXPECT_EQ(123, d["foo"][0].GetInt());
  1147. SetValueByPointer(d, "/foo/null", Value().Move());
  1148. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  1149. // Const Value version
  1150. const Value foo(d["foo"], d.GetAllocator());
  1151. SetValueByPointer(d, "/clone", foo);
  1152. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  1153. // Generic version
  1154. SetValueByPointer(d, "/foo/int", -1);
  1155. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  1156. SetValueByPointer(d, "/foo/uint", 0x87654321);
  1157. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  1158. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  1159. SetValueByPointer(d, "/foo/int64", i64);
  1160. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  1161. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  1162. SetValueByPointer(d, "/foo/uint64", u64);
  1163. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  1164. SetValueByPointer(d, "/foo/true", true);
  1165. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  1166. SetValueByPointer(d, "/foo/false", false);
  1167. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  1168. // StringRef version
  1169. SetValueByPointer(d, "/foo/hello", "Hello");
  1170. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  1171. // Copy string version
  1172. {
  1173. char buffer[256];
  1174. strcpy(buffer, "World");
  1175. SetValueByPointer(d, "/foo/world", buffer);
  1176. memset(buffer, 0, sizeof(buffer));
  1177. }
  1178. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  1179. #if RAPIDJSON_HAS_STDSTRING
  1180. SetValueByPointer(d, "/foo/c++", std::string("C++"));
  1181. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  1182. #endif
  1183. }
  1184. TEST(Pointer, SwapValueByPointer) {
  1185. Document d;
  1186. d.Parse(kJson);
  1187. Document::AllocatorType& a = d.GetAllocator();
  1188. SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"), a);
  1189. EXPECT_STREQ("baz", d["foo"][0].GetString());
  1190. EXPECT_STREQ("bar", d["foo"][1].GetString());
  1191. SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"), a);
  1192. EXPECT_STREQ("bar", d["foo"][0].GetString());
  1193. EXPECT_STREQ("baz", d["foo"][1].GetString());
  1194. }
  1195. TEST(Pointer, SwapValueByPointer_NoAllocator) {
  1196. Document d;
  1197. d.Parse(kJson);
  1198. SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"));
  1199. EXPECT_STREQ("baz", d["foo"][0].GetString());
  1200. EXPECT_STREQ("bar", d["foo"][1].GetString());
  1201. SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"));
  1202. EXPECT_STREQ("bar", d["foo"][0].GetString());
  1203. EXPECT_STREQ("baz", d["foo"][1].GetString());
  1204. }
  1205. TEST(Pointer, EraseValueByPointer_Pointer) {
  1206. Document d;
  1207. d.Parse(kJson);
  1208. EXPECT_FALSE(EraseValueByPointer(d, Pointer("")));
  1209. EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
  1210. EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo/0")));
  1211. EXPECT_EQ(1u, d["foo"].Size());
  1212. EXPECT_STREQ("baz", d["foo"][0].GetString());
  1213. EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo/0")));
  1214. EXPECT_TRUE(d["foo"].Empty());
  1215. EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo")));
  1216. EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
  1217. }
  1218. TEST(Pointer, EraseValueByPointer_String) {
  1219. Document d;
  1220. d.Parse(kJson);
  1221. EXPECT_FALSE(EraseValueByPointer(d, ""));
  1222. EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
  1223. EXPECT_TRUE(EraseValueByPointer(d, "/foo/0"));
  1224. EXPECT_EQ(1u, d["foo"].Size());
  1225. EXPECT_STREQ("baz", d["foo"][0].GetString());
  1226. EXPECT_TRUE(EraseValueByPointer(d, "/foo/0"));
  1227. EXPECT_TRUE(d["foo"].Empty());
  1228. EXPECT_TRUE(EraseValueByPointer(d, "/foo"));
  1229. EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
  1230. }
  1231. TEST(Pointer, Ambiguity) {
  1232. {
  1233. Document d;
  1234. d.Parse("{\"0\" : [123]}");
  1235. EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
  1236. Pointer("/0/a").Set(d, 456); // Change array [123] to object {456}
  1237. EXPECT_EQ(456, Pointer("/0/a").Get(d)->GetInt());
  1238. }
  1239. {
  1240. Document d;
  1241. EXPECT_FALSE(d.Parse("[{\"0\": 123}]").HasParseError());
  1242. EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
  1243. Pointer("/0/1").Set(d, 456); // 1 is treated as "1" to index object
  1244. EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
  1245. EXPECT_EQ(456, Pointer("/0/1").Get(d)->GetInt());
  1246. }
  1247. }
  1248. // https://github.com/miloyip/rapidjson/issues/483
  1249. namespace myjson {
  1250. class MyAllocator
  1251. {
  1252. public:
  1253. static const bool kNeedFree = true;
  1254. void * Malloc(size_t _size) { return malloc(_size); }
  1255. void * Realloc(void *_org_p, size_t _org_size, size_t _new_size) { (void)_org_size; return realloc(_org_p, _new_size); }
  1256. static void Free(void *_p) { return free(_p); }
  1257. };
  1258. typedef rapidjson::GenericDocument<
  1259. rapidjson::UTF8<>,
  1260. rapidjson::MemoryPoolAllocator< MyAllocator >,
  1261. MyAllocator
  1262. > Document;
  1263. typedef rapidjson::GenericPointer<
  1264. ::myjson::Document::ValueType,
  1265. MyAllocator
  1266. > Pointer;
  1267. typedef ::myjson::Document::ValueType Value;
  1268. }
  1269. TEST(Pointer, Issue483) {
  1270. std::string mystr, path;
  1271. myjson::Document document;
  1272. myjson::Value value(rapidjson::kStringType);
  1273. value.SetString(mystr.c_str(), static_cast<SizeType>(mystr.length()), document.GetAllocator());
  1274. myjson::Pointer(path.c_str()).Set(document, value, document.GetAllocator());
  1275. }