1 /*
2  * MessagePack for C simple 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 #ifndef MSGPACK_SBUFFER_H
11 #define MSGPACK_SBUFFER_H
12 
13 #include <stdlib.h>
14 #include <string.h>
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 
21 /**
22  * @defgroup msgpack_sbuffer Simple buffer
23  * @ingroup msgpack_buffer
24  * @{
25  */
26 
27 typedef struct msgpack_sbuffer {
28     size_t size;
29     char* data;
30     size_t alloc;
31 } msgpack_sbuffer;
32 
msgpack_sbuffer_init(msgpack_sbuffer * sbuf)33 static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf)
34 {
35     memset(sbuf, 0, sizeof(msgpack_sbuffer));
36 }
37 
msgpack_sbuffer_destroy(msgpack_sbuffer * sbuf)38 static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf)
39 {
40     free(sbuf->data);
41 }
42 
msgpack_sbuffer_new(void)43 static inline msgpack_sbuffer* msgpack_sbuffer_new(void)
44 {
45     return (msgpack_sbuffer*)calloc(1, sizeof(msgpack_sbuffer));
46 }
47 
msgpack_sbuffer_free(msgpack_sbuffer * sbuf)48 static inline void msgpack_sbuffer_free(msgpack_sbuffer* sbuf)
49 {
50     if(sbuf == NULL) { return; }
51     msgpack_sbuffer_destroy(sbuf);
52     free(sbuf);
53 }
54 
55 #ifndef MSGPACK_SBUFFER_INIT_SIZE
56 #define MSGPACK_SBUFFER_INIT_SIZE 8192
57 #endif
58 
msgpack_sbuffer_write(void * data,const char * buf,size_t len)59 static inline int msgpack_sbuffer_write(void* data, const char* buf, size_t len)
60 {
61     msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data;
62 
63     if(sbuf->alloc - sbuf->size < len) {
64         void* tmp;
65         size_t nsize = (sbuf->alloc) ?
66                 sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
67 
68         while(nsize < sbuf->size + len) {
69             size_t tmp_nsize = nsize * 2;
70             if (tmp_nsize <= nsize) {
71                 nsize = sbuf->size + len;
72                 break;
73             }
74             nsize = tmp_nsize;
75         }
76 
77         tmp = realloc(sbuf->data, nsize);
78         if(!tmp) { return -1; }
79 
80         sbuf->data = (char*)tmp;
81         sbuf->alloc = nsize;
82     }
83 
84     memcpy(sbuf->data + sbuf->size, buf, len);
85     sbuf->size += len;
86     return 0;
87 }
88 
msgpack_sbuffer_release(msgpack_sbuffer * sbuf)89 static inline char* msgpack_sbuffer_release(msgpack_sbuffer* sbuf)
90 {
91     char* tmp = sbuf->data;
92     sbuf->size = 0;
93     sbuf->data = NULL;
94     sbuf->alloc = 0;
95     return tmp;
96 }
97 
msgpack_sbuffer_clear(msgpack_sbuffer * sbuf)98 static inline void msgpack_sbuffer_clear(msgpack_sbuffer* sbuf)
99 {
100     sbuf->size = 0;
101 }
102 
103 /** @} */
104 
105 
106 #ifdef __cplusplus
107 }
108 #endif
109 
110 #endif /* msgpack/sbuffer.h */
111