1 /* 2 * Copyright 2006-2008 The FLWOR Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ZORBA_STORE_JSON_ITEMS_H 18 #define ZORBA_STORE_JSON_ITEMS_H 19 20 #include <vector> 21 22 #include <zorba/config.h> 23 #include "util/unordered_map.h" 24 25 #include "store/api/item_handle.h" 26 #include "store/api/iterator.h" 27 28 #include "atomic_items.h" 29 #include "simple_collection.h" 30 31 32 namespace zorba 33 { 34 35 namespace store 36 { 37 class CopyMode; 38 } 39 40 namespace simplestore 41 { 42 43 namespace json 44 { 45 46 /****************************************************************************** 47 48 *******************************************************************************/ 49 50 class JSONNull : public AtomicItem 51 { 52 protected: SYNC_CODE(mutable RCLock theRCLock;)53 SYNC_CODE(mutable RCLock theRCLock;) 54 55 public: 56 JSONNull() : AtomicItem() { } 57 ~JSONNull()58 virtual ~JSONNull() {} 59 SYNC_CODE(RCLock * getRCLock ()const{ return &theRCLock; })60 SYNC_CODE(RCLock* getRCLock() const { return &theRCLock; }) 61 62 zstring getStringValue() const { return "null"; } 63 getStringValue2(zstring & val)64 void getStringValue2(zstring& val) const { val = "null"; } 65 appendStringValue(zstring & buf)66 void appendStringValue(zstring& buf) const { buf += "null"; } 67 68 void getTypedValue(store::Item_t& val, store::Iterator_t& iter) const; 69 getTypeCode()70 store::SchemaTypeCode getTypeCode() const { return store::JS_NULL; } 71 72 store::Item* getType() const; 73 74 bool equals( 75 const store::Item* other, 76 long timezone = 0, 77 const XQPCollator* collation = 0) const; 78 79 uint32_t hash(long timezone = 0, const XQPCollator* aCollation = 0) const; 80 getEBV()81 bool getEBV() const { return false; } 82 }; 83 84 85 /****************************************************************************** 86 87 *******************************************************************************/ 88 89 class JSONTree 90 { 91 private: 92 simplestore::Collection * theCollection; 93 TreeId theId; 94 JSONItem * theRoot; 95 96 public: JSONTree()97 JSONTree() : theCollection(NULL), theId(), theRoot(NULL) 98 {} 99 getCollection()100 simplestore::Collection* getCollection() const 101 { 102 return theCollection; 103 } 104 setCollection(simplestore::Collection * aCollection)105 void setCollection(simplestore::Collection* aCollection) 106 { 107 theCollection = aCollection; 108 } 109 getTreeId()110 const TreeId& getTreeId() const 111 { 112 return theId; 113 } 114 setTreeId(const TreeId & aId)115 void setTreeId(const TreeId& aId) 116 { 117 theId = aId; 118 } 119 getRoot()120 JSONItem* getRoot() const 121 { 122 return theRoot; 123 } 124 setRoot(JSONItem * aRoot)125 void setRoot(JSONItem* aRoot) 126 { 127 theRoot = aRoot; 128 } 129 }; 130 131 132 /****************************************************************************** 133 134 *******************************************************************************/ 135 136 class JSONItem : public store::Item 137 { 138 protected: 139 SYNC_CODE(mutable RCLock theRCLock;) 140 141 JSONTree * theTree; 142 143 public: SYNC_CODE(RCLock * getRCLock ()const{ return &theRCLock; })144 SYNC_CODE(RCLock* getRCLock() const { return &theRCLock; }) 145 146 JSONItem() : store::Item(JSONIQ), theTree(NULL) {} 147 148 virtual ~JSONItem(); 149 150 virtual void free(); 151 152 virtual void destroy(); 153 154 const simplestore::Collection* getCollection() const; 155 156 virtual void setTree(JSONTree* aTree) = 0; 157 getTree()158 JSONTree* getTree() const 159 { 160 return theTree; 161 } 162 163 // These two functions are only to be called if in a collection. 164 const TreeId& getTreeId() const; 165 166 JSONItem* getRoot() const; 167 168 void attachToCollection(Collection* aCollection, const TreeId& aTreeId); 169 170 void detachFromCollection(); 171 172 // store API 173 174 virtual bool equals( 175 const store::Item* other, 176 long timezone = 0, 177 const XQPCollator* aCollation = 0) const 178 { 179 return this == other; 180 } 181 182 public: 183 #ifndef NDEBUG 184 virtual void assertInvariant() const; 185 186 virtual bool isThisTreeOfAllDescendants(const JSONTree* aTree) const = 0; 187 188 virtual bool isThisJSONItemInDescendance(const store::Item* aJSONItem) const = 0; 189 #endif 190 }; 191 192 193 /****************************************************************************** 194 195 *******************************************************************************/ 196 197 class JSONObject : public JSONItem 198 { 199 public: ~JSONObject()200 virtual ~JSONObject() {} 201 202 // store API 203 getJSONItemKind()204 virtual store::StoreConsts::JSONItemKind getJSONItemKind() const 205 { 206 return store::StoreConsts::jsonObject; 207 } 208 isJSONObject()209 virtual bool isJSONObject() const { return true; } 210 211 virtual store::Iterator_t getObjectKeys() const = 0; 212 213 virtual store::Item_t getObjectValue(const store::Item_t& aKey) const = 0; 214 215 virtual Item* getType() const; 216 217 // updates 218 219 virtual bool add( 220 const store::Item_t& aName, 221 const store::Item_t& aValue, 222 bool accumulate) = 0; 223 224 virtual store::Item_t remove(const store::Item_t& aName) = 0; 225 226 virtual store::Item_t setValue( 227 const store::Item_t& aName, 228 const store::Item_t& aValue) = 0; 229 230 virtual bool rename( 231 const store::Item_t& aName, 232 const store::Item_t& aNewName) = 0; 233 }; 234 235 236 /****************************************************************************** 237 238 *******************************************************************************/ 239 240 class SimpleJSONObject : public JSONObject 241 { 242 protected: 243 class ConstCharStarHash 244 { 245 public: 246 typedef size_t result_type; operator()247 size_t operator()(const char* a) const 248 { 249 size_t hash = 5381; 250 int c; 251 252 while ((c = *a++)) 253 hash = ((hash << 5) + hash) + c; 254 255 return hash; 256 } 257 }; 258 259 class ConstCharStarComparator 260 { 261 public: operator()262 bool operator()(const char* a, const char* b) const 263 { 264 return strcmp(a, b) == 0; 265 } 266 }; 267 268 typedef std::unordered_map< 269 const char*, 270 csize, 271 ConstCharStarHash, 272 ConstCharStarComparator> Keys; 273 typedef std::vector<std::pair<store::Item*, store::Item*> > Pairs; 274 275 class KeyIterator : public store::Iterator 276 { 277 protected: 278 SimpleJSONObject_t theObject; 279 Pairs::iterator theIter; 280 281 public: KeyIterator(const SimpleJSONObject_t & aObject)282 KeyIterator(const SimpleJSONObject_t& aObject) : theObject(aObject) {} 283 284 virtual ~KeyIterator(); 285 286 virtual void open(); 287 288 virtual bool next(store::Item_t&); 289 290 virtual void reset(); 291 292 virtual void close(); 293 }; 294 295 private: 296 Keys theKeys; 297 Pairs thePairs; 298 299 public: SimpleJSONObject()300 SimpleJSONObject() 301 {} 302 303 virtual ~SimpleJSONObject(); 304 305 // store API 306 307 virtual store::Iterator_t getObjectKeys() const; 308 309 virtual store::Item_t getObjectValue(const store::Item_t& aKey) const; 310 311 virtual store::Item* copy( 312 store::Item* parent, 313 const store::CopyMode& copymode) const; 314 315 virtual zstring getStringValue() const; 316 317 virtual void getStringValue2(zstring& val) const; 318 319 virtual void appendStringValue(zstring& buf) const; 320 321 virtual void getTypedValue(store::Item_t& val, store::Iterator_t& iter) const; 322 323 // updates 324 325 virtual bool add( 326 const store::Item_t& aName, 327 const store::Item_t& aValue, 328 bool accumulate); 329 330 virtual store::Item_t remove(const store::Item_t& aName); 331 332 virtual store::Item_t setValue( 333 const store::Item_t& aName, 334 const store::Item_t& aValue); 335 336 virtual bool rename( 337 const store::Item_t& aName, 338 const store::Item_t& aNewName); 339 340 // root management 341 342 protected: 343 void setTree(JSONTree* aTree); 344 345 // Invariant handling 346 public: 347 #ifndef NDEBUG 348 void assertInvariant() const; 349 350 bool isThisTreeOfAllDescendants(const JSONTree* aTree) const; 351 352 bool isThisJSONItemInDescendance(const store::Item* aJSONItem) const; 353 #endif 354 }; 355 356 357 /****************************************************************************** 358 359 *******************************************************************************/ 360 361 class JSONArray : public JSONItem 362 { 363 public: JSONArray()364 JSONArray() : JSONItem() {} 365 ~JSONArray()366 virtual ~JSONArray() {} 367 368 // store API 369 isJSONArray()370 bool isJSONArray() const { return true; } 371 372 store::StoreConsts::JSONItemKind getJSONItemKind()373 getJSONItemKind() const { return store::StoreConsts::jsonArray; } 374 375 virtual store::Item* 376 getType() const; 377 378 virtual xs_integer getArraySize() const = 0; 379 380 virtual store::Item_t getArrayValue(const xs_integer& position) const = 0; 381 382 virtual store::Iterator_t getArrayValues() const = 0; 383 384 // updates 385 386 virtual void 387 push_back(const store::Item_t& aValue) = 0; 388 389 virtual void 390 push_back(const std::vector<store::Item_t>& members) = 0; 391 392 virtual void 393 push_front(const std::vector<store::Item_t>& members) = 0; 394 395 virtual void 396 insert_before(const xs_integer& pos, const store::Item_t& member) = 0; 397 398 virtual void 399 insert_before(const xs_integer& pos, const std::vector<store::Item_t>& members) = 0; 400 401 virtual void 402 insert_after(const xs_integer& pos, const std::vector<store::Item_t>& members) = 0; 403 404 virtual store::Item_t 405 remove(const xs_integer& pos) = 0; 406 407 virtual store::Item_t 408 replace(const xs_integer& pos, const store::Item_t& value) = 0; 409 }; 410 411 412 /****************************************************************************** 413 414 *******************************************************************************/ 415 416 class SimpleJSONArray : public JSONArray 417 { 418 protected: 419 typedef std::vector<store::Item*> Members; 420 421 class ValuesIterator : public store::Iterator 422 { 423 protected: 424 SimpleJSONArray_t theArray; 425 Members::iterator theIter; 426 427 public: ValuesIterator(const SimpleJSONArray_t & anArray)428 ValuesIterator(const SimpleJSONArray_t& anArray) : theArray(anArray) {} 429 430 virtual ~ValuesIterator(); 431 432 virtual void open(); 433 434 virtual bool next(store::Item_t&); 435 436 virtual void reset(); 437 438 virtual void close(); 439 }; 440 441 private: 442 Members theContent; 443 444 public: SimpleJSONArray()445 SimpleJSONArray() 446 {} 447 448 virtual ~SimpleJSONArray(); 449 450 // store API 451 452 xs_integer getArraySize() const; 453 454 store::Item_t getArrayValue(const xs_integer& position) const; 455 456 store::Iterator_t getArrayValues() const; 457 458 store::Item* copy( 459 store::Item* parent, 460 const store::CopyMode& copymode) const; 461 462 zstring getStringValue() const; 463 464 void getStringValue2(zstring& val) const; 465 466 void appendStringValue(zstring& buf) const; 467 468 void getTypedValue(store::Item_t& val, store::Iterator_t& iter) const; 469 470 // updates 471 472 virtual void 473 push_back(const store::Item_t& aValue); 474 475 virtual void 476 push_back(const std::vector<store::Item_t>& members); 477 478 virtual void 479 push_front(const std::vector<store::Item_t>& members); 480 481 virtual void 482 insert_before(const xs_integer& pos, const store::Item_t& member); 483 484 virtual void 485 insert_before(const xs_integer& pos, const std::vector<store::Item_t>& members); 486 487 virtual void 488 insert_after(const xs_integer& pos, const std::vector<store::Item_t>& members); 489 490 virtual store::Item_t 491 remove(const xs_integer& aPos); 492 493 virtual store::Item_t 494 replace(const xs_integer& aPos, const store::Item_t& value); 495 496 // root management 497 public: 498 void setTree(JSONTree* aTree); 499 500 protected: 501 void add(uint64_t pos, const std::vector<store::Item_t>& aNewMembers); 502 503 static uint64_t cast(const xs_integer& i); 504 505 // Invariant handling 506 public: 507 #ifndef NDEBUG 508 bool isThisTreeOfAllDescendants(const JSONTree* aTree) const; 509 510 bool isThisJSONItemInDescendance(const store::Item* aJSONItem) const; 511 #endif 512 }; 513 514 515 #ifndef NDEBUG 516 #define ASSERT_INVARIANT() assertInvariant() 517 #else 518 #define ASSERT_INVARIANT() 519 #endif 520 521 } // namespace json 522 } // namespace simplestore 523 } // namespace zorba 524 #endif /* ZORBA_STORE_JSON_ITEMS_H */ 525 526 /* 527 * Local variables: 528 * mode: c++ 529 * End: 530 */ 531 /* vim:set et sw=2 ts=2: */ 532 533