00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdlib.h>
00018 #include <string.h>
00019
00020 #include "buffer.h"
00021
00022 #define INITIAL_BUFFER_SIZE 256
00023
00024 struct buffer {
00025 char* buffer;
00026 int size;
00027 int position;
00028 };
00029
00030
00031
00032 buffer_t buffer_new(void) {
00033 buffer_t buffer;
00034 buffer = (buffer_t)malloc(sizeof(struct buffer));
00035 if (buffer == NULL) {
00036 return NULL;
00037 }
00038
00039 buffer->size = INITIAL_BUFFER_SIZE;
00040 buffer->position = 0;
00041 buffer->buffer = (char*)malloc(sizeof(char) * INITIAL_BUFFER_SIZE);
00042 if (buffer->buffer == NULL) {
00043 free(buffer);
00044 return NULL;
00045 }
00046
00047 return buffer;
00048 }
00049
00050
00051
00052 int buffer_free(buffer_t buffer) {
00053 if (buffer == NULL) {
00054 return 1;
00055 }
00056 free(buffer->buffer);
00057 free(buffer);
00058 return 0;
00059 }
00060
00061
00062
00063 static int buffer_grow(buffer_t buffer, int min_length) {
00064 int size = buffer->size;
00065 char* old_buffer = buffer->buffer;
00066 if (size >= min_length) {
00067 return 0;
00068 }
00069 while (size < min_length) {
00070 size *= 2;
00071 }
00072 buffer->buffer = (char*)realloc(buffer->buffer, sizeof(char) * size);
00073 if (buffer->buffer == NULL) {
00074 free(old_buffer);
00075 free(buffer);
00076 return 1;
00077 }
00078 buffer->size = size;
00079 return 0;
00080 }
00081
00082
00083
00084 static int buffer_assure_space(buffer_t buffer, int size) {
00085 if (buffer->position + size <= buffer->size) {
00086 return 0;
00087 }
00088 return buffer_grow(buffer, buffer->position + size);
00089 }
00090
00091
00092
00093 buffer_position buffer_save_space(buffer_t buffer, int size) {
00094 int position = buffer->position;
00095 if (buffer_assure_space(buffer, size) != 0) {
00096 return -1;
00097 }
00098 buffer->position += size;
00099 return position;
00100 }
00101
00102
00103
00104 int buffer_write(buffer_t buffer, const char* data, int size) {
00105 if (buffer_assure_space(buffer, size) != 0) {
00106 return 1;
00107 }
00108
00109 memcpy(buffer->buffer + buffer->position, data, size);
00110 buffer->position += size;
00111 return 0;
00112 }
00113
00114
00115
00116
00117 int buffer_write_at_position(buffer_t buffer, buffer_position position,
00118 const char* data, int size) {
00119 if (position + size > buffer->size) {
00120 buffer_free(buffer);
00121 return 1;
00122 }
00123
00124 memcpy(buffer->buffer + position, data, size);
00125 return 0;
00126 }
00127
00128
00129 int buffer_get_position(buffer_t buffer) {
00130 return buffer->position;
00131 }
00132
00133 char* buffer_get_buffer(buffer_t buffer) {
00134 return buffer->buffer;
00135 }