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