]> git.saurik.com Git - apple/network_cmds.git/blame - unbound/ldns/sbuffer.c
network_cmds-596.100.2.tar.gz
[apple/network_cmds.git] / unbound / ldns / sbuffer.c
CommitLineData
89c4ed63
A
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 "ldns/sbuffer.h"
16#include <stdarg.h>
17
18sldns_buffer *
19sldns_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
43void
44sldns_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
62void
63sldns_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
71int
72sldns_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
90int
91sldns_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
110int
111sldns_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
148void
149sldns_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
161void *
162sldns_buffer_export(sldns_buffer *buffer)
163{
164 buffer->_fixed = 1;
165 return buffer->_data;
166}
167
168void
169sldns_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}