#ifndef BROTLI_ENC_MEMORY_H_\r
#define BROTLI_ENC_MEMORY_H_\r
\r
-#include "../common/types.h"\r
-#include "./port.h"\r
+#include <string.h> /* memcpy */\r
+\r
+#include "../common/platform.h"\r
+#include <brotli/types.h>\r
\r
#if defined(__cplusplus) || defined(c_plusplus)\r
extern "C" {\r
void* opaque);\r
\r
BROTLI_INTERNAL void* BrotliAllocate(MemoryManager* m, size_t n);\r
-#define BROTLI_ALLOC(M, T, N) ((T*)BrotliAllocate((M), (N) * sizeof(T)))\r
+#define BROTLI_ALLOC(M, T, N) \\r
+ ((N) > 0 ? ((T*)BrotliAllocate((M), (N) * sizeof(T))) : NULL)\r
\r
BROTLI_INTERNAL void BrotliFree(MemoryManager* m, void* p);\r
#define BROTLI_FREE(M, P) { \\r
\r
BROTLI_INTERNAL void BrotliWipeOutMemoryManager(MemoryManager* m);\r
\r
+/*\r
+Dynamically grows array capacity to at least the requested size\r
+M: MemoryManager\r
+T: data type\r
+A: array\r
+C: capacity\r
+R: requested size\r
+*/\r
+#define BROTLI_ENSURE_CAPACITY(M, T, A, C, R) { \\r
+ if (C < (R)) { \\r
+ size_t _new_size = (C == 0) ? (R) : C; \\r
+ T* new_array; \\r
+ while (_new_size < (R)) _new_size *= 2; \\r
+ new_array = BROTLI_ALLOC((M), T, _new_size); \\r
+ if (!BROTLI_IS_OOM(M) && C != 0) \\r
+ memcpy(new_array, A, C * sizeof(T)); \\r
+ BROTLI_FREE((M), A); \\r
+ A = new_array; \\r
+ C = _new_size; \\r
+ } \\r
+}\r
+\r
+/*\r
+Appends value and dynamically grows array capacity when needed\r
+M: MemoryManager\r
+T: data type\r
+A: array\r
+C: array capacity\r
+S: array size\r
+V: value to append\r
+*/\r
+#define BROTLI_ENSURE_CAPACITY_APPEND(M, T, A, C, S, V) { \\r
+ (S)++; \\r
+ BROTLI_ENSURE_CAPACITY(M, T, A, C, S); \\r
+ A[(S) - 1] = (V); \\r
+}\r
+\r
#if defined(__cplusplus) || defined(c_plusplus)\r
} /* extern "C" */\r
#endif\r