00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00043 #include <libdrizzle/common.h>
00044
00045
00046
00047
00048
00049 drizzle_field_t drizzle_field_read(drizzle_result_st *result, size_t *offset,
00050 size_t *size, size_t *total,
00051 drizzle_return_t *ret_ptr)
00052 {
00053 drizzle_return_t unused_ret;
00054 if (ret_ptr == NULL)
00055 {
00056 ret_ptr= &unused_ret;
00057 }
00058
00059 if (result == NULL)
00060 {
00061 *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
00062 return drizzle_field_t();
00063 }
00064
00065 if (drizzle_state_none(result->con))
00066 {
00067 if (result->field_current == result->column_count)
00068 {
00069 *ret_ptr= DRIZZLE_RETURN_ROW_END;
00070 return NULL;
00071 }
00072
00073 drizzle_state_push(result->con, drizzle_state_field_read);
00074 }
00075
00076 *ret_ptr= drizzle_state_loop(result->con);
00077 if (*ret_ptr == DRIZZLE_RETURN_OK and
00078 result->options & DRIZZLE_RESULT_ROW_BREAK)
00079 {
00080 *ret_ptr= DRIZZLE_RETURN_ROW_BREAK;
00081 }
00082
00083 if (offset)
00084 {
00085 *offset= result->field_offset;
00086 }
00087
00088 if (size)
00089 {
00090 *size= result->field_size;
00091 }
00092
00093 if (total)
00094 {
00095 *total= result->field_total;
00096 }
00097
00098 return result->field;
00099 }
00100
00101 drizzle_field_t drizzle_field_buffer(drizzle_result_st *result, size_t *total,
00102 drizzle_return_t *ret_ptr)
00103 {
00104 size_t offset= 0;
00105 size_t size= 0;
00106
00107 drizzle_return_t unused_ret;
00108 if (ret_ptr == NULL)
00109 {
00110 ret_ptr= &unused_ret;
00111 }
00112
00113 if (result == NULL)
00114 {
00115 *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
00116 return drizzle_field_t();
00117 }
00118
00119 drizzle_field_t field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
00120
00121 if (*ret_ptr != DRIZZLE_RETURN_OK)
00122 {
00123 return NULL;
00124 }
00125
00126 if (field == NULL)
00127 {
00128 *total= 0;
00129 return NULL;
00130 }
00131
00132 if (result->field_buffer == NULL)
00133 {
00134 result->field_buffer= (drizzle_field_t)realloc(NULL, (*total) +1);
00135 if (result->field_buffer == NULL)
00136 {
00137 drizzle_set_error(result->con->drizzle, __func__, "Failed to allocate.");
00138 *ret_ptr= DRIZZLE_RETURN_MEMORY;
00139 return NULL;
00140 }
00141 }
00142
00143 memcpy(result->field_buffer + offset, field, size);
00144
00145 while ((offset + size) != (*total))
00146 {
00147 field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
00148 if (*ret_ptr != DRIZZLE_RETURN_OK)
00149 {
00150 return NULL;
00151 }
00152
00153 memcpy(result->field_buffer + offset, field, size);
00154 }
00155
00156 field= result->field_buffer;
00157 result->field_buffer= NULL;
00158 field[*total]= 0;
00159
00160 return field;
00161 }
00162
00163 void drizzle_field_free(drizzle_field_t field)
00164 {
00165 if (field)
00166 {
00167 free(field);
00168 }
00169 }
00170
00171
00172
00173
00174
00175 drizzle_return_t drizzle_field_write(drizzle_result_st *result,
00176 const drizzle_field_t field, size_t size,
00177 size_t total)
00178 {
00179 if (result == NULL)
00180 {
00181 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00182 }
00183
00184 drizzle_return_t ret;
00185
00186 if (drizzle_state_none(result->con))
00187 {
00188 if (result->options & DRIZZLE_RESULT_ROW_BREAK)
00189 {
00190 result->options&= int(~DRIZZLE_RESULT_ROW_BREAK);
00191 result->field= field;
00192 result->field_size= size;
00193 }
00194 else
00195 {
00196 result->field= field;
00197 result->field_size= size;
00198 result->field_offset= 0;
00199 result->field_total= total;
00200 }
00201
00202 drizzle_state_push(result->con, drizzle_state_field_write);
00203 }
00204 else if (result->field == NULL)
00205 {
00206 result->field= field;
00207 result->field_size= size;
00208 }
00209
00210 ret= drizzle_state_loop(result->con);
00211 if (ret == DRIZZLE_RETURN_PAUSE)
00212 ret= DRIZZLE_RETURN_OK;
00213
00214 return ret;
00215 }
00216
00217
00218
00219
00220
00221 drizzle_return_t drizzle_state_field_read(drizzle_con_st *con)
00222 {
00223 if (con == NULL)
00224 {
00225 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00226 }
00227 drizzle_log_debug(con->drizzle, "drizzle_state_field_read");
00228
00229 if (con->buffer_size == 0)
00230 {
00231 drizzle_state_push(con, drizzle_state_read);
00232 return DRIZZLE_RETURN_OK;
00233 }
00234
00235 con->result->field_offset+= con->result->field_size;
00236 if (con->result->field_offset == con->result->field_total)
00237 {
00238 con->result->field_offset= 0;
00239 con->result->field_size= 0;
00240
00241 drizzle_return_t ret;
00242 con->result->field_total= (size_t)drizzle_unpack_length(con, &ret);
00243 if (ret == DRIZZLE_RETURN_NULL_SIZE)
00244 {
00245 con->result->field= NULL;
00246 con->result->field_current++;
00247 drizzle_state_pop(con);
00248 return DRIZZLE_RETURN_OK;
00249 }
00250 else if (ret != DRIZZLE_RETURN_OK)
00251 {
00252 if (ret == DRIZZLE_RETURN_IO_WAIT)
00253 {
00254 drizzle_state_push(con, drizzle_state_read);
00255 return DRIZZLE_RETURN_OK;
00256 }
00257
00258 return ret;
00259 }
00260
00261 drizzle_log_debug(con->drizzle,
00262 "field_offset= %zu, field_size= %zu, field_total= %zu",
00263 con->result->field_offset, con->result->field_size,
00264 con->result->field_total);
00265
00266 if ((size_t)(con->buffer_size) >= con->result->field_total)
00267 {
00268 con->result->field_size= con->result->field_total;
00269 }
00270 else
00271 {
00272 con->result->field_size= con->buffer_size;
00273 }
00274 }
00275 else
00276 {
00277 if ((con->result->field_offset + con->buffer_size) >=
00278 con->result->field_total)
00279 {
00280 con->result->field_size= (con->result->field_total -
00281 con->result->field_offset);
00282 }
00283 else
00284 {
00285 con->result->field_size= con->buffer_size;
00286 }
00287 }
00288
00289
00290 if (con->result->field_size > (size_t)con->packet_size)
00291 {
00292 con->result->field_size= con->packet_size;
00293
00294 if (con->options & DRIZZLE_CON_RAW_PACKET)
00295 {
00296 con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
00297 }
00298 else
00299 {
00300 drizzle_state_pop(con);
00301 drizzle_state_push(con, drizzle_state_packet_read);
00302 drizzle_state_push(con, drizzle_state_field_read);
00303 }
00304 }
00305
00306 con->result->field= (char *)con->buffer_ptr;
00307 con->buffer_ptr+= con->result->field_size;
00308 con->buffer_size-= con->result->field_size;
00309 con->packet_size-= con->result->field_size;
00310
00311 drizzle_log_debug(con->drizzle,
00312 "field_offset= %zu, field_size= %zu, field_total= %zu",
00313 con->result->field_offset, con->result->field_size,
00314 con->result->field_total);
00315
00316 if ((con->result->field_offset + con->result->field_size) ==
00317 con->result->field_total)
00318 {
00319 if (con->result->column_buffer != NULL &&
00320 con->result->column_buffer[con->result->field_current].max_size <
00321 con->result->field_total)
00322 {
00323 con->result->column_buffer[con->result->field_current].max_size=
00324 con->result->field_total;
00325 }
00326
00327 con->result->field_current++;
00328 }
00329
00330 if (con->result->field_total == 0 || con->result->field_size > 0 ||
00331 con->packet_size == 0)
00332 {
00333 drizzle_state_pop(con);
00334 }
00335
00336 return DRIZZLE_RETURN_OK;
00337 }
00338
00339 drizzle_return_t drizzle_state_field_write(drizzle_con_st *con)
00340 {
00341 if (con == NULL)
00342 {
00343 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00344 }
00345
00346 uint8_t *start= con->buffer_ptr + con->buffer_size;
00347 uint8_t *ptr;
00348 size_t free_size;
00349 drizzle_result_st *result= con->result;
00350
00351 drizzle_log_debug(con->drizzle, "drizzle_state_field_write");
00352
00353 if (result->field == NULL && result->field_total != 0)
00354 {
00355 return DRIZZLE_RETURN_PAUSE;
00356 }
00357
00358 free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
00359 ptr= start;
00360
00361 if (result->field_offset == 0)
00362 {
00363
00364 if (free_size < 10)
00365 {
00366 drizzle_state_push(con, drizzle_state_write);
00367 return DRIZZLE_RETURN_OK;
00368 }
00369
00370 if (result->field == NULL)
00371 {
00372 ptr[0]= 251;
00373 ptr++;
00374 }
00375 else if (result->field_total == 0)
00376 {
00377 ptr[0]= 0;
00378 ptr++;
00379 }
00380 else
00381 ptr= drizzle_pack_length(result->field_total, ptr);
00382
00383 free_size-= (size_t)(ptr - start);
00384 con->buffer_size+= (size_t)(ptr - start);
00385 con->packet_size-= (size_t)(ptr - start);
00386 }
00387 else if (result->field_size > DRIZZLE_BUFFER_COPY_THRESHOLD)
00388 {
00389
00390 if (con->buffer_size != 0)
00391 {
00392 drizzle_state_push(con, drizzle_state_write);
00393 return DRIZZLE_RETURN_OK;
00394 }
00395
00396
00397 con->buffer_ptr= (uint8_t *)result->field;
00398 con->buffer_size= result->field_size;
00399 con->packet_size-= result->field_size;
00400 result->field_offset+= result->field_size;
00401 result->field= NULL;
00402
00403 if (result->field_offset == result->field_total)
00404 {
00405 drizzle_state_pop(con);
00406 }
00407 else if (con->packet_size == 0)
00408 {
00409 con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
00410 drizzle_state_pop(con);
00411 }
00412
00413 drizzle_state_push(con, drizzle_state_write);
00414
00415 return DRIZZLE_RETURN_OK;
00416 }
00417
00418 if (result->field_size == 0)
00419 {
00420 drizzle_state_pop(con);
00421 }
00422 else
00423 {
00424 if (result->field_size < free_size)
00425 free_size= result->field_size;
00426
00427 memcpy(ptr, result->field, free_size);
00428 result->field_offset+= free_size;
00429 con->buffer_size+= free_size;
00430 con->packet_size-= free_size;
00431
00432 if (result->field_offset == result->field_total)
00433 {
00434 result->field= NULL;
00435 drizzle_state_pop(con);
00436 }
00437 else
00438 {
00439 if (con->packet_size == 0)
00440 {
00441 con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
00442 drizzle_state_pop(con);
00443 }
00444
00445 if (result->field_size == free_size)
00446 {
00447 result->field= NULL;
00448 }
00449 else
00450 {
00451 result->field+= free_size;
00452 result->field_size-= free_size;
00453 drizzle_state_push(con, drizzle_state_write);
00454 }
00455 }
00456 }
00457
00458 return DRIZZLE_RETURN_OK;
00459 }