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];
97
if (result->field_buffer == NULL)
99
drizzle_set_error(result->con->drizzle, "drizzle_field_buffer", "malloc");
100
*ret_ptr= DRIZZLE_RETURN_MEMORY;
105
memcpy(result->field_buffer + offset, field, size);
107
while ((offset + size) != (*total))
109
field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
110
if (*ret_ptr != DRIZZLE_RETURN_OK)
113
memcpy(result->field_buffer + offset, field, size);
116
field= result->field_buffer;
117
result->field_buffer= NULL;
123
void drizzle_field_free(drizzle_field_t field)
133
drizzle_return_t drizzle_field_write(drizzle_result_st *result,
134
const drizzle_field_t field, size_t size,
137
drizzle_return_t ret;
139
if (drizzle_state_none(result->con))
141
if (result->options & DRIZZLE_RESULT_ROW_BREAK)
143
result->options&= ~DRIZZLE_RESULT_ROW_BREAK;
144
result->field= field;
145
result->field_size= size;
149
result->field= field;
150
result->field_size= size;
151
result->field_offset= 0;
152
result->field_total= total;
155
drizzle_state_push(result->con, drizzle_state_field_write);
157
else if (result->field == NULL)
159
result->field= field;
160
result->field_size= size;
163
ret= drizzle_state_loop(result->con);
164
if (ret == DRIZZLE_RETURN_PAUSE)
165
ret= DRIZZLE_RETURN_OK;
171
* Internal state functions.
174
drizzle_return_t drizzle_state_field_read(drizzle_con_st *con)
176
drizzle_return_t ret;
178
drizzle_log_debug(con->drizzle, "drizzle_state_field_read");
180
if (con->buffer_size == 0)
182
drizzle_state_push(con, drizzle_state_read);
183
return DRIZZLE_RETURN_OK;
186
con->result->field_offset+= con->result->field_size;
187
if (con->result->field_offset == con->result->field_total)
189
con->result->field_offset= 0;
190
con->result->field_size= 0;
192
con->result->field_total= (size_t)drizzle_unpack_length(con, &ret);
193
if (ret == DRIZZLE_RETURN_NULL_SIZE)
195
con->result->field= NULL;
196
con->result->field_current++;
197
drizzle_state_pop(con);
198
return DRIZZLE_RETURN_OK;
200
else if (ret != DRIZZLE_RETURN_OK)
202
if (ret == DRIZZLE_RETURN_IO_WAIT)
204
drizzle_state_push(con, drizzle_state_read);
205
return DRIZZLE_RETURN_OK;
211
drizzle_log_debug(con->drizzle,
212
"field_offset= %zu, field_size= %zu, field_total= %zu",
213
con->result->field_offset, con->result->field_size,
214
con->result->field_total);
216
if ((size_t)(con->buffer_size) >= con->result->field_total)
217
con->result->field_size= con->result->field_total;
219
con->result->field_size= con->buffer_size;
223
if ((con->result->field_offset + con->buffer_size) >=
224
con->result->field_total)
226
con->result->field_size= (con->result->field_total -
227
con->result->field_offset);
230
con->result->field_size= con->buffer_size;
233
/* This is a special case when a row is larger than the packet size. */
234
if (con->result->field_size > (size_t)con->packet_size)
236
con->result->field_size= con->packet_size;
238
if (con->options & DRIZZLE_CON_RAW_PACKET)
239
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
242
drizzle_state_pop(con);
243
drizzle_state_push(con, drizzle_state_packet_read);
244
drizzle_state_push(con, drizzle_state_field_read);
248
con->result->field= (char *)con->buffer_ptr;
249
con->buffer_ptr+= con->result->field_size;
250
con->buffer_size-= con->result->field_size;
251
con->packet_size-= con->result->field_size;
253
drizzle_log_debug(con->drizzle,
254
"field_offset= %zu, field_size= %zu, field_total= %zu",
255
con->result->field_offset, con->result->field_size,
256
con->result->field_total);
258
if ((con->result->field_offset + con->result->field_size) ==
259
con->result->field_total)
261
if (con->result->column_buffer != NULL &&
262
con->result->column_buffer[con->result->field_current].max_size <
263
con->result->field_total)
265
con->result->column_buffer[con->result->field_current].max_size=
266
con->result->field_total;
269
con->result->field_current++;
272
if (con->result->field_total == 0 || con->result->field_size > 0 ||
273
con->packet_size == 0)
275
drizzle_state_pop(con);
278
return DRIZZLE_RETURN_OK;
281
drizzle_return_t drizzle_state_field_write(drizzle_con_st *con)
283
uint8_t *start= con->buffer_ptr + con->buffer_size;
286
drizzle_result_st *result= con->result;
288
drizzle_log_debug(con->drizzle, "drizzle_state_field_write");
290
if (result->field == NULL && result->field_total != 0)
291
return DRIZZLE_RETURN_PAUSE;
293
free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
296
if (result->field_offset == 0)
298
/* Make sure we can fit the max length and 1 byte of data in (9 + 1). */
301
drizzle_state_push(con, drizzle_state_write);
302
return DRIZZLE_RETURN_OK;
305
if (result->field == NULL)
310
else if (result->field_total == 0)
316
ptr= drizzle_pack_length(result->field_total, ptr);
318
free_size-= (size_t)(ptr - start);
319
con->buffer_size+= (size_t)(ptr - start);
320
con->packet_size-= (size_t)(ptr - start);
322
else if (result->field_size > DRIZZLE_BUFFER_COPY_THRESHOLD)
324
/* Flush the internal buffer first. */
325
if (con->buffer_size != 0)
327
drizzle_state_push(con, drizzle_state_write);
328
return DRIZZLE_RETURN_OK;
331
/* We do this to write directly from the field buffer to avoid memcpy(). */
332
con->buffer_ptr= (uint8_t *)result->field;
333
con->buffer_size= result->field_size;
334
con->packet_size-= result->field_size;
335
result->field_offset+= result->field_size;
338
if (result->field_offset == result->field_total)
339
drizzle_state_pop(con);
340
else if (con->packet_size == 0)
342
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
343
drizzle_state_pop(con);
346
drizzle_state_push(con, drizzle_state_write);
347
return DRIZZLE_RETURN_OK;
350
if (result->field_size == 0)
351
drizzle_state_pop(con);
354
if (result->field_size < free_size)
355
free_size= result->field_size;
357
memcpy(ptr, result->field, free_size);
358
result->field_offset+= free_size;
359
con->buffer_size+= free_size;
360
con->packet_size-= free_size;
362
if (result->field_offset == result->field_total)
365
drizzle_state_pop(con);
369
if (con->packet_size == 0)
371
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
372
drizzle_state_pop(con);
375
if (result->field_size == free_size)
379
result->field+= free_size;
380
result->field_size-= free_size;
381
drizzle_state_push(con, drizzle_state_write);
386
return DRIZZLE_RETURN_OK;