Jamoma API  0.6.0.a19
JSONMemory.h
1 #ifndef JSON_MEMORY_H
2 #define JSON_MEMORY_H
3 
4 #include <cstdlib> //for malloc, realloc, and free
5 #include <cstring> //for memmove
6 #include "JSONDebug.h"
7 
8 #if defined(JSON_DEBUG) || defined(JSON_SAFE)
9  #define JSON_FREE_PASSTYPE &
10 #else
11  #define JSON_FREE_PASSTYPE
12 #endif
13 
14 #if defined(JSON_MEMORY_CALLBACKS) || defined(JSON_MEMORY_POOL)
15  class JSONMemory {
16  public:
17  static void * json_malloc(size_t siz) json_malloc_attr;
18  static void * json_realloc(void * ptr, size_t siz) json_malloc_attr;
19  static void json_free(void * ptr) json_nothrow;
20  static void registerMemoryCallbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre) json_nothrow json_cold;
21  private:
22  JSONMemory(void);
23  };
24 
25  template <typename T> static inline T * json_malloc(size_t count) json_malloc_attr;
26  template <typename T> static inline T * json_malloc(size_t count) json_nothrow {
27  return (T *)JSONMemory::json_malloc(sizeof(T) * count);
28  }
29 
30  template <typename T> static inline T * json_realloc(T * ptr, size_t count) json_malloc_attr;
31  template <typename T> static inline T * json_realloc(T * ptr, size_t count) json_nothrow {
32  return (T *)JSONMemory::json_realloc(ptr, sizeof(T) * count);
33  }
34 
35  template <typename T> static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr) json_nothrow {
36  JSONMemory::json_free(ptr);
37  #if defined(JSON_DEBUG) || defined(JSON_SAFE) //in debug or safe mode, set the pointer to 0 so that it can't be used again
38  ptr = 0;
39  #endif
40  }
41 #else
42 
43  template <typename T> static inline T * json_malloc(size_t count) json_malloc_attr;
44  template <typename T> static inline T * json_malloc(size_t count) json_nothrow {
45  #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
46  void * result = std::malloc(count * sizeof(T));
47  JSON_ASSERT(result != 0, JSON_TEXT("Out of memory"));
48  #ifdef JSON_NULL_MEMORY
49  std::memset(result, '\0', count * sizeof(T));
50  #endif
51  return (T *)result;
52  #else
53  return (T *)std::malloc(count * sizeof(T));
54  #endif
55  }
56 
57  template <typename T> static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr) json_nothrow {
58  std::free(ptr);
59  #if defined(JSON_DEBUG) || defined(JSON_SAFE) //in debug or safe mode, set the pointer to 0 so that it can't be used again
60  ptr = 0;
61  #endif
62  }
63 
64  template <typename T> static inline T * json_realloc(T * ptr, size_t count) json_malloc_attr;
65  template <typename T> static inline T * json_realloc(T * ptr, size_t count) json_nothrow {
66  #ifdef JSON_DEBUG //in debug mode, check the results of realloc to be sure it was successful
67  void * result = std::realloc(ptr, count * sizeof(T));
68  JSON_ASSERT(result != 0, JSON_TEXT("Out of memory"));
69  return (T *)result;
70  #else
71  return (T *)std::realloc(ptr, count * sizeof(T));
72  #endif
73  }
74 #endif
75 
76 #ifdef JSON_MEMORY_MANAGE
77  #include <map>
78  class JSONNode;
79  struct auto_expand {
80  public:
81  LIBJSON_OBJECT(auto_expand);
82  auto_expand(void) json_nothrow : mymap(){ LIBJSON_CTOR;}
83  ~auto_expand(void) json_nothrow { purge(); LIBJSON_DTOR; }
84  void purge(void) json_nothrow;
85  inline void clear(void) json_nothrow { purge(); mymap.clear(); }
86  inline void * insert(void * ptr) json_nothrow { mymap[ptr] = ptr; return ptr; }
87  inline void remove(void * ptr) json_nothrow {
88  JSON_MAP(void *, void *)::iterator i = mymap.find(ptr);
89  JSON_ASSERT(i != mymap.end(), JSON_TEXT("Removing a non-managed item"));
90  mymap.erase(i);
91  }
92  JSON_MAP(void *, void *) mymap;
93  private:
94  auto_expand(const auto_expand &);
95  auto_expand & operator = (const auto_expand &);
96  };
97 
98  struct auto_expand_node {
99  public:
100  LIBJSON_OBJECT(auto_expand_node);
101  auto_expand_node(void) json_nothrow : mymap(){ LIBJSON_CTOR; }
102  ~auto_expand_node(void) json_nothrow { purge(); LIBJSON_DTOR; }
103  void purge(void) json_nothrow ;
104  inline void clear(void) json_nothrow { purge(); mymap.clear(); }
105  inline JSONNode * insert(JSONNode * ptr) json_nothrow { mymap[ptr] = ptr; return ptr; }
106  inline void remove(void * ptr) json_nothrow {
107  JSON_MAP(void *, JSONNode *)::iterator i = mymap.find(ptr);
108  if(json_likely(i != mymap.end())) mymap.erase(i);
109  }
110  JSON_MAP(void *, JSONNode *) mymap;
111  private:
112  auto_expand_node(const auto_expand_node &);
113  auto_expand_node & operator = (const auto_expand_node &);
114  };
115 
116  #ifdef JSON_STREAM
117  class JSONStream;
118  struct auto_expand_stream {
119  public:
120  LIBJSON_OBJECT(auto_expand_stream);
121  auto_expand_stream(void) json_nothrow : mymap(){ LIBJSON_CTOR; }
122  ~auto_expand_stream(void) json_nothrow { purge(); LIBJSON_DTOR; }
123  void purge(void) json_nothrow ;
124  inline void clear(void) json_nothrow { purge(); mymap.clear(); }
125  inline JSONStream * insert(JSONStream * ptr) json_nothrow { mymap[ptr] = ptr; return ptr; }
126  inline void remove(void * ptr) json_nothrow {
127  JSON_MAP(void *, JSONStream *)::iterator i = mymap.find(ptr);
128  if(json_likely(i != mymap.end())) mymap.erase(i);
129  }
130  JSON_MAP(void *, JSONStream *) mymap;
131  private:
132  auto_expand_stream(const auto_expand_stream &);
133  auto_expand_stream & operator = (const auto_expand_stream &);
134  };
135  #endif
136 #endif
137 
138 //The C++ way, use an self-deleting pointer and let the optimizer decide when it gets destroyed
139 template <typename T>
140 class json_auto {
141  public:
142  LIBJSON_OBJECT(json_auto);
143  json_auto(void) json_nothrow : ptr(0){ LIBJSON_CTOR; }
144  json_auto(size_t count) json_nothrow : ptr(json_malloc<T>(count)){ LIBJSON_CTOR; }
145  json_auto(T * arg) json_nothrow : ptr(arg){ LIBJSON_CTOR; }
146  ~json_auto(void) json_nothrow {
147  libjson_free<T>(ptr);
148  LIBJSON_DTOR;
149  }
150  inline void set(T * p) json_nothrow{
151  ptr = p;
152  }
153  T * ptr;
154  private:
155  json_auto(const json_auto &);
156  json_auto & operator =(const json_auto &);
157 };
158 
159 //Clears a string, if required, frees the memory
160 static inline void clearString(json_string & str) json_nothrow {
161  #ifdef JSON_LESS_MEMORY
162  json_string().swap(str);
163  #else
164  str.clear();
165  #endif
166 }
167 
168 //Shrinks a string
169 static inline void shrinkString(json_string & str) json_nothrow {
170  #ifdef JSON_LESS_MEMORY
171  if (str.capacity() != str.length()) str = json_string(str.begin(), str.end());
172  #endif
173 }
174 
175 #endif