unrarsrc  6.1.7
About: unrar extracts, views and tests the contents of archives created with the RAR archiver.
  Fossies Dox: unrarsrc-6.1.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

strfn.cpp
Go to the documentation of this file.
1#include "rar.hpp"
2
3const char *NullToEmpty(const char *Str)
4{
5 return Str==NULL ? "":Str;
6}
7
8
9const wchar *NullToEmpty(const wchar *Str)
10{
11 return Str==NULL ? L"":Str;
12}
13
14
15void IntToExt(const char *Src,char *Dest,size_t DestSize)
16{
17#ifdef _WIN_ALL
18 // OemToCharBuff does not stop at 0, so let's check source length.
19 size_t SrcLength=strlen(Src)+1;
20 if (DestSize>SrcLength)
21 DestSize=SrcLength;
22 OemToCharBuffA(Src,Dest,(DWORD)DestSize);
23 Dest[DestSize-1]=0;
24#else
25 if (Dest!=Src)
26 strncpyz(Dest,Src,DestSize);
27#endif
28}
29
30
31// Convert archived names and comments to Unicode.
32// Allows user to select a code page in GUI.
33void ArcCharToWide(const char *Src,wchar *Dest,size_t DestSize,ACTW_ENCODING Encoding)
34{
35#if defined(_WIN_ALL) // Console Windows RAR.
36 if (Encoding==ACTW_UTF8)
37 UtfToWide(Src,Dest,DestSize);
38 else
39 {
40 Array<char> NameA;
41 if (Encoding==ACTW_OEM)
42 {
43 NameA.Alloc(DestSize+1);
44 IntToExt(Src,&NameA[0],NameA.Size());
45 Src=&NameA[0];
46 }
47 CharToWide(Src,Dest,DestSize);
48 }
49#else // RAR for Unix.
50 if (Encoding==ACTW_UTF8)
51 UtfToWide(Src,Dest,DestSize);
52 else
53 CharToWide(Src,Dest,DestSize);
54#endif
55 // Ensure that we return a zero terminate string for security reason.
56 // While [Jni]CharToWide might already do it, be protected in case of future
57 // changes in these functions.
58 if (DestSize>0)
59 Dest[DestSize-1]=0;
60}
61
62
63
64
65int stricomp(const char *s1,const char *s2)
66{
67#ifdef _WIN_ALL
68 return CompareStringA(LOCALE_USER_DEFAULT,NORM_IGNORECASE|SORT_STRINGSORT,s1,-1,s2,-1)-2;
69#else
70 while (toupper(*s1)==toupper(*s2))
71 {
72 if (*s1==0)
73 return 0;
74 s1++;
75 s2++;
76 }
77 return s1 < s2 ? -1 : 1;
78#endif
79}
80
81
82int strnicomp(const char *s1,const char *s2,size_t n)
83{
84#ifdef _WIN_ALL
85 // If we specify 'n' exceeding the actual string length, CompareString goes
86 // beyond the trailing zero and compares garbage. So we need to limit 'n'
87 // to real string length.
88 // It is important to use strnlen (or memchr(...,0)) instead of strlen,
89 // because data can be not zero terminated.
90 size_t l1=Min(strnlen(s1,n),n);
91 size_t l2=Min(strnlen(s2,n),n);
92 return CompareStringA(LOCALE_USER_DEFAULT,NORM_IGNORECASE|SORT_STRINGSORT,s1,(int)l1,s2,(int)l2)-2;
93#else
94 if (n==0)
95 return 0;
96 while (toupper(*s1)==toupper(*s2))
97 {
98 if (*s1==0 || --n==0)
99 return 0;
100 s1++;
101 s2++;
102 }
103 return s1 < s2 ? -1 : 1;
104#endif
105}
106
107
109{
110 for (int I=(int)wcslen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n' || Str[I]==' ' || Str[I]=='\t');I--)
111 Str[I]=0;
112 return Str;
113}
114
115
117{
118 for (int I=(int)wcslen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n');I--)
119 Str[I]=0;
120 return Str;
121}
122
123
124#if defined(SFX_MODULE)
125// char version of etoupperw. Used in console SFX module only.
126// Fast toupper for English only input and output. Additionally to speed,
127// it also avoids Turkish small i to big I with dot conversion problem.
128// We do not define 'c' as 'int' to avoid necessity to cast all
129// signed chars passed to this function to unsigned char.
130unsigned char etoupper(unsigned char c)
131{
132 return c>='a' && c<='z' ? c-'a'+'A' : c;
133}
134#endif
135
136
137// Fast toupper for English only input and output. Additionally to speed,
138// it also avoids Turkish small i to big I with dot conversion problem.
139// We do not define 'c' as 'int' to avoid necessity to cast all
140// signed wchars passed to this function to unsigned char.
142{
143 return c>='a' && c<='z' ? c-'a'+'A' : c;
144}
145
146
147// We do not want to cast every signed char to unsigned when passing to
148// isdigit, so we implement the replacement. Shall work for Unicode too.
149// If chars are signed, conversion from char to int could generate negative
150// values, resulting in undefined behavior in standard isdigit.
151bool IsDigit(int ch)
152{
153 return ch>='0' && ch<='9';
154}
155
156
157// We do not want to cast every signed char to unsigned when passing to
158// isspace, so we implement the replacement. Shall work for Unicode too.
159// If chars are signed, conversion from char to int could generate negative
160// values, resulting in undefined behavior in standard isspace.
161bool IsSpace(int ch)
162{
163 return ch==' ' || ch=='\t';
164}
165
166
167// We do not want to cast every signed char to unsigned when passing to
168// isalpha, so we implement the replacement. Shall work for Unicode too.
169// If chars are signed, conversion from char to int could generate negative
170// values, resulting in undefined behavior in standard function.
171bool IsAlpha(int ch)
172{
173 return ch>='A' && ch<='Z' || ch>='a' && ch<='z';
174}
175
176
177
178
179void BinToHex(const byte *Bin,size_t BinSize,char *HexA,wchar *HexW,size_t HexSize)
180{
181 uint A=0,W=0; // ASCII and Unicode hex output positions.
182 for (uint I=0;I<BinSize;I++)
183 {
184 uint High=Bin[I] >> 4;
185 uint Low=Bin[I] & 0xf;
186 uint HighHex=High>9 ? 'a'+High-10:'0'+High;
187 uint LowHex=Low>9 ? 'a'+Low-10:'0'+Low;
188 if (HexA!=NULL && A<HexSize-2) // Need space for 2 chars and final zero.
189 {
190 HexA[A++]=(char)HighHex;
191 HexA[A++]=(char)LowHex;
192 }
193 if (HexW!=NULL && W<HexSize-2) // Need space for 2 chars and final zero.
194 {
195 HexW[W++]=HighHex;
196 HexW[W++]=LowHex;
197 }
198 }
199 if (HexA!=NULL && HexSize>0)
200 HexA[A]=0;
201 if (HexW!=NULL && HexSize>0)
202 HexW[W]=0;
203}
204
205
206#ifndef SFX_MODULE
208{
209 uint Digits=1;
210 while (Number>=10)
211 {
212 Number/=10;
213 Digits++;
214 }
215 return Digits;
216}
217#endif
218
219
220bool LowAscii(const char *Str)
221{
222 for (size_t I=0;Str[I]!=0;I++)
223 if (/*(byte)Str[I]<32 || */(byte)Str[I]>127)
224 return false;
225 return true;
226}
227
228
229bool LowAscii(const wchar *Str)
230{
231 for (size_t I=0;Str[I]!=0;I++)
232 {
233 // We convert wchar_t to uint just in case if some compiler
234 // uses signed wchar_t.
235 if (/*(uint)Str[I]<32 || */(uint)Str[I]>127)
236 return false;
237 }
238 return true;
239}
240
241
242int wcsicompc(const wchar *s1,const wchar *s2) // For path comparison.
243{
244#if defined(_UNIX)
245 return wcscmp(s1,s2);
246#else
247 return wcsicomp(s1,s2);
248#endif
249}
250
251
252int wcsnicompc(const wchar *s1,const wchar *s2,size_t n)
253{
254#if defined(_UNIX)
255 return wcsncmp(s1,s2,n);
256#else
257 return wcsnicomp(s1,s2,n);
258#endif
259}
260
261
262// Safe copy: copies maxlen-1 max and for maxlen>0 returns zero terminated dest.
263void strncpyz(char *dest, const char *src, size_t maxlen)
264{
265 if (maxlen>0)
266 {
267 while (--maxlen>0 && *src!=0)
268 *dest++=*src++;
269 *dest=0;
270 }
271}
272
273
274// Safe copy: copies maxlen-1 max and for maxlen>0 returns zero terminated dest.
275void wcsncpyz(wchar *dest, const wchar *src, size_t maxlen)
276{
277 if (maxlen>0)
278 {
279 while (--maxlen>0 && *src!=0)
280 *dest++=*src++;
281 *dest=0;
282 }
283}
284
285
286// Safe append: resulting dest length cannot exceed maxlen and dest
287// is always zero terminated. 'maxlen' parameter defines the entire
288// dest buffer size and is not compatible with wcsncat.
289void strncatz(char* dest, const char* src, size_t maxlen)
290{
291 size_t length = strlen(dest);
292 if (maxlen > length)
293 strncpyz(dest + length, src, maxlen - length);
294}
295
296
297// Safe append: resulting dest length cannot exceed maxlen and dest
298// is always zero terminated. 'maxlen' parameter defines the entire
299// dest buffer size and is not compatible with wcsncat.
300void wcsncatz(wchar* dest, const wchar* src, size_t maxlen)
301{
302 size_t length = wcslen(dest);
303 if (maxlen > length)
304 wcsncpyz(dest + length, src, maxlen - length);
305}
306
307
308void itoa(int64 n,char *Str,size_t MaxSize)
309{
310 char NumStr[50];
311 size_t Pos=0;
312
313 int Neg=n < 0 ? 1 : 0;
314 if (Neg)
315 n=-n;
316
317 do
318 {
319 if (Pos+1>=MaxSize-Neg)
320 break;
321 NumStr[Pos++]=char(n%10)+'0';
322 n=n/10;
323 } while (n!=0);
324
325 if (Neg)
326 NumStr[Pos++]='-';
327
328 for (size_t I=0;I<Pos;I++)
329 Str[I]=NumStr[Pos-I-1];
330 Str[Pos]=0;
331}
332
333
334void itoa(int64 n,wchar *Str,size_t MaxSize)
335{
336 wchar NumStr[50];
337 size_t Pos=0;
338
339 int Neg=n < 0 ? 1 : 0;
340 if (Neg)
341 n=-n;
342
343 do
344 {
345 if (Pos+1>=MaxSize-Neg)
346 break;
347 NumStr[Pos++]=wchar(n%10)+'0';
348 n=n/10;
349 } while (n!=0);
350
351 if (Neg)
352 NumStr[Pos++]='-';
353
354 for (size_t I=0;I<Pos;I++)
355 Str[I]=NumStr[Pos-I-1];
356 Str[Pos]=0;
357}
358
359
360const wchar* GetWide(const char *Src)
361{
362 const size_t MaxLength=NM;
363 static wchar StrTable[4][MaxLength];
364 static uint StrNum=0;
365 if (++StrNum >= ASIZE(StrTable))
366 StrNum=0;
367 wchar *Str=StrTable[StrNum];
368 CharToWide(Src,Str,MaxLength);
369 Str[MaxLength-1]=0;
370 return Str;
371}
372
373
374// Parse string containing parameters separated with spaces.
375// Support quote marks. Param can be NULL to return the pointer to next
376// parameter, which can be used to estimate the buffer size for Param.
377const wchar* GetCmdParam(const wchar *CmdLine,wchar *Param,size_t MaxSize)
378{
379 while (IsSpace(*CmdLine))
380 CmdLine++;
381 if (*CmdLine==0)
382 return NULL;
383
384 size_t ParamSize=0;
385 bool Quote=false;
386 while (*CmdLine!=0 && (Quote || !IsSpace(*CmdLine)))
387 {
388 if (*CmdLine=='\"')
389 {
390 if (CmdLine[1]=='\"')
391 {
392 // Insert the quote character instead of two adjoining quote characters.
393 if (Param!=NULL && ParamSize<MaxSize-1)
394 Param[ParamSize++]='\"';
395 CmdLine++;
396 }
397 else
398 Quote=!Quote;
399 }
400 else
401 if (Param!=NULL && ParamSize<MaxSize-1)
402 Param[ParamSize++]=*CmdLine;
403 CmdLine++;
404 }
405 if (Param!=NULL)
406 Param[ParamSize]=0;
407 return CmdLine;
408}
409
410
411#ifndef RARDLL
412// For compatibility with existing translations we use %s to print Unicode
413// strings in format strings and convert them to %ls here. %s could work
414// without such conversion in Windows, but not in Unix wprintf.
415void PrintfPrepareFmt(const wchar *Org,wchar *Cvt,size_t MaxSize)
416{
417 uint Src=0,Dest=0;
418 while (Org[Src]!=0 && Dest<MaxSize-1)
419 {
420 if (Org[Src]=='%' && (Src==0 || Org[Src-1]!='%'))
421 {
422 uint SPos=Src+1;
423 // Skipping a possible width specifier like %-50s.
424 while (IsDigit(Org[SPos]) || Org[SPos]=='-')
425 SPos++;
426 if (Org[SPos]=='s' && Dest<MaxSize-(SPos-Src+1))
427 {
428 while (Src<SPos)
429 Cvt[Dest++]=Org[Src++];
430 Cvt[Dest++]='l';
431 }
432 }
433#ifdef _WIN_ALL
434 // Convert \n to \r\n in Windows. Important when writing to log,
435 // so other tools like Notebook can view resulting log properly.
436 if (Org[Src]=='\n' && (Src==0 || Org[Src-1]!='\r'))
437 Cvt[Dest++]='\r';
438#endif
439
440 Cvt[Dest++]=Org[Src++];
441 }
442 Cvt[Dest]=0;
443}
444#endif
Definition: array.hpp:7
size_t Size()
Definition: array.hpp:94
void Alloc(size_t Items)
Definition: array.hpp:139
#define Min(x, y)
Definition: rardefs.hpp:4
#define ASIZE(x)
Definition: rardefs.hpp:10
wchar_t wchar
Definition: rartypes.hpp:13
int64_t int64
Definition: rartypes.hpp:12
unsigned int uint
Definition: rartypes.hpp:8
int wcsicompc(const wchar *s1, const wchar *s2)
Definition: strfn.cpp:242
bool IsAlpha(int ch)
Definition: strfn.cpp:171
const wchar * GetCmdParam(const wchar *CmdLine, wchar *Param, size_t MaxSize)
Definition: strfn.cpp:377
void BinToHex(const byte *Bin, size_t BinSize, char *HexA, wchar *HexW, size_t HexSize)
Definition: strfn.cpp:179
uint GetDigits(uint Number)
Definition: strfn.cpp:207
void itoa(int64 n, char *Str, size_t MaxSize)
Definition: strfn.cpp:308
bool IsSpace(int ch)
Definition: strfn.cpp:161
void wcsncpyz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:275
void strncpyz(char *dest, const char *src, size_t maxlen)
Definition: strfn.cpp:263
void strncatz(char *dest, const char *src, size_t maxlen)
Definition: strfn.cpp:289
void PrintfPrepareFmt(const wchar *Org, wchar *Cvt, size_t MaxSize)
Definition: strfn.cpp:415
void IntToExt(const char *Src, char *Dest, size_t DestSize)
Definition: strfn.cpp:15
int strnicomp(const char *s1, const char *s2, size_t n)
Definition: strfn.cpp:82
int stricomp(const char *s1, const char *s2)
Definition: strfn.cpp:65
int wcsnicompc(const wchar *s1, const wchar *s2, size_t n)
Definition: strfn.cpp:252
wchar * RemoveLF(wchar *Str)
Definition: strfn.cpp:116
void wcsncatz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:300
wchar * RemoveEOL(wchar *Str)
Definition: strfn.cpp:108
bool LowAscii(const char *Str)
Definition: strfn.cpp:220
void ArcCharToWide(const char *Src, wchar *Dest, size_t DestSize, ACTW_ENCODING Encoding)
Definition: strfn.cpp:33
const wchar * GetWide(const char *Src)
Definition: strfn.cpp:360
bool IsDigit(int ch)
Definition: strfn.cpp:151
wchar etoupperw(wchar c)
Definition: strfn.cpp:141
const char * NullToEmpty(const char *Str)
Definition: strfn.cpp:3
ACTW_ENCODING
Definition: strfn.hpp:8
@ ACTW_OEM
Definition: strfn.hpp:8
@ ACTW_UTF8
Definition: strfn.hpp:8
int wcsicomp(const wchar *s1, const wchar *s2)
Definition: unicode.cpp:425
bool CharToWide(const char *Src, wchar *Dest, size_t DestSize)
Definition: unicode.cpp:85
int wcsnicomp(const wchar *s1, const wchar *s2, size_t n)
Definition: unicode.cpp:446
bool UtfToWide(const char *Src, wchar *Dest, size_t DestSize)
Definition: unicode.cpp:324