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