pointer.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  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. #ifndef RAPIDJSON_POINTER_H_
  15. #define RAPIDJSON_POINTER_H_
  16. #include "document.h"
  17. RAPIDJSON_NAMESPACE_BEGIN
  18. static const SizeType kPointerInvalidIndex = ~SizeType(0);
  19. enum PointerParseErrorCode {
  20. kPointerParseErrorNone = 0,
  21. kPointerParseErrorTokenMustBeginWithSolidus,
  22. kPointerParseErrorInvalidEscape
  23. };
  24. template <typename ValueType, typename Allocator = CrtAllocator>
  25. class GenericPointer {
  26. public:
  27. typedef typename ValueType::EncodingType EncodingType;
  28. typedef typename EncodingType::Ch Ch;
  29. struct Token {
  30. const Ch* name;
  31. SizeType length;
  32. SizeType index; //!< A valid index if not equal to kPointerInvalidIndex.
  33. };
  34. GenericPointer() :
  35. allocator_(),
  36. ownAllocator_(),
  37. nameBuffer_(),
  38. tokens_(),
  39. tokenCount_(),
  40. parseErrorOffset_(),
  41. parseErrorCode_(kPointerParseErrorNone)
  42. {
  43. }
  44. explicit GenericPointer(const Ch* source, Allocator* allocator = 0) :
  45. allocator_(allocator),
  46. ownAllocator_(),
  47. nameBuffer_(),
  48. tokens_(),
  49. tokenCount_(),
  50. parseErrorOffset_(),
  51. parseErrorCode_(kPointerParseErrorNone)
  52. {
  53. Parse(source, internal::StrLen(source));
  54. }
  55. GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) :
  56. allocator_(allocator),
  57. ownAllocator_(),
  58. nameBuffer_(),
  59. tokens_(),
  60. tokenCount_(),
  61. parseErrorOffset_(),
  62. parseErrorCode_(kPointerParseErrorNone)
  63. {
  64. Parse(source, length);
  65. }
  66. GenericPointer(const Token* tokens, size_t tokenCount) :
  67. allocator_(),
  68. ownAllocator_(),
  69. nameBuffer_(),
  70. tokens_(const_cast<Token*>(tokens)),
  71. tokenCount_(tokenCount),
  72. parseErrorOffset_(),
  73. parseErrorCode_(kPointerParseErrorNone)
  74. {
  75. }
  76. GenericPointer(const GenericPointer& rhs) :
  77. allocator_(),
  78. ownAllocator_(),
  79. nameBuffer_(),
  80. tokens_(),
  81. tokenCount_(),
  82. parseErrorOffset_(),
  83. parseErrorCode_(kPointerParseErrorNone)
  84. {
  85. *this = rhs;
  86. }
  87. ~GenericPointer() {
  88. if (nameBuffer_) {
  89. Allocator::Free(nameBuffer_);
  90. Allocator::Free(tokens_);
  91. }
  92. RAPIDJSON_DELETE(ownAllocator_);
  93. }
  94. GenericPointer& operator=(const GenericPointer& rhs) {
  95. this->~GenericPointer();
  96. tokenCount_ = rhs.tokenCount_;
  97. parseErrorOffset_ = rhs.parseErrorOffset_;
  98. parseErrorCode_ = rhs.parseErrorCode_;
  99. if (rhs.nameBuffer_) {
  100. if (!allocator_)
  101. ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
  102. size_t nameBufferSize = tokenCount_; // null terminators
  103. for (Token *t = rhs.tokens_; t != rhs.tokens_ + tokenCount_; ++t)
  104. nameBufferSize += t->length;
  105. nameBuffer_ = (Ch*)allocator_->Malloc(nameBufferSize * sizeof(Ch));
  106. std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize);
  107. tokens_ = (Token*)allocator_->Malloc(tokenCount_ * sizeof(Token));
  108. std::memcpy(tokens_, rhs.tokens_, tokenCount_ * sizeof(Token));
  109. // Adjust pointers to name buffer
  110. std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
  111. for (Token *t = rhs.tokens_; t != rhs.tokens_ + tokenCount_; ++t)
  112. t->name += diff;
  113. }
  114. else
  115. tokens_ = rhs.tokens_;
  116. return *this;
  117. }
  118. bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
  119. size_t GetParseErrorOffset() const { return parseErrorOffset_; }
  120. PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
  121. const Token* GetTokens() const { return tokens_; }
  122. size_t GetTokenCount() const { return tokenCount_; }
  123. template<typename OutputStream>
  124. void Stringify(OutputStream& os) const {
  125. RAPIDJSON_ASSERT(IsValid());
  126. for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
  127. os.Put('/');
  128. for (size_t j = 0; j < t->length; j++) {
  129. Ch c = t->name[j];
  130. if (c == '~') { os.Put('~'); os.Put('0'); }
  131. else if (c == '/') { os.Put('~'); os.Put('1'); }
  132. else os.Put(c);
  133. }
  134. }
  135. }
  136. ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
  137. RAPIDJSON_ASSERT(IsValid());
  138. ValueType* v = &root;
  139. bool exist = true;
  140. for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
  141. if (t->index == kPointerInvalidIndex) { // object name
  142. // Handling of '-' for last element of array
  143. if (t->name[0] == '-' && t->length == 1) {
  144. if (!v->IsArray())
  145. v->SetArray(); // Change to Array
  146. v->PushBack(Value().Move(), allocator);
  147. v = &((*v)[v->Size() - 1]);
  148. exist = false;
  149. }
  150. else {
  151. if (!v->IsObject())
  152. v->SetObject(); // Change to Object
  153. typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
  154. if (m == v->MemberEnd()) {
  155. v->AddMember(Value(t->name, t->length, allocator).Move(), Value().Move(), allocator);
  156. v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
  157. exist = false;
  158. }
  159. else
  160. v = &m->value;
  161. }
  162. }
  163. else { // array index
  164. if (!v->IsArray())
  165. v->SetArray(); // Change to Array
  166. if (t->index >= v->Size()) {
  167. v->Reserve(t->index + 1, allocator);
  168. while (t->index >= v->Size())
  169. v->PushBack(Value().Move(), allocator);
  170. exist = false;
  171. }
  172. v = &((*v)[t->index]);
  173. }
  174. }
  175. if (alreadyExist)
  176. *alreadyExist = exist;
  177. return *v;
  178. }
  179. ValueType* Get(ValueType& root) const {
  180. RAPIDJSON_ASSERT(IsValid());
  181. ValueType* v = &root;
  182. for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
  183. switch (v->GetType()) {
  184. case kObjectType:
  185. {
  186. typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
  187. if (m == v->MemberEnd())
  188. return 0;
  189. v = &m->value;
  190. }
  191. break;
  192. case kArrayType:
  193. if (t->index == kPointerInvalidIndex || t->index >= v->Size())
  194. return 0;
  195. v = &((*v)[t->index]);
  196. break;
  197. default:
  198. return 0;
  199. }
  200. }
  201. return v;
  202. }
  203. const ValueType* Get(const ValueType& root) const {
  204. return Get(const_cast<ValueType&>(root));
  205. }
  206. ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
  207. bool alreadyExist;
  208. Value& v = Create(root, allocator, &alreadyExist);
  209. if (!alreadyExist) {
  210. Value clone(defaultValue, allocator);
  211. v = clone;
  212. }
  213. return v;
  214. }
  215. ValueType& GetWithDefault(ValueType& root, GenericStringRef<Ch> defaultValue, typename ValueType::AllocatorType& allocator) const {
  216. ValueType v(defaultValue);
  217. return GetWithDefault(root, v, allocator);
  218. }
  219. ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
  220. bool alreadyExist;
  221. Value& v = Create(root, allocator, &alreadyExist);
  222. if (!alreadyExist) {
  223. Value clone(defaultValue, allocator); // This has overhead, so do it inside if.
  224. v = clone;
  225. }
  226. return v;
  227. }
  228. template <typename T>
  229. RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
  230. GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
  231. ValueType v(defaultValue);
  232. return GetWithDefault(root, v, allocator);
  233. }
  234. // Move semantics, create parents if non-exist
  235. ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
  236. return Create(root, allocator) = value;
  237. }
  238. // Copy semantics, create parents if non-exist
  239. ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
  240. return Create(root, allocator).CopyFrom(value, allocator);
  241. }
  242. ValueType& Set(ValueType& root, GenericStringRef<Ch> value, typename ValueType::AllocatorType& allocator) const {
  243. ValueType v(value);
  244. return Create(root, allocator) = v;
  245. }
  246. ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
  247. ValueType v(value, allocator);
  248. return Create(root, allocator) = v;
  249. }
  250. template <typename T>
  251. RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
  252. Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
  253. ValueType v(value);
  254. return Create(root, allocator) = v;
  255. }
  256. // Create parents if non-exist
  257. ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
  258. return Create(root, allocator).Swap(value);
  259. }
  260. private:
  261. void Parse(const Ch* source, size_t length) {
  262. // Create own allocator if user did not supply.
  263. if (!allocator_)
  264. ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
  265. // Create a buffer as same size of source
  266. RAPIDJSON_ASSERT(nameBuffer_ == 0);
  267. nameBuffer_ = (Ch*)allocator_->Malloc(length * sizeof(Ch));
  268. RAPIDJSON_ASSERT(tokens_ == 0);
  269. tokens_ = (Token*)allocator_->Malloc(length * sizeof(Token)); // Maximum possible tokens in the source
  270. tokenCount_ = 0;
  271. Ch* name = nameBuffer_;
  272. size_t i = 0;
  273. if (length != 0 && source[i] != '/') {
  274. parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus;
  275. goto error;
  276. }
  277. while (i < length) {
  278. RAPIDJSON_ASSERT(source[i] == '/');
  279. i++; // consumes '/'
  280. Token& token = tokens_[tokenCount_++];
  281. token.name = name;
  282. bool isNumber = true;
  283. while (i < length && source[i] != '/') {
  284. Ch c = source[i++];
  285. // Escaping "~0" -> '~', "~1" -> '/'
  286. if (c == '~') {
  287. if (i < length) {
  288. c = source[i];
  289. if (c == '0') c = '~';
  290. else if (c == '1') c = '/';
  291. else {
  292. parseErrorCode_ = kPointerParseErrorInvalidEscape;
  293. goto error;
  294. }
  295. i++;
  296. }
  297. else {
  298. parseErrorCode_ = kPointerParseErrorInvalidEscape;
  299. goto error;
  300. }
  301. }
  302. // First check for index: all of characters are digit
  303. if (c < '0' || c > '9')
  304. isNumber = false;
  305. *name++ = c;
  306. }
  307. token.length = name - token.name;
  308. *name++ = '\0'; // Null terminator
  309. // Second check for index: more than one digit cannot have leading zero
  310. if (isNumber && token.length > 1 && token.name[0] == '0')
  311. isNumber = false;
  312. // String to SizeType conversion
  313. SizeType n = 0;
  314. if (isNumber) {
  315. for (size_t j = 0; j < token.length; j++) {
  316. SizeType m = n * 10 + static_cast<SizeType>(token.name[j] - '0');
  317. if (m < n) { // overflow detection
  318. isNumber = false;
  319. break;
  320. }
  321. n = m;
  322. }
  323. }
  324. token.index = isNumber ? n : kPointerInvalidIndex;
  325. }
  326. RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
  327. tokens_ = (Token*)allocator_->Realloc(tokens_, length * sizeof(Token), tokenCount_ * sizeof(Token)); // Shrink tokens_
  328. parseErrorCode_ = kPointerParseErrorNone;
  329. return;
  330. error:
  331. Allocator::Free(nameBuffer_);
  332. Allocator::Free(tokens_);
  333. nameBuffer_ = 0;
  334. tokens_ = 0;
  335. tokenCount_ = 0;
  336. parseErrorOffset_ = i;
  337. return;
  338. }
  339. Allocator* allocator_;
  340. Allocator* ownAllocator_;
  341. Ch* nameBuffer_;
  342. Token* tokens_;
  343. size_t tokenCount_;
  344. size_t parseErrorOffset_;
  345. PointerParseErrorCode parseErrorCode_;
  346. };
  347. template <typename T>
  348. typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
  349. return pointer.Create(root, a);
  350. }
  351. template <typename T, typename CharType, size_t N>
  352. typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
  353. const GenericPointer<typename T::ValueType> pointer(source, N - 1);
  354. return CreateValueByPointer(root, pointer, a);
  355. }
  356. template <typename T>
  357. typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
  358. return pointer.Get(root);
  359. }
  360. template <typename T>
  361. const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer) {
  362. return pointer.Get(root);
  363. }
  364. template <typename T, typename CharType, size_t N>
  365. typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N]) {
  366. const GenericPointer<typename T::ValueType> pointer(source, N - 1);
  367. return GetValueByPointer(root, pointer);
  368. }
  369. template <typename T, typename CharType, size_t N>
  370. const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N]) {
  371. const GenericPointer<typename T::ValueType> pointer(source, N - 1);
  372. return GetValueByPointer(root, pointer);
  373. }
  374. template <typename T>
  375. typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
  376. return pointer.GetWithDefault(root, defaultValue, a);
  377. }
  378. template <typename T, typename CharType, size_t N>
  379. typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
  380. const GenericPointer<typename T::ValueType> pointer(source, N - 1);
  381. return GetValueByPointerWithDefault(root, pointer, defaultValue, a);
  382. }
  383. template <typename T>
  384. typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
  385. return pointer.Set(root, value, a);
  386. }
  387. template <typename T>
  388. typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, GenericStringRef<typename T::Ch> value, typename T::AllocatorType& a) {
  389. return pointer.Set(root, value, a);
  390. }
  391. template <typename T>
  392. typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
  393. return pointer.Set(root, value, a);
  394. }
  395. template <typename T, typename T2>
  396. RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
  397. SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
  398. return pointer.Set(root, value, a);
  399. }
  400. template <typename T, typename CharType, size_t N>
  401. typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
  402. const GenericPointer<typename T::ValueType> pointer(source, N - 1);
  403. return SetValueByPointer(root, pointer, value, a);
  404. }
  405. template <typename T, typename CharType, size_t N>
  406. typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], GenericStringRef<typename T::Ch> value, typename T::AllocatorType& a) {
  407. const GenericPointer<typename T::ValueType> pointer(source, N - 1);
  408. return SetValueByPointer(root, pointer, value, a);
  409. }
  410. template <typename T, typename CharType, size_t N>
  411. typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
  412. const GenericPointer<typename T::ValueType> pointer(source, N - 1);
  413. return SetValueByPointer(root, pointer, value, a);
  414. }
  415. template <typename T, typename CharType, size_t N, typename T2>
  416. RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
  417. SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
  418. const GenericPointer<typename T::ValueType> pointer(source, N - 1);
  419. return SetValueByPointer(root, pointer, value, a);
  420. }
  421. template <typename T>
  422. typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
  423. return pointer.Swap(root, value, a);
  424. }
  425. template <typename T, typename CharType, size_t N>
  426. typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
  427. const GenericPointer<typename T::ValueType> pointer(source, N - 1);
  428. return SwapValueByPointer(root, pointer, value, a);
  429. }
  430. typedef GenericPointer<Value> Pointer;
  431. RAPIDJSON_NAMESPACE_END
  432. #endif // RAPIDJSON_POINTER_H_