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
17extern "C" {
18#endif
19
20
21/**
22 * @defgroup msgpack_sbuffer Simple buffer
23 * @ingroup msgpack_buffer
24 * @{
25 */
26
27typedef struct msgpack_sbuffer {
28    size_t size;
29    char* data;
30    size_t alloc;
31} msgpack_sbuffer;
32
33static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf)
34{
35    memset(sbuf, 0, sizeof(msgpack_sbuffer));
36}
37
38static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf)
39{
40    free(sbuf->data);
41}
42
43static inline msgpack_sbuffer* msgpack_sbuffer_new(void)
44{
45    return (msgpack_sbuffer*)calloc(1, sizeof(msgpack_sbuffer));
46}
47
48static 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
59static 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
89static 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
98static 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