| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #ifndef JSON_MEMORY_H
- #define JSON_MEMORY_H
- #include <cstdlib> //for malloc, realloc, and free
- #include <cstring> //for memmove
- #include "JSONDebug.h"
- #if defined(JSON_DEBUG) || defined(JSON_SAFE)
- #define JSON_FREE_PASSTYPE &
- #else
- #define JSON_FREE_PASSTYPE
- #endif
- #if defined(JSON_MEMORY_CALLBACKS) || defined(JSON_MEMORY_POOL)
- class JSONMemory {
- public:
- static void * json_malloc(size_t siz) json_malloc_attr;
- static void * json_realloc(void * ptr, size_t siz) json_malloc_attr;
- static void json_free(void * ptr) json_nothrow;
- static void registerMemoryCallbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre) json_nothrow json_cold;
- private:
- JSONMemory(void);
- };
- template <typename T> static inline T * json_malloc(size_t count) json_malloc_attr;
- template <typename T> static inline T * json_malloc(size_t count) json_nothrow {
- return (T *)JSONMemory::json_malloc(sizeof(T) * count);
- }
- template <typename T> static inline T * json_realloc(T * ptr, size_t count) json_malloc_attr;
- template <typename T> static inline T * json_realloc(T * ptr, size_t count) json_nothrow {
- return (T *)JSONMemory::json_realloc(ptr, sizeof(T) * count);
- }
- template <typename T> static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr) json_nothrow {
- JSONMemory::json_free(ptr);
- #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
- ptr = 0;
- #endif
- }
- #else
- template <typename T> static inline T * json_malloc(size_t count) json_malloc_attr;
- template <typename T> static inline T * json_malloc(size_t count) json_nothrow {
- #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
- void * result = std::malloc(count * sizeof(T));
- JSON_ASSERT(result != 0, JSON_TEXT("Out of memory"));
- #ifdef JSON_NULL_MEMORY
- std::memset(result, '\0', count * sizeof(T));
- #endif
- return (T *)result;
- #else
- return (T *)std::malloc(count * sizeof(T));
- #endif
- }
- template <typename T> static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr) json_nothrow {
- std::free(ptr);
- #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
- ptr = 0;
- #endif
- }
- template <typename T> static inline T * json_realloc(T * ptr, size_t count) json_malloc_attr;
- template <typename T> static inline T * json_realloc(T * ptr, size_t count) json_nothrow {
- #ifdef JSON_DEBUG //in debug mode, check the results of realloc to be sure it was successful
- void * result = std::realloc(ptr, count * sizeof(T));
- JSON_ASSERT(result != 0, JSON_TEXT("Out of memory"));
- return (T *)result;
- #else
- return (T *)std::realloc(ptr, count * sizeof(T));
- #endif
- }
- #endif
- #ifdef JSON_MEMORY_MANAGE
- #include <map>
- class JSONNode;
- struct auto_expand {
- public:
- LIBJSON_OBJECT(auto_expand);
- auto_expand(void) json_nothrow : mymap(){ LIBJSON_CTOR;}
- ~auto_expand(void) json_nothrow { purge(); LIBJSON_DTOR; }
- void purge(void) json_nothrow;
- inline void clear(void) json_nothrow { purge(); mymap.clear(); }
- inline void * insert(void * ptr) json_nothrow { mymap[ptr] = ptr; return ptr; }
- inline void remove(void * ptr) json_nothrow {
- JSON_MAP(void *, void *)::iterator i = mymap.find(ptr);
- JSON_ASSERT(i != mymap.end(), JSON_TEXT("Removing a non-managed item"));
- mymap.erase(i);
- }
- JSON_MAP(void *, void *) mymap;
- private:
- auto_expand(const auto_expand &);
- auto_expand & operator = (const auto_expand &);
- };
- struct auto_expand_node {
- public:
- LIBJSON_OBJECT(auto_expand_node);
- auto_expand_node(void) json_nothrow : mymap(){ LIBJSON_CTOR; }
- ~auto_expand_node(void) json_nothrow { purge(); LIBJSON_DTOR; }
- void purge(void) json_nothrow ;
- inline void clear(void) json_nothrow { purge(); mymap.clear(); }
- inline JSONNode * insert(JSONNode * ptr) json_nothrow { mymap[ptr] = ptr; return ptr; }
- inline void remove(void * ptr) json_nothrow {
- JSON_MAP(void *, JSONNode *)::iterator i = mymap.find(ptr);
- if(json_likely(i != mymap.end())) mymap.erase(i);
- }
- JSON_MAP(void *, JSONNode *) mymap;
- private:
- auto_expand_node(const auto_expand_node &);
- auto_expand_node & operator = (const auto_expand_node &);
- };
- #ifdef JSON_STREAM
- class JSONStream;
- struct auto_expand_stream {
- public:
- LIBJSON_OBJECT(auto_expand_stream);
- auto_expand_stream(void) json_nothrow : mymap(){ LIBJSON_CTOR; }
- ~auto_expand_stream(void) json_nothrow { purge(); LIBJSON_DTOR; }
- void purge(void) json_nothrow ;
- inline void clear(void) json_nothrow { purge(); mymap.clear(); }
- inline JSONStream * insert(JSONStream * ptr) json_nothrow { mymap[ptr] = ptr; return ptr; }
- inline void remove(void * ptr) json_nothrow {
- JSON_MAP(void *, JSONStream *)::iterator i = mymap.find(ptr);
- if(json_likely(i != mymap.end())) mymap.erase(i);
- }
- JSON_MAP(void *, JSONStream *) mymap;
- private:
- auto_expand_stream(const auto_expand_stream &);
- auto_expand_stream & operator = (const auto_expand_stream &);
- };
- #endif
- #endif
- //The C++ way, use an self-deleting pointer and let the optimizer decide when it gets destroyed
- template <typename T>
- class json_auto {
- public:
- LIBJSON_OBJECT(json_auto);
- json_auto(void) json_nothrow : ptr(0){ LIBJSON_CTOR; }
- json_auto(size_t count) json_nothrow : ptr(json_malloc<T>(count)){ LIBJSON_CTOR; }
- json_auto(T * arg) json_nothrow : ptr(arg){ LIBJSON_CTOR; }
- ~json_auto(void) json_nothrow {
- libjson_free<T>(ptr);
- LIBJSON_DTOR;
- }
- inline void set(T * p) json_nothrow{
- ptr = p;
- }
- T * ptr;
- private:
- json_auto(const json_auto &);
- json_auto & operator =(const json_auto &);
- };
- //Clears a string, if required, frees the memory
- static inline void clearString(json_string & str) json_nothrow {
- #ifdef JSON_LESS_MEMORY
- json_string().swap(str);
- #else
- str.clear();
- #endif
- }
- //Shrinks a string
- static inline void shrinkString(json_string & str) json_nothrow {
- #ifdef JSON_LESS_MEMORY
- if (str.capacity() != str.length()) str = json_string(str.begin(), str.end());
- #endif
- }
- #endif
|