Bumping manifests a=b2g-bump
[gecko.git] / xpcom / ds / nsCRT.cpp
blob3bb53f86fba01b96753719bcc294b8665360734f
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /**
8 * MODULE NOTES:
9 * @update gess7/30/98
11 * Much as I hate to do it, we were using string compares wrong.
12 * Often, programmers call functions like strcmp(s1,s2), and pass
13 * one or more null strings. Rather than blow up on these, I've
14 * added quick checks to ensure that cases like this don't cause
15 * us to fail.
17 * In general, if you pass a null into any of these string compare
18 * routines, we simply return 0.
22 #include "nsCRT.h"
23 #include "nsDebug.h"
25 //----------------------------------------------------------------------
28 ////////////////////////////////////////////////////////////////////////////////
29 // My lovely strtok routine
31 #define IS_DELIM(m, c) ((m)[(c) >> 3] & (1 << ((c) & 7)))
32 #define SET_DELIM(m, c) ((m)[(c) >> 3] |= (1 << ((c) & 7)))
33 #define DELIM_TABLE_SIZE 32
35 char*
36 nsCRT::strtok(char* aString, const char* aDelims, char** aNewStr)
38 NS_ASSERTION(aString,
39 "Unlike regular strtok, the first argument cannot be null.");
41 char delimTable[DELIM_TABLE_SIZE];
42 uint32_t i;
43 char* result;
44 char* str = aString;
46 for (i = 0; i < DELIM_TABLE_SIZE; ++i) {
47 delimTable[i] = '\0';
50 for (i = 0; aDelims[i]; i++) {
51 SET_DELIM(delimTable, static_cast<uint8_t>(aDelims[i]));
53 NS_ASSERTION(aDelims[i] == '\0', "too many delimiters");
55 // skip to beginning
56 while (*str && IS_DELIM(delimTable, static_cast<uint8_t>(*str))) {
57 str++;
59 result = str;
61 // fix up the end of the token
62 while (*str) {
63 if (IS_DELIM(delimTable, static_cast<uint8_t>(*str))) {
64 *str++ = '\0';
65 break;
67 str++;
69 *aNewStr = str;
71 return str == result ? nullptr : result;
74 ////////////////////////////////////////////////////////////////////////////////
76 /**
77 * Compare unichar string ptrs, stopping at the 1st null
78 * NOTE: If both are null, we return 0.
79 * NOTE: We terminate the search upon encountering a nullptr
81 * @update gess 11/10/99
82 * @param s1 and s2 both point to unichar strings
83 * @return 0 if they match, -1 if s1<s2; 1 if s1>s2
85 int32_t
86 nsCRT::strcmp(const char16_t* aStr1, const char16_t* aStr2)
88 if (aStr1 && aStr2) {
89 for (;;) {
90 char16_t c1 = *aStr1++;
91 char16_t c2 = *aStr2++;
92 if (c1 != c2) {
93 if (c1 < c2) {
94 return -1;
96 return 1;
98 if (c1 == 0 || c2 == 0) {
99 break;
102 } else {
103 if (aStr1) { // aStr2 must have been null
104 return -1;
106 if (aStr2) { // aStr1 must have been null
107 return 1;
110 return 0;
114 * Compare unichar string ptrs, stopping at the 1st null or nth char.
115 * NOTE: If either is null, we return 0.
116 * NOTE: We DO NOT terminate the search upon encountering nullptr's before N
118 * @update gess 11/10/99
119 * @param s1 and s2 both point to unichar strings
120 * @return 0 if they match, -1 if s1<s2; 1 if s1>s2
122 int32_t
123 nsCRT::strncmp(const char16_t* aStr1, const char16_t* aStr2, uint32_t aNum)
125 if (aStr1 && aStr2) {
126 if (aNum != 0) {
127 do {
128 char16_t c1 = *aStr1++;
129 char16_t c2 = *aStr2++;
130 if (c1 != c2) {
131 if (c1 < c2) {
132 return -1;
134 return 1;
136 } while (--aNum != 0);
139 return 0;
142 const char*
143 nsCRT::memmem(const char* aHaystack, uint32_t aHaystackLen,
144 const char* aNeedle, uint32_t aNeedleLen)
146 // Sanity checking
147 if (!(aHaystack && aNeedle && aHaystackLen && aNeedleLen &&
148 aNeedleLen <= aHaystackLen)) {
149 return nullptr;
152 #ifdef HAVE_MEMMEM
153 return (const char*)::memmem(aHaystack, aHaystackLen, aNeedle, aNeedleLen);
154 #else
155 // No memmem means we need to roll our own. This isn't really optimized
156 // for performance ... if that becomes an issue we can take some inspiration
157 // from the js string compare code in jsstr.cpp
158 for (uint32_t i = 0; i < aHaystackLen - aNeedleLen; i++) {
159 if (!memcmp(aHaystack + i, aNeedle, aNeedleLen)) {
160 return aHaystack + i;
163 #endif
164 return nullptr;
167 // This should use NSPR but NSPR isn't exporting its PR_strtoll function
168 // Until then...
169 int64_t
170 nsCRT::atoll(const char* aStr)
172 if (!aStr) {
173 return 0;
176 int64_t ll = 0;
178 while (*aStr && *aStr >= '0' && *aStr <= '9') {
179 ll *= 10;
180 ll += *aStr - '0';
181 aStr++;
184 return ll;