StringAsciiChars.h (2148B)
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 #ifndef builtin_intl_StringAsciiChars_h 8 #define builtin_intl_StringAsciiChars_h 9 10 #include "mozilla/Assertions.h" 11 #include "mozilla/Attributes.h" 12 #include "mozilla/Maybe.h" 13 #include "mozilla/Span.h" 14 15 #include <stddef.h> 16 17 #include "js/GCAPI.h" 18 #include "js/TypeDecls.h" 19 #include "js/Vector.h" 20 21 #include "vm/StringType.h" 22 23 namespace js::intl { 24 25 /** 26 * String view of an ASCII-only string. 27 * 28 * This holds a reference to a JSLinearString and can produce a string view 29 * into that string. If the string is represented by Latin1 characters, the 30 * span is returned directly. If the string is represented by UTF-16 31 * characters, it copies the char16_t characters into a char array, and then 32 * returns a span based on the copy. 33 * 34 * This allows us to avoid copying for the common use case that the ASCII 35 * characters are represented in Latin1. 36 */ 37 class MOZ_STACK_CLASS StringAsciiChars final { 38 // When copying string characters, use this many bytes of inline storage. 39 static const size_t InlineCapacity = 24; 40 41 JS::AutoCheckCannotGC nogc_; 42 43 const JSLinearString* str_; 44 45 mozilla::Maybe<Vector<Latin1Char, InlineCapacity>> ownChars_; 46 47 public: 48 explicit StringAsciiChars(const JSLinearString* str) : str_(str) { 49 MOZ_ASSERT(StringIsAscii(str)); 50 } 51 52 operator mozilla::Span<const char>() const { 53 if (str_->hasLatin1Chars()) { 54 return mozilla::AsChars(str_->latin1Range(nogc_)); 55 } 56 return mozilla::AsChars(mozilla::Span<const Latin1Char>(*ownChars_)); 57 } 58 59 [[nodiscard]] bool init(JSContext* cx) { 60 if (str_->hasLatin1Chars()) { 61 return true; 62 } 63 64 ownChars_.emplace(cx); 65 if (!ownChars_->resize(str_->length())) { 66 return false; 67 } 68 69 js::CopyChars(ownChars_->begin(), *str_); 70 71 return true; 72 } 73 }; 74 75 } // namespace js::intl 76 77 #endif // builtin_intl_StringAsciiChars_h