sessiond: Add msgpack-c 3.3.0 to the tree
[lttng-tools.git] / src / vendor / msgpack / vrefbuffer.c
1 /*
2 * MessagePack for C zero-copy buffer implementation
3 *
4 * Copyright (C) 2008-2009 FURUHASHI Sadayuki
5 *
6 * Distributed under the Boost Software License, Version 1.0.
7 * (See accompanying file LICENSE_1_0.txt or copy at
8 * http://www.boost.org/LICENSE_1_0.txt)
9 */
10 #include "vendor/msgpack/vrefbuffer.h"
11 #include <stdlib.h>
12 #include <string.h>
13
14 #define MSGPACK_PACKER_MAX_BUFFER_SIZE 9
15
16 struct msgpack_vrefbuffer_chunk {
17 struct msgpack_vrefbuffer_chunk* next;
18 /* data ... */
19 };
20
21 bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
22 size_t ref_size, size_t chunk_size)
23 {
24 size_t nfirst;
25 struct iovec* array;
26 msgpack_vrefbuffer_chunk* chunk;
27
28 if (ref_size == 0) {
29 ref_size = MSGPACK_VREFBUFFER_REF_SIZE;
30 }
31 if(chunk_size == 0) {
32 chunk_size = MSGPACK_VREFBUFFER_CHUNK_SIZE;
33 }
34 vbuf->chunk_size = chunk_size;
35 vbuf->ref_size =
36 ref_size > MSGPACK_PACKER_MAX_BUFFER_SIZE + 1 ?
37 ref_size : MSGPACK_PACKER_MAX_BUFFER_SIZE + 1 ;
38
39 if((sizeof(msgpack_vrefbuffer_chunk) + chunk_size) < chunk_size) {
40 return false;
41 }
42
43 nfirst = (sizeof(struct iovec) < 72/2) ?
44 72 / sizeof(struct iovec) : 8;
45
46 array = (struct iovec*)malloc(
47 sizeof(struct iovec) * nfirst);
48 if(array == NULL) {
49 return false;
50 }
51
52 vbuf->tail = array;
53 vbuf->end = array + nfirst;
54 vbuf->array = array;
55
56 chunk = (msgpack_vrefbuffer_chunk*)malloc(
57 sizeof(msgpack_vrefbuffer_chunk) + chunk_size);
58 if(chunk == NULL) {
59 free(array);
60 return false;
61 }
62 else {
63 msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
64
65 ib->free = chunk_size;
66 ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
67 ib->head = chunk;
68 chunk->next = NULL;
69
70 return true;
71 }
72 }
73
74 void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf)
75 {
76 msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head;
77 while(true) {
78 msgpack_vrefbuffer_chunk* n = c->next;
79 free(c);
80 if(n != NULL) {
81 c = n;
82 } else {
83 break;
84 }
85 }
86 free(vbuf->array);
87 }
88
89 void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vbuf)
90 {
91 msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head->next;
92 msgpack_vrefbuffer_chunk* n;
93 while(c != NULL) {
94 n = c->next;
95 free(c);
96 c = n;
97 }
98
99 {
100 msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
101 msgpack_vrefbuffer_chunk* chunk = ib->head;
102 chunk->next = NULL;
103 ib->free = vbuf->chunk_size;
104 ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
105
106 vbuf->tail = vbuf->array;
107 }
108 }
109
110 int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
111 const char* buf, size_t len)
112 {
113 if(vbuf->tail == vbuf->end) {
114 const size_t nused = (size_t)(vbuf->tail - vbuf->array);
115 const size_t nnext = nused * 2;
116
117 struct iovec* nvec = (struct iovec*)realloc(
118 vbuf->array, sizeof(struct iovec)*nnext);
119 if(nvec == NULL) {
120 return -1;
121 }
122
123 vbuf->array = nvec;
124 vbuf->end = nvec + nnext;
125 vbuf->tail = nvec + nused;
126 }
127
128 vbuf->tail->iov_base = (char*)buf;
129 vbuf->tail->iov_len = len;
130 ++vbuf->tail;
131
132 return 0;
133 }
134
135 int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
136 const char* buf, size_t len)
137 {
138 msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
139 char* m;
140
141 if(ib->free < len) {
142 msgpack_vrefbuffer_chunk* chunk;
143 size_t sz = vbuf->chunk_size;
144 if(sz < len) {
145 sz = len;
146 }
147
148 if((sizeof(msgpack_vrefbuffer_chunk) + sz) < sz){
149 return -1;
150 }
151 chunk = (msgpack_vrefbuffer_chunk*)malloc(
152 sizeof(msgpack_vrefbuffer_chunk) + sz);
153 if(chunk == NULL) {
154 return -1;
155 }
156
157 chunk->next = ib->head;
158 ib->head = chunk;
159 ib->free = sz;
160 ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
161 }
162
163 m = ib->ptr;
164 memcpy(m, buf, len);
165 ib->free -= len;
166 ib->ptr += len;
167
168 if(vbuf->tail != vbuf->array && m ==
169 (const char*)((vbuf->tail-1)->iov_base) + (vbuf->tail-1)->iov_len) {
170 (vbuf->tail-1)->iov_len += len;
171 return 0;
172 } else {
173 return msgpack_vrefbuffer_append_ref(vbuf, m, len);
174 }
175 }
176
177 int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to)
178 {
179 size_t sz = vbuf->chunk_size;
180 msgpack_vrefbuffer_chunk* empty;
181
182 if((sizeof(msgpack_vrefbuffer_chunk) + sz) < sz){
183 return -1;
184 }
185
186 empty = (msgpack_vrefbuffer_chunk*)malloc(
187 sizeof(msgpack_vrefbuffer_chunk) + sz);
188 if(empty == NULL) {
189 return -1;
190 }
191
192 empty->next = NULL;
193
194 {
195 const size_t nused = (size_t)(vbuf->tail - vbuf->array);
196 if(to->tail + nused < vbuf->end) {
197 struct iovec* nvec;
198 const size_t tosize = (size_t)(to->tail - to->array);
199 const size_t reqsize = nused + tosize;
200 size_t nnext = (size_t)(to->end - to->array) * 2;
201 while(nnext < reqsize) {
202 size_t tmp_nnext = nnext * 2;
203 if (tmp_nnext <= nnext) {
204 nnext = reqsize;
205 break;
206 }
207 nnext = tmp_nnext;
208 }
209
210 nvec = (struct iovec*)realloc(
211 to->array, sizeof(struct iovec)*nnext);
212 if(nvec == NULL) {
213 free(empty);
214 return -1;
215 }
216
217 to->array = nvec;
218 to->end = nvec + nnext;
219 to->tail = nvec + tosize;
220 }
221
222 memcpy(to->tail, vbuf->array, sizeof(struct iovec)*nused);
223
224 to->tail += nused;
225 vbuf->tail = vbuf->array;
226
227 {
228 msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
229 msgpack_vrefbuffer_inner_buffer* const toib = &to->inner_buffer;
230
231 msgpack_vrefbuffer_chunk* last = ib->head;
232 while(last->next != NULL) {
233 last = last->next;
234 }
235 last->next = toib->head;
236 toib->head = ib->head;
237
238 if(toib->free < ib->free) {
239 toib->free = ib->free;
240 toib->ptr = ib->ptr;
241 }
242
243 ib->head = empty;
244 ib->free = sz;
245 ib->ptr = ((char*)empty) + sizeof(msgpack_vrefbuffer_chunk);
246 }
247 }
248
249 return 0;
250 }
This page took 0.04816 seconds and 4 git commands to generate.