xpcom/ds/nsCRT.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial