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
00042 #include "common.h"
00043
00044
00045
00046
00047
00048 drizzle_field_t drizzle_field_read(drizzle_result_st *result, size_t *offset,
00049 size_t *size, size_t *total,
00050 drizzle_return_t *ret_ptr)
00051 {
00052 if (drizzle_state_none(result->con))
00053 {
00054 if (result->field_current == result->column_count)
00055 {
00056 *ret_ptr= DRIZZLE_RETURN_ROW_END;
00057 return NULL;
00058 }
00059
00060 drizzle_state_push(result->con, drizzle_state_field_read);
00061 }
00062
00063 *ret_ptr= drizzle_state_loop(result->con);
00064 if (*ret_ptr == DRIZZLE_RETURN_OK &&
00065 result->options & DRIZZLE_RESULT_ROW_BREAK)
00066 {
00067 *ret_ptr= DRIZZLE_RETURN_ROW_BREAK;
00068 }
00069
00070 *offset= result->field_offset;
00071 *size= result->field_size;
00072 *total= result->field_total;
00073
00074 return result->field;
00075 }
00076
00077 drizzle_field_t drizzle_field_buffer(drizzle_result_st *result, size_t *total,
00078 drizzle_return_t *ret_ptr)
00079 {
00080 drizzle_field_t field;
00081 size_t offset= 0;
00082 size_t size= 0;
00083
00084 field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
00085 if (*ret_ptr != DRIZZLE_RETURN_OK)
00086 return NULL;
00087
00088 if (field == NULL)
00089 {
00090 *total= 0;
00091 return NULL;
00092 }
00093
00094 if (result->field_buffer == NULL)
00095 {
00096 result->field_buffer= malloc((*total) + 1);
00097 if (result->field_buffer == NULL)
00098 {
00099 drizzle_set_error(result->con->drizzle, "drizzle_field_buffer", "malloc");
00100 *ret_ptr= DRIZZLE_RETURN_MEMORY;
00101 return NULL;
00102 }
00103 }
00104
00105 memcpy(result->field_buffer + offset, field, size);
00106
00107 while ((offset + size) != (*total))
00108 {
00109 field= drizzle_field_read(result, &offset, &size, total, ret_ptr);
00110 if (*ret_ptr != DRIZZLE_RETURN_OK)
00111 return NULL;
00112
00113 memcpy(result->field_buffer + offset, field, size);
00114 }
00115
00116 field= result->field_buffer;
00117 result->field_buffer= NULL;
00118 field[*total]= 0;
00119
00120 return field;
00121 }
00122
00123 void drizzle_field_free(drizzle_field_t field)
00124 {
00125 if (field != NULL)
00126 free(field);
00127 }
00128
00129
00130
00131
00132
00133 drizzle_return_t drizzle_field_write(drizzle_result_st *result,
00134 const drizzle_field_t field, size_t size,
00135 size_t total)
00136 {
00137 drizzle_return_t ret;
00138
00139 if (drizzle_state_none(result->con))
00140 {
00141 if (result->options & DRIZZLE_RESULT_ROW_BREAK)
00142 {
00143 result->options&= (drizzle_result_options_t)~DRIZZLE_RESULT_ROW_BREAK;
00144 result->field= field;
00145 result->field_size= size;
00146 }
00147 else
00148 {
00149 result->field= field;
00150 result->field_size= size;
00151 result->field_offset= 0;
00152 result->field_total= total;
00153 }
00154
00155 drizzle_state_push(result->con, drizzle_state_field_write);
00156 }
00157 else if (result->field == NULL)
00158 {
00159 result->field= field;
00160 result->field_size= size;
00161 }
00162
00163 ret= drizzle_state_loop(result->con);
00164 if (ret == DRIZZLE_RETURN_PAUSE)
00165 ret= DRIZZLE_RETURN_OK;
00166
00167 return ret;
00168 }
00169
00170
00171
00172
00173
00174 drizzle_return_t drizzle_state_field_read(drizzle_con_st *con)
00175 {
00176 drizzle_return_t ret;
00177
00178 drizzle_log_debug(con->drizzle, "drizzle_state_field_read");
00179
00180 if (con->buffer_size == 0)
00181 {
00182 drizzle_state_push(con, drizzle_state_read);
00183 return DRIZZLE_RETURN_OK;
00184 }
00185
00186 con->result->field_offset+= con->result->field_size;
00187 if (con->result->field_offset == con->result->field_total)
00188 {
00189 con->result->field_offset= 0;
00190 con->result->field_size= 0;
00191
00192 con->result->field_total= (size_t)drizzle_unpack_length(con, &ret);
00193 if (ret == DRIZZLE_RETURN_NULL_SIZE)
00194 {
00195 con->result->field= NULL;
00196 con->result->field_current++;
00197 drizzle_state_pop(con);
00198 return DRIZZLE_RETURN_OK;
00199 }
00200 else if (ret != DRIZZLE_RETURN_OK)
00201 {
00202 if (ret == DRIZZLE_RETURN_IO_WAIT)
00203 {
00204 drizzle_state_push(con, drizzle_state_read);
00205 return DRIZZLE_RETURN_OK;
00206 }
00207
00208 return ret;
00209 }
00210
00211 drizzle_log_debug(con->drizzle,
00212 "field_offset= %zu, field_size= %zu, field_total= %zu",
00213 con->result->field_offset, con->result->field_size,
00214 con->result->field_total);
00215
00216 if ((size_t)(con->buffer_size) >= con->result->field_total)
00217 con->result->field_size= con->result->field_total;
00218 else
00219 con->result->field_size= con->buffer_size;
00220 }
00221 else
00222 {
00223 if ((con->result->field_offset + con->buffer_size) >=
00224 con->result->field_total)
00225 {
00226 con->result->field_size= (con->result->field_total -
00227 con->result->field_offset);
00228 }
00229 else
00230 con->result->field_size= con->buffer_size;
00231 }
00232
00233
00234 if (con->result->field_size > (size_t)con->packet_size)
00235 {
00236 con->result->field_size= con->packet_size;
00237
00238 if (con->options & DRIZZLE_CON_RAW_PACKET)
00239 con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
00240 else
00241 {
00242 drizzle_state_pop(con);
00243 drizzle_state_push(con, drizzle_state_packet_read);
00244 drizzle_state_push(con, drizzle_state_field_read);
00245 }
00246 }
00247
00248 con->result->field= (char *)con->buffer_ptr;
00249 con->buffer_ptr+= con->result->field_size;
00250 con->buffer_size-= con->result->field_size;
00251 con->packet_size-= con->result->field_size;
00252
00253 drizzle_log_debug(con->drizzle,
00254 "field_offset= %zu, field_size= %zu, field_total= %zu",
00255 con->result->field_offset, con->result->field_size,
00256 con->result->field_total);
00257
00258 if ((con->result->field_offset + con->result->field_size) ==
00259 con->result->field_total)
00260 {
00261 if (con->result->column_buffer != NULL &&
00262 con->result->column_buffer[con->result->field_current].max_size <
00263 con->result->field_total)
00264 {
00265 con->result->column_buffer[con->result->field_current].max_size=
00266 con->result->field_total;
00267 }
00268
00269 con->result->field_current++;
00270 }
00271
00272 if (con->result->field_total == 0 || con->result->field_size > 0 ||
00273 con->packet_size == 0)
00274 {
00275 drizzle_state_pop(con);
00276 }
00277
00278 return DRIZZLE_RETURN_OK;
00279 }
00280
00281 drizzle_return_t drizzle_state_field_write(drizzle_con_st *con)
00282 {
00283 uint8_t *start= con->buffer_ptr + con->buffer_size;
00284 uint8_t *ptr;
00285 size_t free_size;
00286 drizzle_result_st *result= con->result;
00287
00288 drizzle_log_debug(con->drizzle, "drizzle_state_field_write");
00289
00290 if (result->field == NULL && result->field_total != 0)
00291 return DRIZZLE_RETURN_PAUSE;
00292
00293 free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
00294 ptr= start;
00295
00296 if (result->field_offset == 0)
00297 {
00298
00299 if (free_size < 10)
00300 {
00301 drizzle_state_push(con, drizzle_state_write);
00302 return DRIZZLE_RETURN_OK;
00303 }
00304
00305 if (result->field == NULL)
00306 {
00307 ptr[0]= 251;
00308 ptr++;
00309 }
00310 else if (result->field_total == 0)
00311 {
00312 ptr[0]= 0;
00313 ptr++;
00314 }
00315 else
00316 ptr= drizzle_pack_length(result->field_total, ptr);
00317
00318 free_size-= (size_t)(ptr - start);
00319 con->buffer_size+= (size_t)(ptr - start);
00320 con->packet_size-= (size_t)(ptr - start);
00321 }
00322 else if (result->field_size > DRIZZLE_BUFFER_COPY_THRESHOLD)
00323 {
00324
00325 if (con->buffer_size != 0)
00326 {
00327 drizzle_state_push(con, drizzle_state_write);
00328 return DRIZZLE_RETURN_OK;
00329 }
00330
00331
00332 con->buffer_ptr= (uint8_t *)result->field;
00333 con->buffer_size= result->field_size;
00334 con->packet_size-= result->field_size;
00335 result->field_offset+= result->field_size;
00336 result->field= NULL;
00337
00338 if (result->field_offset == result->field_total)
00339 drizzle_state_pop(con);
00340 else if (con->packet_size == 0)
00341 {
00342 con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
00343 drizzle_state_pop(con);
00344 }
00345
00346 drizzle_state_push(con, drizzle_state_write);
00347 return DRIZZLE_RETURN_OK;
00348 }
00349
00350 if (result->field_size == 0)
00351 drizzle_state_pop(con);
00352 else
00353 {
00354 if (result->field_size < free_size)
00355 free_size= result->field_size;
00356
00357 memcpy(ptr, result->field, free_size);
00358 result->field_offset+= free_size;
00359 con->buffer_size+= free_size;
00360 con->packet_size-= free_size;
00361
00362 if (result->field_offset == result->field_total)
00363 {
00364 result->field= NULL;
00365 drizzle_state_pop(con);
00366 }
00367 else
00368 {
00369 if (con->packet_size == 0)
00370 {
00371 con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
00372 drizzle_state_pop(con);
00373 }
00374
00375 if (result->field_size == free_size)
00376 result->field= NULL;
00377 else
00378 {
00379 result->field+= free_size;
00380 result->field_size-= free_size;
00381 drizzle_state_push(con, drizzle_state_write);
00382 }
00383 }
00384 }
00385
00386 return DRIZZLE_RETURN_OK;
00387 }