Usermode/ld-acess - Clean up loadlib.c, improved debug
[tpg/acess2.git] / KernelLand / Kernel / utf16.c
1 /*
2  * Acess2 Kernel
3  * - By John Hodge (thePowersGang) 
4  *
5  * utf16.c
6  * - UTF-16 Translation/Manipulation
7  */
8 #define DEBUG   0
9 #include <acess.h>
10 #include <utf16.h>
11 #include <ctype.h>
12
13 int ReadUTF16(const Uint16 *Str16, Uint32 *Codepoint)
14 {
15         if( 0xD800 < *Str16 && *Str16 <= 0xDFFF )
16         {
17                 // UTF-16 surrogate pair
18                 // > 0xDC00 is the second word
19                 if( Str16[0] > 0xDC00 ) {
20                         *Codepoint = 0;
21                         return 1;
22                 }
23                 if( Str16[1] < 0xD800 || Str16[1] >= 0xDC00 ) {
24                         *Codepoint = 0;
25                         return 2;
26                 }
27                 // 2^16 + 20-bit
28                 *Codepoint = 0x10000 + (((Str16[0] & 0x3FF) << 10) | (Str16[1] & 0x3FF));
29                 return 2;
30         }
31         else {
32                 *Codepoint = *Str16;
33                 return 1;
34         }
35 }
36
37 size_t UTF16_ConvertToUTF8(size_t DestLen, char *Dest, size_t SrcLen, const Uint16 *Source)
38 {
39          int    len = 0;
40         for( ; *Source && SrcLen --; Source ++ )
41         {
42                 // TODO: Decode/Reencode
43                 if( Dest && len < DestLen )
44                         Dest[len] = *Source;
45                 len += 1;
46         }
47         if( Dest && len < DestLen )
48                 Dest[len] = 0;
49         return len;
50 }
51
52 int UTF16_CompareWithUTF8Ex(size_t Str16Len, const Uint16 *Str16, const char *Str8, int bCaseInsensitive)
53 {
54          int    pos16 = 0, pos8 = 0;
55         const Uint8     *str8 = (const Uint8 *)Str8;
56         
57         while( pos16 < Str16Len && Str16[pos16] && str8[pos8] )
58         {
59                 Uint32  cp8, cp16;
60                 pos16 += ReadUTF16(Str16+pos16, &cp16);
61                 pos8 += ReadUTF8(str8 + pos8, &cp8);
62                 if( bCaseInsensitive ) {
63                         cp16 = toupper(cp16);
64                         cp8 = toupper(cp8);
65                 }
66         
67                 LOG("cp16 = %x, cp8 = %x", cp16, cp8);
68                 if(cp16 == cp8) continue ;
69                 
70                 if(cp16 < cp8)
71                         return -1;
72                 else
73                         return 1;
74         }
75         if( pos16 == Str16Len )
76                 return 0;
77         if( Str16[pos16] && str8[pos8] )
78                 return 0;
79         if( Str16[pos16] )
80                 return 1;
81         else
82                 return -1;
83 }
84
85 int UTF16_CompareWithUTF8(size_t Str16Len, const Uint16 *Str16, const char *Str8)
86 {
87         return UTF16_CompareWithUTF8Ex(Str16Len, Str16, Str8, 0);
88 }
89
90 int UTF16_CompareWithUTF8CI(size_t Str16Len, const Uint16 *Str16, const char *Str8)
91 {
92         return UTF16_CompareWithUTF8Ex(Str16Len, Str16, Str8, 1);
93 }
94

UCC git Repository :: git.ucc.asn.au