/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99: * 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/. */ #ifndef jsstrinlines_h___ #define jsstrinlines_h___ #include "mozilla/Attributes.h" #include "jsatom.h" #include "jsstr.h" #include "jscntxtinlines.h" #include "jsgcinlines.h" #include "vm/String-inl.h" namespace js { class RopeBuilder { JSContext *cx; RootedString res; RopeBuilder(const RopeBuilder &other) MOZ_DELETE; void operator=(const RopeBuilder &other) MOZ_DELETE; public: RopeBuilder(JSContext *cx) : cx(cx), res(cx, cx->runtime->emptyString) {} inline bool append(HandleString str) { res = ConcatStrings(cx, res, str); return !!res; } inline JSString *result() { return res; } }; class StringSegmentRange { /* * If malloc() shows up in any profiles from this vector, we can add a new * StackAllocPolicy which stashes a reusable freed-at-gc buffer in the cx. */ AutoStringVector stack; Rooted cur; bool settle(JSString *str) { while (str->isRope()) { JSRope &rope = str->asRope(); if (!stack.append(rope.rightChild())) return false; str = rope.leftChild(); } cur = &str->asLinear(); return true; } public: StringSegmentRange(JSContext *cx) : stack(cx), cur(cx) {} JS_WARN_UNUSED_RESULT bool init(JSString *str) { JS_ASSERT(stack.empty()); return settle(str); } bool empty() const { return cur == NULL; } JSLinearString *front() const { JS_ASSERT(!cur->isRope()); return cur; } JS_WARN_UNUSED_RESULT bool popFront() { JS_ASSERT(!empty()); if (stack.empty()) { cur = NULL; return true; } return settle(stack.popCopy()); } }; /* * Return s advanced past any Unicode white space characters. */ static inline const jschar * SkipSpace(const jschar *s, const jschar *end) { JS_ASSERT(s <= end); while (s < end && unicode::IsSpace(*s)) s++; return s; } /* * Return less than, equal to, or greater than zero depending on whether * s1 is less than, equal to, or greater than s2. */ inline bool CompareChars(const jschar *s1, size_t l1, const jschar *s2, size_t l2, int32_t *result) { size_t n = Min(l1, l2); for (size_t i = 0; i < n; i++) { if (int32_t cmp = s1[i] - s2[i]) { *result = cmp; return true; } } *result = (int32_t)(l1 - l2); return true; } } /* namespace js */ #endif /* jsstrinlines_h___ */