pointertest.cpp 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529
  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, static_cast<SizeType>(sizeof(s) / sizeof(s[0]) - 1), kPointerInvalidIndex }
  396. #define INDEX(i) { #i, static_cast<SizeType>(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. CrtAllocator allocator;
  413. Pointer p("/foo/0", &allocator);
  414. Pointer q(p);
  415. EXPECT_TRUE(q.IsValid());
  416. EXPECT_EQ(2u, q.GetTokenCount());
  417. EXPECT_EQ(3u, q.GetTokens()[0].length);
  418. EXPECT_STREQ("foo", q.GetTokens()[0].name);
  419. EXPECT_EQ(1u, q.GetTokens()[1].length);
  420. EXPECT_STREQ("0", q.GetTokens()[1].name);
  421. EXPECT_EQ(0u, q.GetTokens()[1].index);
  422. EXPECT_EQ(&p.GetAllocator(), &q.GetAllocator());
  423. }
  424. // Static tokens
  425. {
  426. Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
  427. Pointer q(p);
  428. EXPECT_TRUE(q.IsValid());
  429. EXPECT_EQ(2u, q.GetTokenCount());
  430. EXPECT_EQ(3u, q.GetTokens()[0].length);
  431. EXPECT_STREQ("foo", q.GetTokens()[0].name);
  432. EXPECT_EQ(1u, q.GetTokens()[1].length);
  433. EXPECT_STREQ("0", q.GetTokens()[1].name);
  434. EXPECT_EQ(0u, q.GetTokens()[1].index);
  435. }
  436. }
  437. TEST(Pointer, Assignment) {
  438. {
  439. CrtAllocator allocator;
  440. Pointer p("/foo/0", &allocator);
  441. Pointer q;
  442. q = p;
  443. EXPECT_TRUE(q.IsValid());
  444. EXPECT_EQ(2u, q.GetTokenCount());
  445. EXPECT_EQ(3u, q.GetTokens()[0].length);
  446. EXPECT_STREQ("foo", q.GetTokens()[0].name);
  447. EXPECT_EQ(1u, q.GetTokens()[1].length);
  448. EXPECT_STREQ("0", q.GetTokens()[1].name);
  449. EXPECT_EQ(0u, q.GetTokens()[1].index);
  450. EXPECT_NE(&p.GetAllocator(), &q.GetAllocator());
  451. q = q;
  452. EXPECT_TRUE(q.IsValid());
  453. EXPECT_EQ(2u, q.GetTokenCount());
  454. EXPECT_EQ(3u, q.GetTokens()[0].length);
  455. EXPECT_STREQ("foo", q.GetTokens()[0].name);
  456. EXPECT_EQ(1u, q.GetTokens()[1].length);
  457. EXPECT_STREQ("0", q.GetTokens()[1].name);
  458. EXPECT_EQ(0u, q.GetTokens()[1].index);
  459. EXPECT_NE(&p.GetAllocator(), &q.GetAllocator());
  460. }
  461. // Static tokens
  462. {
  463. Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
  464. Pointer q;
  465. q = p;
  466. EXPECT_TRUE(q.IsValid());
  467. EXPECT_EQ(2u, q.GetTokenCount());
  468. EXPECT_EQ(3u, q.GetTokens()[0].length);
  469. EXPECT_STREQ("foo", q.GetTokens()[0].name);
  470. EXPECT_EQ(1u, q.GetTokens()[1].length);
  471. EXPECT_STREQ("0", q.GetTokens()[1].name);
  472. EXPECT_EQ(0u, q.GetTokens()[1].index);
  473. }
  474. }
  475. TEST(Pointer, Append) {
  476. {
  477. Pointer p;
  478. Pointer q = p.Append("foo");
  479. EXPECT_TRUE(Pointer("/foo") == q);
  480. q = q.Append(1234);
  481. EXPECT_TRUE(Pointer("/foo/1234") == q);
  482. q = q.Append("");
  483. EXPECT_TRUE(Pointer("/foo/1234/") == q);
  484. }
  485. {
  486. Pointer p;
  487. Pointer q = p.Append(Value("foo").Move());
  488. EXPECT_TRUE(Pointer("/foo") == q);
  489. q = q.Append(Value(1234).Move());
  490. EXPECT_TRUE(Pointer("/foo/1234") == q);
  491. q = q.Append(Value(kStringType).Move());
  492. EXPECT_TRUE(Pointer("/foo/1234/") == q);
  493. }
  494. #if RAPIDJSON_HAS_STDSTRING
  495. {
  496. Pointer p;
  497. Pointer q = p.Append(std::string("foo"));
  498. EXPECT_TRUE(Pointer("/foo") == q);
  499. }
  500. #endif
  501. }
  502. TEST(Pointer, Equality) {
  503. EXPECT_TRUE(Pointer("/foo/0") == Pointer("/foo/0"));
  504. EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/1"));
  505. EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/0/1"));
  506. EXPECT_FALSE(Pointer("/foo/0") == Pointer("a"));
  507. EXPECT_FALSE(Pointer("a") == Pointer("a")); // Invalid always not equal
  508. }
  509. TEST(Pointer, Inequality) {
  510. EXPECT_FALSE(Pointer("/foo/0") != Pointer("/foo/0"));
  511. EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/1"));
  512. EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/0/1"));
  513. EXPECT_TRUE(Pointer("/foo/0") != Pointer("a"));
  514. EXPECT_TRUE(Pointer("a") != Pointer("a")); // Invalid always not equal
  515. }
  516. TEST(Pointer, Create) {
  517. Document d;
  518. {
  519. Value* v = &Pointer("").Create(d, d.GetAllocator());
  520. EXPECT_EQ(&d, v);
  521. }
  522. {
  523. Value* v = &Pointer("/foo").Create(d, d.GetAllocator());
  524. EXPECT_EQ(&d["foo"], v);
  525. }
  526. {
  527. Value* v = &Pointer("/foo/0").Create(d, d.GetAllocator());
  528. EXPECT_EQ(&d["foo"][0], v);
  529. }
  530. {
  531. Value* v = &Pointer("/foo/-").Create(d, d.GetAllocator());
  532. EXPECT_EQ(&d["foo"][1], v);
  533. }
  534. {
  535. Value* v = &Pointer("/foo/-/-").Create(d, d.GetAllocator());
  536. // "foo/-" is a newly created null value x.
  537. // "foo/-/-" finds that x is not an array, it converts x to empty object
  538. // and treats - as "-" member name
  539. EXPECT_EQ(&d["foo"][2]["-"], v);
  540. }
  541. {
  542. // Document with no allocator
  543. Value* v = &Pointer("/foo/-").Create(d);
  544. EXPECT_EQ(&d["foo"][3], v);
  545. }
  546. {
  547. // Value (not document) must give allocator
  548. Value* v = &Pointer("/-").Create(d["foo"], d.GetAllocator());
  549. EXPECT_EQ(&d["foo"][4], v);
  550. }
  551. }
  552. TEST(Pointer, Get) {
  553. Document d;
  554. d.Parse(kJson);
  555. EXPECT_EQ(&d, Pointer("").Get(d));
  556. EXPECT_EQ(&d["foo"], Pointer("/foo").Get(d));
  557. EXPECT_EQ(&d["foo"][0], Pointer("/foo/0").Get(d));
  558. EXPECT_EQ(&d[""], Pointer("/").Get(d));
  559. EXPECT_EQ(&d["a/b"], Pointer("/a~1b").Get(d));
  560. EXPECT_EQ(&d["c%d"], Pointer("/c%d").Get(d));
  561. EXPECT_EQ(&d["e^f"], Pointer("/e^f").Get(d));
  562. EXPECT_EQ(&d["g|h"], Pointer("/g|h").Get(d));
  563. EXPECT_EQ(&d["i\\j"], Pointer("/i\\j").Get(d));
  564. EXPECT_EQ(&d["k\"l"], Pointer("/k\"l").Get(d));
  565. EXPECT_EQ(&d[" "], Pointer("/ ").Get(d));
  566. EXPECT_EQ(&d["m~n"], Pointer("/m~0n").Get(d));
  567. EXPECT_TRUE(Pointer("/abc").Get(d) == 0);
  568. size_t unresolvedTokenIndex;
  569. EXPECT_TRUE(Pointer("/foo/2").Get(d, &unresolvedTokenIndex) == 0); // Out of boundary
  570. EXPECT_EQ(1, unresolvedTokenIndex);
  571. EXPECT_TRUE(Pointer("/foo/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
  572. EXPECT_EQ(1, unresolvedTokenIndex);
  573. EXPECT_TRUE(Pointer("/foo/0/0").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  574. EXPECT_EQ(2, unresolvedTokenIndex);
  575. EXPECT_TRUE(Pointer("/foo/0/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  576. EXPECT_EQ(2, unresolvedTokenIndex);
  577. }
  578. TEST(Pointer, GetWithDefault) {
  579. Document d;
  580. d.Parse(kJson);
  581. // Value version
  582. Document::AllocatorType& a = d.GetAllocator();
  583. const Value v("qux");
  584. EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v, a));
  585. EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v, a));
  586. EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v, a));
  587. EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move(), a));
  588. EXPECT_STREQ("last", d["foo"][3].GetString());
  589. EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, Value().Move(), a).IsNull());
  590. EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, "x", a).IsNull());
  591. // Generic version
  592. EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -1, a).GetInt());
  593. EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -2, a).GetInt());
  594. EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x87654321, a).GetUint());
  595. EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x12345678, a).GetUint());
  596. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  597. EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64, a).GetInt64());
  598. EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64 + 1, a).GetInt64());
  599. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  600. EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64, a).GetUint64());
  601. EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64 - 1, a).GetUint64());
  602. EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, true, a).IsTrue());
  603. EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, false, a).IsTrue());
  604. EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, false, a).IsFalse());
  605. EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, true, a).IsFalse());
  606. // StringRef version
  607. EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d, "Hello", a).GetString());
  608. // Copy string version
  609. {
  610. char buffer[256];
  611. strcpy(buffer, "World");
  612. EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d, buffer, a).GetString());
  613. memset(buffer, 0, sizeof(buffer));
  614. }
  615. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  616. #if RAPIDJSON_HAS_STDSTRING
  617. EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d, std::string("C++"), a).GetString());
  618. #endif
  619. }
  620. TEST(Pointer, GetWithDefault_NoAllocator) {
  621. Document d;
  622. d.Parse(kJson);
  623. // Value version
  624. const Value v("qux");
  625. EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v));
  626. EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v));
  627. EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v));
  628. EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move()));
  629. EXPECT_STREQ("last", d["foo"][3].GetString());
  630. EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, Value().Move()).IsNull());
  631. EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, "x").IsNull());
  632. // Generic version
  633. EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -1).GetInt());
  634. EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -2).GetInt());
  635. EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x87654321).GetUint());
  636. EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x12345678).GetUint());
  637. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  638. EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64).GetInt64());
  639. EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64 + 1).GetInt64());
  640. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  641. EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64).GetUint64());
  642. EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64 - 1).GetUint64());
  643. EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, true).IsTrue());
  644. EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, false).IsTrue());
  645. EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, false).IsFalse());
  646. EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, true).IsFalse());
  647. // StringRef version
  648. EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d, "Hello").GetString());
  649. // Copy string version
  650. {
  651. char buffer[256];
  652. strcpy(buffer, "World");
  653. EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d, buffer).GetString());
  654. memset(buffer, 0, sizeof(buffer));
  655. }
  656. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  657. #if RAPIDJSON_HAS_STDSTRING
  658. EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d, std::string("C++")).GetString());
  659. #endif
  660. }
  661. TEST(Pointer, Set) {
  662. Document d;
  663. d.Parse(kJson);
  664. Document::AllocatorType& a = d.GetAllocator();
  665. // Value version
  666. Pointer("/foo/0").Set(d, Value(123).Move(), a);
  667. EXPECT_EQ(123, d["foo"][0].GetInt());
  668. Pointer("/foo/-").Set(d, Value(456).Move(), a);
  669. EXPECT_EQ(456, d["foo"][2].GetInt());
  670. Pointer("/foo/null").Set(d, Value().Move(), a);
  671. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  672. // Const Value version
  673. const Value foo(d["foo"], a);
  674. Pointer("/clone").Set(d, foo, a);
  675. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  676. // Generic version
  677. Pointer("/foo/int").Set(d, -1, a);
  678. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  679. Pointer("/foo/uint").Set(d, 0x87654321, a);
  680. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  681. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  682. Pointer("/foo/int64").Set(d, i64, a);
  683. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  684. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  685. Pointer("/foo/uint64").Set(d, u64, a);
  686. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  687. Pointer("/foo/true").Set(d, true, a);
  688. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  689. Pointer("/foo/false").Set(d, false, a);
  690. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  691. // StringRef version
  692. Pointer("/foo/hello").Set(d, "Hello", a);
  693. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  694. // Copy string version
  695. {
  696. char buffer[256];
  697. strcpy(buffer, "World");
  698. Pointer("/foo/world").Set(d, buffer, a);
  699. memset(buffer, 0, sizeof(buffer));
  700. }
  701. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  702. #if RAPIDJSON_HAS_STDSTRING
  703. Pointer("/foo/c++").Set(d, std::string("C++"), a);
  704. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  705. #endif
  706. }
  707. TEST(Pointer, Set_NoAllocator) {
  708. Document d;
  709. d.Parse(kJson);
  710. // Value version
  711. Pointer("/foo/0").Set(d, Value(123).Move());
  712. EXPECT_EQ(123, d["foo"][0].GetInt());
  713. Pointer("/foo/-").Set(d, Value(456).Move());
  714. EXPECT_EQ(456, d["foo"][2].GetInt());
  715. Pointer("/foo/null").Set(d, Value().Move());
  716. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  717. // Const Value version
  718. const Value foo(d["foo"], d.GetAllocator());
  719. Pointer("/clone").Set(d, foo);
  720. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  721. // Generic version
  722. Pointer("/foo/int").Set(d, -1);
  723. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  724. Pointer("/foo/uint").Set(d, 0x87654321);
  725. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  726. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  727. Pointer("/foo/int64").Set(d, i64);
  728. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  729. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  730. Pointer("/foo/uint64").Set(d, u64);
  731. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  732. Pointer("/foo/true").Set(d, true);
  733. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  734. Pointer("/foo/false").Set(d, false);
  735. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  736. // StringRef version
  737. Pointer("/foo/hello").Set(d, "Hello");
  738. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  739. // Copy string version
  740. {
  741. char buffer[256];
  742. strcpy(buffer, "World");
  743. Pointer("/foo/world").Set(d, buffer);
  744. memset(buffer, 0, sizeof(buffer));
  745. }
  746. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  747. #if RAPIDJSON_HAS_STDSTRING
  748. Pointer("/foo/c++").Set(d, std::string("C++"));
  749. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  750. #endif
  751. }
  752. TEST(Pointer, Swap) {
  753. Document d;
  754. d.Parse(kJson);
  755. Document::AllocatorType& a = d.GetAllocator();
  756. Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d), a);
  757. EXPECT_STREQ("baz", d["foo"][0].GetString());
  758. EXPECT_STREQ("bar", d["foo"][1].GetString());
  759. }
  760. TEST(Pointer, Swap_NoAllocator) {
  761. Document d;
  762. d.Parse(kJson);
  763. Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d));
  764. EXPECT_STREQ("baz", d["foo"][0].GetString());
  765. EXPECT_STREQ("bar", d["foo"][1].GetString());
  766. }
  767. TEST(Pointer, Erase) {
  768. Document d;
  769. d.Parse(kJson);
  770. EXPECT_FALSE(Pointer("").Erase(d));
  771. EXPECT_FALSE(Pointer("/nonexist").Erase(d));
  772. EXPECT_FALSE(Pointer("/nonexist/nonexist").Erase(d));
  773. EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
  774. EXPECT_FALSE(Pointer("/foo/nonexist/nonexist").Erase(d));
  775. EXPECT_FALSE(Pointer("/foo/0/nonexist").Erase(d));
  776. EXPECT_FALSE(Pointer("/foo/0/nonexist/nonexist").Erase(d));
  777. EXPECT_FALSE(Pointer("/foo/2/nonexist").Erase(d));
  778. EXPECT_TRUE(Pointer("/foo/0").Erase(d));
  779. EXPECT_EQ(1u, d["foo"].Size());
  780. EXPECT_STREQ("baz", d["foo"][0].GetString());
  781. EXPECT_TRUE(Pointer("/foo/0").Erase(d));
  782. EXPECT_TRUE(d["foo"].Empty());
  783. EXPECT_TRUE(Pointer("/foo").Erase(d));
  784. EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
  785. Pointer("/a/0/b/0").Create(d);
  786. EXPECT_TRUE(Pointer("/a/0/b/0").Get(d) != 0);
  787. EXPECT_TRUE(Pointer("/a/0/b/0").Erase(d));
  788. EXPECT_TRUE(Pointer("/a/0/b/0").Get(d) == 0);
  789. EXPECT_TRUE(Pointer("/a/0/b").Get(d) != 0);
  790. EXPECT_TRUE(Pointer("/a/0/b").Erase(d));
  791. EXPECT_TRUE(Pointer("/a/0/b").Get(d) == 0);
  792. EXPECT_TRUE(Pointer("/a/0").Get(d) != 0);
  793. EXPECT_TRUE(Pointer("/a/0").Erase(d));
  794. EXPECT_TRUE(Pointer("/a/0").Get(d) == 0);
  795. EXPECT_TRUE(Pointer("/a").Get(d) != 0);
  796. EXPECT_TRUE(Pointer("/a").Erase(d));
  797. EXPECT_TRUE(Pointer("/a").Get(d) == 0);
  798. }
  799. TEST(Pointer, CreateValueByPointer) {
  800. Document d;
  801. Document::AllocatorType& a = d.GetAllocator();
  802. {
  803. Value& v = CreateValueByPointer(d, Pointer("/foo/0"), a);
  804. EXPECT_EQ(&d["foo"][0], &v);
  805. }
  806. {
  807. Value& v = CreateValueByPointer(d, "/foo/1", a);
  808. EXPECT_EQ(&d["foo"][1], &v);
  809. }
  810. }
  811. TEST(Pointer, CreateValueByPointer_NoAllocator) {
  812. Document d;
  813. {
  814. Value& v = CreateValueByPointer(d, Pointer("/foo/0"));
  815. EXPECT_EQ(&d["foo"][0], &v);
  816. }
  817. {
  818. Value& v = CreateValueByPointer(d, "/foo/1");
  819. EXPECT_EQ(&d["foo"][1], &v);
  820. }
  821. }
  822. TEST(Pointer, GetValueByPointer) {
  823. Document d;
  824. d.Parse(kJson);
  825. EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, Pointer("/foo/0")));
  826. EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, "/foo/0"));
  827. size_t unresolvedTokenIndex;
  828. EXPECT_TRUE(GetValueByPointer(d, "/foo/2", &unresolvedTokenIndex) == 0); // Out of boundary
  829. EXPECT_EQ(1, unresolvedTokenIndex);
  830. EXPECT_TRUE(GetValueByPointer(d, "/foo/a", &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
  831. EXPECT_EQ(1, unresolvedTokenIndex);
  832. EXPECT_TRUE(GetValueByPointer(d, "/foo/0/0", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  833. EXPECT_EQ(2, unresolvedTokenIndex);
  834. EXPECT_TRUE(GetValueByPointer(d, "/foo/0/a", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  835. EXPECT_EQ(2, unresolvedTokenIndex);
  836. // const version
  837. const Value& v = d;
  838. EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, Pointer("/foo/0")));
  839. EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, "/foo/0"));
  840. EXPECT_TRUE(GetValueByPointer(v, "/foo/2", &unresolvedTokenIndex) == 0); // Out of boundary
  841. EXPECT_EQ(1, unresolvedTokenIndex);
  842. EXPECT_TRUE(GetValueByPointer(v, "/foo/a", &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
  843. EXPECT_EQ(1, unresolvedTokenIndex);
  844. EXPECT_TRUE(GetValueByPointer(v, "/foo/0/0", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  845. EXPECT_EQ(2, unresolvedTokenIndex);
  846. EXPECT_TRUE(GetValueByPointer(v, "/foo/0/a", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
  847. EXPECT_EQ(2, unresolvedTokenIndex);
  848. }
  849. TEST(Pointer, GetValueByPointerWithDefault_Pointer) {
  850. Document d;
  851. d.Parse(kJson);
  852. Document::AllocatorType& a = d.GetAllocator();
  853. const Value v("qux");
  854. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
  855. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
  856. EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, Pointer("/foo/1"), v, a));
  857. EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, Pointer("/foo/2"), v, a));
  858. EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, Pointer("/foo/-"), Value("last").Move(), a));
  859. EXPECT_STREQ("last", d["foo"][3].GetString());
  860. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), Value().Move(), a).IsNull());
  861. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), "x", a).IsNull());
  862. // Generic version
  863. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -1, a).GetInt());
  864. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -2, a).GetInt());
  865. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x87654321, a).GetUint());
  866. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x12345678, a).GetUint());
  867. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  868. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64, a).GetInt64());
  869. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64 + 1, a).GetInt64());
  870. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  871. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64, a).GetUint64());
  872. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64 - 1, a).GetUint64());
  873. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), true, a).IsTrue());
  874. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), false, a).IsTrue());
  875. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), false, a).IsFalse());
  876. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), true, a).IsFalse());
  877. // StringRef version
  878. EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, Pointer("/foo/hello"), "Hello", a).GetString());
  879. // Copy string version
  880. {
  881. char buffer[256];
  882. strcpy(buffer, "World");
  883. EXPECT_STREQ("World", GetValueByPointerWithDefault(d, Pointer("/foo/world"), buffer, a).GetString());
  884. memset(buffer, 0, sizeof(buffer));
  885. }
  886. EXPECT_STREQ("World", GetValueByPointer(d, Pointer("/foo/world"))->GetString());
  887. #if RAPIDJSON_HAS_STDSTRING
  888. EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++"), a).GetString());
  889. #endif
  890. }
  891. TEST(Pointer, GetValueByPointerWithDefault_String) {
  892. Document d;
  893. d.Parse(kJson);
  894. Document::AllocatorType& a = d.GetAllocator();
  895. const Value v("qux");
  896. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v, a));
  897. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v, a));
  898. EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v, a));
  899. EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, "/foo/2", v, a));
  900. EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, "/foo/-", Value("last").Move(), a));
  901. EXPECT_STREQ("last", d["foo"][3].GetString());
  902. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", Value().Move(), a).IsNull());
  903. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", "x", a).IsNull());
  904. // Generic version
  905. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -1, a).GetInt());
  906. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -2, a).GetInt());
  907. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x87654321, a).GetUint());
  908. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x12345678, a).GetUint());
  909. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  910. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64, a).GetInt64());
  911. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64 + 1, a).GetInt64());
  912. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  913. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64, a).GetUint64());
  914. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64 - 1, a).GetUint64());
  915. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", true, a).IsTrue());
  916. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", false, a).IsTrue());
  917. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", false, a).IsFalse());
  918. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", true, a).IsFalse());
  919. // StringRef version
  920. EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, "/foo/hello", "Hello", a).GetString());
  921. // Copy string version
  922. {
  923. char buffer[256];
  924. strcpy(buffer, "World");
  925. EXPECT_STREQ("World", GetValueByPointerWithDefault(d, "/foo/world", buffer, a).GetString());
  926. memset(buffer, 0, sizeof(buffer));
  927. }
  928. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  929. #if RAPIDJSON_HAS_STDSTRING
  930. EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, "/foo/C++", std::string("C++"), a).GetString());
  931. #endif
  932. }
  933. TEST(Pointer, GetValueByPointerWithDefault_Pointer_NoAllocator) {
  934. Document d;
  935. d.Parse(kJson);
  936. const Value v("qux");
  937. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v));
  938. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v));
  939. EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, Pointer("/foo/1"), v));
  940. EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, Pointer("/foo/2"), v));
  941. EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, Pointer("/foo/-"), Value("last").Move()));
  942. EXPECT_STREQ("last", d["foo"][3].GetString());
  943. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), Value().Move()).IsNull());
  944. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), "x").IsNull());
  945. // Generic version
  946. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -1).GetInt());
  947. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -2).GetInt());
  948. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x87654321).GetUint());
  949. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x12345678).GetUint());
  950. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  951. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64).GetInt64());
  952. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64 + 1).GetInt64());
  953. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  954. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64).GetUint64());
  955. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64 - 1).GetUint64());
  956. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), true).IsTrue());
  957. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), false).IsTrue());
  958. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), false).IsFalse());
  959. EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), true).IsFalse());
  960. // StringRef version
  961. EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, Pointer("/foo/hello"), "Hello").GetString());
  962. // Copy string version
  963. {
  964. char buffer[256];
  965. strcpy(buffer, "World");
  966. EXPECT_STREQ("World", GetValueByPointerWithDefault(d, Pointer("/foo/world"), buffer).GetString());
  967. memset(buffer, 0, sizeof(buffer));
  968. }
  969. EXPECT_STREQ("World", GetValueByPointer(d, Pointer("/foo/world"))->GetString());
  970. #if RAPIDJSON_HAS_STDSTRING
  971. EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++")).GetString());
  972. #endif
  973. }
  974. TEST(Pointer, GetValueByPointerWithDefault_String_NoAllocator) {
  975. Document d;
  976. d.Parse(kJson);
  977. const Value v("qux");
  978. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v));
  979. EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v));
  980. EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v));
  981. EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, "/foo/2", v));
  982. EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, "/foo/-", Value("last").Move()));
  983. EXPECT_STREQ("last", d["foo"][3].GetString());
  984. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", Value().Move()).IsNull());
  985. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", "x").IsNull());
  986. // Generic version
  987. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -1).GetInt());
  988. EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -2).GetInt());
  989. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x87654321).GetUint());
  990. EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x12345678).GetUint());
  991. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  992. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64).GetInt64());
  993. EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64 + 1).GetInt64());
  994. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  995. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64).GetUint64());
  996. EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64 - 1).GetUint64());
  997. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", true).IsTrue());
  998. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", false).IsTrue());
  999. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", false).IsFalse());
  1000. EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", true).IsFalse());
  1001. // StringRef version
  1002. EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, "/foo/hello", "Hello").GetString());
  1003. // Copy string version
  1004. {
  1005. char buffer[256];
  1006. strcpy(buffer, "World");
  1007. EXPECT_STREQ("World", GetValueByPointerWithDefault(d, "/foo/world", buffer).GetString());
  1008. memset(buffer, 0, sizeof(buffer));
  1009. }
  1010. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  1011. #if RAPIDJSON_HAS_STDSTRING
  1012. EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++")).GetString());
  1013. #endif
  1014. }
  1015. TEST(Pointer, SetValueByPointer_Pointer) {
  1016. Document d;
  1017. d.Parse(kJson);
  1018. Document::AllocatorType& a = d.GetAllocator();
  1019. // Value version
  1020. SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move(), a);
  1021. EXPECT_EQ(123, d["foo"][0].GetInt());
  1022. SetValueByPointer(d, Pointer("/foo/null"), Value().Move(), a);
  1023. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  1024. // Const Value version
  1025. const Value foo(d["foo"], d.GetAllocator());
  1026. SetValueByPointer(d, Pointer("/clone"), foo, a);
  1027. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  1028. // Generic version
  1029. SetValueByPointer(d, Pointer("/foo/int"), -1, a);
  1030. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  1031. SetValueByPointer(d, Pointer("/foo/uint"), 0x87654321, a);
  1032. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  1033. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  1034. SetValueByPointer(d, Pointer("/foo/int64"), i64, a);
  1035. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  1036. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  1037. SetValueByPointer(d, Pointer("/foo/uint64"), u64, a);
  1038. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  1039. SetValueByPointer(d, Pointer("/foo/true"), true, a);
  1040. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  1041. SetValueByPointer(d, Pointer("/foo/false"), false, a);
  1042. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  1043. // StringRef version
  1044. SetValueByPointer(d, Pointer("/foo/hello"), "Hello", a);
  1045. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  1046. // Copy string version
  1047. {
  1048. char buffer[256];
  1049. strcpy(buffer, "World");
  1050. SetValueByPointer(d, Pointer("/foo/world"), buffer, a);
  1051. memset(buffer, 0, sizeof(buffer));
  1052. }
  1053. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  1054. #if RAPIDJSON_HAS_STDSTRING
  1055. SetValueByPointer(d, Pointer("/foo/c++"), std::string("C++"), a);
  1056. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  1057. #endif
  1058. }
  1059. TEST(Pointer, SetValueByPointer_String) {
  1060. Document d;
  1061. d.Parse(kJson);
  1062. Document::AllocatorType& a = d.GetAllocator();
  1063. // Value version
  1064. SetValueByPointer(d, "/foo/0", Value(123).Move(), a);
  1065. EXPECT_EQ(123, d["foo"][0].GetInt());
  1066. SetValueByPointer(d, "/foo/null", Value().Move(), a);
  1067. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  1068. // Const Value version
  1069. const Value foo(d["foo"], d.GetAllocator());
  1070. SetValueByPointer(d, "/clone", foo, a);
  1071. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  1072. // Generic version
  1073. SetValueByPointer(d, "/foo/int", -1, a);
  1074. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  1075. SetValueByPointer(d, "/foo/uint", 0x87654321, a);
  1076. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  1077. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  1078. SetValueByPointer(d, "/foo/int64", i64, a);
  1079. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  1080. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  1081. SetValueByPointer(d, "/foo/uint64", u64, a);
  1082. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  1083. SetValueByPointer(d, "/foo/true", true, a);
  1084. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  1085. SetValueByPointer(d, "/foo/false", false, a);
  1086. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  1087. // StringRef version
  1088. SetValueByPointer(d, "/foo/hello", "Hello", a);
  1089. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  1090. // Copy string version
  1091. {
  1092. char buffer[256];
  1093. strcpy(buffer, "World");
  1094. SetValueByPointer(d, "/foo/world", buffer, a);
  1095. memset(buffer, 0, sizeof(buffer));
  1096. }
  1097. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  1098. #if RAPIDJSON_HAS_STDSTRING
  1099. SetValueByPointer(d, "/foo/c++", std::string("C++"), a);
  1100. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  1101. #endif
  1102. }
  1103. TEST(Pointer, SetValueByPointer_Pointer_NoAllocator) {
  1104. Document d;
  1105. d.Parse(kJson);
  1106. // Value version
  1107. SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move());
  1108. EXPECT_EQ(123, d["foo"][0].GetInt());
  1109. SetValueByPointer(d, Pointer("/foo/null"), Value().Move());
  1110. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  1111. // Const Value version
  1112. const Value foo(d["foo"], d.GetAllocator());
  1113. SetValueByPointer(d, Pointer("/clone"), foo);
  1114. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  1115. // Generic version
  1116. SetValueByPointer(d, Pointer("/foo/int"), -1);
  1117. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  1118. SetValueByPointer(d, Pointer("/foo/uint"), 0x87654321);
  1119. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  1120. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  1121. SetValueByPointer(d, Pointer("/foo/int64"), i64);
  1122. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  1123. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  1124. SetValueByPointer(d, Pointer("/foo/uint64"), u64);
  1125. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  1126. SetValueByPointer(d, Pointer("/foo/true"), true);
  1127. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  1128. SetValueByPointer(d, Pointer("/foo/false"), false);
  1129. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  1130. // StringRef version
  1131. SetValueByPointer(d, Pointer("/foo/hello"), "Hello");
  1132. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  1133. // Copy string version
  1134. {
  1135. char buffer[256];
  1136. strcpy(buffer, "World");
  1137. SetValueByPointer(d, Pointer("/foo/world"), buffer);
  1138. memset(buffer, 0, sizeof(buffer));
  1139. }
  1140. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  1141. #if RAPIDJSON_HAS_STDSTRING
  1142. SetValueByPointer(d, Pointer("/foo/c++"), std::string("C++"));
  1143. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  1144. #endif
  1145. }
  1146. TEST(Pointer, SetValueByPointer_String_NoAllocator) {
  1147. Document d;
  1148. d.Parse(kJson);
  1149. // Value version
  1150. SetValueByPointer(d, "/foo/0", Value(123).Move());
  1151. EXPECT_EQ(123, d["foo"][0].GetInt());
  1152. SetValueByPointer(d, "/foo/null", Value().Move());
  1153. EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
  1154. // Const Value version
  1155. const Value foo(d["foo"], d.GetAllocator());
  1156. SetValueByPointer(d, "/clone", foo);
  1157. EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
  1158. // Generic version
  1159. SetValueByPointer(d, "/foo/int", -1);
  1160. EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
  1161. SetValueByPointer(d, "/foo/uint", 0x87654321);
  1162. EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
  1163. const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
  1164. SetValueByPointer(d, "/foo/int64", i64);
  1165. EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
  1166. const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
  1167. SetValueByPointer(d, "/foo/uint64", u64);
  1168. EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
  1169. SetValueByPointer(d, "/foo/true", true);
  1170. EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
  1171. SetValueByPointer(d, "/foo/false", false);
  1172. EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
  1173. // StringRef version
  1174. SetValueByPointer(d, "/foo/hello", "Hello");
  1175. EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
  1176. // Copy string version
  1177. {
  1178. char buffer[256];
  1179. strcpy(buffer, "World");
  1180. SetValueByPointer(d, "/foo/world", buffer);
  1181. memset(buffer, 0, sizeof(buffer));
  1182. }
  1183. EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
  1184. #if RAPIDJSON_HAS_STDSTRING
  1185. SetValueByPointer(d, "/foo/c++", std::string("C++"));
  1186. EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
  1187. #endif
  1188. }
  1189. TEST(Pointer, SwapValueByPointer) {
  1190. Document d;
  1191. d.Parse(kJson);
  1192. Document::AllocatorType& a = d.GetAllocator();
  1193. SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"), a);
  1194. EXPECT_STREQ("baz", d["foo"][0].GetString());
  1195. EXPECT_STREQ("bar", d["foo"][1].GetString());
  1196. SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"), a);
  1197. EXPECT_STREQ("bar", d["foo"][0].GetString());
  1198. EXPECT_STREQ("baz", d["foo"][1].GetString());
  1199. }
  1200. TEST(Pointer, SwapValueByPointer_NoAllocator) {
  1201. Document d;
  1202. d.Parse(kJson);
  1203. SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"));
  1204. EXPECT_STREQ("baz", d["foo"][0].GetString());
  1205. EXPECT_STREQ("bar", d["foo"][1].GetString());
  1206. SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"));
  1207. EXPECT_STREQ("bar", d["foo"][0].GetString());
  1208. EXPECT_STREQ("baz", d["foo"][1].GetString());
  1209. }
  1210. TEST(Pointer, EraseValueByPointer_Pointer) {
  1211. Document d;
  1212. d.Parse(kJson);
  1213. EXPECT_FALSE(EraseValueByPointer(d, Pointer("")));
  1214. EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
  1215. EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo/0")));
  1216. EXPECT_EQ(1u, d["foo"].Size());
  1217. EXPECT_STREQ("baz", d["foo"][0].GetString());
  1218. EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo/0")));
  1219. EXPECT_TRUE(d["foo"].Empty());
  1220. EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo")));
  1221. EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
  1222. }
  1223. TEST(Pointer, EraseValueByPointer_String) {
  1224. Document d;
  1225. d.Parse(kJson);
  1226. EXPECT_FALSE(EraseValueByPointer(d, ""));
  1227. EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
  1228. EXPECT_TRUE(EraseValueByPointer(d, "/foo/0"));
  1229. EXPECT_EQ(1u, d["foo"].Size());
  1230. EXPECT_STREQ("baz", d["foo"][0].GetString());
  1231. EXPECT_TRUE(EraseValueByPointer(d, "/foo/0"));
  1232. EXPECT_TRUE(d["foo"].Empty());
  1233. EXPECT_TRUE(EraseValueByPointer(d, "/foo"));
  1234. EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
  1235. }
  1236. TEST(Pointer, Ambiguity) {
  1237. {
  1238. Document d;
  1239. d.Parse("{\"0\" : [123]}");
  1240. EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
  1241. Pointer("/0/a").Set(d, 456); // Change array [123] to object {456}
  1242. EXPECT_EQ(456, Pointer("/0/a").Get(d)->GetInt());
  1243. }
  1244. {
  1245. Document d;
  1246. EXPECT_FALSE(d.Parse("[{\"0\": 123}]").HasParseError());
  1247. EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
  1248. Pointer("/0/1").Set(d, 456); // 1 is treated as "1" to index object
  1249. EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
  1250. EXPECT_EQ(456, Pointer("/0/1").Get(d)->GetInt());
  1251. }
  1252. }
  1253. // https://github.com/Tencent/rapidjson/issues/483
  1254. namespace myjson {
  1255. class MyAllocator
  1256. {
  1257. public:
  1258. static const bool kNeedFree = true;
  1259. void * Malloc(size_t _size) { return malloc(_size); }
  1260. void * Realloc(void *_org_p, size_t _org_size, size_t _new_size) { (void)_org_size; return realloc(_org_p, _new_size); }
  1261. static void Free(void *_p) { return free(_p); }
  1262. };
  1263. typedef rapidjson::GenericDocument<
  1264. rapidjson::UTF8<>,
  1265. rapidjson::MemoryPoolAllocator< MyAllocator >,
  1266. MyAllocator
  1267. > Document;
  1268. typedef rapidjson::GenericPointer<
  1269. ::myjson::Document::ValueType,
  1270. MyAllocator
  1271. > Pointer;
  1272. typedef ::myjson::Document::ValueType Value;
  1273. }
  1274. TEST(Pointer, Issue483) {
  1275. std::string mystr, path;
  1276. myjson::Document document;
  1277. myjson::Value value(rapidjson::kStringType);
  1278. value.SetString(mystr.c_str(), static_cast<SizeType>(mystr.length()), document.GetAllocator());
  1279. myjson::Pointer(path.c_str()).Set(document, value, document.GetAllocator());
  1280. }