2
* Drizzle Client & Protocol Library
4
* Copyright (C) 2008 Eric Day (eday@oddments.org)
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions are
11
* * Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
14
* * Redistributions in binary form must reproduce the above
15
* copyright notice, this list of conditions and the following disclaimer
16
* in the documentation and/or other materials provided with the
19
* * The names of its contributors may not be used to endorse or
20
* promote products derived from this software without specific prior
23
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
* @brief Field definitions
48
drizzle_field_t drizzle_field_read(drizzle_result_st *result, size_t *offset,
49
size_t *size, size_t *total,
50
drizzle_return_t *ret_ptr)
52
if (drizzle_state_none(result->con))
54
if (result->field_current == result->column_count)
56
*ret_ptr= DRIZZLE_RETURN_ROW_END;
60
drizzle_state_push(result->con, drizzle_state_field_read);
63
*ret_ptr= drizzle_state_loop(result->con);
64
if (*ret_ptr == DRIZZLE_RETURN_OK &&
65
result->options & DRIZZLE_RESULT_ROW_BREAK)
67
*ret_ptr= DRIZZLE_RETURN_ROW_BREAK;
70
*offset= result->field_offset;
71
*size= result->field_size;
72
*total= result->field_total;
77
drizzle_field_t drizzle_field_buffer(drizzle_result_st *result, size_t *total,
78
drizzle_return_t *ret_ptr)
80
drizzle_field_t field;
84
field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
85
if (*ret_ptr != DRIZZLE_RETURN_OK)
94
if (result->field_buffer == NULL)
96
result->field_buffer= new drizzle_field_t_type[(*total) + 1];
99
memcpy(result->field_buffer + offset, field, size);
101
while ((offset + size) != (*total))
103
field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
104
if (*ret_ptr != DRIZZLE_RETURN_OK)
107
memcpy(result->field_buffer + offset, field, size);
110
field= result->field_buffer;
111
result->field_buffer= NULL;
117
void drizzle_field_free(drizzle_field_t field)
126
drizzle_return_t drizzle_field_write(drizzle_result_st *result,
127
const drizzle_field_t field, size_t size,
130
drizzle_return_t ret;
132
if (drizzle_state_none(result->con))
134
if (result->options & DRIZZLE_RESULT_ROW_BREAK)
136
result->options&= ~DRIZZLE_RESULT_ROW_BREAK;
137
result->field= field;
138
result->field_size= size;
142
result->field= field;
143
result->field_size= size;
144
result->field_offset= 0;
145
result->field_total= total;
148
drizzle_state_push(result->con, drizzle_state_field_write);
150
else if (result->field == NULL)
152
result->field= field;
153
result->field_size= size;
156
ret= drizzle_state_loop(result->con);
157
if (ret == DRIZZLE_RETURN_PAUSE)
158
ret= DRIZZLE_RETURN_OK;
164
* Internal state functions.
167
drizzle_return_t drizzle_state_field_read(drizzle_con_st *con)
169
drizzle_return_t ret;
171
drizzle_log_debug(con->drizzle, "drizzle_state_field_read");
173
if (con->buffer_size == 0)
175
drizzle_state_push(con, drizzle_state_read);
176
return DRIZZLE_RETURN_OK;
179
con->result->field_offset+= con->result->field_size;
180
if (con->result->field_offset == con->result->field_total)
182
con->result->field_offset= 0;
183
con->result->field_size= 0;
185
con->result->field_total= (size_t)drizzle_unpack_length(con, &ret);
186
if (ret == DRIZZLE_RETURN_NULL_SIZE)
188
con->result->field= NULL;
189
con->result->field_current++;
190
drizzle_state_pop(con);
191
return DRIZZLE_RETURN_OK;
193
else if (ret != DRIZZLE_RETURN_OK)
195
if (ret == DRIZZLE_RETURN_IO_WAIT)
197
drizzle_state_push(con, drizzle_state_read);
198
return DRIZZLE_RETURN_OK;
204
drizzle_log_debug(con->drizzle,
205
"field_offset= %zu, field_size= %zu, field_total= %zu",
206
con->result->field_offset, con->result->field_size,
207
con->result->field_total);
209
if ((size_t)(con->buffer_size) >= con->result->field_total)
210
con->result->field_size= con->result->field_total;
212
con->result->field_size= con->buffer_size;
216
if ((con->result->field_offset + con->buffer_size) >=
217
con->result->field_total)
219
con->result->field_size= (con->result->field_total -
220
con->result->field_offset);
223
con->result->field_size= con->buffer_size;
226
/* This is a special case when a row is larger than the packet size. */
227
if (con->result->field_size > (size_t)con->packet_size)
229
con->result->field_size= con->packet_size;
231
if (con->options & DRIZZLE_CON_RAW_PACKET)
232
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
235
drizzle_state_pop(con);
236
drizzle_state_push(con, drizzle_state_packet_read);
237
drizzle_state_push(con, drizzle_state_field_read);
241
con->result->field= (char *)con->buffer_ptr;
242
con->buffer_ptr+= con->result->field_size;
243
con->buffer_size-= con->result->field_size;
244
con->packet_size-= con->result->field_size;
246
drizzle_log_debug(con->drizzle,
247
"field_offset= %zu, field_size= %zu, field_total= %zu",
248
con->result->field_offset, con->result->field_size,
249
con->result->field_total);
251
if ((con->result->field_offset + con->result->field_size) ==
252
con->result->field_total)
254
if (con->result->column_buffer != NULL &&
255
con->result->column_buffer[con->result->field_current].max_size <
256
con->result->field_total)
258
con->result->column_buffer[con->result->field_current].max_size=
259
con->result->field_total;
262
con->result->field_current++;
265
if (con->result->field_total == 0 || con->result->field_size > 0 ||
266
con->packet_size == 0)
268
drizzle_state_pop(con);
271
return DRIZZLE_RETURN_OK;
274
drizzle_return_t drizzle_state_field_write(drizzle_con_st *con)
276
uint8_t *start= con->buffer_ptr + con->buffer_size;
279
drizzle_result_st *result= con->result;
281
drizzle_log_debug(con->drizzle, "drizzle_state_field_write");
283
if (result->field == NULL && result->field_total != 0)
284
return DRIZZLE_RETURN_PAUSE;
286
free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
289
if (result->field_offset == 0)
291
/* Make sure we can fit the max length and 1 byte of data in (9 + 1). */
294
drizzle_state_push(con, drizzle_state_write);
295
return DRIZZLE_RETURN_OK;
298
if (result->field == NULL)
303
else if (result->field_total == 0)
309
ptr= drizzle_pack_length(result->field_total, ptr);
311
free_size-= (size_t)(ptr - start);
312
con->buffer_size+= (size_t)(ptr - start);
313
con->packet_size-= (size_t)(ptr - start);
315
else if (result->field_size > DRIZZLE_BUFFER_COPY_THRESHOLD)
317
/* Flush the internal buffer first. */
318
if (con->buffer_size != 0)
320
drizzle_state_push(con, drizzle_state_write);
321
return DRIZZLE_RETURN_OK;
324
/* We do this to write directly from the field buffer to avoid memcpy(). */
325
con->buffer_ptr= (uint8_t *)result->field;
326
con->buffer_size= result->field_size;
327
con->packet_size-= result->field_size;
328
result->field_offset+= result->field_size;
331
if (result->field_offset == result->field_total)
332
drizzle_state_pop(con);
333
else if (con->packet_size == 0)
335
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
336
drizzle_state_pop(con);
339
drizzle_state_push(con, drizzle_state_write);
340
return DRIZZLE_RETURN_OK;
343
if (result->field_size == 0)
344
drizzle_state_pop(con);
347
if (result->field_size < free_size)
348
free_size= result->field_size;
350
memcpy(ptr, result->field, free_size);
351
result->field_offset+= free_size;
352
con->buffer_size+= free_size;
353
con->packet_size-= free_size;
355
if (result->field_offset == result->field_total)
358
drizzle_state_pop(con);
362
if (con->packet_size == 0)
364
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
365
drizzle_state_pop(con);
368
if (result->field_size == free_size)
372
result->field+= free_size;
373
result->field_size-= free_size;
374
drizzle_state_push(con, drizzle_state_write);
379
return DRIZZLE_RETURN_OK;