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: 2025-02-21 09:36:06 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "common.h"
       2             : #include <assert.h>
       3             : 
       4             : static char *
       5        5526 : add_char(char *s, SQLWCHAR ch)
       6             : {
       7        5526 :         if (ch == '\\')
       8           0 :                 s += sprintf(s, "\\\\");
       9        5526 :         else if (ch == '\t')
      10           0 :                 s += sprintf(s, "\\t");
      11        5526 :         else if (ch == '\r')
      12           0 :                 s += sprintf(s, "\\r");
      13        5526 :         else if (ch == '\n')
      14           0 :                 s += sprintf(s, "\\n");
      15        5526 :         else if ((unsigned int) ch < 32u)
      16           0 :                 s += sprintf(s, "\\x%02x", (unsigned int) ch);
      17        5526 :         else if ((unsigned int) ch < 256u)
      18        5502 :                 s += sprintf(s, "%c", (char) ch);
      19             :         else
      20          24 :                 s += sprintf(s, "\\u%04x", (unsigned int) ch);
      21        5526 :         return s;
      22             : }
      23             : 
      24             : void
      25        1364 : 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        1364 :         out[0] = 0;
      44        1364 :         s = out;
      45        1364 :         switch (out_c_type) {
      46         202 :         case SQL_C_NUMERIC:
      47         202 :                 num = &IN.num;
      48         202 :                 s += sprintf(s, "%d %d %d ", num->precision, num->scale, num->sign);
      49         202 :                 i = SQL_MAX_NUMERIC_LEN;
      50        3434 :                 for (; i > 0 && !num->val[--i];)
      51        3030 :                         continue;
      52         202 :                 for (; i >= 0; --i)
      53         202 :                         s += sprintf(s, "%02X", num->val[i]);
      54             :                 break;
      55             :         case SQL_C_BINARY:
      56             :                 assert(in_len >= 0);
      57        4064 :                 for (i = 0; i < in_len; ++i)
      58        4064 :                         s += sprintf(s, "%02X", IN.bin[i]);
      59             :                 break;
      60         506 :         case SQL_C_CHAR:
      61         506 :                 assert(IN.s[in_len] == 0);
      62         506 :                 s += sprintf(s, "%u ", (unsigned int) in_len);
      63        5458 :                 for (i = 0; i < in_len; ++i)
      64        4952 :                         s = add_char(s, (unsigned char) IN.s[i]);
      65         506 :                 *s = 0;
      66         506 :                 break;
      67          62 :         case SQL_C_WCHAR:
      68          62 :                 assert(in_len >=0 && (in_len % sizeof(SQLWCHAR)) == 0);
      69          62 :                 s += sprintf(s, "%u ", (unsigned int) (in_len / sizeof(SQLWCHAR)));
      70         636 :                 for (i = 0; i < in_len / sizeof(SQLWCHAR); ++i)
      71         574 :                         s = add_char(s, IN.ws[i]);
      72          62 :                 *s = 0;
      73          62 :                 break;
      74          40 :         case SQL_C_LONG:
      75          40 :                 assert(in_len == sizeof(SQLINTEGER));
      76          40 :                 sprintf(s, "%ld", (long int) IN.i);
      77          40 :                 break;
      78          20 :         case SQL_C_SBIGINT:
      79          20 :                 assert(in_len == sizeof(SQLBIGINT));
      80          20 :                 sprintf(s, "%" PRId64, (int64_t) IN.bi);
      81          20 :                 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          20 :         case SQL_C_TIMESTAMP:
      87         140 :                 sprintf(s, "%04d-%02u-%02u %02u:%02u:%02u.%03u",
      88          60 :                         IN.ts.year, IN.ts.month, IN.ts.day,
      89          60 :                         IN.ts.hour, IN.ts.minute, IN.ts.second,
      90          20 :                         (unsigned) (IN.ts.fraction / 1000000u));
      91          20 :                 break;
      92             :         default:
      93             :                 /* not supported */
      94           0 :                 assert(0);
      95             :                 break;
      96             :         }
      97        1364 : }

Generated by: LCOV version 1.13