GadgetSeed  0.9.6
charcode.c
[詳解]
1 /** @file
2  @brief 文字コード
3 
4  @date 2018.02.12
5  @author Takashi SHUDO
6 
7  @page character_code 文字コード
8 
9  GadgetSeed は文字コード UTF-8、SJIS、UTF-16 を変換する為のAPIがあります。
10 
11  これらのAPIを使用するには FatFs を有効にする必要があります。
12 
13  UTF-16 は BOM無しビッグエンディアンのみ使用できます。
14 
15 
16  ---
17  @section character_code_api 文字コード変換API
18 
19  include ファイル : charcode.h
20 
21  | API名 | 機能 |
22  |:--------------------------|:--------------------------------------|
23  | sjiscode_to_utf16code() | @copybrief sjiscode_to_utf16code |
24  | sjisstr_to_utf8str() | @copybrief sjisstr_to_utf8str |
25  | sj2utf8() | @copybrief sj2utf8 |
26  | utf16code_to_utf8code() | @copybrief utf16code_to_utf8code |
27  | utf16str_to_utf8str() | @copybrief utf16str_to_utf8str |
28  | utf162utf8() | @copybrief utf162utf8 |
29  | utf8code_to_utf16code() | @copybrief utf8code_to_utf16code |
30  | utf8str_to_utf16str() | @copybrief utf8str_to_utf16str |
31 */
32 
33 #include "sysconfig.h"
34 
35 #ifdef GSC_COMP_ENABLE_FATFS
36 #include "ff.h"
37 #define MAX_CONVERT_LEN FF_MAX_LFN
38 #else
39 #define MAX_CONVERT_LEN 255
40 #endif
41 
42 #include "charcode.h"
43 #include "tkprintf.h"
44 
45 //#define DEBUGTBITS 0x01
46 #include "dtprintf.h"
47 
48 
49 #ifdef GSC_COMP_ENABLE_FATFS
50 /**
51  @brief SJIS から UTF-16 へ変換
52 
53  @param[in] sjiscode SJIS文字
54 
55  @return UTF-16文字
56 */
58 {
59  ushort rt = ff_oem2uni(sjiscode, FF_CODE_PAGE);
60 
61  return rt;
62 }
63 
64 /**
65  @brief SJIS 文字列から UTF-8 文字列へ変換
66 
67  @param[out] utf8str UTF-8文字列
68  @param[in] sjiscode SJIS文字列
69  @param[in] count 出力UTF-8文字列最大長
70 
71  @return UTF-8文字列
72 */
73 uchar * sjisstr_to_utf8str(uchar *utf8str, uchar *sjisstr, unsigned int count)
74 {
75  uchar *rt = utf8str;
76  ushort wch, cwch;
77  unsigned int l = 0;
78 
79  while((*sjisstr) != 0) {
80  if(l < count) {
81  if(*sjisstr < 0x80) {
82  *utf8str = *sjisstr;
83  utf8str ++;
84  sjisstr ++;
85  l ++;
86  } else {
87  uchar code[3];
88  int i, clen;
89  wch = (ushort)((((ushort)(*sjisstr)) << 8) + (*(sjisstr+1)));
90  sjisstr += 2;
91 
92  cwch = sjiscode_to_utf16code(wch);
93 
94  clen = utf16code_to_utf8code(code, cwch);
95 
96  for(i=0; i<clen; i++) {
97  if(l < count) {
98  *utf8str = code[i];
99  utf8str ++;
100  l ++;
101  } else {
102  // 最後のUTF-8文字がcountに入らない場合、中途半端な文字データになる
103  break;
104  }
105  }
106  }
107  } else {
108  break;
109  }
110  }
111 
112  *utf8str = 0;
113 
114  return rt;
115 }
116 
117 /**
118  @brief SJIS 文字列から最大文字バイト数固定 UTF-8 文字列へ変換
119 
120  @param[in] sjiscode SJIS文字列
121 
122  @return UTF-8文字列
123 */
124 uchar * sj2utf8(uchar *sjisstr)
125 {
126  static uchar utf8str[MAX_CONVERT_LEN+1];
127 
128  (void)sjisstr_to_utf8str(utf8str, sjisstr, MAX_CONVERT_LEN);
129 
130  return &utf8str[0];
131 }
132 #endif
133 
134 /**
135  @brief UTF-16 文字から UTF-8 文字へ変換
136 
137  @param[out] utf8str UTF-8文字
138  @param[in] utf16code UTF-16文字
139 
140  @return UTF-8文字バイト数
141 */
142 int utf16code_to_utf8code(uchar *utf8code, ushort utf16code)
143 {
144  int rt = 0;
145  uchar code[2];
146 
147  code[0] = (uchar)(utf16code >> 8);
148  code[1] = (uchar)(utf16code & 0xff);
149 
150  if(utf16code < 0x80) {
151  // 00000000-0xxxxxxx -> 0xxxxxxx
152  utf8code[0] = code[1];
153  rt = 1;
154  } else if(utf16code < 0x800) {
155  // 00000xxx-xxyyyyyy -> 110xxxxx-10yyyyyy
156  utf8code[0] = (uchar)0xC0 + ((code[0] & 0x7) << 2) + ((code[1] & 0xC0) >> 6);
157  utf8code[1] = (uchar)0x80 + (code[1] & 0x3F);
158  rt = 2;
159  } else {
160  // xxxxyyyy-yyzzzzzz -> 1110xxxx-10yyyyyy-10zzzzzz
161  utf8code[2] = (uchar)0x80 + (code[1] & 0x3F);
162  utf8code[1] = (uchar)0x80 + ((code[1] & 0xC0) >> 6) + ((code[0] & 0xF) << 2);
163  utf8code[0] = (uchar)0xE0 + ((code[0] & 0xF0) >> 4);
164  rt = 3;
165  }
166 
167  return rt;
168 }
169 
170 /**
171  @brief UTF-16 文字列から UTF-8 文字列へ変換
172 
173  @param[out] utf8str UTF-8文字列
174  @param[in] utf16str UTF-16文字列
175  @param[in] count 最大出力UTF-8文字列バイト数
176 
177  @return UTF-8文字列バイト長
178 */
179 int utf16str_to_utf8str(uchar *utf8str, ushort *utf16str, unsigned int count)
180 {
181  unsigned int len = 0;
182  uchar *u8p = utf8str;
183  ushort *u16p = utf16str;
184 
185  while((*u16p) != 0) {
186  if(len < count) {
187  if(*u16p < 0x0080) {
188  *u8p = (uchar)*u16p;
189  u8p ++;
190  u16p ++;
191  len ++;
192  } else {
193  uchar code[3];
194  int i, clen;
195 
196  clen = utf16code_to_utf8code(code, *u16p);
197  u16p ++;
198 
199  for(i=0; i<clen; i++) {
200  if(len < count) {
201  *u8p = code[i];
202  u8p ++;
203  len ++;
204  } else {
205  // 最後のUTF-8文字がcountに入らない場合、中途半端な文字データになる
206  break;
207  }
208  }
209  }
210  } else {
211  break;
212  }
213  }
214 
215  *u8p = 0;
216 
217  XDUMP(0x01, (unsigned char *)utf16str, len);
218  XDUMP(0x01, utf8str, len);
219 
220  return (int)len;
221 }
222 
223 /**
224  @brief UTF-16 文字列から最大文字バイト数固定 UTF-8 文字列へ変換
225 
226  @param[in] utf16str UTF-16文字列
227 
228  @return UTF-8文字列
229 */
230 uchar * utf162utf8(ushort *utf16str)
231 {
232  static uchar utf8str[MAX_CONVERT_LEN+1];
233 
234  (void)utf16str_to_utf8str(utf8str, utf16str, MAX_CONVERT_LEN);
235 
236  return &utf8str[0];
237 }
238 
239 /**
240  @brief UTF-8 文字から UTF-16 文字へ変換
241 
242  @param[out] utf16code UTF-16文字
243  @param[in] utf8code UTF-8文字
244 
245  @return UTF-8文字バイト数
246 */
247 int utf8code_to_utf16code(ushort *utf16code, uchar *utf8code)
248 {
249  if(*utf8code < 0x80) {
250  *utf16code = *utf8code;
251  return 1;
252  } else if((*utf8code & 0xe0) == 0xc0) {
253  // 110xxxxx-10yyyyyy -> 00000xxx-xxyyyyyy
254  *utf16code = (unsigned short)(((((unsigned short)utf8code[0] & 0x1f) >> 2) << 8) +
255  ((utf8code[0] & 0x03) << 6) +
256  (utf8code[1] & 0x3f));
257  return 2;
258  } else if((*utf8code & 0xf0) == 0xe0) {
259  // 1110xxxx-10yyyyyy-10zzzzzz -> xxxxyyyy-yyzzzzzz
260  *utf16code = (unsigned short)(((((unsigned short)utf8code[0] & 0x0f) << 4) << 8) +
261  ((((unsigned short)utf8code[1] & 0x3c) >> 2) << 8) +
262  ((utf8code[1] & 0x03) << 6) +
263  (utf8code[2] & 0x3f));
264  return 3;
265  } else if((*utf8code & 0xf8) == 0xf0) {
266  *utf16code = 0; // 未サポート
267  return 4;
268  } else if((*utf8code & 0xfc) == 0xf8) {
269  *utf16code = 0; // 未サポート
270  return 5;
271  } else if((*utf8code & 0xfe) == 0xfc) {
272  *utf16code = 0; // 未サポート
273  return 6;
274  } else {
275  //SYSERR_PRINT("Unsuport UTF-8 CODE %02X %02X %02X\n", utf8code[0], utf8code[1], utf8code[2]);
276  return 0; // どれにも該当しない
277  }
278 }
279 
280 /**
281  @brief UTF-8 文字列から UTF-16 文字列へ変換
282 
283  @param[out] utf16str UTF-16文字列
284  @param[in] utf8str UTF-8文字列
285  @param[in] count 最大出力UTF-16文字列バイト数
286 
287  @return 変換後UTF-16文字列バイト長
288 */
289 int utf8str_to_utf16str(ushort *utf16str, uchar *utf8str, unsigned int count)
290 {
291  ushort cwch;
292  unsigned int len = 0;
293 
294  while((*utf8str) != 0) {
295  if(len < count) {
296  if(*utf8str < 0x80) {
297  *utf16str = *utf8str;
298  utf16str ++;
299  utf8str ++;
300  len ++;
301  } else {
302  int clen;
303 
304  clen = utf8code_to_utf16code(&cwch, utf8str);
305  utf8str += clen;
306 
307  if((len+1) < count) {
308  if(clen > 1) {
309  *utf16str = cwch;
310  utf16str ++;
311  len ++;
312  } else {
313  // 最後の文字がcountに入らない場合、中途半端な文字データになる
314  break;
315  }
316  }
317  }
318  } else {
319  break;
320  }
321  }
322 
323  *utf16str = 0;
324 
325  return (int)len;
326 }
unsigned char uchar
GadgetSeedの文字(列)は unsigned char 型となる
Definition: str.h:13
アプリケーション(タスク)デバッグ用マクロ
文字コード処理
int utf8str_to_utf16str(ushort *utf16str, uchar *utf8str, unsigned int count)
UTF-8 文字列から UTF-16 文字列へ変換
Definition: charcode.c:289
int utf8code_to_utf16code(ushort *utf16code, uchar *utf8code)
UTF-8 文字から UTF-16 文字へ変換
Definition: charcode.c:247
カーネル用機能限定printf
uchar * sj2utf8(uchar *sjisstr)
SJIS 文字列から最大文字バイト数固定 UTF-8 文字列へ変換
Definition: charcode.c:124
ushort sjiscode_to_utf16code(ushort sjiscode)
SJIS から UTF-16 へ変換
Definition: charcode.c:57
uchar * utf162utf8(ushort *utf16str)
UTF-16 文字列から最大文字バイト数固定 UTF-8 文字列へ変換
Definition: charcode.c:230
int utf16code_to_utf8code(uchar *utf8code, ushort utf16code)
UTF-16 文字から UTF-8 文字へ変換
Definition: charcode.c:142
uchar * sjisstr_to_utf8str(uchar *utf8str, uchar *sjisstr, unsigned int count)
SJIS 文字列から UTF-8 文字列へ変換
Definition: charcode.c:73
unsigned short ushort
2バイト(UTF-16)文字
Definition: str.h:14
int utf16str_to_utf8str(uchar *utf8str, ushort *utf16str, unsigned int count)
UTF-16 文字列から UTF-8 文字列へ変換
Definition: charcode.c:179