tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

StringUtils.h (3862B)


      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 /* String utility functions used by the module loader. */
      8 
      9 #ifndef shell_StringUtils_h
     10 #define shell_StringUtils_h
     11 
     12 #include "js/StableStringChars.h"
     13 #include "js/String.h"
     14 
     15 namespace js {
     16 namespace shell {
     17 
     18 inline char16_t CharAt(JSLinearString* str, size_t index) {
     19  return str->latin1OrTwoByteChar(index);
     20 }
     21 
     22 inline JSLinearString* SubString(JSContext* cx, JSLinearString* str,
     23                                 size_t start, size_t end) {
     24  MOZ_ASSERT(start <= str->length());
     25  MOZ_ASSERT(end >= start && end <= str->length());
     26  return NewDependentString(cx, str, start, end - start);
     27 }
     28 
     29 inline JSLinearString* SubString(JSContext* cx, JSLinearString* str,
     30                                 size_t start) {
     31  return SubString(cx, str, start, str->length());
     32 }
     33 
     34 template <size_t NullTerminatedLength>
     35 bool StringStartsWith(JSLinearString* str,
     36                      const char16_t (&chars)[NullTerminatedLength]) {
     37  MOZ_ASSERT(NullTerminatedLength > 0);
     38  const size_t length = NullTerminatedLength - 1;
     39  MOZ_ASSERT(chars[length] == '\0');
     40 
     41  if (str->length() < length) {
     42    return false;
     43  }
     44 
     45  for (size_t i = 0; i < length; i++) {
     46    if (CharAt(str, i) != chars[i]) {
     47      return false;
     48    }
     49  }
     50 
     51  return true;
     52 }
     53 
     54 template <size_t NullTerminatedLength>
     55 bool StringEquals(JSLinearString* str,
     56                  const char16_t (&chars)[NullTerminatedLength]) {
     57  MOZ_ASSERT(NullTerminatedLength > 0);
     58  const size_t length = NullTerminatedLength - 1;
     59  MOZ_ASSERT(chars[length] == '\0');
     60 
     61  return str->length() == length && StringStartsWith(str, chars);
     62 }
     63 
     64 inline int32_t IndexOf(Handle<JSLinearString*> str, char16_t target,
     65                       size_t start = 0) {
     66  int32_t length = str->length();
     67  for (int32_t i = start; i < length; i++) {
     68    if (CharAt(str, i) == target) {
     69      return i;
     70    }
     71  }
     72 
     73  return -1;
     74 }
     75 
     76 inline int32_t LastIndexOf(Handle<JSLinearString*> str, char16_t target) {
     77  int32_t length = str->length();
     78  for (int32_t i = length - 1; i >= 0; i--) {
     79    if (CharAt(str, i) == target) {
     80      return i;
     81    }
     82  }
     83 
     84  return -1;
     85 }
     86 
     87 inline JSLinearString* ReplaceCharGlobally(JSContext* cx,
     88                                           Handle<JSLinearString*> str,
     89                                           char16_t target,
     90                                           char16_t replacement) {
     91  int32_t i = IndexOf(str, target);
     92  if (i == -1) {
     93    return str;
     94  }
     95 
     96  JS::AutoStableStringChars chars(cx);
     97  if (!chars.initTwoByte(cx, str)) {
     98    return nullptr;
     99  }
    100 
    101  Vector<char16_t> buf(cx);
    102  if (!buf.append(chars.twoByteChars(), str->length())) {
    103    return nullptr;
    104  }
    105 
    106  for (; i < int32_t(buf.length()); i++) {
    107    if (buf[i] == target) {
    108      buf[i] = replacement;
    109    }
    110  }
    111 
    112  RootedString result(cx, JS_NewUCStringCopyN(cx, buf.begin(), buf.length()));
    113  if (!result) {
    114    return nullptr;
    115  }
    116 
    117  return JS_EnsureLinearString(cx, result);
    118 }
    119 
    120 inline JSString* JoinStrings(JSContext* cx,
    121                             Handle<GCVector<JSLinearString*>> strings,
    122                             Handle<JSLinearString*> separator) {
    123  RootedString result(cx, JS_GetEmptyString(cx));
    124 
    125  for (size_t i = 0; i < strings.length(); i++) {
    126    HandleString str = strings[i];
    127    if (i != 0) {
    128      result = JS_ConcatStrings(cx, result, separator);
    129      if (!result) {
    130        return nullptr;
    131      }
    132    }
    133 
    134    result = JS_ConcatStrings(cx, result, str);
    135    if (!result) {
    136      return nullptr;
    137    }
    138  }
    139 
    140  return result;
    141 }
    142 
    143 }  // namespace shell
    144 }  // namespace js
    145 
    146 #endif  // shell_StringUtils_h