Line data Source code
1 : #include "common.h"
2 : #include <assert.h>
3 :
4 : static char *
5 3988 : add_char(char *s, SQLWCHAR ch)
6 : {
7 3988 : if (ch == '\\')
8 0 : s += sprintf(s, "\\\\");
9 3988 : else if (ch == '\t')
10 0 : s += sprintf(s, "\\t");
11 3988 : else if (ch == '\r')
12 0 : s += sprintf(s, "\\r");
13 3988 : else if (ch == '\n')
14 0 : s += sprintf(s, "\\n");
15 3988 : else if ((unsigned int) ch < 32u)
16 0 : s += sprintf(s, "\\x%02x", (unsigned int) ch);
17 3988 : else if ((unsigned int) ch < 256u)
18 3968 : s += sprintf(s, "%c", (char) ch);
19 : else
20 20 : s += sprintf(s, "\\u%04x", (unsigned int) ch);
21 3988 : return s;
22 : }
23 :
24 : void
25 1052 : odbc_c2string(char *out, SQLSMALLINT out_c_type, const void *in, size_t in_len)
26 : {
27 : typedef union {
28 : unsigned char bin[256];
29 : char s[256];
30 : SQLWCHAR ws[256/sizeof(SQLWCHAR)];
31 : SQLINTEGER i;
32 : SQLBIGINT bi;
33 : SQLSMALLINT si;
34 : SQL_NUMERIC_STRUCT num;
35 : SQL_TIMESTAMP_STRUCT ts;
36 : } buf_t;
37 : #undef IN
38 : #define IN (*((const buf_t*) in))
39 : int i;
40 : const SQL_NUMERIC_STRUCT *num;
41 : char *s;
42 :
43 1052 : out[0] = 0;
44 1052 : s = out;
45 1052 : switch (out_c_type) {
46 158 : case SQL_C_NUMERIC:
47 158 : num = &IN.num;
48 158 : s += sprintf(s, "%d %d %d ", num->precision, num->scale, num->sign);
49 158 : i = SQL_MAX_NUMERIC_LEN;
50 2686 : for (; i > 0 && !num->val[--i];)
51 2370 : continue;
52 158 : for (; i >= 0; --i)
53 158 : s += sprintf(s, "%02X", num->val[i]);
54 : break;
55 : case SQL_C_BINARY:
56 : assert(in_len >= 0);
57 3128 : for (i = 0; i < in_len; ++i)
58 3128 : s += sprintf(s, "%02X", IN.bin[i]);
59 : break;
60 372 : case SQL_C_CHAR:
61 372 : assert(IN.s[in_len] == 0);
62 372 : s += sprintf(s, "%u ", (unsigned int) in_len);
63 3900 : for (i = 0; i < in_len; ++i)
64 3528 : s = add_char(s, (unsigned char) IN.s[i]);
65 372 : *s = 0;
66 372 : break;
67 50 : case SQL_C_WCHAR:
68 50 : assert(in_len >=0 && (in_len % sizeof(SQLWCHAR)) == 0);
69 50 : s += sprintf(s, "%u ", (unsigned int) (in_len / sizeof(SQLWCHAR)));
70 510 : for (i = 0; i < in_len / sizeof(SQLWCHAR); ++i)
71 460 : s = add_char(s, IN.ws[i]);
72 50 : *s = 0;
73 50 : break;
74 32 : case SQL_C_LONG:
75 32 : assert(in_len == sizeof(SQLINTEGER));
76 32 : sprintf(s, "%ld", (long int) IN.i);
77 32 : break;
78 16 : case SQL_C_SBIGINT:
79 16 : assert(in_len == sizeof(SQLBIGINT));
80 16 : sprintf(s, "%" PRId64, IN.bi);
81 16 : break;
82 0 : case SQL_C_SHORT:
83 0 : assert(in_len == sizeof(SQLSMALLINT));
84 0 : sprintf(s, "%d", (int) IN.si);
85 0 : break;
86 16 : case SQL_C_TIMESTAMP:
87 112 : sprintf(s, "%04d-%02u-%02u %02u:%02u:%02u.%03u",
88 48 : IN.ts.year, IN.ts.month, IN.ts.day,
89 48 : IN.ts.hour, IN.ts.minute, IN.ts.second,
90 16 : (unsigned) (IN.ts.fraction / 1000000u));
91 16 : break;
92 : default:
93 : /* not supported */
94 0 : assert(0);
95 : break;
96 : }
97 1052 : }
|