Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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
10 *
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.
16 *
17 * In general, if you pass a null into any of these string compare
18 * routines, we simply return 0.
19 */
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* nsCRT::strtok(char* string, const char* delims, char* *newStr)
36 {
37 NS_ASSERTION(string, "Unlike regular strtok, the first argument cannot be null.");
39 char delimTable[DELIM_TABLE_SIZE];
40 uint32_t i;
41 char* result;
42 char* str = string;
44 for (i = 0; i < DELIM_TABLE_SIZE; i++)
45 delimTable[i] = '\0';
47 for (i = 0; delims[i]; i++) {
48 SET_DELIM(delimTable, static_cast<uint8_t>(delims[i]));
49 }
50 NS_ASSERTION(delims[i] == '\0', "too many delimiters");
52 // skip to beginning
53 while (*str && IS_DELIM(delimTable, static_cast<uint8_t>(*str))) {
54 str++;
55 }
56 result = str;
58 // fix up the end of the token
59 while (*str) {
60 if (IS_DELIM(delimTable, static_cast<uint8_t>(*str))) {
61 *str++ = '\0';
62 break;
63 }
64 str++;
65 }
66 *newStr = str;
68 return str == result ? nullptr : result;
69 }
71 ////////////////////////////////////////////////////////////////////////////////
73 /**
74 * Compare unichar string ptrs, stopping at the 1st null
75 * NOTE: If both are null, we return 0.
76 * NOTE: We terminate the search upon encountering a nullptr
77 *
78 * @update gess 11/10/99
79 * @param s1 and s2 both point to unichar strings
80 * @return 0 if they match, -1 if s1<s2; 1 if s1>s2
81 */
82 int32_t nsCRT::strcmp(const char16_t* s1, const char16_t* s2) {
83 if(s1 && s2) {
84 for (;;) {
85 char16_t c1 = *s1++;
86 char16_t c2 = *s2++;
87 if (c1 != c2) {
88 if (c1 < c2) return -1;
89 return 1;
90 }
91 if ((0==c1) || (0==c2)) break;
92 }
93 }
94 else {
95 if (s1) // s2 must have been null
96 return -1;
97 if (s2) // s1 must have been null
98 return 1;
99 }
100 return 0;
101 }
103 /**
104 * Compare unichar string ptrs, stopping at the 1st null or nth char.
105 * NOTE: If either is null, we return 0.
106 * NOTE: We DO NOT terminate the search upon encountering nullptr's before N
107 *
108 * @update gess 11/10/99
109 * @param s1 and s2 both point to unichar strings
110 * @return 0 if they match, -1 if s1<s2; 1 if s1>s2
111 */
112 int32_t nsCRT::strncmp(const char16_t* s1, const char16_t* s2, uint32_t n) {
113 if(s1 && s2) {
114 if(n != 0) {
115 do {
116 char16_t c1 = *s1++;
117 char16_t c2 = *s2++;
118 if (c1 != c2) {
119 if (c1 < c2) return -1;
120 return 1;
121 }
122 } while (--n != 0);
123 }
124 }
125 return 0;
126 }
128 const char* nsCRT::memmem(const char* haystack, uint32_t haystackLen,
129 const char* needle, uint32_t needleLen)
130 {
131 // Sanity checking
132 if (!(haystack && needle && haystackLen && needleLen &&
133 needleLen <= haystackLen))
134 return nullptr;
136 #ifdef HAVE_MEMMEM
137 return (const char*)::memmem(haystack, haystackLen, needle, needleLen);
138 #else
139 // No memmem means we need to roll our own. This isn't really optimized
140 // for performance ... if that becomes an issue we can take some inspiration
141 // from the js string compare code in jsstr.cpp
142 for (uint32_t i = 0; i < haystackLen - needleLen; i++) {
143 if (!memcmp(haystack + i, needle, needleLen))
144 return haystack + i;
145 }
146 #endif
147 return nullptr;
148 }
150 // This should use NSPR but NSPR isn't exporting its PR_strtoll function
151 // Until then...
152 int64_t nsCRT::atoll(const char *str)
153 {
154 if (!str)
155 return 0;
157 int64_t ll = 0;
159 while (*str && *str >= '0' && *str <= '9') {
160 ll *= 10;
161 ll += *str - '0';
162 str++;
163 }
165 return ll;
166 }