2
* Drizzle Client & Protocol Library
4
* Copyright (C) 2008 Eric Day (eday@oddments.org)
7
* Use and distribution licensed under the BSD license. See
8
* the COPYING file in this directory for full text.
13
* @brief Field definitions
22
drizzle_field_t drizzle_field_read(drizzle_result_st *result, size_t *offset,
23
size_t *size, size_t *total,
24
drizzle_return_t *ret_ptr)
26
if (drizzle_state_none(result->con))
28
if (result->field_current == result->column_count)
30
*ret_ptr= DRIZZLE_RETURN_ROW_END;
34
drizzle_state_push(result->con, drizzle_state_field_read);
37
*ret_ptr= drizzle_state_loop(result->con);
38
if (*ret_ptr == DRIZZLE_RETURN_OK &&
39
result->options & DRIZZLE_RESULT_ROW_BREAK)
41
*ret_ptr= DRIZZLE_RETURN_ROW_BREAK;
44
*offset= result->field_offset;
45
*size= result->field_size;
46
*total= result->field_total;
51
drizzle_field_t drizzle_field_buffer(drizzle_result_st *result, size_t *total,
52
drizzle_return_t *ret_ptr)
54
drizzle_field_t field;
58
field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
59
if (*ret_ptr != DRIZZLE_RETURN_OK)
68
if (result->field_buffer == NULL)
70
result->field_buffer= malloc((*total) + 1);
71
if (result->field_buffer == NULL)
73
drizzle_set_error(result->con->drizzle, "drizzle_field_buffer", "malloc");
74
*ret_ptr= DRIZZLE_RETURN_MEMORY;
79
memcpy(result->field_buffer + offset, field, size);
81
while ((offset + size) != (*total))
83
field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
84
if (*ret_ptr != DRIZZLE_RETURN_OK)
87
memcpy(result->field_buffer + offset, field, size);
90
field= result->field_buffer;
91
result->field_buffer= NULL;
97
void drizzle_field_free(drizzle_field_t field)
107
drizzle_return_t drizzle_field_write(drizzle_result_st *result,
108
const drizzle_field_t field, size_t size,
111
drizzle_return_t ret;
113
if (drizzle_state_none(result->con))
115
if (result->options & DRIZZLE_RESULT_ROW_BREAK)
117
result->options&= (drizzle_result_options_t)~DRIZZLE_RESULT_ROW_BREAK;
118
result->field= field;
119
result->field_size= size;
123
result->field= field;
124
result->field_size= size;
125
result->field_offset= 0;
126
result->field_total= total;
129
drizzle_state_push(result->con, drizzle_state_field_write);
131
else if (result->field == NULL)
133
result->field= field;
134
result->field_size= size;
137
ret= drizzle_state_loop(result->con);
138
if (ret == DRIZZLE_RETURN_PAUSE)
139
ret= DRIZZLE_RETURN_OK;
145
* Internal state functions.
148
drizzle_return_t drizzle_state_field_read(drizzle_con_st *con)
150
drizzle_return_t ret;
152
drizzle_log_debug(con->drizzle, "drizzle_state_field_read");
154
if (con->buffer_size == 0)
156
drizzle_state_push(con, drizzle_state_read);
157
return DRIZZLE_RETURN_OK;
160
con->result->field_offset+= con->result->field_size;
161
if (con->result->field_offset == con->result->field_total)
163
con->result->field_offset= 0;
164
con->result->field_size= 0;
166
con->result->field_total= (size_t)drizzle_unpack_length(con, &ret);
167
if (ret == DRIZZLE_RETURN_NULL_SIZE)
169
con->result->field= NULL;
170
con->result->field_current++;
171
drizzle_state_pop(con);
172
return DRIZZLE_RETURN_OK;
174
else if (ret != DRIZZLE_RETURN_OK)
176
if (ret == DRIZZLE_RETURN_IO_WAIT)
178
drizzle_state_push(con, drizzle_state_read);
179
return DRIZZLE_RETURN_OK;
185
drizzle_log_debug(con->drizzle,
186
"field_offset= %zu, field_size= %zu, field_total= %zu",
187
con->result->field_offset, con->result->field_size,
188
con->result->field_total);
190
if ((size_t)(con->buffer_size) >= con->result->field_total)
191
con->result->field_size= con->result->field_total;
193
con->result->field_size= con->buffer_size;
197
if ((con->result->field_offset + con->buffer_size) >=
198
con->result->field_total)
200
con->result->field_size= (con->result->field_total -
201
con->result->field_offset);
204
con->result->field_size= con->buffer_size;
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)
210
con->result->field_size= con->packet_size;
212
if (con->options & DRIZZLE_CON_RAW_PACKET)
213
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
216
drizzle_state_pop(con);
217
drizzle_state_push(con, drizzle_state_packet_read);
218
drizzle_state_push(con, drizzle_state_field_read);
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;
227
drizzle_log_debug(con->drizzle,
228
"field_offset= %zu, field_size= %zu, field_total= %zu",
229
con->result->field_offset, con->result->field_size,
230
con->result->field_total);
232
if ((con->result->field_offset + con->result->field_size) ==
233
con->result->field_total)
235
if (con->result->column_buffer != NULL &&
236
con->result->column_buffer[con->result->field_current].max_size <
237
con->result->field_total)
239
con->result->column_buffer[con->result->field_current].max_size=
240
con->result->field_total;
243
con->result->field_current++;
246
if (con->result->field_total == 0 || con->result->field_size > 0 ||
247
con->packet_size == 0)
249
drizzle_state_pop(con);
252
return DRIZZLE_RETURN_OK;
255
drizzle_return_t drizzle_state_field_write(drizzle_con_st *con)
257
uint8_t *start= con->buffer_ptr + con->buffer_size;
260
drizzle_result_st *result= con->result;
262
drizzle_log_debug(con->drizzle, "drizzle_state_field_write");
264
if (result->field == NULL && result->field_total != 0)
265
return DRIZZLE_RETURN_PAUSE;
267
free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
270
if (result->field_offset == 0)
272
/* Make sure we can fit the max length and 1 byte of data in (9 + 1). */
275
drizzle_state_push(con, drizzle_state_write);
276
return DRIZZLE_RETURN_OK;
279
if (result->field == NULL)
284
else if (result->field_total == 0)
290
ptr= drizzle_pack_length(result->field_total, ptr);
292
free_size-= (size_t)(ptr - start);
293
con->buffer_size+= (size_t)(ptr - start);
294
con->packet_size-= (size_t)(ptr - start);
296
else if (result->field_size > DRIZZLE_BUFFER_COPY_THRESHOLD)
298
/* Flush the internal buffer first. */
299
if (con->buffer_size != 0)
301
drizzle_state_push(con, drizzle_state_write);
302
return DRIZZLE_RETURN_OK;
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;
312
if (result->field_offset == result->field_total)
313
drizzle_state_pop(con);
314
else if (con->packet_size == 0)
316
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
317
drizzle_state_pop(con);
320
drizzle_state_push(con, drizzle_state_write);
321
return DRIZZLE_RETURN_OK;
324
if (result->field_size == 0)
325
drizzle_state_pop(con);
328
if (result->field_size < free_size)
329
free_size= result->field_size;
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;
336
if (result->field_offset == result->field_total)
339
drizzle_state_pop(con);
343
if (con->packet_size == 0)
345
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
346
drizzle_state_pop(con);
349
if (result->field_size == free_size)
353
result->field+= free_size;
354
result->field_size-= free_size;
355
drizzle_state_push(con, drizzle_state_write);
360
return DRIZZLE_RETURN_OK;