Logo Search packages:      
Sourcecode: freetds version File versions

char* tds7_unicode2ascii ( TDSSOCKET *  tds,
const char *  in_string,
char *  out_string,
int  len 
)

convert from ucs2 string to ascii.

Parameters:
in_string ucs2 string (not terminated) to convert to ascii
out_string buffer to store translated string. It should be large enough to handle len bytes. string won't be zero terminated.
len length of input string in characters (2 byte)

Definition at line 116 of file iconv.c.

References tds7_unicode2ascii().

Referenced by tds7_unicode2ascii(), and tds_get_string().

{
      int i;

#if HAVE_ICONV
      TDSICONVINFO *iconv_info;
      ICONV_CONST char *in_ptr;
      char *out_ptr;
      size_t out_bytes, in_bytes;
      char quest_mark[] = "?\0";    /* best to live no-const */
      ICONV_CONST char *pquest_mark;
      size_t lquest_mark;
#endif

      if (!in_string)
            return NULL;

#if HAVE_ICONV
      iconv_info = (TDSICONVINFO *) tds->iconv_info;
      if (iconv_info->use_iconv) {
            out_bytes = len;
            in_bytes = len * 2;
            in_ptr = (ICONV_CONST char *) in_string;
            out_ptr = out_string;
            while (iconv(iconv_info->cdfrom, &in_ptr, &in_bytes, &out_ptr, &out_bytes) == (size_t) - 1) {
                  /* iconv call can reset errno */
                  i = errno;
                  /* reset iconv state */
                  iconv(iconv_info->cdfrom, NULL, NULL, NULL, NULL);
                  if (i != EILSEQ)
                        break;

                  /* skip one UCS-2 sequnce */
                  in_ptr += 2;
                  in_bytes -= 2;

                  /* replace invalid with '?' */
                  pquest_mark = quest_mark;
                  lquest_mark = 2;
                  iconv(iconv_info->cdfrom, &pquest_mark, &lquest_mark, &out_ptr, &out_bytes);
                  if (out_bytes == 0)
                        break;
            }
            /* FIXME best method ?? there is no way to return 
             * less or more than len characters */
            /* something went wrong fill remaining with zeroes 
             * avoiding returning garbage data */
            if (out_bytes)
                  memset(out_ptr, 0, out_bytes);

            return out_string;
      }
#endif

      /* no iconv, strip high order byte if zero or replace with '?' 
       * this is the same of converting to ISO8859-1 charset using iconv */
      /* TODO update docs */
      for (i = 0; i < len; ++i) {
            out_string[i] = in_string[i * 2 + 1] ? '?' : in_string[i * 2];
      }
      return out_string;
}


Generated by  Doxygen 1.6.0   Back to index