開發語言:C++
功能描述:
Unicode內碼轉換器。用於UTF-8、UTF-16(UCS2)、UTF-32(UCS4)之間的編碼轉換。
下載地址:
UnicodeConverter.zip
版本歷史:
V1.0 2010年03月12日
完成正式版本。
源代碼:
UnicodeConverter.h
001
/* ----------------------------------------------------------
002
文件名稱:UnicodeConverter.h
003
004
作者:秦建輝
005
006
MSN:[email protected]
007
008
當前版本:V1.0
009
010
歷史版本:
011
V1.0 2010年03月12日
012
完成正式版本。
013
014
功能描述:
015
Unicode內碼轉換器。用於utf-8、utf-16(UCS2)、utf-32(UCS4)之間的編碼轉換
016
------------------------------------------------------------ */
017
#pragma once
018
019
#include <windows.h>
020
#include <stdio.h>
021
#include <ostream>
022
023
using namespace std;
024
025
class CUnicodeConverter
026
{
027
/* -------------------------------------------------------------
028
內碼轉換
029
------------------------------------------------------------- */
030
public:
031
/*
032
功能:將UCS4編碼轉換成UTF8編碼
033
參數:
034
dwUCS4:要轉換的UCS4編碼
035
pbUTF8:用於存儲轉換後的UTF8編碼。設為NULL,可以獲取長度信息(字節數)
036
返回值:
037
0:無效的UCS4編碼
038
1-6:UTF8編碼的有效長度
039
*/
040
static INT UCS4_To_UTF8( DWORD dwUCS4, BYTE* pbUTF8 );
041
042
/*
043
功能:將UTF8編碼轉換成UCS4編碼
044
參數:
045
pbUTF8:要轉換的UTF8編碼
046
dwUCS4:存儲轉換後的UCS4編碼
047
返回值:
048
0:參數錯誤或無效的UTF8編碼
049
1-6:UTF8編碼的有效長度
050
*/
051
static INT UTF8_To_UCS4( const BYTE* pbUTF8, DWORD& dwUCS4 );
052
053
/*
054
功能:將UCS4編碼轉換成UTF16編碼
055
參數:
056
dwUCS4:要轉換的UCS4編碼
057
pwUTF16:用於存儲轉換後的UTF16編碼。設為NULL,可以獲取長度信息(字符數)
058
返回值:
059
0:無效的UCS4編碼
060
1:轉換成1個UTF16編碼
061
2:轉換成2個UTF16編碼
062
*/
063
static INT UCS4_To_UTF16( DWORD dwUCS4, WORD* pwUTF16 );
064
065
/*
066
功能:將UTF16編碼轉換成UCS4編碼
067
參數:
068
pwUTF16:需要轉換的UTF16編碼
069
dwUCS4:存儲轉換後的UCS4編碼
070
返回值:
071
0:參數錯誤或無效的UTF16編碼
072
1:1個UTF16編碼被轉換
073
2:2個UTF16編碼被轉換
074
*/
075
static INT UTF16_To_UCS4( const WORD* pwUTF16, DWORD& dwUCS4 );
076
077
/*
078
功能:將UTF8字符串轉換成UTF16字符串
079
參數:
080
pbszUTF8Str:需要轉換的UTF8字符串
081
pwszUTF16Str:存儲轉換後的UTF16字符串。設為NULL,可以獲取所需長度信息(字符數)
082
返回值:
083
0:轉換失敗
084
>0:UTF16字符串長度
085
*/
086
static INT UTF8Str_To_UTF16Str( const BYTE* pbszUTF8Str, WORD* pwszUTF16Str );
087
088
/*
089
功能:將UTF16字符串轉換成UTF8字符串
090
參數:
091
pwszUTF16Str:需要轉換的UTF16字符串
092
pbszUTF8Str:存儲轉換後的UTF8字符串。設為NULL,可以獲取所需長度信息(字節數)
093
返回值:
094
0:轉換失敗
095
>0:UTF8字符串長度(不包括NULL字符)
096
*/
097
static INT UTF16Str_To_UTF8Str( const WORD* pwszUTF16Str, BYTE* pbszUTF8Str );
098
099
/* -------------------------------------------------------------
100
C文件寫入操作
101
------------------------------------------------------------- */
102
public:
103
/*
104
功能:向文件中寫入UTF8編碼
105
返回值:
106
寫入的字節數
107
*/
108
static UINT Print_UTF8_By_UCS4( FILE* out, DWORD dwUCS4 );
109
110
/*
111
功能:向文件中寫入UTF16編碼
112
返回值:
113
寫入的字節數
114
*/
115
static UINT Print_UTF16_By_UCS4( FILE* out, DWORD dwUCS4, BOOL isBigEndian = FALSE );
116
117
/*
118
功能:將UTF16字符串以UTF8編碼輸出到文件中
119
返回值:
120
寫入的字節數
121
*/
122
static UINT Print_UTF8Str_By_UTF16Str( FILE* out, const WORD* pwszUTF16Str );
123
124
/*
125
功能:將UTF8字符串以UTF16編碼輸出到文件中
126
返回值:
127
寫入的字節數
128
*/
129
static UINT Print_UTF16Str_By_UTF8Str( FILE* out, const BYTE* pbszUTF8Str, BOOL isBigEndian = FALSE );
130
131
/*
132
功能:向文件中輸出UTF8編碼字節序標記
133
返回值:
134
寫入的字節數
135
*/
136
static UINT Print_UTF8_BOM( FILE* out );
137
138
/*
139
功能:向文件中輸出UTF16編碼字節序標記
140
返回值:
141
寫入的字節數
142
*/
143
static UINT Print_UTF16_BOM( FILE* out, BOOL isBigEndian = FALSE );
144
145
/* -------------------------------------------------------------
146
C++流輸出操作
147
------------------------------------------------------------- */
148
public:
149
/*
150
功能:向流中寫入UTF8編碼
151
返回值:
152
寫入的字節數
153
*/
154
static UINT Print_UTF8_By_UCS4( ostream& os, DWORD dwUCS4 );
155
156
/*
157
功能:向流中寫入UTF16編碼
158
返回值:
159
寫入的字節數
160
*/
161
static UINT Print_UTF16_By_UCS4( ostream& os, DWORD dwUCS4, BOOL isBigEndian = FALSE );
162
163
/*
164
功能:將UTF16字符串以UTF8編碼輸出到流中
165
返回值:
166
寫入的字節數
167
*/
168
static UINT Print_UTF8Str_By_UTF16Str( ostream& os, const WORD* pwszUTF16Str );
169
170
/*
171
功能:將UTF8字符串以UTF16編碼輸出到流中
172
返回值:
173
寫入的字節數
174
*/
175
static UINT Print_UTF16Str_By_UTF8Str( ostream& os, const BYTE* pbszUTF8Str, BOOL isBigEndian = FALSE );
176
177
/*
178
功能:向流中輸出UTF8編碼字節序標記
179
返回值:
180
寫入的字節數
181
*/
182
static UINT Print_UTF8_BOM( ostream& os );
183
184
/*
185
功能:向流中輸出UTF16編碼字節序標記
186
返回值:
187
寫入的字節數
188
*/
189
static UINT Print_UTF16_BOM( ostream& os, BOOL isBigEndian = FALSE );
190
};
191
192
/* ------------------------------
193
END
194
------------------------------ */
UnicodeConverter.cpp
view sourceprint?
001
#include "UnicodeConverter.h"
002
003
/* -------------------------------------------------------------
004
內碼轉換
005
------------------------------------------------------------- */
006
007
// 轉換UCS4編碼到UTF8編碼
008
INT CUnicodeConverter::UCS4_To_UTF8( DWORD dwUCS4, BYTE* pbUTF8 )
009
{
010
const BYTE abPrefix[] = {0, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
011
const DWORD adwCodeUp[] = {
012
0x80, // U+00000000 ~ U+0000007F
013
0x800, // U+00000080 ~ U+000007FF
014
0x10000, // U+00000800 ~ U+0000FFFF
015
0x200000, // U+00010000 ~ U+001FFFFF
016
0x4000000, // U+00200000 ~ U+03FFFFFF
017
0x80000000 // U+04000000 ~ U+7FFFFFFF
018
};
019
020
INT i, iLen;
021
022
// 根據UCS4編碼范圍確定對應的UTF-8編碼字節數
023
iLen = sizeof(adwCodeUp) / sizeof(DWORD);
024
for( i = 0; i < iLen; i++ )
025
{
026
if( dwUCS4 < adwCodeUp[i] )
027
{
028
break;
029
}
030
}
031
032
if( i == iLen )return 0; // 無效的UCS4編碼
033
034
iLen = i + 1; // UTF-8編碼字節數
035
if( pbUTF8 != NULL )
036
{ // 轉換為UTF-8編碼
037
for( ; i > 0; i-- )
038
{
039
pbUTF8[i] = static_cast<BYTE>((dwUCS4 & 0x3F) | 0x80);
040
dwUCS4 >>= 6;
041
}
042
043
pbUTF8[0] = static_cast<BYTE>(dwUCS4 | abPrefix[iLen - 1]);
044
}
045
046
return iLen;
047
}
048
049
// 轉換UTF8編碼到UCS4編碼
050
INT CUnicodeConverter::UTF8_To_UCS4( const BYTE* pbUTF8, DWORD& dwUCS4 )
051
{
052
INT i, iLen;
053
BYTE b;
054
055
if( pbUTF8 == NULL )
056
{ // 參數錯誤
057
return 0;
058
}
059
060
b = *pbUTF8++;
061
if( b < 0x80 )
062
{
063
dwUCS4 = b;
064
return 1;
065
}
066
067
if( b < 0xC0 || b > 0xFD )
068
{ // 非法UTF8
069
return 0;
070
}
071
072
if( b < 0xE0 )
073
{
074
dwUCS4 = b & 0x1F;
075
iLen = 2;
076
}
077
else if( b < 0xF0 )
078
{
079
dwUCS4 = b & 0x0F;
080
iLen = 3;
081
}
082
else if( b < 0xF8 )
083
{
084
dwUCS4 = b & 7;
085
iLen = 4;
086
}
087
else if( b < 0xFC )
088
{
089
dwUCS4 = b & 3;
090
iLen = 5;
091
}
092
else
093
{
094
dwUCS4 = b & 1;
095
iLen = 6;
096
}
097
098
for( i = 1; i < iLen; i++ )
099
{
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
return 0;
112
}
113
else
114
{
115
return iLen;
116
}
117
}
118
119
// 轉換UCS4編碼到UCS2編碼
120
INT CUnicodeConverter::UCS4_To_UTF16( DWORD dwUCS4, WORD* pwUTF16 )
121
{
122
if( dwUCS4 <= 0xFFFF )
123
{
124
if( pwUTF16 != NULL )
125
{
126
*pwUTF16 = static_cast<WORD>(dwUCS4);
127
}
128
129
return 1;
130
}
131
else if( 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
return 2;
140
}
141
else
142
{
143
return 0;
144
}
145
}
146
147
// 轉換UCS2編碼到UCS4編碼
148
INT CUnicodeConverter::UTF16_To_UCS4( const WORD* pwUTF16, DWORD& dwUCS4 )
149
{
150
WORD w1, w2;
151
152
if( pwUTF16 == NULL )
153
{ // 參數錯誤
154
return 0;
155
}
156
157
w1 = pwUTF16[0];
158
if( w1 >= 0xD800 && w1 <= 0xDFFF )
159
{ // 編碼在替代區域(Surrogate Area)
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
return 2;
167
}
168
}
169
170
return 0; // 非法UTF16編碼
171
}
172
else
173
{
174
dwUCS4 = w1;
175
return 1;
176
}
177
}
178
179
// 轉換UTF8字符串到UTF16字符串
180
INT CUnicodeConverter::UTF8Str_To_UTF16Str( const BYTE* pbszUTF8Str, WORD* pwszUTF16Str )
181
{
182
INT iNum, iLen;
183
DWORD dwUCS4;
184
185
if( pbszUTF8Str == NULL )
186
{ // 參數錯誤
187
return 0;
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
return 0;
197
}
198
199
pbszUTF8Str += iLen;
200
201
// UCS4編碼轉換為UTF16編碼
202
iLen = UCS4_To_UTF16( dwUCS4, pwszUTF16Str );
203
if( iLen == 0 )
204
{
205
return 0;
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
return iNum;
222
}
223
224
// 轉換UTF16字符串到UTF8字符串
225
INT CUnicodeConverter::UTF16Str_To_UTF8Str( const WORD* pwszUTF16Str, BYTE* pbszUTF8Str )
226
{
227
INT iNum, iLen;
228
DWORD dwUCS4;
229
230
if( pwszUTF16Str == NULL )
231
{ // 參數錯誤
232
return 0;
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
return 0;
242
}
243
244
pwszUTF16Str += iLen;
245
246
// UCS4編碼轉換為UTF8編碼
247
iLen = UCS4_To_UTF8( dwUCS4, pbszUTF8Str );
248
if( iLen == 0 )
249
{
250
return 0;
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
return iNum;
267
}
268
269
/* -------------------------------------------------------------
270
C文件寫入操作
271
------------------------------------------------------------- */
272
273
// 向文件中輸出UTF8編碼
274
UINT CUnicodeConverter::Print_UTF8_By_UCS4( FILE* out, DWORD dwUCS4 )
275
{
276
INT iLen;
277
BYTE abUTF8[8];
278
279
if( out == NULL )
280
{
281
return 0;
282
}
283
284
iLen = UCS4_To_UTF8( dwUCS4, abUTF8 );
285
if( iLen == 0 )return 0;
286
287
fwrite( abUTF8, 1, iLen, out );
288
289
return iLen;
290
}
291
292
// 向文件中輸出UTF16編碼
293
UINT CUnicodeConverter::Print_UTF16_By_UCS4( FILE* out, DWORD dwUCS4, BOOL isBigEndian )
294
{
295
INT i, iLen;
296
WORD wCode, awUTF16[2];
297
298
if( out == NULL )
299
{
300
return 0;
301
}
302
303
iLen = UCS4_To_UTF16( dwUCS4, awUTF16 );
304
if( iLen == 0 )return 0;
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
UINT CUnicodeConverter::Print_UTF8Str_By_UTF16Str( FILE* out, const WORD* pwszUTF16Str )
326
{
327
INT iCount, iLen;
328
DWORD dwUCS4;
329
330
if( (out == NULL) || (pwszUTF16Str == NULL) )
331
{
332
return 0;
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
return iCount; // 輸出的字節數
351
}
352
353
// 將UTF8字符串以UTF16編碼輸出到文件中
354
UINT CUnicodeConverter::Print_UTF16Str_By_UTF8Str( FILE* out, const BYTE* pbszUTF8Str, BOOL isBigEndian )
355
{
356
INT iCount, iLen;
357
DWORD dwUCS4;
358
359
if( (out == NULL) || (pbszUTF8Str == NULL) )
360
{
361
return 0;
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
return iCount; // 輸出的字節數
380
}
381
382
// 向文件中輸出UTF8字節序標記
383
UINT CUnicodeConverter::Print_UTF8_BOM( FILE* out )
384
{
385
if( out == NULL )
386
{
387
return 0;
388
}
389
390
fputc( 0xEF, out );
391
fputc( 0xBB, out );
392
fputc( 0xBF, out );
393
394
return 3;
395
}
396
397
// 向文件中輸出UTF16字節序標記
398
UINT CUnicodeConverter::Print_UTF16_BOM( FILE* out, BOOL isBigEndian )
399
{
400
if( out == NULL )
401
{
402
return 0;
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
return 2;
417
}
418
419
/* -------------------------------------------------------------
420
C++流輸出操作
421
------------------------------------------------------------- */
422
423
// 向流中輸出UTF8編碼
424
UINT CUnicodeConverter::Print_UTF8_By_UCS4( ostream& os, DWORD dwUCS4 )
425
{
426
INT iLen;
427
BYTE abUTF8[8];
428
429
if( !os )return 0;
430
431
iLen = UCS4_To_UTF8( dwUCS4, abUTF8 );
432
if( iLen == 0 )return 0;
433
434
os.write( reinterpret_cast<CHAR*>(abUTF8), iLen );
435
436
return iLen;
437
}
438
439
// 向流中輸出UTF16編碼
440
UINT CUnicodeConverter::Print_UTF16_By_UCS4( ostream& os, DWORD dwUCS4, BOOL isBigEndian )
441
{
442
INT i, iLen;
443
WORD wCode, awUTF16[2];
444
445
if( !os )return 0;
446
447
iLen = UCS4_To_UTF16( dwUCS4, awUTF16 );
448
if( iLen == 0 )return 0;
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
UINT CUnicodeConverter::Print_UTF8Str_By_UTF16Str( ostream& os, const WORD* pwszUTF16Str )
470
{
471
INT iCount, iLen;
472
DWORD dwUCS4;
473
474
if( !os || (pwszUTF16Str == NULL) )return 0;
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
return iCount; // 輸出的字節數
492
}
493
494
// 將UTF8字符串以UTF16編碼輸出到流中
495
UINT CUnicodeConverter::Print_UTF16Str_By_UTF8Str( ostream& os, const BYTE* pbszUTF8Str, BOOL isBigEndian )
496
{
497
INT iCount, iLen;
498
DWORD dwUCS4;
499
500
if( !os || (pbszUTF8Str == NULL) )return 0;
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
return iCount; // 輸出的字節數
518
}
519
520
// 向流中輸出UTF8字節序標記
521
UINT CUnicodeConverter::Print_UTF8_BOM( ostream& os )
522
{
523
if( !os )return 0;
524
525
os.put( 0xEF );
526
os.put( 0xBB );
527
os.put( 0xBF );
528
529
return 3;
530
}
531
532
// 向流中輸出UTF16字節序標記
533
UINT CUnicodeConverter::Print_UTF16_BOM( ostream& os, BOOL isBigEndian )
534
{
535
if( !os )return 0;
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
return 2;
549
}
550
551
/* ------------------------------
552
END
553
------------------------------ */