"Fossies" - the Fresh Open Source Software Archive 
Member "unrar/strfn.cpp" (4 May 2022, 10318 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "strfn.cpp" see the
Fossies "Dox" file reference documentation.
1 #include "rar.hpp"
2
3 const char *NullToEmpty(const char *Str)
4 {
5 return Str==NULL ? "":Str;
6 }
7
8
9 const wchar *NullToEmpty(const wchar *Str)
10 {
11 return Str==NULL ? L"":Str;
12 }
13
14
15 void 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.
33 void 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
65 int 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
82 int 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
108 wchar* RemoveEOL(wchar *Str)
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
116 wchar* RemoveLF(wchar *Str)
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.
130 unsigned 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.
141 wchar etoupperw(wchar c)
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.
151 bool 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.
161 bool 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.
171 bool IsAlpha(int ch)
172 {
173 return ch>='A' && ch<='Z' || ch>='a' && ch<='z';
174 }
175
176
177
178
179 void 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
207 uint GetDigits(uint Number)
208 {
209 uint Digits=1;
210 while (Number>=10)
211 {
212 Number/=10;
213 Digits++;
214 }
215 return Digits;
216 }
217 #endif
218
219
220 bool 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
229 bool 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
242 int 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
252 int 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.
263 void 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.
275 void 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.
289 void 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.
300 void 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
308 void 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
334 void 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
360 const 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.
377 const 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.
415 void 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