summaryrefslogtreecommitdiffstats
path: root/js/src/shell/StringUtils.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/shell/StringUtils.h')
-rw-r--r--js/src/shell/StringUtils.h146
1 files changed, 146 insertions, 0 deletions
diff --git a/js/src/shell/StringUtils.h b/js/src/shell/StringUtils.h
new file mode 100644
index 0000000000..1267c81eee
--- /dev/null
+++ b/js/src/shell/StringUtils.h
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* String utility functions used by the module loader. */
+
+#ifndef shell_StringUtils_h
+#define shell_StringUtils_h
+
+#include "js/StableStringChars.h"
+#include "js/String.h"
+
+namespace js {
+namespace shell {
+
+inline char16_t CharAt(JSLinearString* str, size_t index) {
+ return str->latin1OrTwoByteChar(index);
+}
+
+inline JSLinearString* SubString(JSContext* cx, JSLinearString* str,
+ size_t start, size_t end) {
+ MOZ_ASSERT(start <= str->length());
+ MOZ_ASSERT(end >= start && end <= str->length());
+ return NewDependentString(cx, str, start, end - start);
+}
+
+inline JSLinearString* SubString(JSContext* cx, JSLinearString* str,
+ size_t start) {
+ return SubString(cx, str, start, str->length());
+}
+
+template <size_t NullTerminatedLength>
+bool StringStartsWith(JSLinearString* str,
+ const char16_t (&chars)[NullTerminatedLength]) {
+ MOZ_ASSERT(NullTerminatedLength > 0);
+ const size_t length = NullTerminatedLength - 1;
+ MOZ_ASSERT(chars[length] == '\0');
+
+ if (str->length() < length) {
+ return false;
+ }
+
+ for (size_t i = 0; i < length; i++) {
+ if (CharAt(str, i) != chars[i]) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+template <size_t NullTerminatedLength>
+bool StringEquals(JSLinearString* str,
+ const char16_t (&chars)[NullTerminatedLength]) {
+ MOZ_ASSERT(NullTerminatedLength > 0);
+ const size_t length = NullTerminatedLength - 1;
+ MOZ_ASSERT(chars[length] == '\0');
+
+ return str->length() == length && StringStartsWith(str, chars);
+}
+
+inline int32_t IndexOf(Handle<JSLinearString*> str, char16_t target,
+ size_t start = 0) {
+ int32_t length = str->length();
+ for (int32_t i = start; i < length; i++) {
+ if (CharAt(str, i) == target) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+inline int32_t LastIndexOf(Handle<JSLinearString*> str, char16_t target) {
+ int32_t length = str->length();
+ for (int32_t i = length - 1; i >= 0; i--) {
+ if (CharAt(str, i) == target) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+inline JSLinearString* ReplaceCharGlobally(JSContext* cx,
+ Handle<JSLinearString*> str,
+ char16_t target,
+ char16_t replacement) {
+ int32_t i = IndexOf(str, target);
+ if (i == -1) {
+ return str;
+ }
+
+ JS::AutoStableStringChars chars(cx);
+ if (!chars.initTwoByte(cx, str)) {
+ return nullptr;
+ }
+
+ Vector<char16_t> buf(cx);
+ if (!buf.append(chars.twoByteChars(), str->length())) {
+ return nullptr;
+ }
+
+ for (; i < int32_t(buf.length()); i++) {
+ if (buf[i] == target) {
+ buf[i] = replacement;
+ }
+ }
+
+ RootedString result(cx, JS_NewUCStringCopyN(cx, buf.begin(), buf.length()));
+ if (!result) {
+ return nullptr;
+ }
+
+ return JS_EnsureLinearString(cx, result);
+}
+
+inline JSString* JoinStrings(JSContext* cx,
+ Handle<GCVector<JSLinearString*>> strings,
+ Handle<JSLinearString*> separator) {
+ RootedString result(cx, JS_GetEmptyString(cx));
+
+ for (size_t i = 0; i < strings.length(); i++) {
+ HandleString str = strings[i];
+ if (i != 0) {
+ result = JS_ConcatStrings(cx, result, separator);
+ if (!result) {
+ return nullptr;
+ }
+ }
+
+ result = JS_ConcatStrings(cx, result, str);
+ if (!result) {
+ return nullptr;
+ }
+ }
+
+ return result;
+}
+
+} // namespace shell
+} // namespace js
+
+#endif // shell_StringUtils_h