diff options
Diffstat (limited to 'plugins/JSON/Source/JSONMemory.h')
-rw-r--r-- | plugins/JSON/Source/JSONMemory.h | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/plugins/JSON/Source/JSONMemory.h b/plugins/JSON/Source/JSONMemory.h new file mode 100644 index 0000000000..4797bd619f --- /dev/null +++ b/plugins/JSON/Source/JSONMemory.h @@ -0,0 +1,134 @@ +#ifndef JSON_MEMORY_H +#define JSON_MEMORY_H + +#include <cstdlib> //for malloc, realloc, and free +#include <cstring> //for memmove +#include "../JSONOptions.h" +#include "JSONDebug.h" + +#if defined(JSON_DEBUG) || defined(JSON_SAFE) + #define JSON_FREE_PASSTYPE & +#else + #define JSON_FREE_PASSTYPE +#endif + +#ifdef JSON_MEMORY_CALLBACKS + class JSONMemory { + public: + static void * json_malloc(size_t siz); + static void * json_realloc(void * ptr, size_t siz); + static void json_free(void * ptr); + static void registerMemoryCallbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre); + }; + + template <typename T> static inline T * json_malloc(size_t count){ + return (T *)JSONMemory::json_malloc(sizeof(T) * count); + } + + template <typename T> static inline T * json_realloc(T * ptr, size_t count){ + return (T *)JSONMemory::json_realloc(ptr, sizeof(T) * count); + } + + template <typename T> static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr){ + 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){ + #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful + void * result = malloc(count * sizeof(T)); + JSON_ASSERT(result, JSON_TEXT("out of memory")); + #ifdef JSON_NULL_MEMORY + memset(result, '\0', count * sizeof(T)); + #endif + return (T *)result; + #else + return (T *)malloc(count * sizeof(T)); + #endif + } + + template <typename T> + static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr){ + 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){ + #ifdef JSON_DEBUG //in debug mode, check the results of realloc to be sure it was successful + void * result = realloc(ptr, count * sizeof(T)); + JSON_ASSERT(result, JSON_TEXT("out of memory")); + #ifdef JSON_NULL_MEMORY + memset(result, '\0', count * sizeof(T)); + #endif + return (T *)result; + #else + return (T *)realloc(ptr, count * sizeof(T)); + #endif + } +#endif + +#ifdef JSON_MEMORY_MANAGE + #include <map> + class JSONNode; + struct auto_expand { + auto_expand(void) : mymap(){} + ~auto_expand(void){ purge(); } + void purge(void); + inline void clear(void){ purge(); mymap.clear(); } + inline void * insert(void * ptr){ mymap[ptr] = ptr; return ptr; } + inline void remove(void * ptr){ + std::map<void *, void *>::iterator i = mymap.find(ptr); + JSON_ASSERT(i != mymap.end(), JSON_TEXT("Removing a non-managed item")); + mymap.erase(i); + } + std::map<void *, void *> mymap; + }; + + struct auto_expand_node { + auto_expand_node(void) : mymap(){} + ~auto_expand_node(void){ purge(); } + void purge(void); + inline void clear(void){ purge(); mymap.clear(); } + inline JSONNode * insert(JSONNode * ptr){ mymap[ptr] = ptr; return ptr; } + inline void remove(void * ptr){ + std::map<void *, JSONNode *>::iterator i = mymap.find(ptr); + if(i != mymap.end()) mymap.erase(i); + } + std::map<void *, JSONNode *> mymap; + }; +#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: + json_auto(void) : ptr(0){} + json_auto(size_t count) : ptr(json_malloc<T>(count)){} + ~json_auto(void){ + libjson_free<T>(ptr); + } + void set(T * p){ + 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){ + #ifdef JSON_LESS_MEMORY + json_string().swap(str); + #else + str.clear(); + #endif +} + +#endif |