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