js/src/jsstr.h

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:705d355f5740
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/. */
6
7 #ifndef jsstr_h
8 #define jsstr_h
9
10 #include "mozilla/HashFunctions.h"
11 #include "mozilla/PodOperations.h"
12
13 #include "jsutil.h"
14 #include "NamespaceImports.h"
15
16 #include "gc/Rooting.h"
17 #include "js/RootingAPI.h"
18 #include "vm/Unicode.h"
19
20 class JSAutoByteString;
21 class JSFlatString;
22 class JSLinearString;
23
24 namespace js {
25
26 class StringBuffer;
27
28 class MutatingRopeSegmentRange;
29
30 template <AllowGC allowGC>
31 extern JSString *
32 ConcatStrings(ThreadSafeContext *cx,
33 typename MaybeRooted<JSString*, allowGC>::HandleType left,
34 typename MaybeRooted<JSString*, allowGC>::HandleType right);
35
36 // Return s advanced past any Unicode white space characters.
37 static inline const jschar *
38 SkipSpace(const jschar *s, const jschar *end)
39 {
40 JS_ASSERT(s <= end);
41
42 while (s < end && unicode::IsSpace(*s))
43 s++;
44
45 return s;
46 }
47
48 // Return less than, equal to, or greater than zero depending on whether
49 // s1 is less than, equal to, or greater than s2.
50 inline int32_t
51 CompareChars(const jschar *s1, size_t l1, const jschar *s2, size_t l2)
52 {
53 size_t n = Min(l1, l2);
54 for (size_t i = 0; i < n; i++) {
55 if (int32_t cmp = s1[i] - s2[i])
56 return cmp;
57 }
58
59 return (int32_t)(l1 - l2);
60 }
61
62 } /* namespace js */
63
64 extern JSString * JS_FASTCALL
65 js_toLowerCase(JSContext *cx, JSString *str);
66
67 extern JSString * JS_FASTCALL
68 js_toUpperCase(JSContext *cx, JSString *str);
69
70 struct JSSubString {
71 size_t length;
72 const jschar *chars;
73 };
74
75 extern const jschar js_empty_ucstr[];
76 extern const JSSubString js_EmptySubString;
77
78 /*
79 * Shorthands for ASCII (7-bit) decimal and hex conversion.
80 * Manually inline isdigit for performance; MSVC doesn't do this for us.
81 */
82 #define JS7_ISDEC(c) ((((unsigned)(c)) - '0') <= 9)
83 #define JS7_UNDEC(c) ((c) - '0')
84 #define JS7_ISHEX(c) ((c) < 128 && isxdigit(c))
85 #define JS7_UNHEX(c) (unsigned)(JS7_ISDEC(c) ? (c) - '0' : 10 + tolower(c) - 'a')
86 #define JS7_ISLET(c) ((c) < 128 && isalpha(c))
87
88 /* Initialize the String class, returning its prototype object. */
89 extern JSObject *
90 js_InitStringClass(JSContext *cx, js::HandleObject obj);
91
92 extern const char js_escape_str[];
93 extern const char js_unescape_str[];
94 extern const char js_uneval_str[];
95 extern const char js_decodeURI_str[];
96 extern const char js_encodeURI_str[];
97 extern const char js_decodeURIComponent_str[];
98 extern const char js_encodeURIComponent_str[];
99
100 /* GC-allocate a string descriptor for the given malloc-allocated chars. */
101 template <js::AllowGC allowGC>
102 extern JSFlatString *
103 js_NewString(js::ThreadSafeContext *cx, jschar *chars, size_t length);
104
105 extern JSLinearString *
106 js_NewDependentString(JSContext *cx, JSString *base, size_t start, size_t length);
107
108 /* Copy a counted string and GC-allocate a descriptor for it. */
109 template <js::AllowGC allowGC>
110 extern JSFlatString *
111 js_NewStringCopyN(js::ExclusiveContext *cx, const jschar *s, size_t n);
112
113 template <js::AllowGC allowGC>
114 extern JSFlatString *
115 js_NewStringCopyN(js::ThreadSafeContext *cx, const char *s, size_t n);
116
117 /* Copy a C string and GC-allocate a descriptor for it. */
118 template <js::AllowGC allowGC>
119 extern JSFlatString *
120 js_NewStringCopyZ(js::ExclusiveContext *cx, const jschar *s);
121
122 template <js::AllowGC allowGC>
123 extern JSFlatString *
124 js_NewStringCopyZ(js::ThreadSafeContext *cx, const char *s);
125
126 /*
127 * Convert a value to a printable C string.
128 */
129 extern const char *
130 js_ValueToPrintable(JSContext *cx, const js::Value &,
131 JSAutoByteString *bytes, bool asSource = false);
132
133 namespace js {
134
135 /*
136 * Convert a non-string value to a string, returning null after reporting an
137 * error, otherwise returning a new string reference.
138 */
139 template <AllowGC allowGC>
140 extern JSString *
141 ToStringSlow(ExclusiveContext *cx, typename MaybeRooted<Value, allowGC>::HandleType arg);
142
143 /*
144 * Convert the given value to a string. This method includes an inline
145 * fast-path for the case where the value is already a string; if the value is
146 * known not to be a string, use ToStringSlow instead.
147 */
148 template <AllowGC allowGC>
149 static MOZ_ALWAYS_INLINE JSString *
150 ToString(JSContext *cx, JS::HandleValue v)
151 {
152 if (v.isString())
153 return v.toString();
154 return ToStringSlow<allowGC>(cx, v);
155 }
156
157 /*
158 * This function implements E-262-3 section 9.8, toString. Convert the given
159 * value to a string of jschars appended to the given buffer. On error, the
160 * passed buffer may have partial results appended.
161 */
162 inline bool
163 ValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb);
164
165 /*
166 * Convert a value to its source expression, returning null after reporting
167 * an error, otherwise returning a new string reference.
168 */
169 extern JSString *
170 ValueToSource(JSContext *cx, HandleValue v);
171
172 /*
173 * Convert a JSString to its source expression; returns null after reporting an
174 * error, otherwise returns a new string reference. No Handle needed since the
175 * input is dead after the GC.
176 */
177 extern JSString *
178 StringToSource(JSContext *cx, JSString *str);
179
180 /*
181 * Test if strings are equal. The caller can call the function even if str1
182 * or str2 are not GC-allocated things.
183 */
184 extern bool
185 EqualStrings(JSContext *cx, JSString *str1, JSString *str2, bool *result);
186
187 /* Use the infallible method instead! */
188 extern bool
189 EqualStrings(JSContext *cx, JSLinearString *str1, JSLinearString *str2, bool *result) MOZ_DELETE;
190
191 /* EqualStrings is infallible on linear strings. */
192 extern bool
193 EqualStrings(JSLinearString *str1, JSLinearString *str2);
194
195 /*
196 * Return less than, equal to, or greater than zero depending on whether
197 * str1 is less than, equal to, or greater than str2.
198 */
199 extern bool
200 CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result);
201
202 extern int32_t
203 CompareAtoms(JSAtom *atom1, JSAtom *atom2);
204
205 /*
206 * Return true if the string matches the given sequence of ASCII bytes.
207 */
208 extern bool
209 StringEqualsAscii(JSLinearString *str, const char *asciiBytes);
210
211 /* Return true if the string contains a pattern anywhere inside it. */
212 extern bool
213 StringHasPattern(const jschar *text, uint32_t textlen,
214 const jschar *pat, uint32_t patlen);
215
216 } /* namespace js */
217
218 extern size_t
219 js_strlen(const jschar *s);
220
221 extern int32_t
222 js_strcmp(const jschar *lhs, const jschar *rhs);
223
224 extern jschar *
225 js_strchr_limit(const jschar *s, jschar c, const jschar *limit);
226
227 static MOZ_ALWAYS_INLINE void
228 js_strncpy(jschar *dst, const jschar *src, size_t nelem)
229 {
230 return mozilla::PodCopy(dst, src, nelem);
231 }
232
233 extern jschar *
234 js_strdup(js::ThreadSafeContext *cx, const jschar *s);
235
236 namespace js {
237
238 /*
239 * Inflate bytes in ASCII encoding to jschars. Return null on error, otherwise
240 * return the jschar that was malloc'ed. length is updated to the length of the
241 * new string (in jschars). A null char is appended, but it is not included in
242 * the length.
243 */
244 extern jschar *
245 InflateString(ThreadSafeContext *cx, const char *bytes, size_t *length);
246
247 /*
248 * Inflate bytes to JS chars in an existing buffer. 'dst' must be large
249 * enough for 'srclen' jschars. The buffer is NOT null-terminated.
250 */
251 inline void
252 InflateStringToBuffer(const char *src, size_t srclen, jschar *dst)
253 {
254 for (size_t i = 0; i < srclen; i++)
255 dst[i] = (unsigned char) src[i];
256 }
257
258 /*
259 * Deflate JS chars to bytes into a buffer. 'bytes' must be large enough for
260 * 'length chars. The buffer is NOT null-terminated. The destination length
261 * must to be initialized with the buffer size and will contain on return the
262 * number of copied bytes.
263 */
264 extern bool
265 DeflateStringToBuffer(JSContext *maybecx, const jschar *chars,
266 size_t charsLength, char *bytes, size_t *length);
267
268 /*
269 * The String.prototype.replace fast-native entry point is exported for joined
270 * function optimization in js{interp,tracer}.cpp.
271 */
272 extern bool
273 str_replace(JSContext *cx, unsigned argc, js::Value *vp);
274
275 extern bool
276 str_fromCharCode(JSContext *cx, unsigned argc, Value *vp);
277
278 } /* namespace js */
279
280 extern bool
281 js_str_toString(JSContext *cx, unsigned argc, js::Value *vp);
282
283 extern bool
284 js_str_charAt(JSContext *cx, unsigned argc, js::Value *vp);
285
286 extern bool
287 js_str_charCodeAt(JSContext *cx, unsigned argc, js::Value *vp);
288
289 /*
290 * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at
291 * least 6 bytes long. Return the number of UTF-8 bytes of data written.
292 */
293 extern int
294 js_OneUcs4ToUtf8Char(uint8_t *utf8Buffer, uint32_t ucs4Char);
295
296 namespace js {
297
298 extern size_t
299 PutEscapedStringImpl(char *buffer, size_t size, FILE *fp, JSLinearString *str, uint32_t quote);
300
301 extern size_t
302 PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, const jschar *chars,
303 size_t length, uint32_t quote);
304
305 /*
306 * Write str into buffer escaping any non-printable or non-ASCII character
307 * using \escapes for JS string literals.
308 * Guarantees that a NUL is at the end of the buffer unless size is 0. Returns
309 * the length of the written output, NOT including the NUL. Thus, a return
310 * value of size or more means that the output was truncated. If buffer
311 * is null, just returns the length of the output. If quote is not 0, it must
312 * be a single or double quote character that will quote the output.
313 */
314 inline size_t
315 PutEscapedString(char *buffer, size_t size, JSLinearString *str, uint32_t quote)
316 {
317 size_t n = PutEscapedStringImpl(buffer, size, nullptr, str, quote);
318
319 /* PutEscapedStringImpl can only fail with a file. */
320 JS_ASSERT(n != size_t(-1));
321 return n;
322 }
323
324 inline size_t
325 PutEscapedString(char *buffer, size_t bufferSize, const jschar *chars, size_t length, uint32_t quote)
326 {
327 size_t n = PutEscapedStringImpl(buffer, bufferSize, nullptr, chars, length, quote);
328
329 /* PutEscapedStringImpl can only fail with a file. */
330 JS_ASSERT(n != size_t(-1));
331 return n;
332 }
333
334 /*
335 * Write str into file escaping any non-printable or non-ASCII character.
336 * If quote is not 0, it must be a single or double quote character that
337 * will quote the output.
338 */
339 inline bool
340 FileEscapedString(FILE *fp, JSLinearString *str, uint32_t quote)
341 {
342 return PutEscapedStringImpl(nullptr, 0, fp, str, quote) != size_t(-1);
343 }
344
345 bool
346 str_match(JSContext *cx, unsigned argc, Value *vp);
347
348 bool
349 str_search(JSContext *cx, unsigned argc, Value *vp);
350
351 bool
352 str_split(JSContext *cx, unsigned argc, Value *vp);
353
354 JSObject *
355 str_split_string(JSContext *cx, HandleTypeObject type, HandleString str, HandleString sep);
356
357 bool
358 str_resolve(JSContext *cx, HandleObject obj, HandleId id, MutableHandleObject objp);
359
360 bool
361 str_replace_regexp_raw(JSContext *cx, HandleString string, HandleObject regexp,
362 HandleString replacement, MutableHandleValue rval);
363
364 bool
365 str_replace_string_raw(JSContext *cx, HandleString string, HandleString pattern,
366 HandleString replacement, MutableHandleValue rval);
367
368 } /* namespace js */
369
370 extern bool
371 js_String(JSContext *cx, unsigned argc, js::Value *vp);
372
373 #endif /* jsstr_h */

mercurial