libdrizzle Developer Documentation

field.c
Go to the documentation of this file.
1/*
2 * Drizzle Client & Protocol Library
3 *
4 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5 * All rights reserved.
6 *
7 * Use and distribution licensed under the BSD license. See
8 * the COPYING file in this directory for full text.
9 */
10
16#include "common.h"
17
18/*
19 * Client definitions
20 */
21
23 size_t *size, size_t *total,
24 drizzle_return_t *ret_ptr)
25{
26 if (drizzle_state_none(result->con))
27 {
28 if (result->field_current == result->column_count)
29 {
30 *ret_ptr= DRIZZLE_RETURN_ROW_END;
31 return NULL;
32 }
33
35 }
36
37 *ret_ptr= drizzle_state_loop(result->con);
38 if (*ret_ptr == DRIZZLE_RETURN_OK &&
40 {
42 }
43
44 *offset= result->field_offset;
45 *size= result->field_size;
46 *total= result->field_total;
47
48 return result->field;
49}
50
52 drizzle_return_t *ret_ptr)
53{
54 drizzle_field_t field;
55 size_t offset= 0;
56 size_t size= 0;
57
58 field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
59 if (*ret_ptr != DRIZZLE_RETURN_OK)
60 return NULL;
61
62 if (field == NULL)
63 {
64 *total= 0;
65 return NULL;
66 }
67
68 if (result->field_buffer == NULL)
69 {
70 result->field_buffer= malloc((*total) + 1);
71 if (result->field_buffer == NULL)
72 {
73 drizzle_set_error(result->con->drizzle, "drizzle_field_buffer", "malloc");
74 *ret_ptr= DRIZZLE_RETURN_MEMORY;
75 return NULL;
76 }
77 }
78
79 memcpy(result->field_buffer + offset, field, size);
80
81 while ((offset + size) != (*total))
82 {
83 field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
84 if (*ret_ptr != DRIZZLE_RETURN_OK)
85 return NULL;
86
87 memcpy(result->field_buffer + offset, field, size);
88 }
89
90 field= result->field_buffer;
91 result->field_buffer= NULL;
92 field[*total]= 0;
93
94 return field;
95}
96
98{
99 if (field != NULL)
100 free(field);
101}
102
103/*
104 * Server definitions
105 */
106
108 const drizzle_field_t field, size_t size,
109 size_t total)
110{
112
113 if (drizzle_state_none(result->con))
114 {
115 if (result->options & DRIZZLE_RESULT_ROW_BREAK)
116 {
118 result->field= field;
119 result->field_size= size;
120 }
121 else
122 {
123 result->field= field;
124 result->field_size= size;
125 result->field_offset= 0;
126 result->field_total= total;
127 }
128
130 }
131 else if (result->field == NULL)
132 {
133 result->field= field;
134 result->field_size= size;
135 }
136
137 ret= drizzle_state_loop(result->con);
138 if (ret == DRIZZLE_RETURN_PAUSE)
140
141 return ret;
142}
143
144/*
145 * Internal state functions.
146 */
147
149{
151
152 drizzle_log_debug(con->drizzle, "drizzle_state_field_read");
153
154 if (con->buffer_size == 0)
155 {
157 return DRIZZLE_RETURN_OK;
158 }
159
160 con->result->field_offset+= con->result->field_size;
161 if (con->result->field_offset == con->result->field_total)
162 {
163 con->result->field_offset= 0;
164 con->result->field_size= 0;
165
166 con->result->field_total= (size_t)drizzle_unpack_length(con, &ret);
167 if (ret == DRIZZLE_RETURN_NULL_SIZE)
168 {
169 con->result->field= NULL;
170 con->result->field_current++;
172 return DRIZZLE_RETURN_OK;
173 }
174 else if (ret != DRIZZLE_RETURN_OK)
175 {
176 if (ret == DRIZZLE_RETURN_IO_WAIT)
177 {
179 return DRIZZLE_RETURN_OK;
180 }
181
182 return ret;
183 }
184
186 "field_offset= %zu, field_size= %zu, field_total= %zu",
188 con->result->field_total);
189
190 if ((size_t)(con->buffer_size) >= con->result->field_total)
191 con->result->field_size= con->result->field_total;
192 else
193 con->result->field_size= con->buffer_size;
194 }
195 else
196 {
197 if ((con->result->field_offset + con->buffer_size) >=
198 con->result->field_total)
199 {
200 con->result->field_size= (con->result->field_total -
201 con->result->field_offset);
202 }
203 else
204 con->result->field_size= con->buffer_size;
205 }
206
207 /* This is a special case when a row is larger than the packet size. */
208 if (con->result->field_size > (size_t)con->packet_size)
209 {
210 con->result->field_size= con->packet_size;
211
214 else
215 {
219 }
220 }
221
222 con->result->field= (char *)con->buffer_ptr;
223 con->buffer_ptr+= con->result->field_size;
224 con->buffer_size-= con->result->field_size;
225 con->packet_size-= con->result->field_size;
226
228 "field_offset= %zu, field_size= %zu, field_total= %zu",
230 con->result->field_total);
231
232 if ((con->result->field_offset + con->result->field_size) ==
233 con->result->field_total)
234 {
235 if (con->result->column_buffer != NULL &&
237 con->result->field_total)
238 {
240 con->result->field_total;
241 }
242
243 con->result->field_current++;
244 }
245
246 if (con->result->field_total == 0 || con->result->field_size > 0 ||
247 con->packet_size == 0)
248 {
250 }
251
252 return DRIZZLE_RETURN_OK;
253}
254
256{
257 uint8_t *start= con->buffer_ptr + con->buffer_size;
258 uint8_t *ptr;
259 size_t free_size;
260 drizzle_result_st *result= con->result;
261
262 drizzle_log_debug(con->drizzle, "drizzle_state_field_write");
263
264 if (result->field == NULL && result->field_total != 0)
266
267 free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
268 ptr= start;
269
270 if (result->field_offset == 0)
271 {
272 /* Make sure we can fit the max length and 1 byte of data in (9 + 1). */
273 if (free_size < 10)
274 {
276 return DRIZZLE_RETURN_OK;
277 }
278
279 if (result->field == NULL)
280 {
281 ptr[0]= 251;
282 ptr++;
283 }
284 else if (result->field_total == 0)
285 {
286 ptr[0]= 0;
287 ptr++;
288 }
289 else
290 ptr= drizzle_pack_length(result->field_total, ptr);
291
292 free_size-= (size_t)(ptr - start);
293 con->buffer_size+= (size_t)(ptr - start);
294 con->packet_size-= (size_t)(ptr - start);
295 }
296 else if (result->field_size > DRIZZLE_BUFFER_COPY_THRESHOLD)
297 {
298 /* Flush the internal buffer first. */
299 if (con->buffer_size != 0)
300 {
302 return DRIZZLE_RETURN_OK;
303 }
304
305 /* We do this to write directly from the field buffer to avoid memcpy(). */
306 con->buffer_ptr= (uint8_t *)result->field;
307 con->buffer_size= result->field_size;
308 con->packet_size-= result->field_size;
309 result->field_offset+= result->field_size;
310 result->field= NULL;
311
312 if (result->field_offset == result->field_total)
314 else if (con->packet_size == 0)
315 {
318 }
319
321 return DRIZZLE_RETURN_OK;
322 }
323
324 if (result->field_size == 0)
326 else
327 {
328 if (result->field_size < free_size)
329 free_size= result->field_size;
330
331 memcpy(ptr, result->field, free_size);
332 result->field_offset+= free_size;
333 con->buffer_size+= free_size;
334 con->packet_size-= free_size;
335
336 if (result->field_offset == result->field_total)
337 {
338 result->field= NULL;
340 }
341 else
342 {
343 if (con->packet_size == 0)
344 {
347 }
348
349 if (result->field_size == free_size)
350 result->field= NULL;
351 else
352 {
353 result->field+= free_size;
354 result->field_size-= free_size;
356 }
357 }
358 }
359
360 return DRIZZLE_RETURN_OK;
361}
System Include Files.
static void drizzle_state_pop(drizzle_con_st *con)
Definition conn_local.h:73
static void drizzle_state_push(drizzle_con_st *con, drizzle_state_fn *function)
Definition conn_local.h:57
static bool drizzle_state_none(drizzle_con_st *con)
Definition conn_local.h:45
@ DRIZZLE_CON_RAW_PACKET
Definition constants.h:136
#define DRIZZLE_MAX_BUFFER_SIZE
Definition constants.h:55
#define DRIZZLE_BUFFER_COPY_THRESHOLD
Definition constants.h:56
drizzle_return_t
Definition constants.h:69
@ DRIZZLE_RETURN_PAUSE
Definition constants.h:72
@ DRIZZLE_RETURN_OK
Definition constants.h:70
@ DRIZZLE_RETURN_IO_WAIT
Definition constants.h:71
@ DRIZZLE_RETURN_ROW_END
Definition constants.h:89
@ DRIZZLE_RETURN_NULL_SIZE
Definition constants.h:86
@ DRIZZLE_RETURN_ROW_BREAK
Definition constants.h:73
@ DRIZZLE_RETURN_MEMORY
Definition constants.h:74
drizzle_field_t drizzle_field_read(drizzle_result_st *result, size_t *offset, size_t *size, size_t *total, drizzle_return_t *ret_ptr)
Definition field.c:22
drizzle_field_t drizzle_field_buffer(drizzle_result_st *result, size_t *total, drizzle_return_t *ret_ptr)
Definition field.c:51
void drizzle_field_free(drizzle_field_t field)
Definition field.c:97
drizzle_return_t drizzle_field_write(drizzle_result_st *result, const drizzle_field_t field, size_t size, size_t total)
Definition field.c:107
static void drizzle_log_debug(drizzle_st *drizzle, const char *format,...)
void drizzle_set_error(drizzle_st *drizzle, const char *function, const char *format,...)
Definition drizzle.c:633
uint8_t * drizzle_pack_length(uint64_t number, uint8_t *ptr)
Definition pack.c:40
uint64_t drizzle_unpack_length(drizzle_con_st *con, drizzle_return_t *ret_ptr)
Definition pack.c:72
drizzle_result_options_t
Definition constants.h:290
@ DRIZZLE_RESULT_ROW_BREAK
Definition constants.h:297
drizzle_return_t drizzle_state_packet_read(drizzle_con_st *con)
Definition state.c:40
drizzle_return_t drizzle_state_write(drizzle_con_st *con)
Definition conn.c:975
drizzle_return_t drizzle_state_read(drizzle_con_st *con)
Definition conn.c:897
drizzle_return_t drizzle_state_field_write(drizzle_con_st *con)
Definition field.c:255
drizzle_return_t drizzle_state_loop(drizzle_con_st *con)
Definition state.c:18
drizzle_return_t drizzle_state_field_read(drizzle_con_st *con)
Definition field.c:148
char * drizzle_field_t
Definition constants.h:412
uint8_t buffer[DRIZZLE_MAX_BUFFER_SIZE]
Definition structs.h:115
drizzle_st * drizzle
Definition structs.h:103
drizzle_result_st * result
Definition structs.h:107
drizzle_con_options_t options
Definition structs.h:84
size_t packet_size
Definition structs.h:96
uint8_t * buffer_ptr
Definition structs.h:98
size_t buffer_size
Definition structs.h:92
drizzle_field_t field
Definition structs.h:172
drizzle_column_st * column_buffer
Definition structs.h:163
size_t field_total
Definition structs.h:169
uint16_t field_current
Definition structs.h:168
drizzle_con_st * con
Definition structs.h:147
drizzle_result_options_t options
Definition structs.h:150
drizzle_field_t field_buffer
Definition structs.h:173
size_t field_size
Definition structs.h:171
size_t field_offset
Definition structs.h:170
uint16_t column_count
Definition structs.h:159