Merge pull request #4324 from FernetMenta/wasapi
[vuplus_xbmc] / lib / UnrarXLib / unicode.cpp
1 #include "rar.hpp"
2
3 // yuvalt: wcstombs is not the way to go since it does not convert
4 // from utf8 to utf16. Luickly, there's a UTF8/UTF16 conversion
5 // functions in here which are used if _APPLE is defined.
6 // Therefore, define _APPLE in this case to do proper conversion
7 #undef MBFUNCTIONS
8 #undef _WIN_32
9 #define _APPLE
10
11 bool WideToChar(const wchar *Src,char *Dest,int DestSize)
12 {
13   bool RetCode=true;
14 #ifdef _WIN_32
15   if (WideCharToMultiByte(CP_ACP,0,Src,-1,Dest,DestSize,NULL,NULL)==0)
16     RetCode=false;
17 #else
18 #ifdef _APPLE
19   WideToUtf(Src,Dest,DestSize);
20 #else
21 #ifdef MBFUNCTIONS
22   if (wcstombs(Dest,Src,DestSize)==(uint)-1)
23     RetCode=false;
24 #else
25   if (UnicodeEnabled())
26   {
27     for (int I=0;I<DestSize;I++)
28     {
29       Dest[I]=(char)Src[I];
30       if (Src[I]==0)
31         break;
32   }
33 #endif
34 #endif
35 #endif
36   return(RetCode);
37 }
38
39
40 bool CharToWide(const char *Src,wchar *Dest,int DestSize)
41 {
42   bool RetCode=true;
43 #ifdef _WIN_32
44   if (MultiByteToWideChar(CP_ACP,0,Src,-1,Dest,DestSize)==0)
45     RetCode=false;
46 #else
47 #ifdef _APPLE
48   UtfToWide(Src,Dest,DestSize);
49 #else
50 #ifdef MBFUNCTIONS
51   mbstowcs(Dest,Src,DestSize);
52 #else
53   if (UnicodeEnabled())
54   {
55     for (int I=0;I<DestSize;I++)
56     {
57       Dest[I]=(wchar_t)Src[I];
58       if (Src[I]==0)
59         break;
60   }
61 #endif
62 #endif
63 #endif
64   return(RetCode);
65 }
66
67
68 byte* WideToRaw(const wchar *Src,byte *Dest,int DestSize)
69 {
70   for (int I=0;I<DestSize;I++,Src++)
71   {
72     Dest[I*2]=(byte)*Src;
73     Dest[I*2+1]=(byte)(*Src>>8);
74     if (*Src==0)
75       break;
76   }
77   return(Dest);
78 }
79
80
81 wchar* RawToWide(const byte *Src,wchar *Dest,int DestSize)
82 {
83   for (int I=0;I<DestSize;I++)
84     if ((Dest[I]=Src[I*2]+(Src[I*2+1]<<8))==0)
85       break;
86   return(Dest);
87 }
88
89
90 #ifdef _APPLE
91 void WideToUtf(const wchar *Src,char *Dest,int DestSize)
92 {
93   DestSize--;
94   while (*Src!=0 && --DestSize>=0)
95   {
96     uint c=*(Src++);
97     if (c<0x80)
98       *(Dest++)=c;
99     else
100       if (c<0x800 && --DestSize>=0)
101       {
102         *(Dest++)=(0xc0|(c>>6));
103         *(Dest++)=(0x80|(c&0x3f));
104       }
105       else
106         if (c<0x10000 && (DestSize-=2)>=0)
107         {
108           *(Dest++)=(0xe0|(c>>12));
109           *(Dest++)=(0x80|((c>>6)&0x3f));
110           *(Dest++)=(0x80|(c&0x3f));
111         }
112   }
113   *Dest=0;
114 }
115 #endif
116
117
118 #ifdef _APPLE
119 void UtfToWide(const char *Src,wchar *Dest,int DestSize)
120 {
121   DestSize--;
122   while (*Src!=0)
123   {
124     uint c=(byte)*(Src++),d;
125     if (c<0x80)
126       d=c;
127     else
128       if ((c>>5)==6)
129       {
130         if ((*Src&0xc0)!=0x80)
131           break;
132         d=((c&0x1f)<<6)|(*Src&0x3f);
133         Src++;
134       }
135       else
136         if ((c>>4)==14)
137         {
138           if ((Src[0]&0xc0)!=0x80 || (Src[1]&0xc0)!=0x80)
139             break;
140           d=((c&0xf)<<12)|((Src[0]&0x3f)<<6)|(Src[1]&0x3f);
141           Src+=2;
142         }
143         else
144           break;
145     if (--DestSize<0)
146       break;
147     *(Dest++)=d;
148   }
149   *Dest=0;
150 }
151 #endif
152
153
154 bool UnicodeEnabled()
155 {
156 #ifdef UNICODE_SUPPORTED
157   #ifdef _EMX
158     return(uni_ready);
159   #else
160     return(true);
161   #endif
162 #else
163   return(false);
164 #endif
165 }
166
167
168 int strlenw(const wchar *str)
169 {
170   int length=0;
171   while (*(str++)!=0)
172     length++;
173   return(length);
174 }
175
176
177 wchar* strcpyw(wchar *dest,const wchar *src)
178 {
179   do {
180     *(dest++)=*src;
181   } while (*(src++)!=0);
182   return(dest);
183 }
184
185
186 wchar* strncpyw(wchar *dest,const wchar *src,int n)
187 {
188   do {
189     *(dest++)=*src;
190   } while (*(src++)!=0 && --n > 0);
191   return(dest);
192 }
193
194
195 wchar* strcatw(wchar *dest,const wchar *src)
196 {
197   return(strcpyw(dest+strlenw(dest),src));
198 }
199
200
201 #ifndef SFX_MODULE
202 wchar* strncatw(wchar *dest,const wchar *src,int n)
203 {
204   dest+=strlenw(dest);
205   while (true)
206     if (--n<0)
207     {
208       *dest=0;
209       break;
210     }
211     else
212       if ((*(dest++)=*(src++))==0)
213         break;
214   return(dest);
215 }
216 #endif
217
218
219 int strcmpw(const wchar *s1,const wchar *s2)
220 {
221   while (*s1==*s2)
222   {
223     if (*s1==0)
224       return(0);
225     s1++;
226     s2++;
227   }
228   return(*s1<*s2 ? -1:1);
229 }
230
231
232 int strncmpw(const wchar *s1,const wchar *s2,int n)
233 {
234   while (n-->0)
235   {
236     if (*s1<*s2)
237       return(-1);
238     if (*s1>*s2)
239       return(-1);
240     if (*s1==0)
241       break;
242     s1++;
243     s2++;
244   }
245   return(0);
246 }
247
248
249 #ifndef SFX_MODULE
250 int stricmpw(const wchar *s1,const wchar *s2)
251 {
252   char Ansi1[NM*sizeof(wchar)],Ansi2[NM*sizeof(wchar)];
253   WideToChar(s1,Ansi1,sizeof(Ansi1));
254   WideToChar(s2,Ansi2,sizeof(Ansi2));
255   return(stricomp(Ansi1,Ansi2));
256 }
257 #endif
258
259
260 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
261 inline int strnicmpw_w2c(const wchar *s1,const wchar *s2,int n)
262 {
263   wchar Wide1[NM*2],Wide2[NM*2];
264   strncpyw(Wide1,s1,sizeof(Wide1)/sizeof(Wide1[0])-1);
265   strncpyw(Wide2,s2,sizeof(Wide2)/sizeof(Wide2[0])-1);
266   Wide1[Min((int)(sizeof(Wide1)/sizeof(Wide1[0])-1),n)]=0;
267   Wide2[Min((int)(sizeof(Wide2)/sizeof(Wide2[0])-1),n)]=0;
268   char Ansi1[NM*2],Ansi2[NM*2];
269   WideToChar(Wide1,Ansi1,sizeof(Ansi1));
270   WideToChar(Wide2,Ansi2,sizeof(Ansi2));
271   return(stricomp(Ansi1,Ansi2));
272 }
273 #endif
274
275
276 #ifndef SFX_MODULE
277 int strnicmpw(const wchar *s1,const wchar *s2,int n)
278 {
279   return(strnicmpw_w2c(s1,s2,n));
280 }
281 #endif
282
283
284 wchar* strchrw(const wchar *s,int c)
285 {
286   while (*s)
287   {
288     if (*s==c)
289       return((wchar *)s);
290     s++;
291   }
292   return(NULL);
293 }
294
295
296 wchar* strrchrw(const wchar *s,int c)
297 {
298   for (int I=strlenw(s)-1;I>=0;I--)
299     if (s[I]==c)
300       return((wchar *)(s+I));
301   return(NULL);
302 }
303
304
305 wchar* strpbrkw(const wchar *s1,const wchar *s2)
306 {
307   while (*s1)
308   {
309     if (strchrw(s2,*s1)!=NULL)
310       return((wchar *)s1);
311     s1++;
312   }
313   return(NULL);
314 }
315
316
317 #ifndef SFX_MODULE
318 wchar* strlowerw(wchar *Str)
319 {
320   for (wchar *ChPtr=Str;*ChPtr;ChPtr++)
321     if (*ChPtr<128)
322       *ChPtr=loctolower((char)*ChPtr);
323   return(Str);
324 }
325 #endif
326
327
328 #ifndef SFX_MODULE
329 wchar* strupperw(wchar *Str)
330 {
331   for (wchar *ChPtr=Str;*ChPtr;ChPtr++)
332     if (*ChPtr<128)
333       *ChPtr=loctoupper((char)*ChPtr);
334   return(Str);
335 }
336 #endif
337
338
339 #ifndef SFX_MODULE
340 int toupperw(int ch)
341 {
342   return((ch<128) ? loctoupper(ch):ch);
343 }
344 #endif
345
346
347 int atoiw(const wchar *s)
348 {
349   int n=0;
350   while (*s>='0' && *s<='9')
351   {
352     n=n*10+(*s-'0');
353     s++;
354   }
355   return(n);
356 }
357
358
359 #ifdef DBCS_SUPPORTED
360 SupportDBCS gdbcs;
361
362 SupportDBCS::SupportDBCS()
363 {
364   Init();
365 }
366
367
368 void SupportDBCS::Init()
369 {
370 #if defined(TARGET_POSIX)
371   DBCSMode = true;
372   for (int I=0;I<sizeof(IsLeadByte)/sizeof(IsLeadByte[0]);I++)
373     IsLeadByte[I]=true;
374 #else
375   CPINFO CPInfo;
376   GetCPInfo(CP_ACP,&CPInfo);
377   DBCSMode=CPInfo.MaxCharSize > 1;
378   for (int I=0;I<sizeof(IsLeadByte)/sizeof(IsLeadByte[0]);I++)
379     IsLeadByte[I]=IsDBCSLeadByte(I);
380 #endif
381 }
382
383
384 char* SupportDBCS::charnext(const char *s)
385 {
386   return (char *)(IsLeadByte[*s] ? s+2:s+1);
387 }
388
389
390 uint SupportDBCS::strlend(const char *s)
391 {
392   uint Length=0;
393   while (*s!=0)
394   {
395     if (IsLeadByte[*s])
396       s+=2;
397     else
398       s++;
399     Length++;
400   }
401   return(Length);
402 }
403
404
405 char* SupportDBCS::strchrd(const char *s, int c)
406 {
407   while (*s!=0)
408     if (IsLeadByte[*s])
409       s+=2;
410     else
411       if (*s==c)
412         return((char *)s);
413       else
414         s++;
415   return(NULL);
416 }
417
418
419 void SupportDBCS::copychrd(char *dest,const char *src)
420 {
421   dest[0]=src[0];
422   if (IsLeadByte[src[0]])
423     dest[1]=src[1];
424 }
425
426
427 char* SupportDBCS::strrchrd(const char *s, int c)
428 {
429   const char *found=NULL;
430   while (*s!=0)
431     if (IsLeadByte[*s])
432       s+=2;
433     else
434     {
435       if (*s==c)
436         found=s;
437       s++;
438     }
439   return((char *)found);
440 }
441 #endif