1 : /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * jeroen.dobbelaere@acunia.com
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 : #include "unicpriv.h"
39 : /*=================================================================================
40 :
41 : =================================================================================*/
42 : typedef PRBool (*uSubGeneratorFunc) (PRUint16 in, unsigned char* out);
43 : /*=================================================================================
44 :
45 : =================================================================================*/
46 :
47 : typedef PRBool (*uGeneratorFunc) (
48 : PRInt32* state,
49 : PRUint16 in,
50 : unsigned char* out,
51 : PRUint32 outbuflen,
52 : PRUint32* outlen
53 : );
54 :
55 : MODULE_PRIVATE PRBool uGenerate(
56 : uScanClassID scanClass,
57 : PRInt32* state,
58 : PRUint16 in,
59 : unsigned char* out,
60 : PRUint32 outbuflen,
61 : PRUint32* outlen
62 : );
63 :
64 : #define uSubGenerator(sub,in,out) (* m_subgenerator[sub])((in),(out))
65 :
66 : PRIVATE PRBool uCheckAndGenAlways1Byte(
67 : PRInt32* state,
68 : PRUint16 in,
69 : unsigned char* out,
70 : PRUint32 outbuflen,
71 : PRUint32* outlen
72 : );
73 : PRIVATE PRBool uCheckAndGenAlways2Byte(
74 : PRInt32* state,
75 : PRUint16 in,
76 : unsigned char* out,
77 : PRUint32 outbuflen,
78 : PRUint32* outlen
79 : );
80 : PRIVATE PRBool uCheckAndGenAlways2ByteShiftGR(
81 : PRInt32* state,
82 : PRUint16 in,
83 : unsigned char* out,
84 : PRUint32 outbuflen,
85 : PRUint32* outlen
86 : );
87 : MODULE_PRIVATE PRBool uGenerateShift(
88 : uShiftOutTable *shift,
89 : PRInt32* state,
90 : PRUint16 in,
91 : unsigned char* out,
92 : PRUint32 outbuflen,
93 : PRUint32* outlen
94 : );
95 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8F(
96 : PRInt32* state,
97 : PRUint16 in,
98 : unsigned char* out,
99 : PRUint32 outbuflen,
100 : PRUint32* outlen
101 : );
102 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA2(
103 : PRInt32* state,
104 : PRUint16 in,
105 : unsigned char* out,
106 : PRUint32 outbuflen,
107 : PRUint32* outlen
108 : );
109 :
110 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA3(
111 : PRInt32* state,
112 : PRUint16 in,
113 : unsigned char* out,
114 : PRUint32 outbuflen,
115 : PRUint32* outlen
116 : );
117 :
118 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA4(
119 : PRInt32* state,
120 : PRUint16 in,
121 : unsigned char* out,
122 : PRUint32 outbuflen,
123 : PRUint32* outlen
124 : );
125 :
126 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA5(
127 : PRInt32* state,
128 : PRUint16 in,
129 : unsigned char* out,
130 : PRUint32 outbuflen,
131 : PRUint32* outlen
132 : );
133 :
134 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA6(
135 : PRInt32* state,
136 : PRUint16 in,
137 : unsigned char* out,
138 : PRUint32 outbuflen,
139 : PRUint32* outlen
140 : );
141 :
142 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA7(
143 : PRInt32* state,
144 : PRUint16 in,
145 : unsigned char* out,
146 : PRUint32 outbuflen,
147 : PRUint32* outlen
148 : );
149 : PRIVATE PRBool uCnGAlways8BytesDecomposedHangul(
150 : PRInt32* state,
151 : PRUint16 in,
152 : unsigned char* out,
153 : PRUint32 outbuflen,
154 : PRUint32* outlen
155 : );
156 :
157 : PRIVATE PRBool uCheckAndGenJohabHangul(
158 : PRInt32* state,
159 : PRUint16 in,
160 : unsigned char* out,
161 : PRUint32 outbuflen,
162 : PRUint32* outlen
163 : );
164 :
165 : PRIVATE PRBool uCheckAndGenJohabSymbol(
166 : PRInt32* state,
167 : PRUint16 in,
168 : unsigned char* out,
169 : PRUint32 outbuflen,
170 : PRUint32* outlen
171 : );
172 :
173 :
174 : PRIVATE PRBool uCheckAndGen4BytesGB18030(
175 : PRInt32* state,
176 : PRUint16 in,
177 : unsigned char* out,
178 : PRUint32 outbuflen,
179 : PRUint32* outlen
180 : );
181 :
182 : PRIVATE PRBool uGenAlways2Byte(
183 : PRUint16 in,
184 : unsigned char* out
185 : );
186 : PRIVATE PRBool uGenAlways2ByteShiftGR(
187 : PRUint16 in,
188 : unsigned char* out
189 : );
190 : PRIVATE PRBool uGenAlways1Byte(
191 : PRUint16 in,
192 : unsigned char* out
193 : );
194 : PRIVATE PRBool uGenAlways1BytePrefix8E(
195 : PRUint16 in,
196 : unsigned char* out
197 : );
198 : /*=================================================================================
199 :
200 : =================================================================================*/
201 : PRIVATE const uGeneratorFunc m_generator[uNumOfCharsetType] =
202 : {
203 : uCheckAndGenAlways1Byte,
204 : uCheckAndGenAlways2Byte,
205 : uCheckAndGenAlways2ByteShiftGR,
206 : uCheckAndGen2ByteGRPrefix8F,
207 : uCheckAndGen2ByteGRPrefix8EA2,
208 : uCheckAndGen2ByteGRPrefix8EA3,
209 : uCheckAndGen2ByteGRPrefix8EA4,
210 : uCheckAndGen2ByteGRPrefix8EA5,
211 : uCheckAndGen2ByteGRPrefix8EA6,
212 : uCheckAndGen2ByteGRPrefix8EA7,
213 : uCnGAlways8BytesDecomposedHangul,
214 : uCheckAndGenJohabHangul,
215 : uCheckAndGenJohabSymbol,
216 : uCheckAndGen4BytesGB18030,
217 : uCheckAndGenAlways2Byte /* place-holder for GR128 */
218 : };
219 :
220 : /*=================================================================================
221 :
222 : =================================================================================*/
223 :
224 : PRIVATE const uSubGeneratorFunc m_subgenerator[uNumOfCharType] =
225 : {
226 : uGenAlways1Byte,
227 : uGenAlways2Byte,
228 : uGenAlways2ByteShiftGR,
229 : uGenAlways1BytePrefix8E
230 :
231 : };
232 : /*=================================================================================
233 :
234 : =================================================================================*/
235 205786 : MODULE_PRIVATE PRBool uGenerate(
236 : uScanClassID scanClass,
237 : PRInt32* state,
238 : PRUint16 in,
239 : unsigned char* out,
240 : PRUint32 outbuflen,
241 : PRUint32* outlen
242 : )
243 : {
244 205786 : return (* m_generator[scanClass]) (state,in,out,outbuflen,outlen);
245 : }
246 : /*=================================================================================
247 :
248 : =================================================================================*/
249 22 : PRIVATE PRBool uGenAlways1Byte(
250 : PRUint16 in,
251 : unsigned char* out
252 : )
253 : {
254 22 : out[0] = (unsigned char)in;
255 22 : return PR_TRUE;
256 : }
257 :
258 : /*=================================================================================
259 :
260 : =================================================================================*/
261 0 : PRIVATE PRBool uGenAlways2Byte(
262 : PRUint16 in,
263 : unsigned char* out
264 : )
265 : {
266 0 : out[0] = (unsigned char)((in >> 8) & 0xff);
267 0 : out[1] = (unsigned char)(in & 0xff);
268 0 : return PR_TRUE;
269 : }
270 : /*=================================================================================
271 :
272 : =================================================================================*/
273 0 : PRIVATE PRBool uGenAlways2ByteShiftGR(
274 : PRUint16 in,
275 : unsigned char* out
276 : )
277 : {
278 0 : out[0] = (unsigned char)(((in >> 8) & 0xff) | 0x80);
279 0 : out[1] = (unsigned char)((in & 0xff) | 0x80);
280 0 : return PR_TRUE;
281 : }
282 : /*=================================================================================
283 :
284 : =================================================================================*/
285 0 : PRIVATE PRBool uGenAlways1BytePrefix8E(
286 : PRUint16 in,
287 : unsigned char* out
288 : )
289 : {
290 0 : out[0] = 0x8E;
291 0 : out[1] = (unsigned char)(in & 0xff);
292 0 : return PR_TRUE;
293 : }
294 : /*=================================================================================
295 :
296 : =================================================================================*/
297 205662 : PRIVATE PRBool uCheckAndGenAlways1Byte(
298 : PRInt32* state,
299 : PRUint16 in,
300 : unsigned char* out,
301 : PRUint32 outbuflen,
302 : PRUint32* outlen
303 : )
304 : {
305 : /* Don't check inlen. The caller should ensure it is larger than 0 */
306 : /* Oops, I don't agree. Code changed to check every time. [CATA] */
307 205662 : if(outbuflen < 1)
308 0 : return PR_FALSE;
309 : else
310 : {
311 205662 : *outlen = 1;
312 205662 : out[0] = in & 0xff;
313 205662 : return PR_TRUE;
314 : }
315 : }
316 :
317 : /*=================================================================================
318 :
319 : =================================================================================*/
320 124 : PRIVATE PRBool uCheckAndGenAlways2Byte(
321 : PRInt32* state,
322 : PRUint16 in,
323 : unsigned char* out,
324 : PRUint32 outbuflen,
325 : PRUint32* outlen
326 : )
327 : {
328 124 : if(outbuflen < 2)
329 0 : return PR_FALSE;
330 : else
331 : {
332 124 : *outlen = 2;
333 124 : out[0] = ((in >> 8 ) & 0xff);
334 124 : out[1] = in & 0xff;
335 124 : return PR_TRUE;
336 : }
337 : }
338 : /*=================================================================================
339 :
340 : =================================================================================*/
341 0 : PRIVATE PRBool uCheckAndGenAlways2ByteShiftGR(
342 : PRInt32* state,
343 : PRUint16 in,
344 : unsigned char* out,
345 : PRUint32 outbuflen,
346 : PRUint32* outlen
347 : )
348 : {
349 0 : if(outbuflen < 2)
350 0 : return PR_FALSE;
351 : else
352 : {
353 0 : *outlen = 2;
354 0 : out[0] = ((in >> 8 ) & 0xff) | 0x80;
355 0 : out[1] = (in & 0xff) | 0x80;
356 0 : return PR_TRUE;
357 : }
358 : }
359 : /*=================================================================================
360 :
361 : =================================================================================*/
362 22 : MODULE_PRIVATE PRBool uGenerateShift(
363 : uShiftOutTable *shift,
364 : PRInt32* state,
365 : PRUint16 in,
366 : unsigned char* out,
367 : PRUint32 outbuflen,
368 : PRUint32* outlen
369 : )
370 : {
371 : PRInt16 i;
372 22 : const uShiftOutCell* cell = &(shift->shiftcell[0]);
373 22 : PRInt16 itemnum = shift->numOfItem;
374 : unsigned char inH, inL;
375 22 : inH = (in >> 8) & 0xff;
376 22 : inL = (in & 0xff );
377 22 : for(i=0;i<itemnum;i++)
378 : {
379 44 : if( ( inL >= cell[i].shiftout_MinLB) &&
380 44 : ( inL <= cell[i].shiftout_MaxLB) &&
381 44 : ( inH >= cell[i].shiftout_MinHB) &&
382 22 : ( inH <= cell[i].shiftout_MaxHB) )
383 : {
384 22 : if(outbuflen < cell[i].reserveLen)
385 : {
386 0 : return PR_FALSE;
387 : }
388 : else
389 : {
390 22 : *outlen = cell[i].reserveLen;
391 22 : return (uSubGenerator(cell[i].classID,in,out));
392 : }
393 : }
394 : }
395 0 : return PR_FALSE;
396 : }
397 : /*=================================================================================
398 :
399 : =================================================================================*/
400 0 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8F( PRInt32* state,
401 : PRUint16 in,
402 : unsigned char* out,
403 : PRUint32 outbuflen,
404 : PRUint32* outlen
405 : )
406 : {
407 0 : if(outbuflen < 3)
408 0 : return PR_FALSE;
409 : else
410 : {
411 0 : *outlen = 3;
412 0 : out[0] = 0x8F;
413 0 : out[1] = ((in >> 8 ) & 0xff) | 0x80;
414 0 : out[2] = (in & 0xff) | 0x80;
415 0 : return PR_TRUE;
416 : }
417 : }
418 : /*=================================================================================
419 :
420 : =================================================================================*/
421 0 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA2( PRInt32* state,
422 : PRUint16 in,
423 : unsigned char* out,
424 : PRUint32 outbuflen,
425 : PRUint32* outlen
426 : )
427 : {
428 0 : if(outbuflen < 4)
429 0 : return PR_FALSE;
430 : else
431 : {
432 0 : *outlen = 4;
433 0 : out[0] = 0x8E;
434 0 : out[1] = 0xA2;
435 0 : out[2] = ((in >> 8 ) & 0xff) | 0x80;
436 0 : out[3] = (in & 0xff) | 0x80;
437 0 : return PR_TRUE;
438 : }
439 : }
440 :
441 :
442 : /*=================================================================================
443 :
444 : =================================================================================*/
445 0 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA3( PRInt32* state,
446 : PRUint16 in,
447 : unsigned char* out,
448 : PRUint32 outbuflen,
449 : PRUint32* outlen
450 : )
451 : {
452 0 : if(outbuflen < 4)
453 0 : return PR_FALSE;
454 : else
455 : {
456 0 : *outlen = 4;
457 0 : out[0] = 0x8E;
458 0 : out[1] = 0xA3;
459 0 : out[2] = ((in >> 8 ) & 0xff) | 0x80;
460 0 : out[3] = (in & 0xff) | 0x80;
461 0 : return PR_TRUE;
462 : }
463 : }
464 : /*=================================================================================
465 :
466 : =================================================================================*/
467 0 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA4( PRInt32* state,
468 : PRUint16 in,
469 : unsigned char* out,
470 : PRUint32 outbuflen,
471 : PRUint32* outlen
472 : )
473 : {
474 0 : if(outbuflen < 4)
475 0 : return PR_FALSE;
476 : else
477 : {
478 0 : *outlen = 4;
479 0 : out[0] = 0x8E;
480 0 : out[1] = 0xA4;
481 0 : out[2] = ((in >> 8 ) & 0xff) | 0x80;
482 0 : out[3] = (in & 0xff) | 0x80;
483 0 : return PR_TRUE;
484 : }
485 : }
486 : /*=================================================================================
487 :
488 : =================================================================================*/
489 0 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA5( PRInt32* state,
490 : PRUint16 in,
491 : unsigned char* out,
492 : PRUint32 outbuflen,
493 : PRUint32* outlen
494 : )
495 : {
496 0 : if(outbuflen < 4)
497 0 : return PR_FALSE;
498 : else
499 : {
500 0 : *outlen = 4;
501 0 : out[0] = 0x8E;
502 0 : out[1] = 0xA5;
503 0 : out[2] = ((in >> 8 ) & 0xff) | 0x80;
504 0 : out[3] = (in & 0xff) | 0x80;
505 0 : return PR_TRUE;
506 : }
507 : }
508 : /*=================================================================================
509 :
510 : =================================================================================*/
511 0 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA6( PRInt32* state,
512 : PRUint16 in,
513 : unsigned char* out,
514 : PRUint32 outbuflen,
515 : PRUint32* outlen
516 : )
517 : {
518 0 : if(outbuflen < 4)
519 0 : return PR_FALSE;
520 : else
521 : {
522 0 : *outlen = 4;
523 0 : out[0] = 0x8E;
524 0 : out[1] = 0xA6;
525 0 : out[2] = ((in >> 8 ) & 0xff) | 0x80;
526 0 : out[3] = (in & 0xff) | 0x80;
527 0 : return PR_TRUE;
528 : }
529 : }
530 : /*=================================================================================
531 :
532 : =================================================================================*/
533 0 : PRIVATE PRBool uCheckAndGen2ByteGRPrefix8EA7( PRInt32* state,
534 : PRUint16 in,
535 : unsigned char* out,
536 : PRUint32 outbuflen,
537 : PRUint32* outlen
538 : )
539 : {
540 0 : if(outbuflen < 4)
541 0 : return PR_FALSE;
542 : else
543 : {
544 0 : *outlen = 4;
545 0 : out[0] = 0x8E;
546 0 : out[1] = 0xA7;
547 0 : out[2] = ((in >> 8 ) & 0xff) | 0x80;
548 0 : out[3] = (in & 0xff) | 0x80;
549 0 : return PR_TRUE;
550 : }
551 : }
552 : /*=================================================================================
553 :
554 : =================================================================================*/
555 : #define SBase 0xAC00
556 : #define LCount 19
557 : #define VCount 21
558 : #define TCount 28
559 : #define NCount (VCount * TCount)
560 : /*=================================================================================
561 :
562 : =================================================================================*/
563 0 : PRIVATE PRBool uCnGAlways8BytesDecomposedHangul(
564 : PRInt32* state,
565 : PRUint16 in,
566 : unsigned char* out,
567 : PRUint32 outbuflen,
568 : PRUint32* outlen
569 : )
570 : {
571 : static const PRUint8 lMap[LCount] = {
572 : 0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xa9, 0xb1, 0xb2, 0xb3, 0xb5,
573 : 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe
574 : };
575 :
576 : static const PRUint8 tMap[TCount] = {
577 : 0xd4, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa9, 0xaa,
578 : 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb4, 0xb5,
579 : 0xb6, 0xb7, 0xb8, 0xba, 0xbb, 0xbc, 0xbd, 0xbe
580 : };
581 :
582 : PRUint16 SIndex, LIndex, VIndex, TIndex;
583 :
584 0 : if(outbuflen < 8)
585 0 : return PR_FALSE;
586 :
587 : /* the following line are copy from Unicode 2.0 page 3-13 */
588 : /* item 1 of Hangul Syllabel Decomposition */
589 0 : SIndex = in - SBase;
590 :
591 : /* the following lines are copy from Unicode 2.0 page 3-14 */
592 : /* item 2 of Hangul Syllabel Decomposition w/ modification */
593 0 : LIndex = SIndex / NCount;
594 0 : VIndex = (SIndex % NCount) / TCount;
595 0 : TIndex = SIndex % TCount;
596 :
597 : /*
598 : * A Hangul syllable not enumerated in KS X 1001 is represented
599 : * by a sequence of 8 bytes beginning with Hangul-filler
600 : * (0xA4D4 in EUC-KR and 0x2454 in ISO-2022-KR) followed by three
601 : * Jamos (2 bytes each the first of which is 0xA4 in EUC-KR) making
602 : * up the syllable. ref. KS X 1001:1998 Annex 3
603 : */
604 0 : *outlen = 8;
605 0 : out[0] = out[2] = out[4] = out[6] = 0xa4;
606 0 : out[1] = 0xd4;
607 0 : out[3] = lMap[LIndex] ;
608 0 : out[5] = (VIndex + 0xbf);
609 0 : out[7] = tMap[TIndex];
610 :
611 0 : return PR_TRUE;
612 : }
613 :
614 0 : PRIVATE PRBool uCheckAndGenJohabHangul(
615 : PRInt32* state,
616 : PRUint16 in,
617 : unsigned char* out,
618 : PRUint32 outbuflen,
619 : PRUint32* outlen
620 : )
621 : {
622 0 : if(outbuflen < 2)
623 0 : return PR_FALSE;
624 : else
625 : {
626 : /*
627 : See Table 4-45 (page 183) of CJKV Information Processing
628 : for detail explanation of the following table.
629 : */
630 : /*
631 : static const PRUint8 lMap[LCount] = {
632 : 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
633 : };
634 : Therefore lMap[i] == i+2;
635 : */
636 :
637 : static const PRUint8 vMap[VCount] = {
638 : /* no 0,1,2 */
639 : 3,4,5,6,7, /* no 8,9 */
640 : 10,11,12,13,14,15, /* no 16,17 */
641 : 18,19,20,21,22,23, /* no 24,25 */
642 : 26,27,28,29
643 : };
644 : static const PRUint8 tMap[TCount] = {
645 : 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17, /* no 18 */
646 : 19,20,21,22,23,24,25,26,27,28,29
647 : };
648 : PRUint16 SIndex, LIndex, VIndex, TIndex, ch;
649 : /* the following line are copy from Unicode 2.0 page 3-13 */
650 : /* item 1 of Hangul Syllabel Decomposition */
651 0 : SIndex = in - SBase;
652 :
653 : /* the following lines are copy from Unicode 2.0 page 3-14 */
654 : /* item 2 of Hangul Syllabel Decomposition w/ modification */
655 0 : LIndex = SIndex / NCount;
656 0 : VIndex = (SIndex % NCount) / TCount;
657 0 : TIndex = SIndex % TCount;
658 :
659 0 : *outlen = 2;
660 0 : ch = 0x8000 |
661 0 : ((LIndex+2)<<10) |
662 0 : (vMap[VIndex]<<5)|
663 0 : tMap[TIndex];
664 0 : out[0] = (ch >> 8);
665 0 : out[1] = ch & 0x00FF;
666 : #if 0
667 : printf("Johab Hangul %x %x in=%x L=%d V=%d T=%d\n", out[0], out[1], in, LIndex, VIndex, TIndex);
668 : #endif
669 0 : return PR_TRUE;
670 : }
671 : }
672 0 : PRIVATE PRBool uCheckAndGenJohabSymbol(
673 : PRInt32* state,
674 : PRUint16 in,
675 : unsigned char* out,
676 : PRUint32 outbuflen,
677 : PRUint32* outlen
678 : )
679 : {
680 0 : if(outbuflen < 2)
681 0 : return PR_FALSE;
682 : else
683 : {
684 : /* The following code are based on the Perl code listed under
685 : * "ISO-2022-KR or EUC-KR to Johab Conversion" (page 1013)
686 : * in the book "CJKV Information Processing" by
687 : * Ken Lunde <lunde@adobe.com>
688 : *
689 : * sub convert2johab($) { # Convert ISO-2022-KR or EUC-KR to Johab
690 : * my @euc = unpack("C*", $_[0]);
691 : * my ($fe_off, $hi_off, $lo_off) = (0,0,1);
692 : * my @out = ();
693 : * while(($hi, $lo) = splice(@euc, 0, 2)) {
694 : * $hi &= 127; $lo &= 127;
695 : * $fe_off = 21 if $hi == 73;
696 : * $fe_off = 34 if $hi == 126;
697 : * ($hi_off, $lo_off) = ($lo_off, $hi_off) if ($hi <74 or $hi >125);
698 : * push(@out, ((($hi+$hi_off) >> 1)+ ($hi <74 ? 200:187)- $fe_off),
699 : * $lo + ((($hi+$lo_off) & 1) ? ($lo > 110 ? 34:16):128));
700 : * }
701 : * return pack("C*", @out);
702 : */
703 :
704 0 : unsigned char fe_off = 0;
705 0 : unsigned char hi_off = 0;
706 0 : unsigned char lo_off = 1;
707 0 : unsigned char hi = (in >> 8) & 0x7F;
708 0 : unsigned char lo = in & 0x7F;
709 0 : if(73 == hi)
710 0 : fe_off = 21;
711 0 : if(126 == hi)
712 0 : fe_off = 34;
713 0 : if( (hi < 74) || ( hi > 125) )
714 : {
715 0 : hi_off = 1;
716 0 : lo_off = 0;
717 : }
718 0 : *outlen = 2;
719 0 : out[0] = ((hi+hi_off) >> 1) + ((hi<74) ? 200 : 187 ) - fe_off;
720 0 : out[1] = lo + (((hi+lo_off) & 1) ? ((lo > 110) ? 34 : 16) :
721 : 128);
722 : #if 0
723 : printf("Johab Symbol %x %x in=%x\n", out[0], out[1], in);
724 : #endif
725 0 : return PR_TRUE;
726 : }
727 : }
728 0 : PRIVATE PRBool uCheckAndGen4BytesGB18030(
729 : PRInt32* state,
730 : PRUint16 in,
731 : unsigned char* out,
732 : PRUint32 outbuflen,
733 : PRUint32* outlen
734 : )
735 : {
736 0 : if(outbuflen < 4)
737 0 : return PR_FALSE;
738 0 : out[0] = (in / (10*126*10)) + 0x81;
739 0 : in %= (10*126*10);
740 0 : out[1] = (in / (10*126)) + 0x30;
741 0 : in %= (10*126);
742 0 : out[2] = (in / (10)) + 0x81;
743 0 : out[3] = (in % 10) + 0x30;
744 0 : *outlen = 4;
745 0 : return PR_TRUE;
746 : }
|