File Coverage

deps/msgpack-c/src/vrefbuffer.c
Criterion Covered Total %
statement 0 129 0.0
branch 0 42 0.0
condition n/a
subroutine n/a
pod n/a
total 0 171 0.0


line stmt bran cond sub pod time code
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 "msgpack/vrefbuffer.h"
11             #include
12             #include
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 0           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 0           vbuf->chunk_size = chunk_size;
29 0           vbuf->ref_size =
30             ref_size > MSGPACK_PACKER_MAX_BUFFER_SIZE + 1 ?
31 0           ref_size : MSGPACK_PACKER_MAX_BUFFER_SIZE + 1 ;
32              
33 0 0         if((sizeof(msgpack_vrefbuffer_chunk) + chunk_size) < chunk_size) {
34 0           return false;
35             }
36              
37 0           nfirst = (sizeof(struct iovec) < 72/2) ?
38             72 / sizeof(struct iovec) : 8;
39              
40 0           array = (struct iovec*)malloc(
41             sizeof(struct iovec) * nfirst);
42 0 0         if(array == NULL) {
43 0           return false;
44             }
45              
46 0           vbuf->tail = array;
47 0           vbuf->end = array + nfirst;
48 0           vbuf->array = array;
49              
50 0           chunk = (msgpack_vrefbuffer_chunk*)malloc(
51             sizeof(msgpack_vrefbuffer_chunk) + chunk_size);
52 0 0         if(chunk == NULL) {
53 0           free(array);
54 0           return false;
55             }
56             else {
57 0           msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
58              
59 0           ib->free = chunk_size;
60 0           ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
61 0           ib->head = chunk;
62 0           chunk->next = NULL;
63              
64 0           return true;
65             }
66             }
67              
68 0           void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf)
69             {
70 0           msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head;
71             while(true) {
72 0           msgpack_vrefbuffer_chunk* n = c->next;
73 0           free(c);
74 0 0         if(n != NULL) {
75 0           c = n;
76             } else {
77 0           break;
78             }
79 0           }
80 0           free(vbuf->array);
81 0           }
82              
83 0           void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vbuf)
84             {
85 0           msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head->next;
86             msgpack_vrefbuffer_chunk* n;
87 0 0         while(c != NULL) {
88 0           n = c->next;
89 0           free(c);
90 0           c = n;
91             }
92              
93             {
94 0           msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
95 0           msgpack_vrefbuffer_chunk* chunk = ib->head;
96 0           chunk->next = NULL;
97 0           ib->free = vbuf->chunk_size;
98 0           ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
99              
100 0           vbuf->tail = vbuf->array;
101             }
102 0           }
103              
104 0           int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
105             const char* buf, size_t len)
106             {
107 0 0         if(vbuf->tail == vbuf->end) {
108 0           const size_t nused = (size_t)(vbuf->tail - vbuf->array);
109 0           const size_t nnext = nused * 2;
110              
111 0           struct iovec* nvec = (struct iovec*)realloc(
112 0           vbuf->array, sizeof(struct iovec)*nnext);
113 0 0         if(nvec == NULL) {
114 0           return -1;
115             }
116              
117 0           vbuf->array = nvec;
118 0           vbuf->end = nvec + nnext;
119 0           vbuf->tail = nvec + nused;
120             }
121              
122 0           vbuf->tail->iov_base = (char*)buf;
123 0           vbuf->tail->iov_len = len;
124 0           ++vbuf->tail;
125              
126 0           return 0;
127             }
128              
129 0           int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
130             const char* buf, size_t len)
131             {
132 0           msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
133             char* m;
134              
135 0 0         if(ib->free < len) {
136             msgpack_vrefbuffer_chunk* chunk;
137 0           size_t sz = vbuf->chunk_size;
138 0 0         if(sz < len) {
139 0           sz = len;
140             }
141              
142 0 0         if((sizeof(msgpack_vrefbuffer_chunk) + sz) < sz){
143 0           return -1;
144             }
145 0           chunk = (msgpack_vrefbuffer_chunk*)malloc(
146             sizeof(msgpack_vrefbuffer_chunk) + sz);
147 0 0         if(chunk == NULL) {
148 0           return -1;
149             }
150              
151 0           chunk->next = ib->head;
152 0           ib->head = chunk;
153 0           ib->free = sz;
154 0           ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
155             }
156              
157 0           m = ib->ptr;
158 0           memcpy(m, buf, len);
159 0           ib->free -= len;
160 0           ib->ptr += len;
161              
162 0 0         if(vbuf->tail != vbuf->array && m ==
    0          
163 0           (const char*)((vbuf->tail-1)->iov_base) + (vbuf->tail-1)->iov_len) {
164 0           (vbuf->tail-1)->iov_len += len;
165 0           return 0;
166             } else {
167 0           return msgpack_vrefbuffer_append_ref(vbuf, m, len);
168             }
169             }
170              
171 0           int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to)
172             {
173 0           size_t sz = vbuf->chunk_size;
174             msgpack_vrefbuffer_chunk* empty;
175              
176 0 0         if((sizeof(msgpack_vrefbuffer_chunk) + sz) < sz){
177 0           return -1;
178             }
179              
180 0           empty = (msgpack_vrefbuffer_chunk*)malloc(
181             sizeof(msgpack_vrefbuffer_chunk) + sz);
182 0 0         if(empty == NULL) {
183 0           return -1;
184             }
185              
186 0           empty->next = NULL;
187              
188             {
189 0           const size_t nused = (size_t)(vbuf->tail - vbuf->array);
190 0 0         if(to->tail + nused < vbuf->end) {
191             struct iovec* nvec;
192 0           const size_t tosize = (size_t)(to->tail - to->array);
193 0           const size_t reqsize = nused + tosize;
194 0           size_t nnext = (size_t)(to->end - to->array) * 2;
195 0 0         while(nnext < reqsize) {
196 0           size_t tmp_nnext = nnext * 2;
197 0 0         if (tmp_nnext <= nnext) {
198 0           nnext = reqsize;
199 0           break;
200             }
201 0           nnext = tmp_nnext;
202             }
203              
204 0           nvec = (struct iovec*)realloc(
205 0           to->array, sizeof(struct iovec)*nnext);
206 0 0         if(nvec == NULL) {
207 0           free(empty);
208 0           return -1;
209             }
210              
211 0           to->array = nvec;
212 0           to->end = nvec + nnext;
213 0           to->tail = nvec + tosize;
214             }
215              
216 0           memcpy(to->tail, vbuf->array, sizeof(struct iovec)*nused);
217              
218 0           to->tail += nused;
219 0           vbuf->tail = vbuf->array;
220              
221             {
222 0           msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
223 0           msgpack_vrefbuffer_inner_buffer* const toib = &to->inner_buffer;
224              
225 0           msgpack_vrefbuffer_chunk* last = ib->head;
226 0 0         while(last->next != NULL) {
227 0           last = last->next;
228             }
229 0           last->next = toib->head;
230 0           toib->head = ib->head;
231              
232 0 0         if(toib->free < ib->free) {
233 0           toib->free = ib->free;
234 0           toib->ptr = ib->ptr;
235             }
236              
237 0           ib->head = empty;
238 0           ib->free = sz;
239 0           ib->ptr = ((char*)empty) + sizeof(msgpack_vrefbuffer_chunk);
240             }
241             }
242              
243 0           return 0;
244             }