1 /*
2  * MessagePack for C simple buffer implementation
3  *
4  * Copyright (C) 2008-2009 FURUHASHI Sadayuki
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18 #ifndef MSGPACK_SBUFFER_H
19 #define MSGPACK_SBUFFER_H
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 
29 /**
30  * @defgroup msgpack_sbuffer Simple buffer
31  * @ingroup msgpack_buffer
32  * @{
33  */
34 
35 typedef struct msgpack_sbuffer {
36     size_t size;
37     char* data;
38     size_t alloc;
39 } msgpack_sbuffer;
40 
msgpack_sbuffer_init(msgpack_sbuffer * sbuf)41 static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf)
42 {
43     memset(sbuf, 0, sizeof(msgpack_sbuffer));
44 }
45 
msgpack_sbuffer_destroy(msgpack_sbuffer * sbuf)46 static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf)
47 {
48     free(sbuf->data);
49 }
50 
msgpack_sbuffer_new(void)51 static inline msgpack_sbuffer* msgpack_sbuffer_new(void)
52 {
53     return (msgpack_sbuffer*)calloc(1, sizeof(msgpack_sbuffer));
54 }
55 
msgpack_sbuffer_free(msgpack_sbuffer * sbuf)56 static inline void msgpack_sbuffer_free(msgpack_sbuffer* sbuf)
57 {
58     if(sbuf == NULL) { return; }
59     msgpack_sbuffer_destroy(sbuf);
60     free(sbuf);
61 }
62 
63 #ifndef MSGPACK_SBUFFER_INIT_SIZE
64 #define MSGPACK_SBUFFER_INIT_SIZE 8192
65 #endif
66 
msgpack_sbuffer_write(void * data,const char * buf,size_t len)67 static inline int msgpack_sbuffer_write(void* data, const char* buf, size_t len)
68 {
69     msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data;
70 
71     if(sbuf->alloc - sbuf->size < len) {
72         void* tmp;
73         size_t nsize = (sbuf->alloc) ?
74                 sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
75 
76         while(nsize < sbuf->size + len) {
77             size_t tmp_nsize = nsize * 2;
78             if (tmp_nsize <= nsize) {
79                 nsize = sbuf->size + len;
80                 break;
81             }
82             nsize = tmp_nsize;
83         }
84 
85         tmp = realloc(sbuf->data, nsize);
86         if(!tmp) { return -1; }
87 
88         sbuf->data = (char*)tmp;
89         sbuf->alloc = nsize;
90     }
91 
92     memcpy(sbuf->data + sbuf->size, buf, len);
93     sbuf->size += len;
94     return 0;
95 }
96 
msgpack_sbuffer_release(msgpack_sbuffer * sbuf)97 static inline char* msgpack_sbuffer_release(msgpack_sbuffer* sbuf)
98 {
99     char* tmp = sbuf->data;
100     sbuf->size = 0;
101     sbuf->data = NULL;
102     sbuf->alloc = 0;
103     return tmp;
104 }
105 
msgpack_sbuffer_clear(msgpack_sbuffer * sbuf)106 static inline void msgpack_sbuffer_clear(msgpack_sbuffer* sbuf)
107 {
108     sbuf->size = 0;
109 }
110 
111 /** @} */
112 
113 
114 #ifdef __cplusplus
115 }
116 #endif
117 
118 #endif /* msgpack/sbuffer.h */
119