1 /* 2 * buffer.c -- generic memory buffer . 3 * 4 * Copyright (c) 2001-2008, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 /** 10 * \file 11 * 12 * This file contains the definition of sldns_buffer, and functions to manipulate those. 13 */ 14 #include "config.h" 15 #include "sldns/sbuffer.h" 16 #include <stdarg.h> 17 18 sldns_buffer * 19 sldns_buffer_new(size_t capacity) 20 { 21 sldns_buffer *buffer = (sldns_buffer*)malloc(sizeof(sldns_buffer)); 22 23 if (!buffer) { 24 return NULL; 25 } 26 27 buffer->_data = (uint8_t *) malloc(capacity); 28 if (!buffer->_data) { 29 free(buffer); 30 return NULL; 31 } 32 33 buffer->_position = 0; 34 buffer->_limit = buffer->_capacity = capacity; 35 buffer->_fixed = 0; 36 buffer->_status_err = 0; 37 38 sldns_buffer_invariant(buffer); 39 40 return buffer; 41 } 42 43 void 44 sldns_buffer_new_frm_data(sldns_buffer *buffer, void *data, size_t size) 45 { 46 assert(data != NULL); 47 48 buffer->_position = 0; 49 buffer->_limit = buffer->_capacity = size; 50 buffer->_fixed = 0; 51 buffer->_data = malloc(size); 52 if(!buffer->_data) { 53 buffer->_status_err = 1; 54 return; 55 } 56 memcpy(buffer->_data, data, size); 57 buffer->_status_err = 0; 58 59 sldns_buffer_invariant(buffer); 60 } 61 62 void 63 sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size) 64 { 65 memset(buffer, 0, sizeof(*buffer)); 66 buffer->_data = data; 67 buffer->_capacity = buffer->_limit = size; 68 buffer->_fixed = 1; 69 } 70 71 int 72 sldns_buffer_set_capacity(sldns_buffer *buffer, size_t capacity) 73 { 74 void *data; 75 76 sldns_buffer_invariant(buffer); 77 assert(buffer->_position <= capacity); 78 79 data = (uint8_t *) realloc(buffer->_data, capacity); 80 if (!data) { 81 buffer->_status_err = 1; 82 return 0; 83 } else { 84 buffer->_data = data; 85 buffer->_limit = buffer->_capacity = capacity; 86 return 1; 87 } 88 } 89 90 int 91 sldns_buffer_reserve(sldns_buffer *buffer, size_t amount) 92 { 93 sldns_buffer_invariant(buffer); 94 assert(!buffer->_fixed); 95 if (buffer->_capacity < buffer->_position + amount) { 96 size_t new_capacity = buffer->_capacity * 3 / 2; 97 98 if (new_capacity < buffer->_position + amount) { 99 new_capacity = buffer->_position + amount; 100 } 101 if (!sldns_buffer_set_capacity(buffer, new_capacity)) { 102 buffer->_status_err = 1; 103 return 0; 104 } 105 } 106 buffer->_limit = buffer->_capacity; 107 return 1; 108 } 109 110 int 111 sldns_buffer_printf(sldns_buffer *buffer, const char *format, ...) 112 { 113 va_list args; 114 int written = 0; 115 size_t remaining; 116 117 if (sldns_buffer_status_ok(buffer)) { 118 sldns_buffer_invariant(buffer); 119 assert(buffer->_limit == buffer->_capacity); 120 121 remaining = sldns_buffer_remaining(buffer); 122 va_start(args, format); 123 written = vsnprintf((char *) sldns_buffer_current(buffer), remaining, 124 format, args); 125 va_end(args); 126 if (written == -1) { 127 buffer->_status_err = 1; 128 return -1; 129 } else if ((size_t) written >= remaining) { 130 if (!sldns_buffer_reserve(buffer, (size_t) written + 1)) { 131 buffer->_status_err = 1; 132 return -1; 133 } 134 va_start(args, format); 135 written = vsnprintf((char *) sldns_buffer_current(buffer), 136 sldns_buffer_remaining(buffer), format, args); 137 va_end(args); 138 if (written == -1) { 139 buffer->_status_err = 1; 140 return -1; 141 } 142 } 143 buffer->_position += written; 144 } 145 return written; 146 } 147 148 void 149 sldns_buffer_free(sldns_buffer *buffer) 150 { 151 if (!buffer) { 152 return; 153 } 154 155 if (!buffer->_fixed) 156 free(buffer->_data); 157 158 free(buffer); 159 } 160 161 void * 162 sldns_buffer_export(sldns_buffer *buffer) 163 { 164 buffer->_fixed = 1; 165 return buffer->_data; 166 } 167 168 void 169 sldns_buffer_copy(sldns_buffer* result, sldns_buffer* from) 170 { 171 size_t tocopy = sldns_buffer_limit(from); 172 173 if(tocopy > sldns_buffer_capacity(result)) 174 tocopy = sldns_buffer_capacity(result); 175 sldns_buffer_clear(result); 176 sldns_buffer_write(result, sldns_buffer_begin(from), tocopy); 177 sldns_buffer_flip(result); 178 } 179