michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: #ifndef nsCRT_h___ michael@0: #define nsCRT_h___ michael@0: michael@0: #include michael@0: #include michael@0: #include "plstr.h" michael@0: #include "nscore.h" michael@0: #include "nsCRTGlue.h" michael@0: michael@0: #if defined(XP_WIN) michael@0: # define NS_LINEBREAK "\015\012" michael@0: # define NS_LINEBREAK_LEN 2 michael@0: #else michael@0: # ifdef XP_UNIX michael@0: # define NS_LINEBREAK "\012" michael@0: # define NS_LINEBREAK_LEN 1 michael@0: # endif /* XP_UNIX */ michael@0: #endif /* XP_WIN */ michael@0: michael@0: extern const char16_t kIsoLatin1ToUCS2[256]; michael@0: michael@0: // This macro can be used in a class declaration for classes that want michael@0: // to ensure that their instance memory is zeroed. michael@0: #define NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW \ michael@0: void* operator new(size_t sz) CPP_THROW_NEW { \ michael@0: void* rv = ::operator new(sz); \ michael@0: if (rv) { \ michael@0: memset(rv, 0, sz); \ michael@0: } \ michael@0: return rv; \ michael@0: } \ michael@0: void operator delete(void* ptr) { \ michael@0: ::operator delete(ptr); \ michael@0: } michael@0: michael@0: // This macro works with the next macro to declare a non-inlined michael@0: // version of the above. michael@0: #define NS_DECL_ZEROING_OPERATOR_NEW \ michael@0: void* operator new(size_t sz) CPP_THROW_NEW; \ michael@0: void operator delete(void* ptr); michael@0: michael@0: #define NS_IMPL_ZEROING_OPERATOR_NEW(_class) \ michael@0: void* _class::operator new(size_t sz) CPP_THROW_NEW { \ michael@0: void* rv = ::operator new(sz); \ michael@0: if (rv) { \ michael@0: memset(rv, 0, sz); \ michael@0: } \ michael@0: return rv; \ michael@0: } \ michael@0: void _class::operator delete(void* ptr) { \ michael@0: ::operator delete(ptr); \ michael@0: } michael@0: michael@0: // Freeing helper michael@0: #define CRTFREEIF(x) if (x) { nsCRT::free(x); x = 0; } michael@0: michael@0: /// This is a wrapper class around all the C runtime functions. michael@0: michael@0: class nsCRT { michael@0: public: michael@0: enum { michael@0: LF='\n' /* Line Feed */, michael@0: VTAB='\v' /* Vertical Tab */, michael@0: CR='\r' /* Carriage Return */ michael@0: }; michael@0: michael@0: /// Compare s1 and s2. michael@0: static int32_t strcmp(const char* s1, const char* s2) { michael@0: return int32_t(PL_strcmp(s1, s2)); michael@0: } michael@0: michael@0: static int32_t strncmp(const char* s1, const char* s2, michael@0: uint32_t aMaxLen) { michael@0: return int32_t(PL_strncmp(s1, s2, aMaxLen)); michael@0: } michael@0: michael@0: /// Case-insensitive string comparison. michael@0: static int32_t strcasecmp(const char* s1, const char* s2) { michael@0: return int32_t(PL_strcasecmp(s1, s2)); michael@0: } michael@0: michael@0: /// Case-insensitive string comparison with length michael@0: static int32_t strncasecmp(const char* s1, const char* s2, uint32_t aMaxLen) { michael@0: int32_t result=int32_t(PL_strncasecmp(s1, s2, aMaxLen)); michael@0: //Egads. PL_strncasecmp is returning *very* negative numbers. michael@0: //Some folks expect -1,0,1, so let's temper its enthusiasm. michael@0: if (result<0) michael@0: result=-1; michael@0: return result; michael@0: } michael@0: michael@0: static int32_t strncmp(const char* s1, const char* s2, int32_t aMaxLen) { michael@0: // inline the first test (assumes strings are not null): michael@0: int32_t diff = ((const unsigned char*)s1)[0] - ((const unsigned char*)s2)[0]; michael@0: if (diff != 0) return diff; michael@0: return int32_t(PL_strncmp(s1,s2,unsigned(aMaxLen))); michael@0: } michael@0: michael@0: /** michael@0: michael@0: How to use this fancy (thread-safe) version of strtok: michael@0: michael@0: void main(void) { michael@0: printf("%s\n\nTokens:\n", string); michael@0: // Establish string and get the first token: michael@0: char* newStr; michael@0: token = nsCRT::strtok(string, seps, &newStr); michael@0: while (token != nullptr) { michael@0: // While there are tokens in "string" michael@0: printf(" %s\n", token); michael@0: // Get next token: michael@0: token = nsCRT::strtok(newStr, seps, &newStr); michael@0: } michael@0: } michael@0: * WARNING - STRTOK WHACKS str THE FIRST TIME IT IS CALLED * michael@0: * MAKE A COPY OF str IF YOU NEED TO USE IT AFTER strtok() * michael@0: */ michael@0: static char* strtok(char* str, const char* delims, char* *newStr); michael@0: michael@0: /// Like strcmp except for ucs2 strings michael@0: static int32_t strcmp(const char16_t* s1, const char16_t* s2); michael@0: /// Like strcmp except for ucs2 strings michael@0: static int32_t strncmp(const char16_t* s1, const char16_t* s2, michael@0: uint32_t aMaxLen); michael@0: michael@0: // The GNU libc has memmem, which is strstr except for binary data michael@0: // This is our own implementation that uses memmem on platforms michael@0: // where it's available. michael@0: static const char* memmem(const char* haystack, uint32_t haystackLen, michael@0: const char* needle, uint32_t needleLen); michael@0: michael@0: // String to longlong michael@0: static int64_t atoll(const char *str); michael@0: michael@0: static char ToUpper(char aChar) { return NS_ToUpper(aChar); } michael@0: static char ToLower(char aChar) { return NS_ToLower(aChar); } michael@0: michael@0: static bool IsUpper(char aChar) { return NS_IsUpper(aChar); } michael@0: static bool IsLower(char aChar) { return NS_IsLower(aChar); } michael@0: michael@0: static bool IsAscii(char16_t aChar) { return NS_IsAscii(aChar); } michael@0: static bool IsAscii(const char16_t* aString) { return NS_IsAscii(aString); } michael@0: static bool IsAsciiAlpha(char16_t aChar) { return NS_IsAsciiAlpha(aChar); } michael@0: static bool IsAsciiDigit(char16_t aChar) { return NS_IsAsciiDigit(aChar); } michael@0: static bool IsAsciiSpace(char16_t aChar) { return NS_IsAsciiWhitespace(aChar); } michael@0: static bool IsAscii(const char* aString) { return NS_IsAscii(aString); } michael@0: static bool IsAscii(const char* aString, uint32_t aLength) { return NS_IsAscii(aString, aLength); } michael@0: }; michael@0: michael@0: michael@0: inline bool michael@0: NS_IS_SPACE(char16_t c) michael@0: { michael@0: return ((int(c) & 0x7f) == int(c)) && isspace(int(c)); michael@0: } michael@0: michael@0: #define NS_IS_CNTRL(i) ((((unsigned int) (i)) > 0x7f) ? (int) 0 : iscntrl(i)) michael@0: #define NS_IS_DIGIT(i) ((((unsigned int) (i)) > 0x7f) ? (int) 0 : isdigit(i)) michael@0: #if defined(XP_WIN) michael@0: #define NS_IS_ALPHA(VAL) (isascii((int)(VAL)) && isalpha((int)(VAL))) michael@0: #else michael@0: #define NS_IS_ALPHA(VAL) ((((unsigned int) (VAL)) > 0x7f) ? (int) 0 : isalpha((int)(VAL))) michael@0: #endif michael@0: michael@0: michael@0: #endif /* nsCRT_h___ */