//作者:京东瀚览家居官方旗舰店 <--点击关注
//文件名:Buffer.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include "buffer.h"
static const char hex_chars[] = "0123456789abcdef";
/**
* init the buffer
*
*/
buffer* buffer_init(void) {
buffer *b;
b = malloc(sizeof(*b));
assert(b);
b->ptr = NULL;
b->size = 0;
b->used = 0;
return b;
}
buffer *buffer_init_buffer(buffer *src) {
buffer *b = buffer_init();
buffer_copy_string_buffer(b, src);
return b;
}
/**
* free the buffer
*
*/
void buffer_free(buffer *b) {
if (!b) return;
free(b->ptr);
free(b);
}
void buffer_reset(buffer *b) {
if (!b) return;
/* limit don't reuse buffer larger than ... bytes */
if (b->size > BUFFER_MAX_REUSE_SIZE) {
free(b->ptr);
b->ptr = NULL;
b->size = 0;
} else if (b->size) {
b->ptr[0] = '\0';
}
b->used = 0;
}
/**
*
* allocate (if neccessary) enough space for 'size' bytes and
* set the 'used' counter to 0
*
*/
#define BUFFER_PIECE_SIZE 64
int buffer_prepare_copy(buffer *b, size_t size) {
if (!b) return -1;
if ((0 == b->size) ||
(size > b->size)) {
if (b->size) free(b->ptr);
b->size = size;
/* always allocate a multiply of BUFFER_PIECE_SIZE */
b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
b->ptr = malloc(b->size);
assert(b->ptr);
}
b->used = 0;
return 0;
}
/**
*
* increase the internal buffer (if neccessary) to append another 'size' byte
* ->used isn't changed
*
*/
int buffer_prepare_append(buffer *b, size_t size) {
if (!b) return -1;
if (0 == b->size) {
b->size = size;
/* always allocate a multiply of BUFFER_PIECE_SIZE */
b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
b->ptr = malloc(b->size);
b->used = 0;
assert(b->ptr);
} else if (b->used + size > b->size) {
b->size += size;
/* always allocate a multiply of BUFFER_PIECE_SIZE */
b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
b->ptr = realloc(b->ptr, b->size);
assert(b->ptr);
}
return 0;
}
int buffer_copy_string(buffer *b, const char *s) {
size_t s_len;
if (!s || !b) return -1;
s_len = strlen(s) + 1;
buffer_prepare_copy(b, s_len);
memcpy(b->ptr, s, s_len);
b->used = s_len;
return 0;
}
int buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
if (!s || !b) return -1;
#if 0
/* removed optimization as we have to keep the empty string
* in some cases for the config handling
*
* url.access-deny = ( "" )
*/
if (s_len == 0) return 0;
#endif
buffer_prepare_copy(b, s_len + 1);
memcpy(b->ptr, s, s_len);
b->ptr[s_len] = '\0';
b->used = s_len + 1;
return 0;
}
int buffer_copy_string_buffer(buffer *b, const buffer *src) {
if (!src) return -1;
if (src->used == 0) {
b->used = 0;
return 0;
}
return buffer_copy_string_len(b, src->ptr, src->used - 1);
}
int buffer_append_string(buffer *b, const char *s) {
size_t s_len;
if (!s || !b) return -1;
s_len = strlen(s);
buffer_prepare_append(b, s_len + 1);
if (b->used == 0)
b->used++;
memcpy(b->ptr + b->used - 1, s, s_len + 1);
b->used += s_len;
return 0;
}
int buffer_append_string_rfill(buffer *b, const char *s, size_t maxlen) {
size_t s_len;
if (!s || !b) return -1;
s_len = strlen(s);
buffer_prepare_append(b, maxlen + 1);
if (b->used == 0)
b->used++;
memcpy(b->ptr + b->used - 1, s, s_len);
if (maxlen > s_len) {
memset(b->ptr + b->used - 1 + s_len, ' ', maxlen - s_len);
}
b->used += maxlen;
b->ptr[b->used - 1] = '\0';
return 0;
}
/**
* append a string to the end of the buffer
*
* the resulting buffer is terminated with a '\0'
* s is treated as a un-terminated string (a \0 is handled a normal character)
*
* @param b a buffer
* @param s the string
* @param s_len size of the string (without the terminating \0)
*/
int buffer_append_string_len(buffer *b, const char *s, size_t s_len) {
if (!s || !b) return -1;
if (s_len == 0) return 0;
buffer_prepare_append(b, s_len + 1);
if (b->used == 0)
b->used++;
memcpy(b->ptr + b->used - 1, s, s_len);
b->used += s_len;
b->ptr[b->used - 1] = '\0';
return 0;
}
int buffer_append_string_buffer(buffer *b, const buffer *src) {
if (!src) return -1;
if (src->used == 0) return 0;
return buffer_append_string_len(b, src->ptr, src->used - 1);
}
int buffer_append_memory(buffer *b, const char *s, size_t s_len) {
if (!s || !b) return -1;
if (s_len == 0) return 0;
buffer_prepare_append(b, s_len);
memcpy(b->ptr + b->used, s, s_len);
b->used += s_len;
return 0;
}
int buffer_copy_memory(buffer *b, const char *s, size_t s_len) {
if (!s || !b) return -1;
b->used = 0;
return buffer_append_memory(b, s, s_len);
}
int buffer_append_long_hex(buffer *b, unsigned long value) {
char *buf;
int shift = 0;
unsigned long copy = value;
while (copy) {
copy >>= 4;
shift++;