1/* -*- c-basic-offset: 2 -*- */
2/*
3 Copyright(C) 2015 Brazil
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License version 2.1 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18
19#include "ts_buf.h"
20
21#include "../grn_ctx.h"
22
23#include "ts_log.h"
24
25#include <string.h>
26
27/*-------------------------------------------------------------
28 * grn_ts_buf
29 */
30
31void
32grn_ts_buf_init(grn_ctx *ctx, grn_ts_buf *buf)
33{
34 buf->ptr = NULL;
35 buf->size = 0;
36 buf->pos = 0;
37}
38
39/*
40grn_rc
41grn_ts_buf_open(grn_ctx *ctx, grn_ts_buf **buf)
42{
43 grn_ts_buf *new_buf = GRN_MALLOCN(grn_ts_buf, 1);
44 if (!new_buf) {
45 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
46 "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
47 sizeof(grn_ts_buf));
48 }
49 grn_ts_buf_init(ctx, new_buf);
50 *buf = new_buf;
51 return GRN_SUCCESS;
52}
53*/
54
55void
56grn_ts_buf_fin(grn_ctx *ctx, grn_ts_buf *buf)
57{
58 if (buf->ptr) {
59 GRN_FREE(buf->ptr);
60 }
61}
62
63/*
64void
65grn_ts_buf_close(grn_ctx *ctx, grn_ts_buf *buf)
66{
67 if (buf) {
68 grn_ts_buf_fin(ctx, buf);
69 }
70}
71*/
72
73grn_rc
74grn_ts_buf_reserve(grn_ctx *ctx, grn_ts_buf *buf, size_t min_size)
75{
76 void *new_ptr;
77 size_t enough_size;
78 if (min_size <= buf->size) {
79 return GRN_SUCCESS;
80 }
81 enough_size = buf->size ? (buf->size << 1) : 1;
82 while (enough_size < min_size) {
83 if ((enough_size << 1) < enough_size) {
84 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
85 "size overflow: %" GRN_FMT_SIZE,
86 min_size);
87 }
88 enough_size <<= 1;
89 }
90 new_ptr = GRN_REALLOC(buf->ptr, enough_size);
91 if (!new_ptr) {
92 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
93 "GRN_REALLOC failed: %" GRN_FMT_SIZE,
94 enough_size);
95 }
96 buf->ptr = new_ptr;
97 buf->size = enough_size;
98 return GRN_SUCCESS;
99}
100
101grn_rc
102grn_ts_buf_resize(grn_ctx *ctx, grn_ts_buf *buf, size_t new_size)
103{
104 void *new_ptr;
105 if (new_size == buf->size) {
106 return GRN_SUCCESS;
107 }
108 if (!new_size) {
109 if (buf->ptr) {
110 GRN_FREE(buf->ptr);
111 buf->ptr = NULL;
112 buf->size = new_size;
113 }
114 return GRN_SUCCESS;
115 }
116 new_ptr = GRN_REALLOC(buf->ptr, new_size);
117 if (!new_ptr) {
118 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
119 "GRN_REALLOC failed: %" GRN_FMT_SIZE,
120 new_size);
121 }
122 buf->ptr = new_ptr;
123 buf->size = new_size;
124 return GRN_SUCCESS;
125}
126
127grn_rc
128grn_ts_buf_write(grn_ctx *ctx, grn_ts_buf *buf, const void *ptr, size_t size)
129{
130 size_t new_pos = buf->pos + size;
131 if (new_pos < buf->pos) {
132 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
133 "size overflow: %" GRN_FMT_SIZE " + %" GRN_FMT_SIZE,
134 buf->pos, size);
135 }
136 if (new_pos > buf->size) {
137 grn_rc rc = grn_ts_buf_reserve(ctx, buf, new_pos);
138 if (rc != GRN_SUCCESS) {
139 return rc;
140 }
141 }
142 grn_memcpy((char *)buf->ptr + buf->pos, ptr, size);
143 buf->pos += size;
144 return GRN_SUCCESS;
145}
146
147/*-------------------------------------------------------------
148 * grn_ts_rbuf
149 */
150
151void
152grn_ts_rbuf_init(grn_ctx *ctx, grn_ts_rbuf *rbuf)
153{
154 rbuf->recs = NULL;
155 rbuf->n_recs = 0;
156 rbuf->max_n_recs = 0;
157}
158
159void
160grn_ts_rbuf_fin(grn_ctx *ctx, grn_ts_rbuf *rbuf)
161{
162 if (rbuf->recs) {
163 GRN_FREE(rbuf->recs);
164 }
165}
166
167grn_rc
168grn_ts_rbuf_open(grn_ctx *ctx, grn_ts_rbuf **rbuf)
169{
170 grn_ts_rbuf *new_rbuf = GRN_MALLOCN(grn_ts_rbuf, 1);
171 if (!new_rbuf) {
172 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
173 "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
174 sizeof(grn_ts_rbuf));
175 }
176 grn_ts_rbuf_init(ctx, new_rbuf);
177 *rbuf = new_rbuf;
178 return GRN_SUCCESS;
179}
180
181void
182grn_ts_rbuf_close(grn_ctx *ctx, grn_ts_rbuf *rbuf)
183{
184 if (rbuf) {
185 grn_ts_rbuf_fin(ctx, rbuf);
186 }
187}
188
189grn_rc
190grn_ts_rbuf_reserve(grn_ctx *ctx, grn_ts_rbuf *rbuf, size_t min_max_n_recs)
191{
192 size_t n_bytes, enough_max_n_recs;
193 grn_ts_record *new_recs;
194 if (min_max_n_recs <= rbuf->max_n_recs) {
195 return GRN_SUCCESS;
196 }
197 enough_max_n_recs = rbuf->max_n_recs ? (rbuf->max_n_recs << 1) : 1;
198 while (enough_max_n_recs < min_max_n_recs) {
199 if ((enough_max_n_recs << 1) < enough_max_n_recs) {
200 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
201 "size overflow: %" GRN_FMT_SIZE,
202 min_max_n_recs);
203 }
204 enough_max_n_recs <<= 1;
205 }
206 n_bytes = sizeof(grn_ts_record) * enough_max_n_recs;
207 new_recs = GRN_REALLOC(rbuf->recs, n_bytes);
208 if (!new_recs) {
209 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
210 "GRN_REALLOC failed: %" GRN_FMT_SIZE,
211 n_bytes);
212 }
213 rbuf->recs = new_recs;
214 rbuf->max_n_recs = enough_max_n_recs;
215 return GRN_SUCCESS;
216}
217
218grn_rc
219grn_ts_rbuf_resize(grn_ctx *ctx, grn_ts_rbuf *rbuf, size_t new_max_n_recs)
220{
221 size_t n_bytes;
222 grn_ts_record *new_recs;
223 if (new_max_n_recs == rbuf->max_n_recs) {
224 return GRN_SUCCESS;
225 }
226 if (!new_max_n_recs) {
227 if (rbuf->recs) {
228 GRN_FREE(rbuf->recs);
229 rbuf->recs = NULL;
230 rbuf->max_n_recs = new_max_n_recs;
231 }
232 return GRN_SUCCESS;
233 }
234 n_bytes = sizeof(grn_ts_record) * new_max_n_recs;
235 new_recs = GRN_REALLOC(rbuf->recs, n_bytes);
236 if (!new_recs) {
237 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
238 "GRN_REALLOC failed: %" GRN_FMT_SIZE,
239 new_max_n_recs);
240 }
241 rbuf->recs = new_recs;
242 rbuf->max_n_recs = new_max_n_recs;
243 return GRN_SUCCESS;
244}
245