Contiki 2.6

small_wctomb_r.c

00001 #include <stdlib.h>
00002 #include <string.h>
00003 #include <wchar.h>
00004 #include <locale.h>
00005 #include "mbctype.h"
00006 
00007 /* The following function concerns caracter coded in more than 0ne byte. For our small_printf we considered only
00008    caracters coded in ASCII and therefore all our caracters are coded in 8 bits (One byte)
00009    If you need the following treatment because caracter that you use are coded in more than one byte 
00010    comment the three following lines */
00011 
00012 #if defined( _SMALL_PRINTF ) || defined(SMALL_SCANF) 
00013 #define _ASCII_CAR
00014 #endif
00015 
00016 
00017 /* for some conversions, we use the __count field as a place to store a state value */
00018 #define __state __count
00019 
00020 #ifndef _ASCII_CAR
00021 extern char __lc_ctype[12];
00022 #endif
00023 int
00024 _DEFUN (_wctomb_r, (r, s, wchar, state),
00025         struct _reent *r     _AND 
00026         char          *s     _AND
00027         wchar_t        wchar _AND
00028         mbstate_t     *state)
00029 {
00030 
00031 #ifndef _ASCII_CAR
00032 
00033  if (strlen (__lc_ctype) <= 1)
00034     { /* fall-through */ }
00035   else if (!strcmp (__lc_ctype, "C-UTF-8"))
00036     {
00037       if (s == NULL)
00038         return 0; /* UTF-8 encoding is not state-dependent */
00039 
00040       if (wchar <= 0x7f)
00041         {
00042           *s = wchar;
00043           return 1;
00044         }
00045       else if (wchar >= 0x80 && wchar <= 0x7ff)
00046         {
00047           *s++ = 0xc0 | ((wchar & 0x7c0) >> 6);
00048           *s   = 0x80 |  (wchar &  0x3f);
00049           return 2;
00050         }
00051       else if (wchar >= 0x800 && wchar <= 0xffff)
00052         {
00053           /* UTF-16 surrogates -- must not occur in normal UCS-4 data */
00054           if (wchar >= 0xd800 && wchar <= 0xdfff)
00055             return -1;
00056 
00057           *s++ = 0xe0 | ((wchar & 0xf000) >> 12);
00058           *s++ = 0x80 | ((wchar &  0xfc0) >> 6);
00059           *s   = 0x80 |  (wchar &   0x3f);
00060           return 3;
00061         }
00062       else if (wchar >= 0x10000 && wchar <= 0x1fffff)
00063         {
00064           *s++ = 0xf0 | ((wchar & 0x1c0000) >> 18);
00065           *s++ = 0x80 | ((wchar &  0x3f000) >> 12);
00066           *s++ = 0x80 | ((wchar &    0xfc0) >> 6);
00067           *s   = 0x80 |  (wchar &     0x3f);
00068           return 4;
00069         }
00070       else if (wchar >= 0x200000 && wchar <= 0x3ffffff)
00071         {
00072           *s++ = 0xf8 | ((wchar & 0x3000000) >> 24);
00073           *s++ = 0x80 | ((wchar &  0xfc0000) >> 18);
00074           *s++ = 0x80 | ((wchar &   0x3f000) >> 12);
00075           *s++ = 0x80 | ((wchar &     0xfc0) >> 6);
00076           *s   = 0x80 |  (wchar &      0x3f);
00077           return 5;
00078         }
00079       else if (wchar >= 0x4000000 && wchar <= 0x7fffffff)
00080         {
00081           *s++ = 0xfc | ((wchar & 0x40000000) >> 30);
00082           *s++ = 0x80 | ((wchar & 0x3f000000) >> 24);
00083           *s++ = 0x80 | ((wchar &   0xfc0000) >> 18);
00084           *s++ = 0x80 | ((wchar &    0x3f000) >> 12);
00085           *s++ = 0x80 | ((wchar &      0xfc0) >> 6);
00086           *s   = 0x80 |  (wchar &       0x3f);
00087           return 6;
00088         }
00089       else
00090         return -1;
00091     }
00092   else if (!strcmp (__lc_ctype, "C-SJIS"))
00093     {
00094       unsigned char char2 = (unsigned char)wchar;
00095       unsigned char char1 = (unsigned char)(wchar >> 8);
00096 
00097       if (s == NULL)
00098         return 0;  /* not state-dependent */
00099 
00100       if (char1 != 0x00)
00101         {
00102         /* first byte is non-zero..validate multi-byte char */
00103           if (_issjis1(char1) && _issjis2(char2)) 
00104             {
00105               *s++ = (char)char1;
00106               *s = (char)char2;
00107               return 2;
00108             }
00109           else
00110             return -1;
00111         }
00112     }
00113   else if (!strcmp (__lc_ctype, "C-EUCJP"))
00114     {
00115       unsigned char char2 = (unsigned char)wchar;
00116       unsigned char char1 = (unsigned char)(wchar >> 8);
00117 
00118       if (s == NULL)
00119         return 0;  /* not state-dependent */
00120 
00121       if (char1 != 0x00)
00122         {
00123         /* first byte is non-zero..validate multi-byte char */
00124           if (_iseucjp (char1) && _iseucjp (char2)) 
00125             {
00126               *s++ = (char)char1;
00127               *s = (char)char2;
00128               return 2;
00129             }
00130           else
00131             return -1;
00132         }
00133     }
00134   else if (!strcmp (__lc_ctype, "C-JIS"))
00135     {
00136       int cnt = 0; 
00137       unsigned char char2 = (unsigned char)wchar;
00138       unsigned char char1 = (unsigned char)(wchar >> 8);
00139 
00140       if (s == NULL)
00141         return 1;  /* state-dependent */
00142 
00143       if (char1 != 0x00)
00144         {
00145         /* first byte is non-zero..validate multi-byte char */
00146           if (_isjis (char1) && _isjis (char2)) 
00147             {
00148               if (state->__state == 0)
00149                 {
00150                   /* must switch from ASCII to JIS state */
00151                   state->__state = 1;
00152                   *s++ = ESC_CHAR;
00153                   *s++ = '$';
00154                   *s++ = 'B';
00155                   cnt = 3;
00156                 }
00157               *s++ = (char)char1;
00158               *s = (char)char2;
00159               return cnt + 2;
00160             }
00161           else
00162             return -1;
00163         }
00164       else
00165         {
00166           if (state->__state != 0)
00167             {
00168               /* must switch from JIS to ASCII state */
00169               state->__state = 0;
00170               *s++ = ESC_CHAR;
00171               *s++ = '(';
00172               *s++ = 'B';
00173               cnt = 3;
00174             }
00175           *s = (char)char2;
00176           return cnt + 1;
00177         }
00178     }
00179 
00180   if (s == NULL)
00181     return 0;
00182  #endif
00183   /* otherwise we are dealing with a single byte character */
00184   *s = (char) wchar;
00185   return 1;
00186 }
00187     
00188