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
42
#include <libdrizzle-1.0/common.h>
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= (drizzle_field_t)malloc((*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)
132
drizzle_return_t drizzle_field_write(drizzle_result_st *result,
133
const drizzle_field_t field, size_t size,
136
drizzle_return_t ret;
138
if (drizzle_state_none(result->con))
140
if (result->options & DRIZZLE_RESULT_ROW_BREAK)
142
result->options&= int(~DRIZZLE_RESULT_ROW_BREAK);
143
result->field= field;
144
result->field_size= size;
148
result->field= field;
149
result->field_size= size;
150
result->field_offset= 0;
151
result->field_total= total;
154
drizzle_state_push(result->con, drizzle_state_field_write);
156
else if (result->field == NULL)
158
result->field= field;
159
result->field_size= size;
162
ret= drizzle_state_loop(result->con);
163
if (ret == DRIZZLE_RETURN_PAUSE)
164
ret= DRIZZLE_RETURN_OK;
170
* Internal state functions.
173
drizzle_return_t drizzle_state_field_read(drizzle_con_st *con)
175
drizzle_return_t ret;
177
drizzle_log_debug(con->drizzle, "drizzle_state_field_read");
179
if (con->buffer_size == 0)
181
drizzle_state_push(con, drizzle_state_read);
182
return DRIZZLE_RETURN_OK;
185
con->result->field_offset+= con->result->field_size;
186
if (con->result->field_offset == con->result->field_total)
188
con->result->field_offset= 0;
189
con->result->field_size= 0;
191
con->result->field_total= (size_t)drizzle_unpack_length(con, &ret);
192
if (ret == DRIZZLE_RETURN_NULL_SIZE)
194
con->result->field= NULL;
195
con->result->field_current++;
196
drizzle_state_pop(con);
197
return DRIZZLE_RETURN_OK;
199
else if (ret != DRIZZLE_RETURN_OK)
201
if (ret == DRIZZLE_RETURN_IO_WAIT)
203
drizzle_state_push(con, drizzle_state_read);
204
return DRIZZLE_RETURN_OK;
210
drizzle_log_debug(con->drizzle,
211
"field_offset= %zu, field_size= %zu, field_total= %zu",
212
con->result->field_offset, con->result->field_size,
213
con->result->field_total);
215
if ((size_t)(con->buffer_size) >= con->result->field_total)
216
con->result->field_size= con->result->field_total;
218
con->result->field_size= con->buffer_size;
222
if ((con->result->field_offset + con->buffer_size) >=
223
con->result->field_total)
225
con->result->field_size= (con->result->field_total -
226
con->result->field_offset);
229
con->result->field_size= con->buffer_size;
232
/* This is a special case when a row is larger than the packet size. */
233
if (con->result->field_size > (size_t)con->packet_size)
235
con->result->field_size= con->packet_size;
237
if (con->options & DRIZZLE_CON_RAW_PACKET)
238
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
241
drizzle_state_pop(con);
242
drizzle_state_push(con, drizzle_state_packet_read);
243
drizzle_state_push(con, drizzle_state_field_read);
247
con->result->field= (char *)con->buffer_ptr;
248
con->buffer_ptr+= con->result->field_size;
249
con->buffer_size-= con->result->field_size;
250
con->packet_size-= con->result->field_size;
252
drizzle_log_debug(con->drizzle,
253
"field_offset= %zu, field_size= %zu, field_total= %zu",
254
con->result->field_offset, con->result->field_size,
255
con->result->field_total);
257
if ((con->result->field_offset + con->result->field_size) ==
258
con->result->field_total)
260
if (con->result->column_buffer != NULL &&
261
con->result->column_buffer[con->result->field_current].max_size <
262
con->result->field_total)
264
con->result->column_buffer[con->result->field_current].max_size=
265
con->result->field_total;
268
con->result->field_current++;
271
if (con->result->field_total == 0 || con->result->field_size > 0 ||
272
con->packet_size == 0)
274
drizzle_state_pop(con);
277
return DRIZZLE_RETURN_OK;
280
drizzle_return_t drizzle_state_field_write(drizzle_con_st *con)
282
uint8_t *start= con->buffer_ptr + con->buffer_size;
285
drizzle_result_st *result= con->result;
287
drizzle_log_debug(con->drizzle, "drizzle_state_field_write");
289
if (result->field == NULL && result->field_total != 0)
290
return DRIZZLE_RETURN_PAUSE;
292
free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
295
if (result->field_offset == 0)
297
/* Make sure we can fit the max length and 1 byte of data in (9 + 1). */
300
drizzle_state_push(con, drizzle_state_write);
301
return DRIZZLE_RETURN_OK;
304
if (result->field == NULL)
309
else if (result->field_total == 0)
315
ptr= drizzle_pack_length(result->field_total, ptr);
317
free_size-= (size_t)(ptr - start);
318
con->buffer_size+= (size_t)(ptr - start);
319
con->packet_size-= (size_t)(ptr - start);
321
else if (result->field_size > DRIZZLE_BUFFER_COPY_THRESHOLD)
323
/* Flush the internal buffer first. */
324
if (con->buffer_size != 0)
326
drizzle_state_push(con, drizzle_state_write);
327
return DRIZZLE_RETURN_OK;
330
/* We do this to write directly from the field buffer to avoid memcpy(). */
331
con->buffer_ptr= (uint8_t *)result->field;
332
con->buffer_size= result->field_size;
333
con->packet_size-= result->field_size;
334
result->field_offset+= result->field_size;
337
if (result->field_offset == result->field_total)
338
drizzle_state_pop(con);
339
else if (con->packet_size == 0)
341
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
342
drizzle_state_pop(con);
345
drizzle_state_push(con, drizzle_state_write);
346
return DRIZZLE_RETURN_OK;
349
if (result->field_size == 0)
350
drizzle_state_pop(con);
353
if (result->field_size < free_size)
354
free_size= result->field_size;
356
memcpy(ptr, result->field, free_size);
357
result->field_offset+= free_size;
358
con->buffer_size+= free_size;
359
con->packet_size-= free_size;
361
if (result->field_offset == result->field_total)
364
drizzle_state_pop(con);
368
if (con->packet_size == 0)
370
con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
371
drizzle_state_pop(con);
374
if (result->field_size == free_size)
378
result->field+= free_size;
379
result->field_size-= free_size;
380
drizzle_state_push(con, drizzle_state_write);
385
return DRIZZLE_RETURN_OK;