📄 convert.c
字号:
ret = 0; } return (ret);}static intis_numeric(const char *datestr){ const char *s; int ret = 1; for (s = datestr; *s; s++) { if (!isdigit((unsigned char) *s)) ret = 0; } return (ret);}static intis_timeformat(const char *datestr){ const char *s; int ret = 1; for (s = datestr; *s; s++) { if (!isdigit((unsigned char) *s) && *s != ':' && *s != '.') break; } if (*s) { if (strcasecmp(s, "am") != 0 && strcasecmp(s, "pm") != 0) ret = 0; } return (ret);}static intstore_year(int year, struct tds_time *t){ if (year < 0) return 0; if (year < 100) { if (year > 49) t->tm_year = year; else t->tm_year = 100 + year; return (1); } if (year < 1753) return (0); if (year <= 9999) { t->tm_year = year - 1900; return (1); } return (0);}static intstore_mday(const char *datestr, struct tds_time *t){ int mday = atoi(datestr); if (mday > 0 && mday < 32) { t->tm_mday = mday; return 1; } return 0;}static intstore_numeric_date(const char *datestr, struct tds_time *t){ int TDS_MONTH = 0; int TDS_DAY = 0; int TDS_YEAR = 0; int state; char last_char = 0; const char *s; int month = 0, year = 0, mday = 0; /* Its YYYY-MM-DD format */ if (strlen(datestr) == 10 && *(datestr + 4) == '-' && *(datestr + 7) == '-') { TDS_YEAR = 0; TDS_MONTH = 1; TDS_DAY = 2; state = TDS_YEAR; } /* else we assume MDY */ else { TDS_MONTH = 0; TDS_DAY = 1; TDS_YEAR = 2; state = TDS_MONTH; } for (s = datestr; *s; s++) { if (!isdigit((unsigned char) *s) && isdigit((unsigned char) last_char)) { state++; } else { if (state == TDS_MONTH) month = (month * 10) + (*s - '0'); if (state == TDS_DAY) mday = (mday * 10) + (*s - '0'); if (state == TDS_YEAR) year = (year * 10) + (*s - '0'); } last_char = *s; } if (month > 0 && month < 13) t->tm_mon = month - 1; else return 0; if (mday > 0 && mday < 32) t->tm_mday = mday; else return 0; return store_year(year, t);}static intstore_dd_mon_yyy_date(char *datestr, struct tds_time *t){ char dd[3]; int mday; char mon[4]; char yyyy[5]; int year; tdsdump_log(TDS_DBG_INFO1, "store_dd_mon_yyy_date: %s\n", datestr); strncpy(dd, datestr, 2); dd[2] = '\0'; mday = atoi(dd); if (mday > 0 && mday < 32) t->tm_mday = mday; else return 0; if (datestr[2] == '-') { strncpy(mon, &datestr[3], 3); mon[3] = '\0'; if (store_monthname(mon, t) < 0) { tdsdump_log(TDS_DBG_INFO1, "store_dd_mon_yyy_date: store_monthname failed\n"); return 0; } strcpy(yyyy, &datestr[7]); year = atoi(yyyy); tdsdump_log(TDS_DBG_INFO1, "store_dd_mon_yyy_date: year %d\n", year); return store_year(year, t); } else { strncpy(mon, &datestr[2], 3); mon[3] = '\0'; if (store_monthname(mon, t) < 0) { tdsdump_log(TDS_DBG_INFO1, "store_dd_mon_yyy_date: store_monthname failed\n"); return 0; } strcpy(yyyy, &datestr[5]); year = atoi(yyyy); tdsdump_log(TDS_DBG_INFO1, "store_dd_mon_yyy_date: year %d\n", year); return store_year(year, t); }}/** * Test if a string is a month name and store correct month number * @return month number (0-11) or -1 if not match * @param datestr string to check * @param t where to store month (if NULL no store is done) */static intstore_monthname(const char *datestr, struct tds_time *t){ int ret; tdsdump_log(TDS_DBG_INFO1, "store_monthname: %ld %s\n", (long) strlen(datestr), datestr); if (strlen(datestr) == 3) { if (strcasecmp(datestr, "jan") == 0) ret = 0; else if (strcasecmp(datestr, "feb") == 0) ret = 1; else if (strcasecmp(datestr, "mar") == 0) ret = 2; else if (strcasecmp(datestr, "apr") == 0) ret = 3; else if (strcasecmp(datestr, "may") == 0) ret = 4; else if (strcasecmp(datestr, "jun") == 0) ret = 5; else if (strcasecmp(datestr, "jul") == 0) ret = 6; else if (strcasecmp(datestr, "aug") == 0) ret = 7; else if (strcasecmp(datestr, "sep") == 0) ret = 8; else if (strcasecmp(datestr, "oct") == 0) ret = 9; else if (strcasecmp(datestr, "nov") == 0) ret = 10; else if (strcasecmp(datestr, "dec") == 0) ret = 11; else return -1; } else { if (strcasecmp(datestr, "january") == 0) ret = 0; else if (strcasecmp(datestr, "february") == 0) ret = 1; else if (strcasecmp(datestr, "march") == 0) ret = 2; else if (strcasecmp(datestr, "april") == 0) ret = 3; else if (strcasecmp(datestr, "june") == 0) ret = 5; else if (strcasecmp(datestr, "july") == 0) ret = 6; else if (strcasecmp(datestr, "august") == 0) ret = 7; else if (strcasecmp(datestr, "september") == 0) ret = 8; else if (strcasecmp(datestr, "october") == 0) ret = 9; else if (strcasecmp(datestr, "november") == 0) ret = 10; else if (strcasecmp(datestr, "december") == 0) ret = 11; else return -1; } if (t) t->tm_mon = ret; return ret;}static intstore_yymmdd_date(const char *datestr, struct tds_time *t){ int month = 0, year = 0, mday = 0; int wholedate; wholedate = atoi(datestr); year = wholedate / 10000; month = (wholedate - (year * 10000)) / 100; mday = (wholedate - (year * 10000) - (month * 100)); if (month > 0 && month < 13) t->tm_mon = month - 1; else return 0; if (mday > 0 && mday < 32) t->tm_mday = mday; else return 0; return (store_year(year, t));}static intstore_time(const char *datestr, struct tds_time *t){ enum { TDS_HOURS, TDS_MINUTES, TDS_SECONDS, TDS_FRACTIONS }; int state = TDS_HOURS; char last_sep = '\0'; const char *s; int hours = 0, minutes = 0, seconds = 0, millisecs = 0; int ret = 1; int ms_len = 0; for (s = datestr; *s && strchr("apmAPM", (int) *s) == NULL; s++) { if (*s == ':' || *s == '.') { last_sep = *s; state++; } else switch (state) { case TDS_HOURS: hours = (hours * 10) + (*s - '0'); break; case TDS_MINUTES: minutes = (minutes * 10) + (*s - '0'); break; case TDS_SECONDS: seconds = (seconds * 10) + (*s - '0'); break; case TDS_FRACTIONS: millisecs = (millisecs * 10) + (*s - '0'); ms_len++; break; } } if (*s) { if (strcasecmp(s, "am") == 0) { if (hours == 12) hours = 0; t->tm_hour = hours; } if (strcasecmp(s, "pm") == 0) { if (hours == 0) ret = 0; if (hours > 0 && hours < 12) t->tm_hour = hours + 12; else t->tm_hour = hours; } } else { if (hours >= 0 && hours < 24) t->tm_hour = hours; else ret = 0; } if (minutes >= 0 && minutes < 60) t->tm_min = minutes; else ret = 0; if (seconds >= 0 && seconds < 60) t->tm_sec = seconds; else ret = 0; tdsdump_log(TDS_DBG_FUNC, "store_time() millisecs = %d\n", millisecs); if (millisecs) { if (millisecs >= 0 && millisecs < 1000) { if (last_sep == ':') t->tm_ms = millisecs; else { if (ms_len == 1) t->tm_ms = millisecs * 100; else if (ms_len == 2) t->tm_ms = millisecs * 10; else t->tm_ms = millisecs; } } else ret = 0; } return (ret);}static intstore_hour(const char *hour, const char *ampm, struct tds_time *t){ int ret = 1; int hours; hours = atoi(hour); if (hours >= 0 && hours < 24) { if (strcasecmp(ampm, "am") == 0) { if (hours == 12) hours = 0; t->tm_hour = hours; } if (strcasecmp(ampm, "pm") == 0) { if (hours == 0) ret = 0; if (hours > 0 && hours < 12) t->tm_hour = hours + 12; else t->tm_hour = hours; } } return ret;}/** * Get same type but nullable * @param srctype type requires * @return nullable type */TDS_INTtds_get_null_type(int srctype){ switch (srctype) { case SYBCHAR: return SYBVARCHAR; break; case SYBINT1: case SYBINT2: case SYBINT4: case SYBINT8: return SYBINTN; break; case SYBREAL: case SYBFLT8: return SYBFLTN; break; case SYBDATETIME: case SYBDATETIME4: return SYBDATETIMN; break; case SYBBIT: return SYBBITN; break; case SYBMONEY: case SYBMONEY4: return SYBMONEYN; break; default: break; } return srctype;}/** * format a date string according to an "extended" strftime(3) formatting definition. * @param buf output buffer * @param maxsize size of buffer in bytes (space include terminator) * @param format format string passed to strftime(3), except that %z represents milliseconds * @param dr date to convert * @return length of string returned, 0 for error */size_ttds_strftime(char *buf, size_t maxsize, const char *format, const TDSDATEREC * dr){ struct tm tm; size_t length; char *our_format; char *pz = NULL; assert(buf); assert(format); assert(dr); assert(0 <= dr->millisecond && dr->millisecond < 1000); tm.tm_sec = dr->second; tm.tm_min = dr->minute; tm.tm_hour = dr->hour; tm.tm_mday = dr->day; tm.tm_mon = dr->month; tm.tm_year = dr->year - 1900; tm.tm_wday = dr->weekday; tm.tm_yday = dr->dayofyear; tm.tm_isdst = 0;#ifdef HAVE_STRUCT_TM_TM_ZONE tm.tm_zone = NULL;#elif defined(HAVE_STRUCT_TM___TM_ZONE) tm.__tm_zone = NULL;#endif /* one more character is required because we replace %z with 3 digits */ our_format = malloc(strlen(format) + 2); if (!our_format) return 0; strcpy(our_format, format); /* * Look for "%z" in the format string. If found, replace it with dr->milliseconds. * For example, if milliseconds is 124, the format string * "%b %d %Y %H:%M:%S.%z" would become * "%b %d %Y %H:%M:%S.124". */ for (pz = our_format; (pz = strstr(pz, "%z")) != NULL; pz++) { /* Skip any escaped cases (%%z) */ if (pz > our_format && *(pz - 1) != '%') break; } if (pz) { sprintf(pz, "%03d", dr->millisecond % 1000); strcat(our_format, format + (pz - our_format) + 2);#if 0 tdsdump_log(TDS_DBG_INFO1, "tds_strftime: our_format '%s', tail '%s'\n", our_format, format + (pz - our_format) + 2);#endif } length = strftime(buf, maxsize, our_format, &tm); free(our_format); return length;}#if 0static TDS_UINTutf16len(const utf16_t * s){ const utf16_t *p = s; while (*p++); return p - s;}#endif/** * Test if a conversion is possible * @param srctype source type * @param desttype destination type * @return 0 if not convertible */unsigned chartds_willconvert(int srctype, int desttype){ typedef struct { int srctype; int desttype; int yn; } ANSWER; static const ANSWER answers[] = {# include "tds_willconvert.h" }; unsigned int i; const ANSWER *p = NULL; tdsdump_log(TDS_DBG_FUNC, "tds_willconvert()\n"); for (i = 0; i < sizeof(answers) / sizeof(ANSWER); i++) { if (srctype == answers[i].srctype && desttype == answers[i].desttype) { tdsdump_log(TDS_DBG_FUNC, "tds_willconvert() %d %d %d\n", answers[i].srctype, answers[i].desttype, answers[i].yn); p = &answers[i]; break; } } if (!p) return 0; if (is_fixed_type(p->desttype) || !p->yn) return p->yn; /* * Return the number of bytes needed to represent the srctype as a string. * This allows an application to use "tds_willconvert(SYBINT4, SYBCHAR)" to * discover he'll need an 11-byte buffer. * * Sizes exclude null terminators but allow for a '-' sign for negative numbers. * If the srctype is also variable, there is no per-type answer; it depends * on the declared length of the input. We just return 0xFF. */ switch (p->srctype) { case SYBBIT: return 1; case SYBSINT1: case SYBUINT1: case SYBINT1: return 3; case SYBUINT2: case SY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -