summaryrefslogtreecommitdiff
path: root/plugins/JSON/Source/JSONMemory.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/JSON/Source/JSONMemory.h')
-rw-r--r--plugins/JSON/Source/JSONMemory.h134
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