utf8_1.c
来自「在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动」· C语言 代码 · 共 276 行
C
276 行
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Brian Bruns * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include "common.h"#include <ctype.h>#include <assert.h>static char software_version[] = "$Id: utf8_1.c,v 1.12 2006/01/24 15:03:28 freddy77 Exp $";static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };static TDSSOCKET *tds;/* Some no-ASCII strings (XML coding) */static const char english[] = "English";static const char spanish[] = "Español";static const char french[] = "Français";static const char portuguese[] = "Português";static const char russian[] = "Русский";static const char arabic[] = "العربية";static const char chinese[] = "简体中文";static const char japanese[] = "日本語";static const char hebrew[] = "עברית";static const char *strings[] = { english, spanish, french, portuguese, russian, arabic, chinese, japanese, hebrew, NULL, /* will be replaced with large data */ NULL, /* will be replaced with large data */ NULL, /* will be replaced with large data */ NULL, /* will be replaced with large data */ NULL};static int max_len = 0;static char *to_utf8(const char *src, char *dest){ unsigned char *p = (unsigned char *) dest; int len = 0; for (; *src;) { if (src[0] == '&' && src[1] == '#') { const char *end = strchr(src, ';'); char tmp[16]; int radix = 10; int n; assert(end); src += 2; if (toupper(*src) == 'X') { radix = 16; ++src; } memcpy(tmp, src, end - src); tmp[end - src] = 0; n = strtol(tmp, NULL, radix); assert(n > 0 && n < 0x10000); if (n >= 0x1000) { *p++ = 0xe0 | (n >> 12); *p++ = 0x80 | ((n >> 6) & 0x3f); *p++ = 0x80 | (n & 0x3f); } else if (n >= 0x80) { *p++ = 0xc0 | (n >> 6); *p++ = 0x80 | (n & 0x3f); } else { *p++ = (unsigned char) n; } src = end + 1; } else { *p++ = *src++; } ++len; } if (len > max_len) max_len = len; *p = 0; return dest;}static voidquery(const char *sql){ if (run_query(tds, sql) != TDS_SUCCEED) { fprintf(stderr, "error executing query: %s\n", sql); exit(1); }}static voidtest(const char *type, const char *test_name){ char buf[256]; char tmp[256]; int i; const char **s; int rc; TDS_INT result_type; int done_flags; sprintf(buf, "CREATE TABLE #tmp (i INT, t %s)", type); query(buf); /* insert all test strings in table */ for (i = 0, s = strings; *s; ++s, ++i) { sprintf(buf, "insert into #tmp values(%d, N'%s')", i, to_utf8(*s, tmp)); query(buf); } /* do a select and check all results */ rc = tds_submit_query(tds, "select t from #tmp order by i"); if (rc != TDS_SUCCEED) { fprintf(stderr, "tds_submit_query() failed\n"); exit(1); } if (tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS) != TDS_SUCCEED) { fprintf(stderr, "tds_process_tokens() failed\n"); exit(1); } if (result_type != TDS_ROWFMT_RESULT) { fprintf(stderr, "expected row fmt() failed\n"); exit(1); } if (tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS) != TDS_SUCCEED) { fprintf(stderr, "tds_process_tokens() failed\n"); exit(1); } if (result_type != TDS_ROW_RESULT) { fprintf(stderr, "expected row result() failed\n"); exit(1); } i = 0; while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_RETURN_ROWFMT|TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCEED) { switch (result_type) { case TDS_ROW_RESULT: { TDSCOLUMN *curcol = tds->current_results->columns[0]; char *src = (char *) curcol->column_data; if (is_blob_type(curcol->column_type)) { TDSBLOB *blob = (TDSBLOB *) src; src = blob->textvalue; } strcpy(buf, to_utf8(strings[i], tmp)); if (strlen(buf) != curcol->column_cur_size || strncmp(buf, src, curcol->column_cur_size) != 0) { int l = curcol->column_cur_size; if (l > 200) l = 200; strncpy(tmp, src, l); tmp[l] = 0; fprintf(stderr, "Wrong result in test %s\n Got: '%s' len %d\n Expected: '%s' len %u\n", test_name, tmp, curcol->column_cur_size, buf, (unsigned int) strlen(buf)); exit(1); } ++i; } break; default: fprintf(stderr, "Unexpected result\n"); exit(1); break; } } if (rc != TDS_NO_MORE_RESULTS) { fprintf(stderr, "tds_process_tokens() unexpected return\n"); exit(1); } while ((rc = tds_process_tokens(tds, &result_type, &done_flags, TDS_TOKEN_RESULTS)) == TDS_SUCCEED) { switch (result_type) { case TDS_NO_MORE_RESULTS: return; case TDS_DONE_RESULT: case TDS_DONEPROC_RESULT: case TDS_DONEINPROC_RESULT: if (!(done_flags & TDS_DONE_ERROR)) break; default: fprintf(stderr, "tds_process_tokens() unexpected result_type\n"); exit(1); break; } } query("DROP TABLE #tmp"); /* do sone select to test results */ /* * for (s = strings; *s; ++s) { * printf("%s\n", to_utf8(*s, tmp)); * } */}intmain(int argc, char **argv){ TDSLOGIN *login; int ret; int verbose = 0; /* use UTF-8 as our coding */ strcpy(CHARSET, "UTF-8"); ret = try_tds_login(&login, &tds, __FILE__, verbose); if (ret != TDS_SUCCEED) { fprintf(stderr, "try_tds_login() failed\n"); return 1; } if (IS_TDS7_PLUS(tds)) { char type[32]; char buf[1024]; int i, len; strcpy(buf, "aaa"); len = 0; for (i = 0; strlen(buf) < 980 && len < 200; ++i) { char tmp[256]; strcat(buf, japanese); len += strlen(to_utf8(japanese, tmp)); } strings[sizeof(strings) / sizeof(strings[0]) - 5] = buf + 3; strings[sizeof(strings) / sizeof(strings[0]) - 4] = buf + 2; strings[sizeof(strings) / sizeof(strings[0]) - 3] = buf + 1; strings[sizeof(strings) / sizeof(strings[0]) - 2] = buf; test("NVARCHAR(500)", "NVARCHAR with large size"); sprintf(type, "NVARCHAR(%d)", max_len); test(type, "NVARCHAR with sufficient size"); test("NTEXT", "TEXT"); /* TODO test parameters */ } try_tds_logout(login, tds, verbose); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?