Skip to content
Browse files

Allow a different memory management strategy in case there is already…

… allocated memory.
  • Loading branch information...
1 parent 089e44d commit f8ea6bab54e32cb458d119cc14d27d6561a17cbb @derickr derickr committed with tricky Dec 6, 2011
Showing with 63 additions and 7 deletions.
  1. +43 −7 igbinary.c
  2. +20 −0 igbinary.h
View
50 igbinary.c
@@ -131,6 +131,7 @@ struct igbinary_serialize_data {
struct hash_si objects; /**< Hash of already serialized objects. */
int string_count; /**< Serialized string count, used for back referencing */
int error; /**< Error number. Not used. */
+ struct igbinary_memory_manager mm; /**< Memory management functions. */
};
/** String/len pair for the igbinary_unserializer_data.
@@ -162,8 +163,13 @@ struct igbinary_unserialize_data {
smart_str string0_buf; /**< Temporary buffer for strings */
};
/* }}} */
+/* {{{ Memory allocator wrapper prototypes */
+static inline void *igbinary_mm_wrapper_malloc(size_t size, void *context);
+static inline void *igbinary_mm_wrapper_realloc(void *ptr, size_t size, void *context);
+static inline void igbinary_mm_wrapper_free(void *ptr, void *context);
+/* }}} */
/* {{{ Serializing functions prototypes */
-inline static int igbinary_serialize_data_init(struct igbinary_serialize_data *igsd, bool scalar TSRMLS_DC);
+inline static int igbinary_serialize_data_init(struct igbinary_serialize_data *igsd, bool scalar, struct igbinary_memory_manager *memory_manager TSRMLS_DC);
inline static void igbinary_serialize_data_deinit(struct igbinary_serialize_data *igsd, int free_buffer TSRMLS_DC);
inline static int igbinary_serialize_header(struct igbinary_serialize_data *igsd TSRMLS_DC);
@@ -348,11 +354,32 @@ PHP_MINFO_FUNCTION(igbinary) {
DISPLAY_INI_ENTRIES();
}
/* }}} */
+/* {{{ Memory allocator wrappers */
+static inline void *igbinary_mm_wrapper_malloc(size_t size, void *context)
+{
+ return emalloc(size);
+}
+
+static inline void *igbinary_mm_wrapper_realloc(void *ptr, size_t size, void *context)
+{
+ return erealloc(ptr, size);
+}
+
+static inline void igbinary_mm_wrapper_free(void *ptr, void *context)
+{
+ return efree(ptr);
+}
+/* }}} */
/* {{{ int igbinary_serialize(uint8_t**, size_t*, zval*) */
IGBINARY_API int igbinary_serialize(uint8_t **ret, size_t *ret_len, zval *z TSRMLS_DC) {
+ return igbinary_serialize_ex(ret, ret_len, z, NULL TSRMLS_CC);
+}
+/* }}} */
+/* {{{ int igbinary_serialize_ex(uint8_t**, size_t*, zval*, igbinary_memory_manager*) */
+IGBINARY_API int igbinary_serialize_ex(uint8_t **ret, size_t *ret_len, zval *z, struct igbinary_memory_manager *memory_manager TSRMLS_DC) {
struct igbinary_serialize_data igsd;
- if (igbinary_serialize_data_init(&igsd, Z_TYPE_P(z) != IS_OBJECT && Z_TYPE_P(z) != IS_ARRAY TSRMLS_CC)) {
+ if (igbinary_serialize_data_init(&igsd, Z_TYPE_P(z) != IS_OBJECT && Z_TYPE_P(z) != IS_ARRAY, memory_manager TSRMLS_CC)) {
zend_error(E_WARNING, "igbinary_serialize: cannot init igsd");
return 1;
}
@@ -458,7 +485,7 @@ PS_SERIALIZER_ENCODE_FUNC(igbinary)
struct igbinary_serialize_data igsd;
char *s;
- if (igbinary_serialize_data_init(&igsd, false TSRMLS_CC)) {
+ if (igbinary_serialize_data_init(&igsd, false, NULL TSRMLS_CC)) {
zend_error(E_WARNING, "igbinary_serialize: cannot init igsd");
return FAILURE;
}
@@ -581,16 +608,25 @@ static int APC_UNSERIALIZER_NAME(igbinary) ( APC_UNSERIALIZER_ARGS ) {
/* {{{ igbinary_serialize_data_init */
/** Inits igbinary_serialize_data. */
-inline static int igbinary_serialize_data_init(struct igbinary_serialize_data *igsd, bool scalar TSRMLS_DC) {
+inline static int igbinary_serialize_data_init(struct igbinary_serialize_data *igsd, bool scalar, struct igbinary_memory_manager *memory_manager TSRMLS_DC) {
int r = 0;
+ if (memory_manager == NULL) {
+ igsd->mm.alloc = igbinary_mm_wrapper_malloc;
+ igsd->mm.realloc = igbinary_mm_wrapper_realloc;
+ igsd->mm.free = igbinary_mm_wrapper_free;
+ igsd->mm.context = NULL;
+ } else {
+ igsd->mm = *memory_manager;
+ }
+
igsd->buffer = NULL;
igsd->buffer_size = 0;
igsd->buffer_capacity = 32;
igsd->string_count = 0;
igsd->error = 0;
- igsd->buffer = (uint8_t *) emalloc(igsd->buffer_capacity);
+ igsd->buffer = (uint8_t *) igsd->mm.alloc(igsd->buffer_capacity, igsd->mm.context);
if (igsd->buffer == NULL) {
return 1;
}
@@ -610,7 +646,7 @@ inline static int igbinary_serialize_data_init(struct igbinary_serialize_data *i
/** Deinits igbinary_serialize_data. */
inline static void igbinary_serialize_data_deinit(struct igbinary_serialize_data *igsd, int free_buffer TSRMLS_DC) {
if (free_buffer && igsd->buffer) {
- efree(igsd->buffer);
+ igsd->mm.free(igsd->buffer, igsd->mm.context);
}
if (!igsd->scalar) {
@@ -636,7 +672,7 @@ inline static int igbinary_serialize_resize(struct igbinary_serialize_data *igsd
igsd->buffer_capacity *= 2;
}
- igsd->buffer = (uint8_t *) erealloc(igsd->buffer, igsd->buffer_capacity);
+ igsd->buffer = (uint8_t *) igsd->mm.realloc(igsd->buffer, igsd->buffer_capacity, igsd->mm.context);
if (igsd->buffer == NULL)
return 1;
View
20 igbinary.h
@@ -32,6 +32,16 @@
#define IGBINARY_VERSION "1.1.2-dev"
+/** Struct that contains pointers to memory allocation and deallocation functions.
+ * @see igbinary_serialize_data
+ */
+struct igbinary_memory_manager {
+ void *(*alloc)(size_t size, void *context);
+ void *(*realloc)(void *ptr, size_t new_size, void *context);
+ void (*free)(void *ptr, void *context);
+ void *context;
+};
+
/** Serialize zval.
* Return buffer is allocated by this function with emalloc.
* @param[out] ret Return buffer
@@ -41,6 +51,16 @@
*/
IGBINARY_API int igbinary_serialize(uint8_t **ret, size_t *ret_len, zval *z TSRMLS_DC);
+/** Serialize zval.
+ * Return buffer is allocated by this function with emalloc.
+ * @param[out] ret Return buffer
+ * @param[out] ret_len Size of return buffer
+ * @param[in] z Variable to be serialized
+ * @param[in] memory_manager Pointer to the structure that contains memory allocation functions.
+ * @return 0 on success, 1 elsewhere.
+ */
+IGBINARY_API int igbinary_serialize_ex(uint8_t **ret, size_t *ret_len, zval *z, struct igbinary_memory_manager *memory_manager TSRMLS_DC);
+
/** Unserialize to zval.
* @param[in] buf Buffer with serialized data.
* @param[in] buf_len Buffer length.

0 comments on commit f8ea6ba

Please sign in to comment.
Something went wrong with that request. Please try again.