1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/ds/nsCRT.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,167 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 + 1.10 +/** 1.11 + * MODULE NOTES: 1.12 + * @update gess7/30/98 1.13 + * 1.14 + * Much as I hate to do it, we were using string compares wrong. 1.15 + * Often, programmers call functions like strcmp(s1,s2), and pass 1.16 + * one or more null strings. Rather than blow up on these, I've 1.17 + * added quick checks to ensure that cases like this don't cause 1.18 + * us to fail. 1.19 + * 1.20 + * In general, if you pass a null into any of these string compare 1.21 + * routines, we simply return 0. 1.22 + */ 1.23 + 1.24 + 1.25 +#include "nsCRT.h" 1.26 +#include "nsDebug.h" 1.27 + 1.28 +//---------------------------------------------------------------------- 1.29 + 1.30 + 1.31 +//////////////////////////////////////////////////////////////////////////////// 1.32 +// My lovely strtok routine 1.33 + 1.34 +#define IS_DELIM(m, c) ((m)[(c) >> 3] & (1 << ((c) & 7))) 1.35 +#define SET_DELIM(m, c) ((m)[(c) >> 3] |= (1 << ((c) & 7))) 1.36 +#define DELIM_TABLE_SIZE 32 1.37 + 1.38 +char* nsCRT::strtok(char* string, const char* delims, char* *newStr) 1.39 +{ 1.40 + NS_ASSERTION(string, "Unlike regular strtok, the first argument cannot be null."); 1.41 + 1.42 + char delimTable[DELIM_TABLE_SIZE]; 1.43 + uint32_t i; 1.44 + char* result; 1.45 + char* str = string; 1.46 + 1.47 + for (i = 0; i < DELIM_TABLE_SIZE; i++) 1.48 + delimTable[i] = '\0'; 1.49 + 1.50 + for (i = 0; delims[i]; i++) { 1.51 + SET_DELIM(delimTable, static_cast<uint8_t>(delims[i])); 1.52 + } 1.53 + NS_ASSERTION(delims[i] == '\0', "too many delimiters"); 1.54 + 1.55 + // skip to beginning 1.56 + while (*str && IS_DELIM(delimTable, static_cast<uint8_t>(*str))) { 1.57 + str++; 1.58 + } 1.59 + result = str; 1.60 + 1.61 + // fix up the end of the token 1.62 + while (*str) { 1.63 + if (IS_DELIM(delimTable, static_cast<uint8_t>(*str))) { 1.64 + *str++ = '\0'; 1.65 + break; 1.66 + } 1.67 + str++; 1.68 + } 1.69 + *newStr = str; 1.70 + 1.71 + return str == result ? nullptr : result; 1.72 +} 1.73 + 1.74 +//////////////////////////////////////////////////////////////////////////////// 1.75 + 1.76 +/** 1.77 + * Compare unichar string ptrs, stopping at the 1st null 1.78 + * NOTE: If both are null, we return 0. 1.79 + * NOTE: We terminate the search upon encountering a nullptr 1.80 + * 1.81 + * @update gess 11/10/99 1.82 + * @param s1 and s2 both point to unichar strings 1.83 + * @return 0 if they match, -1 if s1<s2; 1 if s1>s2 1.84 + */ 1.85 +int32_t nsCRT::strcmp(const char16_t* s1, const char16_t* s2) { 1.86 + if(s1 && s2) { 1.87 + for (;;) { 1.88 + char16_t c1 = *s1++; 1.89 + char16_t c2 = *s2++; 1.90 + if (c1 != c2) { 1.91 + if (c1 < c2) return -1; 1.92 + return 1; 1.93 + } 1.94 + if ((0==c1) || (0==c2)) break; 1.95 + } 1.96 + } 1.97 + else { 1.98 + if (s1) // s2 must have been null 1.99 + return -1; 1.100 + if (s2) // s1 must have been null 1.101 + return 1; 1.102 + } 1.103 + return 0; 1.104 +} 1.105 + 1.106 +/** 1.107 + * Compare unichar string ptrs, stopping at the 1st null or nth char. 1.108 + * NOTE: If either is null, we return 0. 1.109 + * NOTE: We DO NOT terminate the search upon encountering nullptr's before N 1.110 + * 1.111 + * @update gess 11/10/99 1.112 + * @param s1 and s2 both point to unichar strings 1.113 + * @return 0 if they match, -1 if s1<s2; 1 if s1>s2 1.114 + */ 1.115 +int32_t nsCRT::strncmp(const char16_t* s1, const char16_t* s2, uint32_t n) { 1.116 + if(s1 && s2) { 1.117 + if(n != 0) { 1.118 + do { 1.119 + char16_t c1 = *s1++; 1.120 + char16_t c2 = *s2++; 1.121 + if (c1 != c2) { 1.122 + if (c1 < c2) return -1; 1.123 + return 1; 1.124 + } 1.125 + } while (--n != 0); 1.126 + } 1.127 + } 1.128 + return 0; 1.129 +} 1.130 + 1.131 +const char* nsCRT::memmem(const char* haystack, uint32_t haystackLen, 1.132 + const char* needle, uint32_t needleLen) 1.133 +{ 1.134 + // Sanity checking 1.135 + if (!(haystack && needle && haystackLen && needleLen && 1.136 + needleLen <= haystackLen)) 1.137 + return nullptr; 1.138 + 1.139 +#ifdef HAVE_MEMMEM 1.140 + return (const char*)::memmem(haystack, haystackLen, needle, needleLen); 1.141 +#else 1.142 + // No memmem means we need to roll our own. This isn't really optimized 1.143 + // for performance ... if that becomes an issue we can take some inspiration 1.144 + // from the js string compare code in jsstr.cpp 1.145 + for (uint32_t i = 0; i < haystackLen - needleLen; i++) { 1.146 + if (!memcmp(haystack + i, needle, needleLen)) 1.147 + return haystack + i; 1.148 + } 1.149 +#endif 1.150 + return nullptr; 1.151 +} 1.152 + 1.153 +// This should use NSPR but NSPR isn't exporting its PR_strtoll function 1.154 +// Until then... 1.155 +int64_t nsCRT::atoll(const char *str) 1.156 +{ 1.157 + if (!str) 1.158 + return 0; 1.159 + 1.160 + int64_t ll = 0; 1.161 + 1.162 + while (*str && *str >= '0' && *str <= '9') { 1.163 + ll *= 10; 1.164 + ll += *str - '0'; 1.165 + str++; 1.166 + } 1.167 + 1.168 + return ll; 1.169 +} 1.170 +