开发语言:C++

功能描述:

Unicode内码转换器。用于UTF-8、UTF-16(UCS2)、UTF-32(UCS4)之间的编码转换。

下载地址:

UnicodeConverter.zip

版本历史:

V1.02010年03月12日

  • 完成正式版本。

源代码:

UnicodeConverter.h



1. /*----------------------------------------------------------
2. 文件名称:UnicodeConverter.h
3. 
4. 作者:秦建辉
5. 
6. MSN:splashcn@msn.com
7. 
8. 当前版本:V1.0
9. 
10. 历史版本:
11. V1.02010年03月12日
12. 完成正式版本。
13. 
14. 功能描述:
15. Unicode内码转换器。用于utf-8、utf-16(UCS2)、utf-32(UCS4)之间的编码转换
16. ------------------------------------------------------------*/
17. #pragmaonce
18. 
19. #include<windows.h>
20. #include<stdio.h>
21. #include<ostream>
22. 
23. usingnamespacestd;
24. 
25. classCUnicodeConverter
26. {
27. /*-------------------------------------------------------------
28. 内码转换
29. -------------------------------------------------------------*/
30. public:
31. /*
32. 功能:将UCS4编码转换成UTF8编码
33. 参数:
34. dwUCS4:要转换的UCS4编码
35. pbUTF8:用于存储转换后的UTF8编码。设为NULL,可以获取长度信息(字节数)
36. 返回值:
37. 0:无效的UCS4编码
38. 1-6:UTF8编码的有效长度
39. */
40. staticINTUCS4_To_UTF8(DWORDdwUCS4,BYTE*pbUTF8);
41. 
42. /*
43. 功能:将UTF8编码转换成UCS4编码
44. 参数:
45. pbUTF8:要转换的UTF8编码
46. dwUCS4:存储转换后的UCS4编码
47. 返回值:
48. 0:参数错误或无效的UTF8编码
49. 1-6:UTF8编码的有效长度
50. */
51. staticINTUTF8_To_UCS4(constBYTE*pbUTF8,DWORD&dwUCS4);
52. 
53. /*
54. 功能:将UCS4编码转换成UTF16编码
55. 参数:
56. dwUCS4:要转换的UCS4编码
57. pwUTF16:用于存储转换后的UTF16编码。设为NULL,可以获取长度信息(字符数)
58. 返回值:
59. 0:无效的UCS4编码
60. 1:转换成1个UTF16编码
61. 2:转换成2个UTF16编码
62. */
63. staticINTUCS4_To_UTF16(DWORDdwUCS4,WORD*pwUTF16);
64. 
65. /*
66. 功能:将UTF16编码转换成UCS4编码
67. 参数:
68. pwUTF16:需要转换的UTF16编码
69. dwUCS4:存储转换后的UCS4编码
70. 返回值:
71. 0:参数错误或无效的UTF16编码
72. 1:1个UTF16编码被转换
73. 2:2个UTF16编码被转换
74. */
75. staticINTUTF16_To_UCS4(constWORD*pwUTF16,DWORD&dwUCS4);
76. 
77. /*
78. 功能:将UTF8字符串转换成UTF16字符串
79. 参数:
80. pbszUTF8Str:需要转换的UTF8字符串
81. pwszUTF16Str:存储转换后的UTF16字符串。设为NULL,可以获取所需长度信息(字符数)
82. 返回值:
83. 0:转换失败
84. >0:UTF16字符串长度
85. */
86. staticINTUTF8Str_To_UTF16Str(constBYTE*pbszUTF8Str,WORD*pwszUTF16Str);
87. 
88. /*
89. 功能:将UTF16字符串转换成UTF8字符串
90. 参数:
91. pwszUTF16Str:需要转换的UTF16字符串
92. pbszUTF8Str:存储转换后的UTF8字符串。设为NULL,可以获取所需长度信息(字节数)
93. 返回值:
94. 0:转换失败
95. >0:UTF8字符串长度(不包括NULL字符)
96. */
97. staticINTUTF16Str_To_UTF8Str(constWORD*pwszUTF16Str,BYTE*pbszUTF8Str);
98. 
99. /*-------------------------------------------------------------
100. C文件写入操作
101. -------------------------------------------------------------*/
102. public:
103. /*
104. 功能:向文件中写入UTF8编码
105. 返回值:
106. 写入的字节数
107. */
108. staticUINTPrint_UTF8_By_UCS4(FILE*out,DWORDdwUCS4);
109. 
110. /*
111. 功能:向文件中写入UTF16编码
112. 返回值:
113. 写入的字节数
114. */
115. staticUINTPrint_UTF16_By_UCS4(FILE*out,DWORDdwUCS4,BOOLisBigEndian=FALSE);
116. 
117. /*
118. 功能:将UTF16字符串以UTF8编码输出到文件中
119. 返回值:
120. 写入的字节数
121. */
122. staticUINTPrint_UTF8Str_By_UTF16Str(FILE*out,constWORD*pwszUTF16Str);
123. 
124. /*
125. 功能:将UTF8字符串以UTF16编码输出到文件中
126. 返回值:
127. 写入的字节数
128. */
129. staticUINTPrint_UTF16Str_By_UTF8Str(FILE*out,constBYTE*pbszUTF8Str,BOOLisBigEndian=FALSE);
130. 
131. /*
132. 功能:向文件中输出UTF8编码字节序标记
133. 返回值:
134. 写入的字节数
135. */
136. staticUINTPrint_UTF8_BOM(FILE*out);
137. 
138. /*
139. 功能:向文件中输出UTF16编码字节序标记
140. 返回值:
141. 写入的字节数
142. */
143. staticUINTPrint_UTF16_BOM(FILE*out,BOOLisBigEndian=FALSE);
144. 
145. /*-------------------------------------------------------------
146. C++流输出操作
147. -------------------------------------------------------------*/
148. public:
149. /*
150. 功能:向流中写入UTF8编码
151. 返回值:
152. 写入的字节数
153. */
154. staticUINTPrint_UTF8_By_UCS4(ostream&os,DWORDdwUCS4);
155. 
156. /*
157. 功能:向流中写入UTF16编码
158. 返回值:
159. 写入的字节数
160. */
161. staticUINTPrint_UTF16_By_UCS4(ostream&os,DWORDdwUCS4,BOOLisBigEndian=FALSE);
162. 
163. /*
164. 功能:将UTF16字符串以UTF8编码输出到流中
165. 返回值:
166. 写入的字节数
167. */
168. staticUINTPrint_UTF8Str_By_UTF16Str(ostream&os,constWORD*pwszUTF16Str);
169. 
170. /*
171. 功能:将UTF8字符串以UTF16编码输出到流中
172. 返回值:
173. 写入的字节数
174. */
175. staticUINTPrint_UTF16Str_By_UTF8Str(ostream&os,constBYTE*pbszUTF8Str,BOOLisBigEndian=FALSE);
176. 
177. /*
178. 功能:向流中输出UTF8编码字节序标记
179. 返回值:
180. 写入的字节数
181. */
182. staticUINTPrint_UTF8_BOM(ostream&os);
183. 
184. /*
185. 功能:向流中输出UTF16编码字节序标记
186. 返回值:
187. 写入的字节数
188. */
189. staticUINTPrint_UTF16_BOM(ostream&os,BOOLisBigEndian=FALSE);
190. };
191. 
192. /*------------------------------
193. END
194. ------------------------------*/


UnicodeConverter.cpp



1. #include"UnicodeConverter.h"
2. 
3. /*-------------------------------------------------------------
4. 内码转换
5. -------------------------------------------------------------*/
6. 
7. //转换UCS4编码到UTF8编码
8. INTCUnicodeConverter::UCS4_To_UTF8(DWORDdwUCS4,BYTE*pbUTF8)
9. {
10. constBYTEabPrefix[]={0,0xC0,0xE0,0xF0,0xF8,0xFC};
11. constDWORDadwCodeUp[]={
12. 0x80,//U+00000000~U+0000007F
13. 0x800,//U+00000080~U+000007FF
14. 0x10000,//U+00000800~U+0000FFFF
15. 0x200000,//U+00010000~U+001FFFFF
16. 0x4000000,//U+00200000~U+03FFFFFF
17. 0x80000000//U+04000000~U+7FFFFFFF
18. };
19. 
20. INTi,iLen;
21. 
22. //根据UCS4编码范围确定对应的UTF-8编码字节数
23. iLen=sizeof(adwCodeUp)/sizeof(DWORD);
24. for(i=0;i<iLen;i++)
25. {
26. if(dwUCS4<adwCodeUp[i])
27. {
28. break;
29. }
30. }
31. 
32. if(i==iLen)return0;//无效的UCS4编码
33. 
34. iLen=i+1;//UTF-8编码字节数
35. if(pbUTF8!=NULL)
36. {//转换为UTF-8编码
37. for(;i>0;i--)
38. {
39. pbUTF8[i]=static_cast<BYTE>((dwUCS4&0x3F)|0x80);
40. dwUCS4>>=6;
41. }
42. 
43. pbUTF8[0]=static_cast<BYTE>(dwUCS4|abPrefix[iLen-1]);
44. }
45. 
46. returniLen;
47. }
48. 
49. //转换UTF8编码到UCS4编码
50. INTCUnicodeConverter::UTF8_To_UCS4(constBYTE*pbUTF8,DWORD&dwUCS4)
51. {
52. INTi,iLen;
53. BYTEb;
54. 
55. if(pbUTF8==NULL)
56. {//参数错误
57. return0;
58. }
59. 
60. b=*pbUTF8++;
61. if(b<0x80)
62. {
63. dwUCS4=b;
64. return1;
65. }
66. 
67. if(b<0xC0||b>0xFD)
68. {//非法UTF8
69. return0;
70. }
71. 
72. if(b<0xE0)
73. {
74. dwUCS4=b&0x1F;
75. iLen=2;
76. }
77. elseif(b<0xF0)
78. {
79. dwUCS4=b&0x0F;
80. iLen=3;
81. }
82. elseif(b<0xF8)
83. {
84. dwUCS4=b&7;
85. iLen=4;
86. }
87. elseif(b<0xFC)
88. {
89. dwUCS4=b&3;
90. iLen=5;
91. }
92. else
93. {
94. dwUCS4=b&1;
95. iLen=6;
96. }
97. 
98. for(i=1;i<iLen;i++)
99. {
100. b=*pbUTF8++;
101. if(b<0x80||b>0xBF)
102. {//非法UTF8
103. break;
104. }
105. 
106. dwUCS4=(dwUCS4<<6)+(b&0x3F);
107. }
108. 
109. if(i<iLen)
110. {//非法UTF8
111. return0;
112. }
113. else
114. {
115. returniLen;
116. }
117. }
118. 
119. //转换UCS4编码到UCS2编码
120. INTCUnicodeConverter::UCS4_To_UTF16(DWORDdwUCS4,WORD*pwUTF16)
121. {
122. if(dwUCS4<=0xFFFF)
123. {
124. if(pwUTF16!=NULL)
125. {
126. *pwUTF16=static_cast<WORD>(dwUCS4);
127. }
128. 
129. return1;
130. }
131. elseif(dwUCS4<=0xEFFFF)
132. {
133. if(pwUTF16!=NULL)
134. {
135. pwUTF16[0]=static_cast<WORD>(0xD800+(dwUCS4>>10)-0x40);//高10位
136. pwUTF16[1]=static_cast<WORD>(0xDC00+(dwUCS4&0x03FF));//低10位
137. }
138. 
139. return2;
140. }
141. else
142. {
143. return0;
144. }
145. }
146. 
147. //转换UCS2编码到UCS4编码
148. INTCUnicodeConverter::UTF16_To_UCS4(constWORD*pwUTF16,DWORD&dwUCS4)
149. {
150. WORDw1,w2;
151. 
152. if(pwUTF16==NULL)
153. {//参数错误
154. return0;
155. }
156. 
157. w1=pwUTF16[0];
158. if(w1>=0xD800&&w1<=0xDFFF)
159. {//编码在替代区域(SurrogateArea)
160. if(w1<0xDC00)
161. {
162. w2=pwUTF16[1];
163. if(w2>=0xDC00&&w2<=0xDFFF)
164. {
165. dwUCS4=(w2&0x03FF)+(((w1&0x03FF)+0x40)<<10);
166. return2;
167. }
168. }
169. 
170. return0;//非法UTF16编码
171. }
172. else
173. {
174. dwUCS4=w1;
175. return1;
176. }
177. }
178. 
179. //转换UTF8字符串到UTF16字符串
180. INTCUnicodeConverter::UTF8Str_To_UTF16Str(constBYTE*pbszUTF8Str,WORD*pwszUTF16Str)
181. {
182. INTiNum,iLen;
183. DWORDdwUCS4;
184. 
185. if(pbszUTF8Str==NULL)
186. {//参数错误
187. return0;
188. }
189. 
190. iNum=0;//统计有效字符个数
191. while(*pbszUTF8Str)
192. {//UTF8编码转换为UCS4编码
193. iLen=UTF8_To_UCS4(pbszUTF8Str,dwUCS4);
194. if(iLen==0)
195. {//非法的UTF8编码
196. return0;
197. }
198. 
199. pbszUTF8Str+=iLen;
200. 
201. //UCS4编码转换为UTF16编码
202. iLen=UCS4_To_UTF16(dwUCS4,pwszUTF16Str);
203. if(iLen==0)
204. {
205. return0;
206. }
207. 
208. if(pwszUTF16Str!=NULL)
209. {
210. pwszUTF16Str+=iLen;
211. }
212. 
213. iNum+=iLen;
214. }
215. 
216. if(pwszUTF16Str!=NULL)
217. {
218. *pwszUTF16Str=0;//写入字符串结束标记
219. }
220. 
221. returniNum;
222. }
223. 
224. //转换UTF16字符串到UTF8字符串
225. INTCUnicodeConverter::UTF16Str_To_UTF8Str(constWORD*pwszUTF16Str,BYTE*pbszUTF8Str)
226. {
227. INTiNum,iLen;
228. DWORDdwUCS4;
229. 
230. if(pwszUTF16Str==NULL)
231. {//参数错误
232. return0;
233. }
234. 
235. iNum=0;
236. while(*pwszUTF16Str)
237. {//UTF16编码转换为UCS4编码
238. iLen=UTF16_To_UCS4(pwszUTF16Str,dwUCS4);
239. if(iLen==0)
240. {//非法的UTF16编码
241. return0;
242. }
243. 
244. pwszUTF16Str+=iLen;
245. 
246. //UCS4编码转换为UTF8编码
247. iLen=UCS4_To_UTF8(dwUCS4,pbszUTF8Str);
248. if(iLen==0)
249. {
250. return0;
251. }
252. 
253. if(pbszUTF8Str!=NULL)
254. {
255. pbszUTF8Str+=iLen;
256. }
257. 
258. iNum+=iLen;
259. }
260. 
261. if(pbszUTF8Str!=NULL)
262. {
263. *pbszUTF8Str=0;//写入字符串结束标记
264. }
265. 
266. returniNum;
267. }
268. 
269. /*-------------------------------------------------------------
270. C文件写入操作
271. -------------------------------------------------------------*/
272. 
273. //向文件中输出UTF8编码
274. UINTCUnicodeConverter::Print_UTF8_By_UCS4(FILE*out,DWORDdwUCS4)
275. {
276. INTiLen;
277. BYTEabUTF8[8];
278. 
279. if(out==NULL)
280. {
281. return0;
282. }
283. 
284. iLen=UCS4_To_UTF8(dwUCS4,abUTF8);
285. if(iLen==0)return0;
286. 
287. fwrite(abUTF8,1,iLen,out);
288. 
289. returniLen;
290. }
291. 
292. //向文件中输出UTF16编码
293. UINTCUnicodeConverter::Print_UTF16_By_UCS4(FILE*out,DWORDdwUCS4,BOOLisBigEndian)
294. {
295. INTi,iLen;
296. WORDwCode,awUTF16[2];
297. 
298. if(out==NULL)
299. {
300. return0;
301. }
302. 
303. iLen=UCS4_To_UTF16(dwUCS4,awUTF16);
304. if(iLen==0)return0;
305. 
306. for(i=0;i<iLen;i++)
307. {
308. wCode=awUTF16[i];
309. if(isBigEndian)
310. {
311. fputc(wCode>>8,out);//输出高位
312. fputc(wCode&0xFF,out);//输出低位
313. }
314. else
315. {
316. fputc(wCode&0xFF,out);//输出低位
317. fputc(wCode>>8,out);//输出高位
318. }
319. }
320. 
321. return(iLen<<1);
322. }
323. 
324. //将UTF16字符串以UTF8编码输出到文件中
325. UINTCUnicodeConverter::Print_UTF8Str_By_UTF16Str(FILE*out,constWORD*pwszUTF16Str)
326. {
327. INTiCount,iLen;
328. DWORDdwUCS4;
329. 
330. if((out==NULL)||(pwszUTF16Str==NULL))
331. {
332. return0;
333. }
334. 
335. iCount=0;
336. while(*pwszUTF16Str)
337. {//将UTF16编码转换成UCS4编码
338. iLen=UTF16_To_UCS4(pwszUTF16Str,dwUCS4);
339. if(iLen==0)
340. {
341. break;
342. }
343. 
344. pwszUTF16Str+=iLen;
345. 
346. //向文件中输出UTF8编码
347. iCount+=Print_UTF8_By_UCS4(out,dwUCS4);
348. }
349. 
350. returniCount;//输出的字节数
351. }
352. 
353. //将UTF8字符串以UTF16编码输出到文件中
354. UINTCUnicodeConverter::Print_UTF16Str_By_UTF8Str(FILE*out,constBYTE*pbszUTF8Str,BOOLisBigEndian)
355. {
356. INTiCount,iLen;
357. DWORDdwUCS4;
358. 
359. if((out==NULL)||(pbszUTF8Str==NULL))
360. {
361. return0;
362. }
363. 
364. iCount=0;
365. while(*pbszUTF8Str)
366. {//将UTF16编码转换成UCS4编码
367. iLen=UTF8_To_UCS4(pbszUTF8Str,dwUCS4);
368. if(iLen==0)
369. {
370. break;
371. }
372. 
373. pbszUTF8Str+=iLen;
374. 
375. //向文件中输出UTF8编码
376. iCount+=Print_UTF16_By_UCS4(out,dwUCS4,isBigEndian);
377. }
378. 
379. returniCount;//输出的字节数
380. }
381. 
382. //向文件中输出UTF8字节序标记
383. UINTCUnicodeConverter::Print_UTF8_BOM(FILE*out)
384. {
385. if(out==NULL)
386. {
387. return0;
388. }
389. 
390. fputc(0xEF,out);
391. fputc(0xBB,out);
392. fputc(0xBF,out);
393. 
394. return3;
395. }
396. 
397. //向文件中输出UTF16字节序标记
398. UINTCUnicodeConverter::Print_UTF16_BOM(FILE*out,BOOLisBigEndian)
399. {
400. if(out==NULL)
401. {
402. return0;
403. }
404. 
405. if(isBigEndian)
406. {
407. fputc(0xFE,out);
408. fputc(0xFF,out);
409. }
410. else
411. {
412. fputc(0xFF,out);
413. fputc(0xFE,out);
414. }
415. 
416. return2;
417. }
418. 
419. /*-------------------------------------------------------------
420. C++流输出操作
421. -------------------------------------------------------------*/
422. 
423. //向流中输出UTF8编码
424. UINTCUnicodeConverter::Print_UTF8_By_UCS4(ostream&os,DWORDdwUCS4)
425. {
426. INTiLen;
427. BYTEabUTF8[8];
428. 
429. if(!os)return0;
430. 
431. iLen=UCS4_To_UTF8(dwUCS4,abUTF8);
432. if(iLen==0)return0;
433. 
434. os.write(reinterpret_cast<CHAR*>(abUTF8),iLen);
435. 
436. returniLen;
437. }
438. 
439. //向流中输出UTF16编码
440. UINTCUnicodeConverter::Print_UTF16_By_UCS4(ostream&os,DWORDdwUCS4,BOOLisBigEndian)
441. {
442. INTi,iLen;
443. WORDwCode,awUTF16[2];
444. 
445. if(!os)return0;
446. 
447. iLen=UCS4_To_UTF16(dwUCS4,awUTF16);
448. if(iLen==0)return0;
449. 
450. for(i=0;i<iLen;i++)
451. {
452. wCode=awUTF16[i];
453. if(isBigEndian)
454. {
455. os.put(wCode>>8);//输出高位
456. os.put(wCode&0xFF);//输出低位
457. }
458. else
459. {
460. os.put(wCode&0xFF);//输出低位
461. os.put(wCode>>8);//输出高位
462. }
463. }
464. 
465. return(iLen<<1);
466. }
467. 
468. //将UTF16字符串以UTF8编码输出到流中
469. UINTCUnicodeConverter::Print_UTF8Str_By_UTF16Str(ostream&os,constWORD*pwszUTF16Str)
470. {
471. INTiCount,iLen;
472. DWORDdwUCS4;
473. 
474. if(!os||(pwszUTF16Str==NULL))return0;
475. 
476. iCount=0;
477. while(*pwszUTF16Str)
478. {//将UTF16编码转换成UCS4编码
479. iLen=UTF16_To_UCS4(pwszUTF16Str,dwUCS4);
480. if(iLen==0)
481. {
482. break;
483. }
484. 
485. pwszUTF16Str+=iLen;
486. 
487. //向流中输出UTF8编码
488. iCount+=Print_UTF8_By_UCS4(os,dwUCS4);
489. }
490. 
491. returniCount;//输出的字节数
492. }
493. 
494. //将UTF8字符串以UTF16编码输出到流中
495. UINTCUnicodeConverter::Print_UTF16Str_By_UTF8Str(ostream&os,constBYTE*pbszUTF8Str,BOOLisBigEndian)
496. {
497. INTiCount,iLen;
498. DWORDdwUCS4;
499. 
500. if(!os||(pbszUTF8Str==NULL))return0;
501. 
502. iCount=0;
503. while(*pbszUTF8Str)
504. {//将UTF16编码转换成UCS4编码
505. iLen=UTF8_To_UCS4(pbszUTF8Str,dwUCS4);
506. if(iLen==0)
507. {
508. break;
509. }
510. 
511. pbszUTF8Str+=iLen;
512. 
513. //向流中输出UTF8编码
514. iCount+=Print_UTF16_By_UCS4(os,dwUCS4,isBigEndian);
515. }
516. 
517. returniCount;//输出的字节数
518. }
519. 
520. //向流中输出UTF8字节序标记
521. UINTCUnicodeConverter::Print_UTF8_BOM(ostream&os)
522. {
523. if(!os)return0;
524. 
525. os.put(0xEF);
526. os.put(0xBB);
527. os.put(0xBF);
528. 
529. return3;
530. }
531. 
532. //向流中输出UTF16字节序标记
533. UINTCUnicodeConverter::Print_UTF16_BOM(ostream&os,BOOLisBigEndian)
534. {
535. if(!os)return0;
536. 
537. if(isBigEndian)
538. {
539. os.put(0xFE);
540. os.put(0xFF);
541. }
542. else
543. {
544. os.put(0xFF);
545. os.put(0xFE);
546. }
547. 
548. return2;
549. }
550. 
551. /*------------------------------
552. END
553. ------------------------------*/