JSONSharedString.h 11 KB

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