LCOV - code coverage report
Current view: top level - src/odbc/unittests - c2string.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 53 63 84.1 %
Date: 2024-04-18 20:40:06 Functions: 2 2 100.0 %

          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 : }

Generated by: LCOV version 1.13