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_ERROR_SET(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 PDEBUG("drizzle_state_field_read", "%5zu %5zu", con->buffer_size,
00153 con->packet_size)
00154
00155 if (con->buffer_size == 0)
00156 {
00157 DRIZZLE_STATE_PUSH(con, drizzle_state_read)
00158 return DRIZZLE_RETURN_OK;
00159 }
00160
00161 con->result->field_offset+= con->result->field_size;
00162 if (con->result->field_offset == con->result->field_total)
00163 {
00164 con->result->field_offset= 0;
00165 con->result->field_size= 0;
00166
00167 con->result->field_total= (size_t)drizzle_unpack_length(con, &ret);
00168 if (ret == DRIZZLE_RETURN_NULL_SIZE)
00169 {
00170 con->result->field= NULL;
00171 con->result->field_current++;
00172 DRIZZLE_STATE_POP(con)
00173 return DRIZZLE_RETURN_OK;
00174 }
00175 else if (ret != DRIZZLE_RETURN_OK)
00176 {
00177 if (ret == DRIZZLE_RETURN_IO_WAIT)
00178 {
00179 DRIZZLE_STATE_PUSH(con, drizzle_state_read)
00180 return DRIZZLE_RETURN_OK;
00181 }
00182
00183 return ret;
00184 }
00185
00186 PDEBUG("drizzle_state_field_read", "%5zu %5zu %5zu",
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 PDEBUG("drizzle_state_field_read", "%5zu %5zu %5zu",
00228 con->result->field_offset, con->result->field_size,
00229 con->result->field_total)
00230
00231 if ((con->result->field_offset + con->result->field_size) ==
00232 con->result->field_total)
00233 {
00234 if (con->result->column_buffer != NULL &&
00235 con->result->column_buffer[con->result->field_current].max_size <
00236 con->result->field_total)
00237 {
00238 con->result->column_buffer[con->result->field_current].max_size=
00239 con->result->field_total;
00240 }
00241
00242 con->result->field_current++;
00243 }
00244
00245 if (con->result->field_total == 0 || con->result->field_size > 0 ||
00246 con->packet_size == 0)
00247 {
00248 DRIZZLE_STATE_POP(con)
00249 }
00250
00251 return DRIZZLE_RETURN_OK;
00252 }
00253
00254 drizzle_return_t drizzle_state_field_write(drizzle_con_st *con)
00255 {
00256 uint8_t *start= con->buffer_ptr + con->buffer_size;
00257 uint8_t *ptr;
00258 size_t free_size;
00259 drizzle_result_st *result= con->result;
00260
00261 if (result->field == NULL && result->field_total != 0)
00262 return DRIZZLE_RETURN_PAUSE;
00263
00264 free_size= (size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer);
00265 ptr= start;
00266
00267 if (result->field_offset == 0)
00268 {
00269
00270 if (free_size < 10)
00271 {
00272 DRIZZLE_STATE_PUSH(con, drizzle_state_write)
00273 return DRIZZLE_RETURN_OK;
00274 }
00275
00276 if (result->field == NULL)
00277 {
00278 ptr[0]= 251;
00279 ptr++;
00280 }
00281 else if (result->field_total == 0)
00282 {
00283 ptr[0]= 0;
00284 ptr++;
00285 }
00286 else
00287 ptr= drizzle_pack_length(result->field_total, ptr);
00288
00289 free_size-= (size_t)(ptr - start);
00290 con->buffer_size+= (size_t)(ptr - start);
00291 con->packet_size-= (size_t)(ptr - start);
00292 }
00293 else if (result->field_size > DRIZZLE_BUFFER_COPY_THRESHOLD)
00294 {
00295
00296 if (con->buffer_size != 0)
00297 {
00298 DRIZZLE_STATE_PUSH(con, drizzle_state_write)
00299 return DRIZZLE_RETURN_OK;
00300 }
00301
00302
00303 con->buffer_ptr= (uint8_t *)result->field;
00304 con->buffer_size= result->field_size;
00305 con->packet_size-= result->field_size;
00306 result->field_offset+= result->field_size;
00307 result->field= NULL;
00308
00309 if (result->field_offset == result->field_total)
00310 DRIZZLE_STATE_POP(con)
00311 else if (con->packet_size == 0)
00312 {
00313 con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
00314 DRIZZLE_STATE_POP(con)
00315 }
00316
00317 DRIZZLE_STATE_PUSH(con, drizzle_state_write)
00318 return DRIZZLE_RETURN_OK;
00319 }
00320
00321 if (result->field_size == 0)
00322 DRIZZLE_STATE_POP(con)
00323 else
00324 {
00325 if (result->field_size < free_size)
00326 free_size= result->field_size;
00327
00328 memcpy(ptr, result->field, free_size);
00329 result->field_offset+= free_size;
00330 con->buffer_size+= free_size;
00331 con->packet_size-= free_size;
00332
00333 if (result->field_offset == result->field_total)
00334 {
00335 result->field= NULL;
00336 DRIZZLE_STATE_POP(con)
00337 }
00338 else
00339 {
00340 if (con->packet_size == 0)
00341 {
00342 con->result->options|= DRIZZLE_RESULT_ROW_BREAK;
00343 DRIZZLE_STATE_POP(con)
00344 }
00345
00346 if (result->field_size == free_size)
00347 result->field= NULL;
00348 else
00349 {
00350 result->field+= free_size;
00351 result->field_size-= free_size;
00352 DRIZZLE_STATE_PUSH(con, drizzle_state_write)
00353 }
00354 }
00355 }
00356
00357 return DRIZZLE_RETURN_OK;
00358 }