xpcom/ds/nsCRT.cpp

changeset 0
6474c204b198
     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 +

mercurial