Bumping manifests a=b2g-bump
[gecko.git] / js / src / jsstr.h
blobcbb9fde90729282fccc091b99ce3aa69fdf93ae3
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
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/. */
7 #ifndef jsstr_h
8 #define jsstr_h
10 #include "mozilla/HashFunctions.h"
11 #include "mozilla/PodOperations.h"
12 #include "mozilla/UniquePtr.h"
14 #include "jsutil.h"
15 #include "NamespaceImports.h"
17 #include "gc/Rooting.h"
18 #include "js/RootingAPI.h"
19 #include "vm/Unicode.h"
21 class JSAutoByteString;
22 class JSFlatString;
23 class JSLinearString;
25 namespace js {
27 class StringBuffer;
29 class MutatingRopeSegmentRange;
31 template <AllowGC allowGC>
32 extern JSString*
33 ConcatStrings(ThreadSafeContext* cx,
34 typename MaybeRooted<JSString*, allowGC>::HandleType left,
35 typename MaybeRooted<JSString*, allowGC>::HandleType right);
37 // Return s advanced past any Unicode white space characters.
38 template <typename CharT>
39 static inline const CharT*
40 SkipSpace(const CharT* s, const CharT* end)
42 JS_ASSERT(s <= end);
44 while (s < end && unicode::IsSpace(*s))
45 s++;
47 return s;
50 // Return less than, equal to, or greater than zero depending on whether
51 // s1 is less than, equal to, or greater than s2.
52 template <typename Char1, typename Char2>
53 inline int32_t
54 CompareChars(const Char1* s1, size_t len1, const Char2* s2, size_t len2)
56 size_t n = Min(len1, len2);
57 for (size_t i = 0; i < n; i++) {
58 if (int32_t cmp = s1[i] - s2[i])
59 return cmp;
62 return int32_t(len1 - len2);
65 extern int32_t
66 CompareChars(const jschar* s1, size_t len1, JSLinearString* s2);
68 } /* namespace js */
70 struct JSSubString {
71 JSLinearString* base;
72 size_t offset;
73 size_t length;
75 JSSubString() { mozilla::PodZero(this); }
77 void initEmpty(JSLinearString* base) {
78 this->base = base;
79 offset = length = 0;
81 void init(JSLinearString* base, size_t offset, size_t length) {
82 this->base = base;
83 this->offset = offset;
84 this->length = length;
89 * Shorthands for ASCII (7-bit) decimal and hex conversion.
90 * Manually inline isdigit for performance; MSVC doesn't do this for us.
92 #define JS7_ISDEC(c) ((((unsigned)(c)) - '0') <= 9)
93 #define JS7_UNDEC(c) ((c) - '0')
94 #define JS7_ISHEX(c) ((c) < 128 && isxdigit(c))
95 #define JS7_UNHEX(c) (unsigned)(JS7_ISDEC(c) ? (c) - '0' : 10 + tolower(c) - 'a')
96 #define JS7_ISLET(c) ((c) < 128 && isalpha(c))
98 /* Initialize the String class, returning its prototype object. */
99 extern JSObject*
100 js_InitStringClass(JSContext* cx, js::HandleObject obj);
103 * Convert a value to a printable C string.
105 extern const char*
106 js_ValueToPrintable(JSContext* cx, const js::Value&,
107 JSAutoByteString* bytes, bool asSource = false);
109 extern size_t
110 js_strlen(const jschar* s);
112 extern int32_t
113 js_strcmp(const jschar* lhs, const jschar* rhs);
115 template <typename CharT>
116 extern const CharT*
117 js_strchr_limit(const CharT* s, jschar c, const CharT* limit);
119 static MOZ_ALWAYS_INLINE void
120 js_strncpy(jschar* dst, const jschar* src, size_t nelem)
122 return mozilla::PodCopy(dst, src, nelem);
125 namespace js {
127 extern mozilla::UniquePtr<char[], JS::FreePolicy>
128 DuplicateString(ThreadSafeContext* cx, const char* s);
130 extern mozilla::UniquePtr<jschar[], JS::FreePolicy>
131 DuplicateString(ThreadSafeContext* cx, const jschar* s);
134 * Convert a non-string value to a string, returning null after reporting an
135 * error, otherwise returning a new string reference.
137 template <AllowGC allowGC>
138 extern JSString*
139 ToStringSlow(ExclusiveContext* cx, typename MaybeRooted<Value, allowGC>::HandleType arg);
142 * Convert the given value to a string. This method includes an inline
143 * fast-path for the case where the value is already a string; if the value is
144 * known not to be a string, use ToStringSlow instead.
146 template <AllowGC allowGC>
147 static MOZ_ALWAYS_INLINE JSString*
148 ToString(JSContext* cx, JS::HandleValue v)
150 if (v.isString())
151 return v.toString();
152 return ToStringSlow<allowGC>(cx, v);
156 * This function implements E-262-3 section 9.8, toString. Convert the given
157 * value to a string of jschars appended to the given buffer. On error, the
158 * passed buffer may have partial results appended.
160 inline bool
161 ValueToStringBuffer(JSContext* cx, const Value& v, StringBuffer& sb);
164 * Convert a value to its source expression, returning null after reporting
165 * an error, otherwise returning a new string reference.
167 extern JSString*
168 ValueToSource(JSContext* cx, HandleValue v);
171 * Convert a JSString to its source expression; returns null after reporting an
172 * error, otherwise returns a new string reference. No Handle needed since the
173 * input is dead after the GC.
175 extern JSString*
176 StringToSource(JSContext* cx, JSString* str);
179 * Test if strings are equal. The caller can call the function even if str1
180 * or str2 are not GC-allocated things.
182 extern bool
183 EqualStrings(JSContext* cx, JSString* str1, JSString* str2, bool* result);
185 /* Use the infallible method instead! */
186 extern bool
187 EqualStrings(JSContext* cx, JSLinearString* str1, JSLinearString* str2, bool* result) MOZ_DELETE;
189 /* EqualStrings is infallible on linear strings. */
190 extern bool
191 EqualStrings(JSLinearString* str1, JSLinearString* str2);
193 extern bool
194 EqualChars(JSLinearString* str1, JSLinearString* str2);
197 * Return less than, equal to, or greater than zero depending on whether
198 * str1 is less than, equal to, or greater than str2.
200 extern bool
201 CompareStrings(JSContext* cx, JSString* str1, JSString* str2, int32_t* result);
204 * Same as CompareStrings but for atoms. Don't use this to just test
205 * for equality; use this when you need an ordering on atoms.
207 extern int32_t
208 CompareAtoms(JSAtom* atom1, JSAtom* atom2);
211 * Return true if the string matches the given sequence of ASCII bytes.
213 extern bool
214 StringEqualsAscii(JSLinearString* str, const char* asciiBytes);
216 /* Return true if the string contains a pattern anywhere inside it. */
217 extern bool
218 StringHasPattern(JSLinearString* text, const jschar* pat, uint32_t patlen);
220 extern int
221 StringFindPattern(JSLinearString* text, JSLinearString* pat, size_t start);
223 // Whether the string contains any RegExp meta characters (., *, and so forth).
224 // Searches the range [beginOffset, length - endOffset>.
225 extern bool
226 StringHasRegExpMetaChars(JSLinearString* str, size_t beginOffset = 0, size_t endOffset = 0);
228 template <typename Char1, typename Char2>
229 inline bool
230 EqualChars(const Char1* s1, const Char2* s2, size_t len);
232 template <typename Char1>
233 inline bool
234 EqualChars(const Char1* s1, const Char1* s2, size_t len)
236 return mozilla::PodEqual(s1, s2, len);
239 template <typename Char1, typename Char2>
240 inline bool
241 EqualChars(const Char1* s1, const Char2* s2, size_t len)
243 for (const Char1* s1end = s1 + len; s1 < s1end; s1++, s2++) {
244 if (*s1 != *s2)
245 return false;
247 return true;
251 * Inflate bytes in ASCII encoding to jschars. Return null on error, otherwise
252 * return the jschar that was malloc'ed. length is updated to the length of the
253 * new string (in jschars). A null char is appended, but it is not included in
254 * the length.
256 extern jschar*
257 InflateString(ThreadSafeContext* cx, const char* bytes, size_t* length);
260 * Inflate bytes to JS chars in an existing buffer. 'dst' must be large
261 * enough for 'srclen' jschars. The buffer is NOT null-terminated.
263 inline void
264 CopyAndInflateChars(jschar* dst, const char* src, size_t srclen)
266 for (size_t i = 0; i < srclen; i++)
267 dst[i] = (unsigned char) src[i];
270 inline void
271 CopyAndInflateChars(jschar* dst, const JS::Latin1Char* src, size_t srclen)
273 for (size_t i = 0; i < srclen; i++)
274 dst[i] = src[i];
278 * Deflate JS chars to bytes into a buffer. 'bytes' must be large enough for
279 * 'length chars. The buffer is NOT null-terminated. The destination length
280 * must to be initialized with the buffer size and will contain on return the
281 * number of copied bytes.
283 template <typename CharT>
284 extern bool
285 DeflateStringToBuffer(JSContext* maybecx, const CharT* chars,
286 size_t charsLength, char* bytes, size_t* length);
289 * The String.prototype.replace fast-native entry point is exported for joined
290 * function optimization in js{interp,tracer}.cpp.
292 extern bool
293 str_replace(JSContext* cx, unsigned argc, js::Value* vp);
295 extern bool
296 str_fromCharCode(JSContext* cx, unsigned argc, Value* vp);
298 extern bool
299 str_fromCharCode_one_arg(JSContext* cx, HandleValue code, MutableHandleValue rval);
301 } /* namespace js */
303 extern bool
304 js_str_toString(JSContext* cx, unsigned argc, js::Value* vp);
306 extern bool
307 js_str_charAt(JSContext* cx, unsigned argc, js::Value* vp);
309 namespace js {
311 extern bool
312 str_charCodeAt_impl(JSContext* cx, HandleString string, HandleValue index, MutableHandleValue res);
314 } /* namespace js */
316 extern bool
317 js_str_charCodeAt(JSContext* cx, unsigned argc, js::Value* vp);
319 * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at
320 * least 6 bytes long. Return the number of UTF-8 bytes of data written.
322 extern int
323 js_OneUcs4ToUtf8Char(uint8_t* utf8Buffer, uint32_t ucs4Char);
325 namespace js {
327 extern size_t
328 PutEscapedStringImpl(char* buffer, size_t size, FILE* fp, JSLinearString* str, uint32_t quote);
330 template <typename CharT>
331 extern size_t
332 PutEscapedStringImpl(char* buffer, size_t bufferSize, FILE* fp, const CharT* chars,
333 size_t length, uint32_t quote);
336 * Write str into buffer escaping any non-printable or non-ASCII character
337 * using \escapes for JS string literals.
338 * Guarantees that a NUL is at the end of the buffer unless size is 0. Returns
339 * the length of the written output, NOT including the NUL. Thus, a return
340 * value of size or more means that the output was truncated. If buffer
341 * is null, just returns the length of the output. If quote is not 0, it must
342 * be a single or double quote character that will quote the output.
344 inline size_t
345 PutEscapedString(char* buffer, size_t size, JSLinearString* str, uint32_t quote)
347 size_t n = PutEscapedStringImpl(buffer, size, nullptr, str, quote);
349 /* PutEscapedStringImpl can only fail with a file. */
350 JS_ASSERT(n != size_t(-1));
351 return n;
354 template <typename CharT>
355 inline size_t
356 PutEscapedString(char* buffer, size_t bufferSize, const CharT* chars, size_t length, uint32_t quote)
358 size_t n = PutEscapedStringImpl(buffer, bufferSize, nullptr, chars, length, quote);
360 /* PutEscapedStringImpl can only fail with a file. */
361 JS_ASSERT(n != size_t(-1));
362 return n;
366 * Write str into file escaping any non-printable or non-ASCII character.
367 * If quote is not 0, it must be a single or double quote character that
368 * will quote the output.
370 inline bool
371 FileEscapedString(FILE* fp, JSLinearString* str, uint32_t quote)
373 return PutEscapedStringImpl(nullptr, 0, fp, str, quote) != size_t(-1);
376 bool
377 str_match(JSContext* cx, unsigned argc, Value* vp);
379 bool
380 str_search(JSContext* cx, unsigned argc, Value* vp);
382 bool
383 str_split(JSContext* cx, unsigned argc, Value* vp);
385 JSObject*
386 str_split_string(JSContext* cx, HandleTypeObject type, HandleString str, HandleString sep);
388 bool
389 str_resolve(JSContext* cx, HandleObject obj, HandleId id, MutableHandleObject objp);
391 bool
392 str_replace_regexp_raw(JSContext* cx, HandleString string, HandleObject regexp,
393 HandleString replacement, MutableHandleValue rval);
395 bool
396 str_replace_string_raw(JSContext* cx, HandleString string, HandleString pattern,
397 HandleString replacement, MutableHandleValue rval);
399 } /* namespace js */
401 extern bool
402 js_String(JSContext* cx, unsigned argc, js::Value* vp);
404 #endif /* jsstr_h */