Jamoma API  0.6.0.a19
JSONSharedString.h
1 #ifndef JSON_SHARED_STRING_H
2 #define JSON_SHARED_STRING_H
3 
4 /*
5  * This class allows json objects to share string
6  * Since libjson is a parser, it does a lot of substrings, but since
7  * a string with all of the information already exists, those substrings
8  * can be infered by an offset and length and a pointer to the master
9  * string
10  *
11  * EXPERIMENTAL, Not used yet
12  */
13 
14 #include "JSONDebug.h"
15 #include "JSONGlobals.h"
16 #include "JSONMemory.h"
17 
18 /*
19 mallocs: 3351
20 frees: 3351
21 reallocs: 3
22 bytes: 298751 (291 KB)
23 max bytes at once: 3624 (3 KB)
24 avg bytes at once: 970 (0 KB)
25 */
26 
27 #ifdef JSON_LESS_MEMORY
28  #ifdef __GNUC__
29  #pragma pack(push, 1)
30  #elif _MSC_VER
31  #pragma pack(push, json_shared_string_pack, 1)
32  #endif
33 #endif
34 
35 class json_shared_string {
36 public:
37 
38 
39  struct iterator;
40  struct const_iterator {
41  const_iterator(const json_char * p, const json_shared_string * pa) : parent(pa), it(p){}
42 
43  inline const_iterator& operator ++(void) json_nothrow { ++it; return *this; }
44  inline const_iterator& operator --(void) json_nothrow { --it; return *this; }
45  inline const_iterator& operator +=(long i) json_nothrow { it += i; return *this; }
46  inline const_iterator& operator -=(long i) json_nothrow { it -= i; return *this; }
47  inline const_iterator operator ++(int) json_nothrow {
48  const_iterator result(*this);
49  ++it;
50  return result;
51  }
52  inline const_iterator operator --(int) json_nothrow {
53  const_iterator result(*this);
54  --it;
55  return result;
56  }
57  inline const_iterator operator +(long i) const json_nothrow {
58  const_iterator result(*this);
59  result.it += i;
60  return result;
61  }
62  inline const_iterator operator -(long i) const json_nothrow {
63  const_iterator result(*this);
64  result.it -= i;
65  return result;
66  }
67  inline const json_char & operator [](size_t pos) const json_nothrow { return it[pos]; };
68  inline const json_char & operator *(void) const json_nothrow { return *it; }
69  inline const json_char * operator ->(void) const json_nothrow { return it; }
70  inline bool operator == (const const_iterator & other) const json_nothrow { return it == other.it; }
71  inline bool operator != (const const_iterator & other) const json_nothrow { return it != other.it; }
72  inline bool operator > (const const_iterator & other) const json_nothrow { return it > other.it; }
73  inline bool operator >= (const const_iterator & other) const json_nothrow { return it >= other.it; }
74  inline bool operator < (const const_iterator & other) const json_nothrow { return it < other.it; }
75  inline bool operator <= (const const_iterator & other) const json_nothrow { return it <= other.it; }
76 
77  inline bool operator == (const iterator & other) const json_nothrow { return it == other.it; }
78  inline bool operator != (const iterator & other) const json_nothrow { return it != other.it; }
79  inline bool operator > (const iterator & other) const json_nothrow { return it > other.it; }
80  inline bool operator >= (const iterator & other) const json_nothrow { return it >= other.it; }
81  inline bool operator < (const iterator & other) const json_nothrow { return it < other.it; }
82  inline bool operator <= (const iterator & other) const json_nothrow { return it <= other.it; }
83 
84  inline const_iterator & operator =(const const_iterator & orig) json_nothrow { it = orig.it; return *this; }
85  const_iterator (const const_iterator & orig) json_nothrow : it(orig.it) {}
86  private:
87  const json_shared_string * parent;
88  const json_char * it;
89  friend class json_shared_string;
90  friend struct iterator;
91  };
92 
93  struct iterator {
94  iterator(const json_char * p, const json_shared_string * pa) : parent(pa), it(p){}
95 
96  inline iterator& operator ++(void) json_nothrow { ++it; return *this; }
97  inline iterator& operator --(void) json_nothrow { --it; return *this; }
98  inline iterator& operator +=(long i) json_nothrow { it += i; return *this; }
99  inline iterator& operator -=(long i) json_nothrow { it -= i; return *this; }
100  inline iterator operator ++(int) json_nothrow {
101  iterator result(*this);
102  ++it;
103  return result;
104  }
105  inline iterator operator --(int) json_nothrow {
106  iterator result(*this);
107  --it;
108  return result;
109  }
110  inline iterator operator +(long i) const json_nothrow {
111  iterator result(*this);
112  result.it += i;
113  return result;
114  }
115  inline iterator operator -(long i) const json_nothrow {
116  iterator result(*this);
117  result.it -= i;
118  return result;
119  }
120  inline const json_char & operator [](size_t pos) const json_nothrow { return it[pos]; };
121  inline const json_char & operator *(void) const json_nothrow { return *it; }
122  inline const json_char * operator ->(void) const json_nothrow { return it; }
123  inline bool operator == (const const_iterator & other) const json_nothrow { return it == other.it; }
124  inline bool operator != (const const_iterator & other) const json_nothrow { return it != other.it; }
125  inline bool operator > (const const_iterator & other) const json_nothrow { return it > other.it; }
126  inline bool operator >= (const const_iterator & other) const json_nothrow { return it >= other.it; }
127  inline bool operator < (const const_iterator & other) const json_nothrow { return it < other.it; }
128  inline bool operator <= (const const_iterator & other) const json_nothrow { return it <= other.it; }
129 
130  inline bool operator == (const iterator & other) const json_nothrow { return it == other.it; }
131  inline bool operator != (const iterator & other) const json_nothrow { return it != other.it; }
132  inline bool operator > (const iterator & other) const json_nothrow { return it > other.it; }
133  inline bool operator >= (const iterator & other) const json_nothrow { return it >= other.it; }
134  inline bool operator < (const iterator & other) const json_nothrow { return it < other.it; }
135  inline bool operator <= (const iterator & other) const json_nothrow { return it <= other.it; }
136 
137  inline iterator & operator =(const iterator & orig) json_nothrow { it = orig.it; return *this; }
138  iterator (const iterator & orig) json_nothrow : it(orig.it) {}
139  private:
140  const json_shared_string * parent;
141  const json_char * it;
142  friend class json_shared_string;
143  friend struct const_iterator;
144  };
145 
146 
147 
148  inline json_shared_string::iterator begin(void){
149  iterator res = iterator(data(), this);
150  return res;
151  }
152  inline json_shared_string::iterator end(void){
153  iterator res = iterator(data() + len, this);
154  return res;
155  }
156  inline json_shared_string::const_iterator begin(void) const {
157  const_iterator res = const_iterator(data(), this);
158  return res;
159  }
160  inline json_shared_string::const_iterator end(void) const {
161  const_iterator res = const_iterator(data() + len, this);
162  return res;
163  }
164 
165 
166  inline json_string::iterator std_begin(void){
167  return _str -> mystring.begin() + offset;
168  }
169  inline json_string::iterator std_end(void){
170  return std_begin() + len;
171  }
172 
173  inline json_string::const_iterator std_begin(void) const{
174  return _str -> mystring.begin() + offset;
175  }
176  inline json_string::const_iterator std_end(void) const{
177  return std_begin() + len;
178  }
179 
180  inline json_shared_string(void) : offset(0), len(0), _str(new(json_malloc<json_shared_string_internal>(1)) json_shared_string_internal(json_global(EMPTY_JSON_STRING))) {}
181 
182  inline json_shared_string(const json_string & str) : offset(0), len(str.length()), _str(new(json_malloc<json_shared_string_internal>(1)) json_shared_string_internal(str)) {}
183 
184  inline json_shared_string(const json_shared_string & str, size_t _offset, size_t _len) : _str(str._str), offset(str.offset + _offset), len(_len) {
185  ++_str -> refCount;
186  }
187 
188  inline json_shared_string(const json_shared_string & str, size_t _offset) : _str(str._str), offset(str.offset + _offset), len(str.len - _offset) {
189  ++_str -> refCount;
190  }
191 
192  inline json_shared_string(const iterator & s, const iterator & e) : _str(s.parent -> _str), offset(s.it - s.parent -> _str -> mystring.data()), len(e.it - s.it){
193  ++_str -> refCount;
194  }
195 
196  inline ~json_shared_string(void){
197  deref();
198  }
199 
200  inline bool empty(void) const { return len == 0; }
201 
202  size_t find(json_char ch, size_t pos = 0) const {
203  if (_str -> refCount == 1) return _str -> mystring.find(ch, pos);
204  json_string::const_iterator e = std_end();
205  for(json_string::const_iterator b = std_begin() + pos; b != e; ++b){
206  if (*b == ch) return b - std_begin();
207  }
208  return json_string::npos;
209  }
210 
211  inline json_char & operator[] (size_t loc){
212  return _str -> mystring[loc + offset];
213  }
214  inline json_char operator[] (size_t loc) const {
215  return _str -> mystring[loc + offset];
216  }
217  inline void clear(){ len = 0; }
218  inline size_t length() const { return len; }
219  inline const json_char * c_str() const { return toString().c_str(); }
220  inline const json_char * data() const { return _str -> mystring.data() + offset; }
221 
222  inline bool operator != (const json_shared_string & other) const {
223  if ((other._str == _str) && (other.len == len) && (other.offset == offset)) return false;
224  return other.toString() != toString();
225  }
226 
227  inline bool operator == (const json_shared_string & other) const {
228  if ((other._str == _str) && (other.len == len) && (other.offset == offset)) return true;
229  return other.toString() == toString();
230  }
231 
232  inline bool operator == (const json_string & other) const {
233  return other == toString();
234  }
235 
236  json_string & toString(void) const {
237  //gonna have to do a real substring now anyway, so do it completely
238  if (_str -> refCount == 1){
239  if (offset || len != _str -> mystring.length()){
240  _str -> mystring = json_string(std_begin(), std_end());
241  }
242  } else if (offset || len != _str -> mystring.length()){
243  --_str -> refCount; //dont use deref because I know its not going to be deleted
244  _str = new(json_malloc<json_shared_string_internal>(1)) json_shared_string_internal(json_string(std_begin(), std_end()));
245  }
246  offset = 0;
247  return _str -> mystring;
248  }
249 
250 
251  inline void assign(const json_shared_string & other, size_t _offset, size_t _len){
252  if (other._str != _str){
253  deref();
254  _str = other._str;
255  }
256  ++_str -> refCount;
257  offset = other.offset + _offset;
258  len = _len;
259  }
260 
261  json_shared_string(const json_shared_string & other) : _str(other._str), offset(other.offset), len(other.len){
262  ++_str -> refCount;
263  }
264 
265  json_shared_string & operator =(const json_shared_string & other){
266  if (other._str != _str){
267  deref();
268  _str = other._str;
269  ++_str -> refCount;
270  }
271  offset = other.offset;
272  len = other.len;
273  return *this;
274  }
275 
276  json_shared_string & operator += (const json_char c){
277  toString() += c;
278  ++len;
279  return *this;
280  }
281 
282  //when doing a plus equal of another string, see if it shares the string and starts where this one left off, in which case just increase len
283 JSON_PRIVATE
284  struct json_shared_string_internal {
285  inline json_shared_string_internal(const json_string & _mystring) : mystring(_mystring), refCount(1) {}
286  json_string mystring;
287  size_t refCount PACKED(20);
288  };
289  inline void deref(void){
290  if (--_str -> refCount == 0){
291  _str -> ~json_shared_string_internal();
292  libjson_free<json_shared_string_internal>(_str);
293  }
294  }
295  mutable json_shared_string_internal * _str;
296  mutable size_t offset PACKED(20);
297  mutable size_t len PACKED(20);
298 };
299 
300 #ifdef JSON_LESS_MEMORY
301  #ifdef __GNUC__
302  #pragma pack(pop)
303  #elif _MSC_VER
304  #pragma pack(pop, json_shared_string_pack,)
305  #endif
306 #endif
307 
308 #endif
bool TTFOUNDATION_EXPORT operator!=(const TTObject &anObject, const TTObject &anotherObject)
Compare two objects for inequality.
Definition: TTObject.cpp:173
bool TTFOUNDATION_EXPORT operator==(const TTObject &anObject, const TTObject &anotherObject)
Compare two objects for equality.
Definition: TTObject.cpp:167