Back to index

lightning-sunbird  0.9+nobinonly
nsCRT.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038  
00054 #include "nsCRT.h"
00055 #include "nsIServiceManager.h"
00056 
00057 // XXX Bug: These tables don't lowercase the upper 128 characters properly
00058 
00059 // This table maps uppercase characters to lower case characters;
00060 // characters that are neither upper nor lower case are unaffected.
00061 static const unsigned char kUpper2Lower[256] = {
00062     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
00063    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
00064    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
00065    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
00066    64,
00067 
00068     // upper band mapped to lower [A-Z] => [a-z]
00069        97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
00070   112,113,114,115,116,117,118,119,120,121,122,
00071 
00072                                                91, 92, 93, 94, 95,
00073    96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
00074   112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
00075   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
00076   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
00077   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
00078   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
00079   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
00080   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
00081   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
00082   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
00083 };
00084 
00085 static const unsigned char kLower2Upper[256] = {
00086     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
00087    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
00088    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
00089    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
00090    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
00091    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
00092    96,
00093 
00094     // lower band mapped to upper [a-z] => [A-Z]
00095        65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
00096    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
00097 
00098                                               123,124,125,126,127,
00099   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
00100   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
00101   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
00102   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
00103   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
00104   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
00105   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
00106   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
00107 };
00108 
00109 //----------------------------------------------------------------------
00110 
00111 char nsCRT::ToUpper(char aChar)
00112 {
00113   return (char)kLower2Upper[(unsigned char)aChar];
00114 }
00115 
00116 char nsCRT::ToLower(char aChar)
00117 {
00118   return (char)kUpper2Lower[(unsigned char)aChar];
00119 }
00120 
00121 PRBool nsCRT::IsUpper(char aChar)
00122 {
00123   return aChar != nsCRT::ToLower(aChar);
00124 }
00125 
00126 PRBool nsCRT::IsLower(char aChar)
00127 {
00128   return aChar != nsCRT::ToUpper(aChar);
00129 }
00130 
00132 // My lovely strtok routine
00133 
00134 #define IS_DELIM(m, c)          ((m)[(c) >> 3] & (1 << ((c) & 7)))
00135 #define SET_DELIM(m, c)         ((m)[(c) >> 3] |= (1 << ((c) & 7)))
00136 #define DELIM_TABLE_SIZE        32
00137 
00138 char* nsCRT::strtok(char* string, const char* delims, char* *newStr)
00139 {
00140   NS_ASSERTION(string, "Unlike regular strtok, the first argument cannot be null.");
00141 
00142   char delimTable[DELIM_TABLE_SIZE];
00143   PRUint32 i;
00144   char* result;
00145   char* str = string;
00146 
00147   for (i = 0; i < DELIM_TABLE_SIZE; i++)
00148     delimTable[i] = '\0';
00149 
00150   for (i = 0; delims[i]; i++) {
00151     SET_DELIM(delimTable, NS_STATIC_CAST(PRUint8, delims[i]));
00152   }
00153   NS_ASSERTION(delims[i] == '\0', "too many delimiters");
00154 
00155   // skip to beginning
00156   while (*str && IS_DELIM(delimTable, NS_STATIC_CAST(PRUint8, *str))) {
00157     str++;
00158   }
00159   result = str;
00160 
00161   // fix up the end of the token
00162   while (*str) {
00163     if (IS_DELIM(delimTable, NS_STATIC_CAST(PRUint8, *str))) {
00164       *str++ = '\0';
00165       break;
00166     }
00167     str++;
00168   }
00169   *newStr = str;
00170 
00171   return str == result ? NULL : result;
00172 }
00173 
00175 
00176 PRUint32 nsCRT::strlen(const PRUnichar* s)
00177 {
00178   PRUint32 len = 0;
00179   if(s) {
00180     while (*s++ != 0) {
00181       len++;
00182     }
00183   }
00184   return len;
00185 }
00186 
00187 
00197 PRInt32 nsCRT::strcmp(const PRUnichar* s1, const PRUnichar* s2) {
00198   if(s1 && s2) {
00199     for (;;) {
00200       PRUnichar c1 = *s1++;
00201       PRUnichar c2 = *s2++;
00202       if (c1 != c2) {
00203         if (c1 < c2) return -1;
00204         return 1;
00205       }
00206       if ((0==c1) || (0==c2)) break;
00207     }
00208   }
00209   else {
00210     if (s1)                     // s2 must have been null
00211       return -1;
00212     if (s2)                     // s1 must have been null
00213       return 1;
00214   }
00215   return 0;
00216 }
00217 
00227 PRInt32 nsCRT::strncmp(const PRUnichar* s1, const PRUnichar* s2, PRUint32 n) {
00228   if(s1 && s2) { 
00229     if(n != 0) {
00230       do {
00231         PRUnichar c1 = *s1++;
00232         PRUnichar c2 = *s2++;
00233         if (c1 != c2) {
00234           if (c1 < c2) return -1;
00235           return 1;
00236         }
00237       } while (--n != 0);
00238     }
00239   }
00240   return 0;
00241 }
00242 
00243 PRUnichar* nsCRT::strdup(const PRUnichar* str)
00244 {
00245   PRUint32 len = nsCRT::strlen(str);
00246   return strndup(str, len);
00247 }
00248 
00249 PRUnichar* nsCRT::strndup(const PRUnichar* str, PRUint32 len)
00250 {
00251        nsCppSharedAllocator<PRUnichar> shared_allocator;
00252        PRUnichar* rslt = shared_allocator.allocate(len + 1); // add one for the null
00253   // PRUnichar* rslt = new PRUnichar[len + 1];
00254 
00255   if (rslt == NULL) return NULL;
00256   memcpy(rslt, str, len * sizeof(PRUnichar));
00257   rslt[len] = 0;
00258   return rslt;
00259 }
00260 
00271 PRUint32 nsCRT::HashCode(const char* str, PRUint32* resultingStrLen)
00272 {
00273   PRUint32 h = 0;
00274   const char* s = str;
00275 
00276   if (!str) return h;
00277 
00278   unsigned char c;
00279   while ( (c = *s++) )
00280     h = (h>>28) ^ (h<<4) ^ c;
00281 
00282   if ( resultingStrLen )
00283     *resultingStrLen = (s-str)-1;
00284   return h;
00285 }
00286 
00287 PRUint32 nsCRT::HashCode(const PRUnichar* str, PRUint32* resultingStrLen)
00288 {
00289   PRUint32 h = 0;
00290   const PRUnichar* s = str;
00291 
00292   if (!str) return h;
00293 
00294   PRUnichar c;
00295   while ( (c = *s++) )
00296     h = (h>>28) ^ (h<<4) ^ c;
00297 
00298   if ( resultingStrLen )
00299     *resultingStrLen = (s-str)-1;
00300   return h;
00301 }
00302 
00303 PRUint32 nsCRT::BufferHashCode(const PRUnichar* s, PRUint32 len)
00304 {
00305   PRUint32 h = 0;
00306   const PRUnichar* done = s + len;
00307 
00308   while ( s < done )
00309     h = (h>>28) ^ (h<<4) ^ PRUint16(*s++); // cast to unsigned to prevent possible sign extension
00310 
00311   return h;
00312 }
00313 
00314 // This should use NSPR but NSPR isn't exporting its PR_strtoll function
00315 // Until then...
00316 PRInt64 nsCRT::atoll(const char *str)
00317 {
00318     if (!str)
00319         return LL_Zero();
00320 
00321     PRInt64 ll = LL_Zero(), digitll = LL_Zero();
00322 
00323     while (*str && *str >= '0' && *str <= '9') {
00324         LL_MUL(ll, ll, 10);
00325         LL_UI2L(digitll, (*str - '0'));
00326         LL_ADD(ll, ll, digitll);
00327         str++;
00328     }
00329 
00330     return ll;
00331 }
00332 
00340 PRBool nsCRT::IsAscii(PRUnichar aChar) {
00341   return (0x0080 > aChar);
00342 }
00350 PRBool nsCRT::IsAscii(const PRUnichar *aString) {
00351   while(*aString) {
00352      if( 0x0080 <= *aString)
00353         return PR_FALSE;
00354      aString++;
00355   }
00356   return PR_TRUE;
00357 }
00365 PRBool nsCRT::IsAscii(const char *aString) {
00366   while(*aString) {
00367      if( 0x80 & *aString)
00368         return PR_FALSE;
00369      aString++;
00370   }
00371   return PR_TRUE;
00372 }
00381 PRBool nsCRT::IsAscii(const char* aString, PRUint32 aLength)
00382 {
00383     const char* end = aString + aLength;
00384     while (aString < end) {
00385         NS_ASSERTION(*aString, "Null byte before end of data!");
00386         if (0x80 & *aString)
00387             return PR_FALSE;
00388         ++aString;
00389     }
00390     return PR_TRUE;
00391 }
00392 
00400 PRBool nsCRT::IsAsciiAlpha(PRUnichar aChar) {
00401   // XXX i18n
00402   if (((aChar >= 'A') && (aChar <= 'Z')) || ((aChar >= 'a') && (aChar <= 'z'))) {
00403     return PR_TRUE;
00404   }
00405   return PR_FALSE;
00406 }
00407 
00415 PRBool nsCRT::IsAsciiSpace(PRUnichar aChar) {
00416   // XXX i18n
00417   if ((aChar == ' ') || (aChar == '\r') || (aChar == '\n') || (aChar == '\t')) {
00418     return PR_TRUE;
00419   }
00420   return PR_FALSE;
00421 }
00422 
00423 
00424 
00432 PRBool nsCRT::IsAsciiDigit(PRUnichar aChar) {
00433   // XXX i18n
00434   return PRBool((aChar >= '0') && (aChar <= '9'));
00435 }