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 | |
31 | void |
32 | grn_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 | /* |
40 | grn_rc |
41 | grn_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 | |
55 | void |
56 | grn_ts_buf_fin(grn_ctx *ctx, grn_ts_buf *buf) |
57 | { |
58 | if (buf->ptr) { |
59 | GRN_FREE(buf->ptr); |
60 | } |
61 | } |
62 | |
63 | /* |
64 | void |
65 | grn_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 | |
73 | grn_rc |
74 | grn_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 | |
101 | grn_rc |
102 | grn_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 | |
127 | grn_rc |
128 | grn_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 | |
151 | void |
152 | grn_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 | |
159 | void |
160 | grn_ts_rbuf_fin(grn_ctx *ctx, grn_ts_rbuf *rbuf) |
161 | { |
162 | if (rbuf->recs) { |
163 | GRN_FREE(rbuf->recs); |
164 | } |
165 | } |
166 | |
167 | grn_rc |
168 | grn_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 | |
181 | void |
182 | grn_ts_rbuf_close(grn_ctx *ctx, grn_ts_rbuf *rbuf) |
183 | { |
184 | if (rbuf) { |
185 | grn_ts_rbuf_fin(ctx, rbuf); |
186 | } |
187 | } |
188 | |
189 | grn_rc |
190 | grn_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 | |
218 | grn_rc |
219 | grn_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 | |