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         if (!buffer->_fixed)
00144                 LDNS_FREE(buffer->_data);
00145 
00146         LDNS_FREE(buffer);
00147 }
00148 
00149 void *
00150 ldns_buffer_export(ldns_buffer *buffer)
00151 {
00152         buffer->_fixed = 1;
00153         return buffer->_data;
00154 }
00155 
00156 int
00157 ldns_bgetc(ldns_buffer *buffer)
00158 {
00159         if (!ldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) {
00160                 ldns_buffer_set_position(buffer, ldns_buffer_limit(buffer));
00161                 /* ldns_buffer_rewind(buffer);*/
00162                 return EOF;
00163         }
00164         return (int)ldns_buffer_read_u8(buffer);
00165 }
00166 
00167 void 
00168 ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from)
00169 {
00170         size_t tocopy = ldns_buffer_limit(from);
00171 
00172         if(tocopy > ldns_buffer_capacity(result))
00173                 tocopy = ldns_buffer_capacity(result);
00174         ldns_buffer_clear(result);
00175         ldns_buffer_write(result, ldns_buffer_begin(from), tocopy);
00176         ldns_buffer_flip(result);
00177 }

Generated on Wed Dec 19 16:56:49 2012 for ldns by  doxygen 1.4.7