📄 convert.c
字号:
cr->u.Data2 = n; n = 0; break; case 8+1 + 4+1 + 4: if (c != '-') return TDS_CONVERT_SYNTAX; cr->u.Data3 = n; n = 0; break; case 8+1 + 4+1 + 4+1 + 4: /* skip last (optional) dash */ if (c == '-') { if (--srclen < 32 + 3) return TDS_CONVERT_SYNTAX; c = (++src)[i]; } /* fall through */ default: n = n << 4; if (c >= '0' && c <= '9') n += c - '0'; else { c &= 0x20 ^ 0xff; if (c >= 'A' && c <= 'F') n += c - ('A' - 10); else return TDS_CONVERT_SYNTAX; } if (i > (16 + 2) && !(i & 1)) { cr->u.Data4[(i >> 1) - 10] = n; n = 0; } } } } return sizeof(TDS_UNIQUE); default: return TDS_CONVERT_NOAVAIL; break; } /* end switch */} /* tds_convert_char */static TDS_INTtds_convert_bit(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT * cr){ int canonic = src[0] ? 1 : 0; switch (desttype) { case TDS_CONVERT_CHAR: if (cr->cc.len) cr->cc.c[0] = '0' + canonic; return 1; case CASE_ALL_CHAR: cr->c = (TDS_CHAR *) malloc(2); test_alloc(cr->c); cr->c[0] = '0' + canonic; cr->c[1] = 0; return 1; break; case CASE_ALL_BINARY: return binary_to_result(src, 1, cr); break; case SYBINT1: cr->ti = canonic; return sizeof(TDS_TINYINT); break; case SYBINT2: cr->si = canonic; return sizeof(TDS_SMALLINT); break; case SYBINT4: cr->i = canonic; return sizeof(TDS_INT); break; case SYBINT8: cr->bi = canonic; return sizeof(TDS_INT8); break; case SYBFLT8: cr->f = canonic; return sizeof(TDS_FLOAT); break; case SYBREAL: cr->r = (TDS_REAL) canonic; return sizeof(TDS_REAL); break; case SYBBIT: case SYBBITN: cr->ti = src[0]; return sizeof(TDS_TINYINT); break; case SYBMONEY: case SYBMONEY4: return tds_convert_int1(SYBINT1, (src[0]) ? "\1" : "\0", desttype, cr); break; case SYBNUMERIC: case SYBDECIMAL: return stringz_to_numeric(canonic ? "1" : "0", cr); break; /* conversions not allowed */ case SYBUNIQUE: case SYBDATETIME4: case SYBDATETIME: case SYBDATETIMN: default: break; } return TDS_CONVERT_NOAVAIL;}static TDS_INTtds_convert_int1(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT * cr){ TDS_TINYINT buf; TDS_CHAR tmp_str[5]; buf = *((TDS_TINYINT *) src); switch (desttype) { case TDS_CONVERT_CHAR: case CASE_ALL_CHAR: sprintf(tmp_str, "%d", buf); return string_to_result(tmp_str, cr); break; case CASE_ALL_BINARY: return binary_to_result(src, 1, cr); break; case SYBINT1: cr->ti = buf; return sizeof(TDS_TINYINT); break; case SYBINT2: cr->si = buf; return sizeof(TDS_SMALLINT); break; case SYBINT4: cr->i = buf; return sizeof(TDS_INT); break; case SYBINT8: cr->bi = buf; return sizeof(TDS_INT8); break; case SYBBIT: case SYBBITN: cr->ti = buf ? 1 : 0; return sizeof(TDS_TINYINT); break; case SYBFLT8: cr->f = buf; return sizeof(TDS_FLOAT); break; case SYBREAL: cr->r = buf; return sizeof(TDS_REAL); break; case SYBMONEY4: cr->m4.mny4 = buf * 10000; return sizeof(TDS_MONEY4); break; case SYBMONEY: cr->m.mny = buf * 10000; return sizeof(TDS_MONEY); break; case SYBNUMERIC: case SYBDECIMAL: sprintf(tmp_str, "%d", buf); return stringz_to_numeric(tmp_str, cr); break; /* conversions not allowed */ case SYBUNIQUE: case SYBDATETIME4: case SYBDATETIME: case SYBDATETIMN: default: break; } return TDS_CONVERT_NOAVAIL;}static TDS_INTtds_convert_int2(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT * cr){ TDS_SMALLINT buf; TDS_CHAR tmp_str[16]; memcpy(&buf, src, sizeof(buf)); switch (desttype) { case TDS_CONVERT_CHAR: case CASE_ALL_CHAR: sprintf(tmp_str, "%d", buf); return string_to_result(tmp_str, cr); break; case CASE_ALL_BINARY: return binary_to_result(src, 2, cr); break; case SYBINT1: if (!IS_TINYINT(buf)) return TDS_CONVERT_OVERFLOW; cr->ti = (TDS_TINYINT) buf; return sizeof(TDS_TINYINT); break; case SYBINT2: cr->si = buf; return sizeof(TDS_SMALLINT); break; case SYBINT4: cr->i = buf; return sizeof(TDS_INT); break; case SYBINT8: cr->bi = buf; return sizeof(TDS_INT8); break; case SYBBIT: case SYBBITN: cr->ti = buf ? 1 : 0; return sizeof(TDS_TINYINT); break; case SYBFLT8: cr->f = buf; return sizeof(TDS_FLOAT); break; case SYBREAL: cr->r = buf; return sizeof(TDS_REAL); break; case SYBMONEY4: cr->m4.mny4 = buf * 10000; return sizeof(TDS_MONEY4); break; case SYBMONEY: cr->m.mny = buf * 10000; return sizeof(TDS_MONEY); break; case SYBNUMERIC: case SYBDECIMAL: sprintf(tmp_str, "%d", buf); return stringz_to_numeric(tmp_str, cr); break; /* conversions not allowed */ case SYBUNIQUE: case SYBDATETIME4: case SYBDATETIME: case SYBDATETIMN: default: break; } return TDS_CONVERT_NOAVAIL;}static TDS_INTtds_convert_int4(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT * cr){ TDS_INT buf; TDS_CHAR tmp_str[16]; memcpy(&buf, src, sizeof(buf)); switch (desttype) { case TDS_CONVERT_CHAR: case CASE_ALL_CHAR: sprintf(tmp_str, "%d", buf); return string_to_result(tmp_str, cr); break; case CASE_ALL_BINARY: return binary_to_result(src, 4, cr); break; case SYBINT1: if (!IS_TINYINT(buf)) return TDS_CONVERT_OVERFLOW; cr->ti = buf; return sizeof(TDS_TINYINT); break; case SYBINT2: if (!IS_SMALLINT(buf)) return TDS_CONVERT_OVERFLOW; cr->si = buf; return sizeof(TDS_SMALLINT); break; case SYBINT4: cr->i = buf; return sizeof(TDS_INT); break; case SYBINT8: cr->bi = buf; return sizeof(TDS_INT8); break; case SYBBIT: case SYBBITN: cr->ti = buf ? 1 : 0; return sizeof(TDS_TINYINT); break; case SYBFLT8: cr->f = buf; return sizeof(TDS_FLOAT); break; case SYBREAL: cr->r = (TDS_REAL) buf; return sizeof(TDS_REAL); break; case SYBMONEY4: if (buf > 214748 || buf < -214748) return TDS_CONVERT_OVERFLOW; cr->m4.mny4 = buf * 10000; return sizeof(TDS_MONEY4); break; case SYBMONEY: cr->m.mny = (TDS_INT8) buf *10000; return sizeof(TDS_MONEY); break; case SYBNUMERIC: case SYBDECIMAL: sprintf(tmp_str, "%d", buf); return stringz_to_numeric(tmp_str, cr); break; /* conversions not allowed */ case SYBUNIQUE: case SYBDATETIME4: case SYBDATETIME: case SYBDATETIMN: default: break; } return TDS_CONVERT_NOAVAIL;}static TDS_INTtds_convert_int8(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT * cr){ TDS_INT8 buf; TDS_CHAR tmp_str[24]; memcpy(&buf, src, sizeof(buf)); switch (desttype) { case TDS_CONVERT_CHAR: case CASE_ALL_CHAR: /* TODO: fix for all platform. Search for lltoa/_i64toa */#if defined(WIN32) _i64toa(buf, tmp_str, 10);#elif SIZEOF_LONG < 8 sprintf(tmp_str, "%" TDS_I64_FORMAT, buf);#else sprintf(tmp_str, "%ld", buf);#endif return string_to_result(tmp_str, cr); break; case CASE_ALL_BINARY: return binary_to_result(src, sizeof(TDS_INT8), cr); break; case SYBINT1: if (!IS_TINYINT(buf)) return TDS_CONVERT_OVERFLOW; cr->ti = (TDS_TINYINT) buf; return sizeof(TDS_TINYINT); break; case SYBINT2: if (!IS_SMALLINT(buf)) return TDS_CONVERT_OVERFLOW; cr->si = (TDS_SMALLINT) buf; return sizeof(TDS_SMALLINT); break; case SYBINT4: if (!IS_INT(buf)) return TDS_CONVERT_OVERFLOW; cr->i = (TDS_INT) buf; return sizeof(TDS_INT); break; case SYBINT8: cr->bi = buf; return sizeof(TDS_INT8); break; case SYBBIT: case SYBBITN: cr->ti = buf ? 1 : 0; return sizeof(TDS_TINYINT); break; case SYBFLT8: cr->f = (TDS_FLOAT) buf; return sizeof(TDS_FLOAT); break; case SYBREAL: cr->r = (TDS_REAL) buf; return sizeof(TDS_REAL); break; case SYBMONEY4: if (buf > 214748 || buf < -214748) return TDS_CONVERT_OVERFLOW; cr->m4.mny4 = (TDS_INT) (buf * 10000); return sizeof(TDS_MONEY4); break; case SYBMONEY: if (buf > (TDS_INT8_MAX / 10000) || buf < (TDS_INT8_MIN / 10000)) return TDS_CONVERT_OVERFLOW; cr->m.mny = buf * 10000; return sizeof(TDS_MONEY); break; case SYBNUMERIC: case SYBDECIMAL: /* TODO portability problem. See above */#if defined(WIN32) _i64toa(buf, tmp_str, 10);#elif SIZEOF_LONG < 8 sprintf(tmp_str, "%" TDS_I64_FORMAT, buf);#else sprintf(tmp_str, "%ld", buf);#endif return stringz_to_numeric(tmp_str, cr); break; /* conversions not allowed */ case SYBUNIQUE: case SYBDATETIME4: case SYBDATETIME: case SYBDATETIMN: default: break; } return TDS_CONVERT_NOAVAIL;}static TDS_INTtds_convert_numeric(int srctype, const TDS_NUMERIC * src, TDS_INT srclen, int desttype, CONV_RESULT * cr){ char tmpstr[MAXPRECISION]; TDS_INT i, ret; TDS_INT8 bi; switch (desttype) { case TDS_CONVERT_CHAR: case CASE_ALL_CHAR: if (tds_numeric_to_string(src, tmpstr) < 0) return TDS_CONVERT_FAIL; return string_to_result(tmpstr, cr); break; case CASE_ALL_BINARY: return binary_to_result(src, sizeof(TDS_NUMERIC), cr); break; case SYBINT1: cr->n = *src; ret = tds_numeric_change_prec_scale(&(cr->n), 3, 0); if (ret < 0) return ret; if (cr->n.array[1] || (cr->n.array[0] && cr->n.array[2])) return TDS_CONVERT_OVERFLOW; cr->ti = cr->n.array[2]; return sizeof(TDS_TINYINT); break; case SYBINT2: cr->n = *src; ret = tds_numeric_change_prec_scale(&(cr->n), 5, 0); if (ret < 0) return ret; if (cr->n.array[1]) return TDS_CONVERT_OVERFLOW; i = TDS_GET_UA2BE(&(cr->n.array[2])); if (cr->n.array[0]) i = -i; if (((i >> 15) ^ cr->n.array[0]) & 1) return TDS_CONVERT_OVERFLOW; cr->si = (TDS_SMALLINT) i; return sizeof(TDS_SMALLINT); break; case SYBINT4: cr->n = *src; ret = tds_numeric_change_prec_scale(&(cr->n), 10, 0); if (ret < 0) return ret; if (cr->n.array[1]) return TDS_CONVERT_OVERFLOW; i = TDS_GET_UA4BE(&(cr->n.array[2])); if (cr->n.array[0]) i = -i; if (((i >> 31) ^ cr->n.array[0]) & 1) return TDS_CONVERT_OVERFLOW; cr->i = i; return sizeof(TDS_INT); break; case SYBINT8: cr->n = *src; ret = tds_numeric_change_prec_scale(&(cr->n), 20, 0); if (ret < 0) return ret; if (cr->n.array[1]) return TDS_CONVERT_OVERFLOW; bi = TDS_GET_UA4BE(&(cr->n.array[2])); bi = (bi << 32) + TDS_GET_UA4BE(&(cr->n.array[6])); if (cr->n.array[0]) bi = -bi; if (((bi >> 63) ^ cr->n.array[0]) & 1) return TDS_CONVERT_OVERFLOW; cr->bi = bi; return sizeof(TDS_INT8); break; case SYBBIT: case SYBBITN: cr->ti = 0; for (i = tds_numeric_bytes_per_prec[src->precision]; --i > 0;) if (src->array[i] != 0) { cr->ti = 1; break; } return sizeof(TDS_TINYINT); break; case SYBNUMERIC: case SYBDECIMAL: { unsigned char prec = cr->n.precision, scale = cr->n.scale; cr->n = *src; return tds_numeric_change_prec_scale(&(cr->n), prec, scale); } break; case SYBFLT8: if (tds_numeric_to_string(src, tmpstr) < 0) return TDS_CONVERT_FAIL; cr->f = atof(tmpstr); return 8; break; case SYBREAL: if (tds_numeric_to_string(src, tmpstr) < 0) return TDS_CONVERT_FAIL; cr->r = (TDS_REAL) atof(tmpstr); return 4; break; /* TODO conversions to money */ /* conversions not allowed */ case SYBUNIQUE: case SYBDATETIME4: case SYBDATETIME: case SYBDATETIMN: default: break; } return TDS_CONVERT_NOAVAIL;}static TDS_INTtds_convert_money4(int srctype, const TDS_CHAR * src, int srclen, int desttype, CONV_RESULT * cr){ TDS_MONEY4 mny; long dollars, fraction; char tmp_str[33]; char *p; memcpy(&mny, src, sizeof(mny)); switch (desttype) { case TDS_CONVERT_CHAR: case CASE_ALL_CHAR: /* * round to 2 decimal digits * rounding with dollars = (mny.mny4 + 5000) /10000 * can give arithmetic overflow so I use * dollars = (mny.mny4/50 + 1)/2 */ /* TODO round also all conversions to int and from money ?? */ p = tmp_str; if (mny.mny4 < 0) { *p++ = '-'; /* here (-mny.mny4 / 50 + 1 ) / 2 can cause overflow in -mny.mny4 */ dollars = -(mny.mny4 / 50 - 1 ) / 2; } else { dollars = (mny.mny4 / 50 + 1 ) / 2; } /* print only 2 decimal digits as server does */ sprintf(p, "%ld.%02lu", dollars / 100, dollars % 100); return string_to_result(tmp_str, cr); break; case CASE_ALL_BINARY: return binary_to_result(src, sizeof(TDS_MONEY4), cr); break; case SYBINT1: dollars = mny.mny4 / 10000; if (!IS_TINYINT(dollars)) return TDS_CONVERT_OVERFLOW; cr->ti = (TDS_TINYINT) dollars; return sizeof(TDS_TINYINT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -