buffer.c

Go to the documentation of this file.
00001 /*
00002  * buffer.c -- generic memory buffer .
00003  *
00004  * Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
00005  *
00006  * See LICENSE for the license.
00007  *
00008  */
00009 
00010 #include <ldns/config.h>
00011 
00012 #include <ldns/ldns.h>
00013 #include <ldns/buffer.h>
00014 
00015 ldns_buffer *
00016 ldns_buffer_new(size_t capacity)
00017 {
00018         ldns_buffer *buffer = LDNS_MALLOC(ldns_buffer);
00019 
00020         if (!buffer) {
00021                 return NULL;
00022         }
00023         
00024         buffer->_data = (uint8_t *) LDNS_XMALLOC(uint8_t, capacity);
00025         if (!buffer->_data) {
00026                 LDNS_FREE(buffer);
00027                 return NULL;
00028         }
00029         
00030         buffer->_position = 0;
00031         buffer->_limit = buffer->_capacity = capacity;
00032         buffer->_fixed = 0;
00033         buffer->_status = LDNS_STATUS_OK;
00034         
00035         ldns_buffer_invariant(buffer);
00036         
00037         return buffer;
00038 }
00039 
00040 void
00041 ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size)
00042 {
00043         assert(data != NULL);
00044 
00045         buffer->_position = 0; 
00046         buffer->_limit = buffer->_capacity = size;
00047         buffer->_fixed = 0;
00048         buffer->_data = LDNS_XMALLOC(uint8_t, size);
00049         if(!buffer->_data) {
00050                 buffer->_status = LDNS_STATUS_MEM_ERR;
00051                 return;
00052         }
00053         memcpy(buffer->_data, data, size);
00054         buffer->_status = LDNS_STATUS_OK;
00055         
00056         ldns_buffer_invariant(buffer);
00057 }
00058 
00059 bool
00060 ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
00061 {
00062         void *data;
00063         
00064         ldns_buffer_invariant(buffer);
00065         assert(buffer->_position <= capacity);
00066 
00067         data = (uint8_t *) LDNS_XREALLOC(buffer->_data, uint8_t, capacity);
00068         if (!data) {
00069                 buffer->_status = LDNS_STATUS_MEM_ERR;
00070                 return false;
00071         } else {
00072                 buffer->_data = data;
00073                 buffer->_limit = buffer->_capacity = capacity;
00074                 return true;
00075         }
00076 }
00077 
00078 bool
00079 ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
00080 {
00081         ldns_buffer_invariant(buffer);
00082         assert(!buffer->_fixed);
00083         if (buffer->_capacity < buffer->_position + amount) {
00084                 size_t new_capacity = buffer->_capacity * 3 / 2;
00085 
00086                 if (new_capacity < buffer->_position + amount) {
00087                         new_capacity = buffer->_position + amount;
00088                 }
00089                 if (!ldns_buffer_set_capacity(buffer, new_capacity)) {
00090                         buffer->_status = LDNS_STATUS_MEM_ERR;
00091                         return false;
00092                 }
00093         }
00094         buffer->_limit = buffer->_capacity;
00095         return true;
00096 }
00097 
00098 int
00099 ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...)
00100 {
00101         va_list args;
00102         int written = 0;
00103         size_t remaining;
00104         
00105         if (ldns_buffer_status_ok(buffer)) {
00106                 ldns_buffer_invariant(buffer);
00107                 assert(buffer->_limit == buffer->_capacity);
00108 
00109                 remaining = ldns_buffer_remaining(buffer);
00110                 va_start(args, format);
00111                 written = vsnprintf((char *) ldns_buffer_current(buffer), remaining,
00112                                     format, args);
00113                 va_end(args);
00114                 if (written == -1) {
00115                         buffer->_status = LDNS_STATUS_INTERNAL_ERR;
00116                         return -1;
00117                 } else if ((size_t) written >= remaining) {
00118                         if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
00119                                 buffer->_status = LDNS_STATUS_MEM_ERR;
00120                                 return -1;
00121                         }
00122                         va_start(args, format);
00123                         written = vsnprintf((char *) ldns_buffer_current(buffer),
00124                             ldns_buffer_remaining(buffer), format, args);
00125                         va_end(args);
00126                         if (written == -1) {
00127                                 buffer->_status = LDNS_STATUS_INTERNAL_ERR;
00128                                 return -1;
00129                         }
00130                 }
00131                 buffer->_position += written;
00132         }
00133         return written;
00134 }
00135 
00136 void
00137 ldns_buffer_free(ldns_buffer *buffer)
00138 {
00139         if (!buffer) {
00140                 return;
00141         }
00142 
00143         LDNS_FREE(buffer->_data);
00144 
00145         LDNS_FREE(buffer);
00146 }
00147 
00148 void *
00149 ldns_buffer_export(ldns_buffer *buffer)
00150 {
00151         buffer->_fixed = 1;
00152         return buffer->_data;
00153 }
00154 
00155 int
00156 ldns_bgetc(ldns_buffer *buffer)
00157 {
00158         if (!ldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) {
00159                 ldns_buffer_set_position(buffer, ldns_buffer_limit(buffer));
00160                 /* ldns_buffer_rewind(buffer);*/
00161                 return EOF;
00162         }
00163         return (int)ldns_buffer_read_u8(buffer);
00164 }
00165 
00166 void 
00167 ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from)
00168 {
00169         size_t tocopy = ldns_buffer_limit(from);
00170 
00171         if(tocopy > ldns_buffer_capacity(result))
00172                 tocopy = ldns_buffer_capacity(result);
00173         ldns_buffer_clear(result);
00174         ldns_buffer_write(result, ldns_buffer_begin(from), tocopy);
00175         ldns_buffer_flip(result);
00176 }

Generated on Thu Apr 5 23:03:54 2012 for ldns by  doxygen 1.4.7