/** * Enlarge an autobuffer if necessary * @param autobuf pointer to autobuf object * @param new_size number of bytes necessary in autobuffer * @return -1 if an out-of-memory error happened, 0 otherwise */ static int _autobuf_enlarge(struct autobuf *autobuf, size_t new_size) { char *p; size_t roundUpSize; new_size++; if (new_size > autobuf->_total) { roundUpSize = ROUND_UP_TO_POWER_OF_2(new_size+1, getpagesize()); p = realloc(autobuf->_buf, roundUpSize); if (p == NULL) { #ifdef WIN32 WSASetLastError(ENOMEM); #else errno = ENOMEM; #endif autobuf->_error = true; return -1; } autobuf->_buf = p; memset(&autobuf->_buf[autobuf->_total], 0, roundUpSize - autobuf->_total); autobuf->_total = roundUpSize; } return 0; }
/** * Remove a prefix from an autobuffer. This function can be used * to create an autobuffer based fifo. * @param autobuf pointer to autobuf object * @param file code file where this function was called (supplied by macro) * @param line line number in file where this function was called (supplied by macro) * @param file code file where this function was called (supplied by macro) * @param line line number in file where this function was called (supplied by macro) * @param len number of bytes to be removed */ void abuf_pull(struct autobuf * autobuf, int len) { char *p; int newsize; if (autobuf == NULL) return; if (len != autobuf->len) { memmove(autobuf->buf, &autobuf->buf[len], autobuf->len - len); } autobuf->len -= len; newsize = ROUND_UP_TO_POWER_OF_2(autobuf->len + 1, AUTOBUFCHUNK); if (newsize + 2*AUTOBUFCHUNK >= autobuf->size) { /* only reduce buffer size if difference is larger than two chunks */ return; } /* generate smaller buffer */ p = autobuf_realloc(autobuf->buf, newsize); if (p == NULL) { /* keep the longer buffer if we cannot get a smaller one */ return; } autobuf->buf = p; autobuf->size = newsize; return; }
/** * Initialize an autobuffer and allocate a chunk of memory * @param autobuf pointer to autobuf object * @param file code file where this function was called (supplied by macro) * @param line line number in file where this function was called (supplied by macro) * @param initial_size size of allocated memory, might be 0 * @return -1 if an out-of-memory error happened, 0 otherwise */ int abuf_init(struct autobuf *autobuf, int initial_size) { autobuf->len = 0; if (initial_size <= 0) { autobuf->size = 0; autobuf->buf = NULL; return 0; } autobuf->size = ROUND_UP_TO_POWER_OF_2(initial_size, AUTOBUFCHUNK); autobuf->buf = autobuf_malloc(autobuf->size); if (autobuf->buf == NULL) { autobuf->size = 0; return -1; } *autobuf->buf = '\0'; return 0; }
/** * Enlarge an autobuffer if necessary * @param autobuf pointer to autobuf object * @param file code file where this function was called (supplied by macro) * @param line line number in file where this function was called (supplied by macro) * @param new_size number of bytes necessary in autobuffer * @return -1 if an out-of-memory error happened, 0 otherwise */ static int int_autobuf_enlarge(struct autobuf *autobuf, int new_size) { new_size++; if (new_size > autobuf->size) { char *p; int roundUpSize = ROUND_UP_TO_POWER_OF_2(new_size, AUTOBUFCHUNK); p = autobuf_realloc(autobuf->buf, roundUpSize); if (p == NULL) { #ifdef WIN32 WSASetLastError(ENOMEM); #else errno = ENOMEM; #endif return -1; } autobuf->buf = p; memset(&autobuf->buf[autobuf->size], 0, roundUpSize - autobuf->size); autobuf->size = roundUpSize; } return 0; }