"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