buffer.c

Go to the documentation of this file.
00001 /*
00002  * buffer.c -- generic memory buffer .
00003  *
00004  * Copyright (c) 2001-2006, 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->_data = LDNS_XMALLOC(uint8_t, size);
00048         memcpy(buffer->_data, data, size);
00049         buffer->_fixed = 0;
00050         buffer->_status = LDNS_STATUS_OK;
00051         
00052         ldns_buffer_invariant(buffer);
00053 }
00054 
00055 void
00056 ldns_buffer_clear(ldns_buffer *buffer)
00057 {
00058         ldns_buffer_invariant(buffer);
00059         
00060         /* reset status here? */
00061         
00062         buffer->_position = 0;
00063         buffer->_limit = buffer->_capacity;
00064 }
00065 
00066 void
00067 ldns_buffer_flip(ldns_buffer *buffer)
00068 {
00069         ldns_buffer_invariant(buffer);
00070         
00071         buffer->_limit = buffer->_position;
00072         buffer->_position = 0;
00073 }
00074 
00075 void
00076 ldns_buffer_rewind(ldns_buffer *buffer)
00077 {
00078         ldns_buffer_invariant(buffer);
00079         
00080         buffer->_position = 0;
00081 }
00082 
00083 bool
00084 ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
00085 {
00086         void *data;
00087         
00088         ldns_buffer_invariant(buffer);
00089         assert(buffer->_position <= capacity);
00090 
00091         data = (uint8_t *) LDNS_XREALLOC(buffer->_data, uint8_t, capacity);
00092         if (!data) {
00093                 buffer->_status = LDNS_STATUS_MEM_ERR;
00094                 return false;
00095         } else {
00096                 buffer->_data = data;
00097                 buffer->_limit = buffer->_capacity = capacity;
00098                 return true;
00099         }
00100 }
00101 
00102 bool
00103 ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
00104 {
00105         ldns_buffer_invariant(buffer);
00106         assert(!buffer->_fixed);
00107         if (buffer->_capacity < buffer->_position + amount) {
00108                 size_t new_capacity = buffer->_capacity * 3 / 2;
00109 
00110                 if (new_capacity < buffer->_position + amount) {
00111                         new_capacity = buffer->_position + amount;
00112                 }
00113                 if (!ldns_buffer_set_capacity(buffer, new_capacity)) {
00114                         buffer->_status = LDNS_STATUS_MEM_ERR;
00115                         return false;
00116                 }
00117         }
00118         buffer->_limit = buffer->_capacity;
00119         return true;
00120 }
00121 
00122 int
00123 ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...)
00124 {
00125         va_list args;
00126         int written = 0;
00127         size_t remaining;
00128         
00129         if (ldns_buffer_status_ok(buffer)) {
00130                 ldns_buffer_invariant(buffer);
00131                 assert(buffer->_limit == buffer->_capacity);
00132 
00133                 remaining = ldns_buffer_remaining(buffer);
00134                 va_start(args, format);
00135                 written = vsnprintf((char *) ldns_buffer_current(buffer), remaining,
00136                                     format, args);
00137                 va_end(args);
00138                 if (written == -1) {
00139                         buffer->_status = LDNS_STATUS_INTERNAL_ERR;
00140                         return -1;
00141                 } else if ((size_t) written >= remaining) {
00142                         if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
00143                                 buffer->_status = LDNS_STATUS_MEM_ERR;
00144                                 return -1;
00145                         }
00146                         va_start(args, format);
00147                         written = vsnprintf((char *) ldns_buffer_current(buffer),
00148                             ldns_buffer_remaining(buffer), format, args);
00149                         va_end(args);
00150                         if (written == -1) {
00151                                 buffer->_status = LDNS_STATUS_INTERNAL_ERR;
00152                                 return -1;
00153                         }
00154                 }
00155                 buffer->_position += written;
00156         }
00157         return written;
00158 }
00159 
00160 void
00161 ldns_buffer_free(ldns_buffer *buffer)
00162 {
00163         if (!buffer) {
00164                 return;
00165         }
00166 
00167         LDNS_FREE(buffer->_data);
00168 
00169         LDNS_FREE(buffer);
00170 }
00171 
00172 void *
00173 ldns_buffer_export(ldns_buffer *buffer)
00174 {
00175         buffer->_fixed = 1;
00176         return buffer->_data;
00177 }
00178 
00179 int
00180 ldns_bgetc(ldns_buffer *buffer)
00181 {
00182         if (!ldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) {
00183                 ldns_buffer_set_position(buffer, ldns_buffer_limit(buffer));
00184                 /* ldns_buffer_rewind(buffer);*/
00185                 return EOF;
00186         }
00187         return (int)ldns_buffer_read_u8(buffer);
00188 }

Generated on Thu Nov 29 13:39:18 2007 for ldns by  doxygen 1.5.2