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