static void convert_from_long(MYSQL_BIND *r_param, const MYSQL_FIELD *field, longlong val, my_bool is_unsigned) { switch (r_param->buffer_type) { case MYSQL_TYPE_TINY: *(uchar *)r_param->buffer= (uchar)val; *r_param->error= r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX8) : NUMERIC_TRUNCATION(val, INT_MIN8, INT_MAX8); r_param->buffer_length= 1; break; case MYSQL_TYPE_SHORT: case MYSQL_TYPE_YEAR: shortstore(r_param->buffer, (short)val); *r_param->error= r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX16) : NUMERIC_TRUNCATION(val, INT_MIN16, INT_MAX16); r_param->buffer_length= 2; break; case MYSQL_TYPE_LONG: longstore(r_param->buffer, (int32)val); *r_param->error= r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX32) : NUMERIC_TRUNCATION(val, INT_MIN32, INT_MAX32); r_param->buffer_length= 4; break; case MYSQL_TYPE_LONGLONG: *r_param->error= (val < 0 && r_param->is_unsigned != is_unsigned); longlongstore(r_param->buffer, val); r_param->buffer_length= 8; break; case MYSQL_TYPE_DOUBLE: { volatile double dbl; dbl= (is_unsigned) ? ulonglong2double((ulonglong)val) : (double)val; doublestore(r_param->buffer, dbl); *r_param->error= is_unsigned ? (ulonglong )dbl != (ulonglong)val : (longlong)dbl != (longlong)val; r_param->buffer_length= 8; break; } case MYSQL_TYPE_FLOAT: { float fval; fval= is_unsigned ? (float)(ulonglong)(val) : (float)val; float4store(r_param->buffer, fval); *r_param->error= is_unsigned ? (ulonglong)fval != (ulonglong)val : (longlong)fval != val; r_param->buffer_length= 4; } break; default: { char buffer[22]; char *endptr; uint len; endptr= ma_ll2str(val, buffer, is_unsigned ? 10 : -10); len= (uint)(endptr - buffer); /* check if field flag is zerofill */ convert_froma_string(r_param, buffer, len); } break; } }
static void convert_froma_string(MYSQL_BIND *r_param, char *buffer, size_t len) { int error= 0; switch (r_param->buffer_type) { case MYSQL_TYPE_TINY: { longlong val= my_atoll(buffer, buffer + len, &error); *r_param->error= error ? 1 : r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX8) : NUMERIC_TRUNCATION(val, INT_MIN8, INT_MAX8) || error > 0; int1store(r_param->buffer, (uchar) val); r_param->buffer_length= sizeof(uchar); } break; case MYSQL_TYPE_YEAR: case MYSQL_TYPE_SHORT: { longlong val= my_atoll(buffer, buffer + len, &error); *r_param->error= error ? 1 : r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX16) : NUMERIC_TRUNCATION(val, INT_MIN16, INT_MAX16) || error > 0; shortstore(r_param->buffer, (short)val); r_param->buffer_length= sizeof(short); } break; case MYSQL_TYPE_LONG: { longlong val= my_atoll(buffer, buffer + len, &error); *r_param->error=error ? 1 : r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX32) : NUMERIC_TRUNCATION(val, INT_MIN32, INT_MAX32) || error > 0; longstore(r_param->buffer, (int32)val); r_param->buffer_length= sizeof(uint32); } break; case MYSQL_TYPE_LONGLONG: { longlong val= my_atoll(buffer, buffer + len, &error); *r_param->error= error > 0; /* no need to check for truncation */ longlongstore(r_param->buffer, val); r_param->buffer_length= sizeof(longlong); } break; case MYSQL_TYPE_DOUBLE: { double val= my_atod(buffer, buffer + len, &error); *r_param->error= error > 0; /* no need to check for truncation */ float8store(r_param->buffer, val); r_param->buffer_length= sizeof(double); } break; case MYSQL_TYPE_FLOAT: { float val= (float)my_atod(buffer, buffer + len, &error); *r_param->error= error > 0; /* no need to check for truncation */ float4store(r_param->buffer, val); r_param->buffer_length= sizeof(float); } break; case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: { MYSQL_TIME *tm= (MYSQL_TIME *)r_param->buffer; str_to_TIME(buffer, len, tm); break; } break; case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: default: { char *start= buffer + r_param->offset; /* stmt_fetch_column sets offset */ char *end= buffer + len; size_t copylen= 0; if (start < end) { copylen= end - start; if (r_param->buffer_length) memcpy(r_param->buffer, start, MIN(copylen, r_param->buffer_length)); } if (copylen < r_param->buffer_length) ((char *)r_param->buffer)[copylen]= '\0'; *r_param->error= (copylen > r_param->buffer_length); *r_param->length= (ulong)len; } break; } }
/************************************************** read data in binary type **************************************************/ int mysac_encode_value(MYSAC_BIND *val, char *out, int len) { /* int j; int i; char nul; unsigned long len; int tmp_len; char *wh; char _null_ptr[16]; char *null_ptr; unsigned char bit; */ int l; // int data_len; struct timeval *tv; struct tm *tm; unsigned int v; char sign; switch (val->type) { /* read null */ case MYSQL_TYPE_NULL: l = 0; break; /* read blob */ case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: /* decimal ? maybe for very big num ... crypto key ? */ case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: /* .... */ case MYSQL_TYPE_BIT: /* read text */ case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_VARCHAR: /* read date */ case MYSQL_TYPE_NEWDATE: l = set_my_lcb(val->value_len, 0, out, len); if (l < 0) return -1; len -= l; if (len < val->value_len) return -1; memcpy(&out[l], val->value, val->value_len); l += val->value_len; break; case MYSQL_TYPE_TINY: if (len < 1) return -1; l = 1; out[0] = *(int *)val->value; break; case MYSQL_TYPE_SHORT: if (len < 2) return -1; l = 2; to_my_2(*(int *)val->value, out); break; case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: if (len < 4) return -1; l = 4; to_my_4(*(int *)val->value, out); break; case MYSQL_TYPE_LONGLONG: if (len < 8) return -1; l = 8; to_my_8(*(long long int *)val->value, out); break; case MYSQL_TYPE_FLOAT: if (len < 4) return -1; l = 4; float4store((*(long *)val->value), out); break; case MYSQL_TYPE_DOUBLE: if (len < 8) return -1; l = 8; float8store(*(long *)val->value, out); break; /* libmysql/libmysql.c:3370 * static void read_binary_time(MYSQL_TIME *tm, uchar **pos) * * n*lcb 4*j 1*h 1*m 1*s 1*sig 4*usec soit 12 bytes */ case MYSQL_TYPE_TIME: l = set_my_lcb(12, 0, out, len); if (l < 0) return -1; len -= l; if (len < 12) return -1; tv = (struct timeval *)val->value; if (tv->tv_sec < 0) { tv->tv_sec = - tv->tv_sec; sign = 1; } else sign = 0; /* nb days */ to_my_4(tv->tv_sec / 86400, &out[l]); l += 4; /* remainder in secs */ v = tv->tv_sec % 86400; /* nb hours */ out[l] = v / 3600; l++; /* remainder in secs */ v = v % 3600; /* nb mins */ out[l] = v / 60; l++; /* secs */ out[l] = v % 60; l++; /* signe */ out[l] = sign; l++; /* u secs */ to_my_4(tv->tv_usec, &out[l]); l += 4; break; case MYSQL_TYPE_YEAR: if (len < 2) return -1; tm = (struct tm *)val->value; to_my_2(tm->tm_year + 1900, out); l = 2; break; /* libmysql/libmysql.c:3400 * static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos) * * 1*lcb 2*year 1*mon 1*day 1*hour 1*min 1*sec */ case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATETIME: l = set_my_lcb(7, 0, out, len); if (l < 0) return -1; len -= l; if (len < 7) return -1; tm = (struct tm *)val->value; to_my_2(tm->tm_year + 1900, &out[l]); l += 2; out[l] = tm->tm_mon + 1; l++; out[l] = tm->tm_mday; l++; out[l] = tm->tm_hour; l++; out[l] = tm->tm_min; l++; out[l] = tm->tm_sec; l++; break; /* libmysql/libmysql.c:3430 * static void read_binary_date(MYSQL_TIME *tm, uchar **pos) * * 1*lcb 2*year 1*mon 1*day */ case MYSQL_TYPE_DATE: l = set_my_lcb(4, 0, out, len); if (l < 0) return -1; len -= l; if (len < 4) return -1; tm = (struct tm *)val->value; to_my_2(tm->tm_year + 1900, &out[l]); l += 2; out[l] = tm->tm_mon + 1; l++; out[l] = tm->tm_mday; l++; break; case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: case MYSQL_TYPE_GEOMETRY: /* TODO: a faire */ break; } return l; }