From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- xpcom/ds/nsCRT.cpp | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 xpcom/ds/nsCRT.cpp (limited to 'xpcom/ds/nsCRT.cpp') diff --git a/xpcom/ds/nsCRT.cpp b/xpcom/ds/nsCRT.cpp new file mode 100644 index 000000000..0d11a8c26 --- /dev/null +++ b/xpcom/ds/nsCRT.cpp @@ -0,0 +1,187 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + * MODULE NOTES: + * @update gess7/30/98 + * + * Much as I hate to do it, we were using string compares wrong. + * Often, programmers call functions like strcmp(s1,s2), and pass + * one or more null strings. Rather than blow up on these, I've + * added quick checks to ensure that cases like this don't cause + * us to fail. + * + * In general, if you pass a null into any of these string compare + * routines, we simply return 0. + */ + + +#include "nsCRT.h" +#include "nsDebug.h" + +//---------------------------------------------------------------------- + + +//////////////////////////////////////////////////////////////////////////////// +// My lovely strtok routine + +#define IS_DELIM(m, c) ((m)[(c) >> 3] & (1 << ((c) & 7))) +#define SET_DELIM(m, c) ((m)[(c) >> 3] |= (1 << ((c) & 7))) +#define DELIM_TABLE_SIZE 32 + +char* +nsCRT::strtok(char* aString, const char* aDelims, char** aNewStr) +{ + NS_ASSERTION(aString, + "Unlike regular strtok, the first argument cannot be null."); + + char delimTable[DELIM_TABLE_SIZE]; + uint32_t i; + char* result; + char* str = aString; + + for (i = 0; i < DELIM_TABLE_SIZE; ++i) { + delimTable[i] = '\0'; + } + + for (i = 0; aDelims[i]; i++) { + SET_DELIM(delimTable, static_cast(aDelims[i])); + } + NS_ASSERTION(aDelims[i] == '\0', "too many delimiters"); + + // skip to beginning + while (*str && IS_DELIM(delimTable, static_cast(*str))) { + str++; + } + result = str; + + // fix up the end of the token + while (*str) { + if (IS_DELIM(delimTable, static_cast(*str))) { + *str++ = '\0'; + break; + } + str++; + } + *aNewStr = str; + + return str == result ? nullptr : result; +} + +//////////////////////////////////////////////////////////////////////////////// + +/** + * Compare unichar string ptrs, stopping at the 1st null + * NOTE: If both are null, we return 0. + * NOTE: We terminate the search upon encountering a nullptr + * + * @update gess 11/10/99 + * @param s1 and s2 both point to unichar strings + * @return 0 if they match, -1 if s1s2 + */ +int32_t +nsCRT::strcmp(const char16_t* aStr1, const char16_t* aStr2) +{ + if (aStr1 && aStr2) { + for (;;) { + char16_t c1 = *aStr1++; + char16_t c2 = *aStr2++; + if (c1 != c2) { + if (c1 < c2) { + return -1; + } + return 1; + } + if (c1 == 0 || c2 == 0) { + break; + } + } + } else { + if (aStr1) { // aStr2 must have been null + return -1; + } + if (aStr2) { // aStr1 must have been null + return 1; + } + } + return 0; +} + +/** + * Compare unichar string ptrs, stopping at the 1st null or nth char. + * NOTE: If either is null, we return 0. + * NOTE: We DO NOT terminate the search upon encountering nullptr's before N + * + * @update gess 11/10/99 + * @param s1 and s2 both point to unichar strings + * @return 0 if they match, -1 if s1s2 + */ +int32_t +nsCRT::strncmp(const char16_t* aStr1, const char16_t* aStr2, uint32_t aNum) +{ + if (aStr1 && aStr2) { + if (aNum != 0) { + do { + char16_t c1 = *aStr1++; + char16_t c2 = *aStr2++; + if (c1 != c2) { + if (c1 < c2) { + return -1; + } + return 1; + } + } while (--aNum != 0); + } + } + return 0; +} + +const char* +nsCRT::memmem(const char* aHaystack, uint32_t aHaystackLen, + const char* aNeedle, uint32_t aNeedleLen) +{ + // Sanity checking + if (!(aHaystack && aNeedle && aHaystackLen && aNeedleLen && + aNeedleLen <= aHaystackLen)) { + return nullptr; + } + +#ifdef HAVE_MEMMEM + return (const char*)::memmem(aHaystack, aHaystackLen, aNeedle, aNeedleLen); +#else + // No memmem means we need to roll our own. This isn't really optimized + // for performance ... if that becomes an issue we can take some inspiration + // from the js string compare code in jsstr.cpp + for (uint32_t i = 0; i < aHaystackLen - aNeedleLen; i++) { + if (!memcmp(aHaystack + i, aNeedle, aNeedleLen)) { + return aHaystack + i; + } + } +#endif + return nullptr; +} + +// This should use NSPR but NSPR isn't exporting its PR_strtoll function +// Until then... +int64_t +nsCRT::atoll(const char* aStr) +{ + if (!aStr) { + return 0; + } + + int64_t ll = 0; + + while (*aStr && *aStr >= '0' && *aStr <= '9') { + ll *= 10; + ll += *aStr - '0'; + aStr++; + } + + return ll; +} + -- cgit v1.2.3