1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : *
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla Communicator client code, released
17 : * March 31, 1998.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * Netscape Communications Corporation.
21 : * Portions created by the Initial Developer are Copyright (C) 1998
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef jsstr_h___
41 : #define jsstr_h___
42 :
43 : #include <ctype.h>
44 : #include "jsapi.h"
45 : #include "jsatom.h"
46 : #include "jsprvtd.h"
47 : #include "jslock.h"
48 : #include "jscell.h"
49 : #include "jsutil.h"
50 :
51 : #include "js/HashTable.h"
52 : #include "vm/Unicode.h"
53 :
54 : namespace js {
55 :
56 : /* Implemented in jsstrinlines.h */
57 : class StringBuffer;
58 :
59 : /*
60 : * When an algorithm does not need a string represented as a single linear
61 : * array of characters, this range utility may be used to traverse the string a
62 : * sequence of linear arrays of characters. This avoids flattening ropes.
63 : *
64 : * Implemented in jsstrinlines.h.
65 : */
66 : class StringSegmentRange;
67 : class MutatingRopeSegmentRange;
68 :
69 : /*
70 : * Utility for building a rope (lazy concatenation) of strings.
71 : */
72 : class RopeBuilder;
73 :
74 : } /* namespace js */
75 :
76 : extern JSString * JS_FASTCALL
77 : js_ConcatStrings(JSContext *cx, JSString *s1, JSString *s2);
78 :
79 : extern JSString * JS_FASTCALL
80 : js_toLowerCase(JSContext *cx, JSString *str);
81 :
82 : extern JSString * JS_FASTCALL
83 : js_toUpperCase(JSContext *cx, JSString *str);
84 :
85 : struct JSSubString {
86 : size_t length;
87 : const jschar *chars;
88 : };
89 :
90 : extern jschar js_empty_ucstr[];
91 : extern JSSubString js_EmptySubString;
92 :
93 : /*
94 : * Shorthands for ASCII (7-bit) decimal and hex conversion.
95 : * Manually inline isdigit for performance; MSVC doesn't do this for us.
96 : */
97 : #define JS7_ISDEC(c) ((((unsigned)(c)) - '0') <= 9)
98 : #define JS7_UNDEC(c) ((c) - '0')
99 : #define JS7_ISHEX(c) ((c) < 128 && isxdigit(c))
100 : #define JS7_UNHEX(c) (unsigned)(JS7_ISDEC(c) ? (c) - '0' : 10 + tolower(c) - 'a')
101 : #define JS7_ISLET(c) ((c) < 128 && isalpha(c))
102 :
103 : /* Initialize the String class, returning its prototype object. */
104 : extern JSObject *
105 : js_InitStringClass(JSContext *cx, JSObject *obj);
106 :
107 : extern const char js_escape_str[];
108 : extern const char js_unescape_str[];
109 : extern const char js_uneval_str[];
110 : extern const char js_decodeURI_str[];
111 : extern const char js_encodeURI_str[];
112 : extern const char js_decodeURIComponent_str[];
113 : extern const char js_encodeURIComponent_str[];
114 :
115 : /* GC-allocate a string descriptor for the given malloc-allocated chars. */
116 : extern JSFixedString *
117 : js_NewString(JSContext *cx, jschar *chars, size_t length);
118 :
119 : extern JSLinearString *
120 : js_NewDependentString(JSContext *cx, JSString *base, size_t start, size_t length);
121 :
122 : /* Copy a counted string and GC-allocate a descriptor for it. */
123 : extern JSFixedString *
124 : js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n);
125 :
126 : extern JSFixedString *
127 : js_NewStringCopyN(JSContext *cx, const char *s, size_t n);
128 :
129 : /* Copy a C string and GC-allocate a descriptor for it. */
130 : extern JSFixedString *
131 : js_NewStringCopyZ(JSContext *cx, const jschar *s);
132 :
133 : extern JSFixedString *
134 : js_NewStringCopyZ(JSContext *cx, const char *s);
135 :
136 : /*
137 : * Convert a value to a printable C string.
138 : */
139 : extern const char *
140 : js_ValueToPrintable(JSContext *cx, const js::Value &,
141 : JSAutoByteString *bytes, bool asSource = false);
142 :
143 : namespace js {
144 :
145 : /*
146 : * Convert a non-string value to a string, returning null after reporting an
147 : * error, otherwise returning a new string reference.
148 : */
149 : extern JSString *
150 : ToStringSlow(JSContext *cx, const Value &v);
151 :
152 : /*
153 : * Convert the given value to a string. This method includes an inline
154 : * fast-path for the case where the value is already a string; if the value is
155 : * known not to be a string, use ToStringSlow instead.
156 : */
157 : static JS_ALWAYS_INLINE JSString *
158 10164975 : ToString(JSContext *cx, const js::Value &v)
159 : {
160 10164975 : if (v.isString())
161 5733710 : return v.toString();
162 4431265 : return ToStringSlow(cx, v);
163 : }
164 :
165 : /*
166 : * This function implements E-262-3 section 9.8, toString. Convert the given
167 : * value to a string of jschars appended to the given buffer. On error, the
168 : * passed buffer may have partial results appended.
169 : */
170 : inline bool
171 : ValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb);
172 :
173 : } /* namespace js */
174 :
175 : /*
176 : * Convert a value to its source expression, returning null after reporting
177 : * an error, otherwise returning a new string reference.
178 : */
179 : extern JS_FRIEND_API(JSString *)
180 : js_ValueToSource(JSContext *cx, const js::Value &v);
181 :
182 : namespace js {
183 :
184 : /*
185 : * Test if strings are equal. The caller can call the function even if str1
186 : * or str2 are not GC-allocated things.
187 : */
188 : extern bool
189 : EqualStrings(JSContext *cx, JSString *str1, JSString *str2, bool *result);
190 :
191 : /* Use the infallible method instead! */
192 : extern bool
193 : EqualStrings(JSContext *cx, JSLinearString *str1, JSLinearString *str2, bool *result) MOZ_DELETE;
194 :
195 : /* EqualStrings is infallible on linear strings. */
196 : extern bool
197 : EqualStrings(JSLinearString *str1, JSLinearString *str2);
198 :
199 : /*
200 : * Return less than, equal to, or greater than zero depending on whether
201 : * str1 is less than, equal to, or greater than str2.
202 : */
203 : extern bool
204 : CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result);
205 :
206 : /*
207 : * Return true if the string matches the given sequence of ASCII bytes.
208 : */
209 : extern bool
210 : StringEqualsAscii(JSLinearString *str, const char *asciiBytes);
211 :
212 : } /* namespace js */
213 :
214 : extern size_t
215 : js_strlen(const jschar *s);
216 :
217 : extern jschar *
218 : js_strchr(const jschar *s, jschar c);
219 :
220 : extern jschar *
221 : js_strchr_limit(const jschar *s, jschar c, const jschar *limit);
222 :
223 : static JS_ALWAYS_INLINE void
224 8185441 : js_strncpy(jschar *dst, const jschar *src, size_t nelem)
225 : {
226 8185441 : return js::PodCopy(dst, src, nelem);
227 : }
228 :
229 : namespace js {
230 :
231 : /*
232 : * Inflate bytes to jschars. Return null on error, otherwise return the jschar
233 : * or byte vector that was malloc'ed. length is updated to the length of the
234 : * new string (in jschars).
235 : */
236 : extern jschar *
237 : InflateString(JSContext *cx, const char *bytes, size_t *length,
238 : FlationCoding fc = NormalEncoding);
239 :
240 : extern char *
241 : DeflateString(JSContext *cx, const jschar *chars, size_t length);
242 :
243 : /*
244 : * Inflate bytes to JS chars in an existing buffer. 'chars' must be large
245 : * enough for 'length' jschars. The buffer is NOT null-terminated.
246 : *
247 : * charsLength must be be initialized with the destination buffer size and, on
248 : * return, will contain on return the number of copied chars.
249 : */
250 : extern bool
251 : InflateStringToBuffer(JSContext *cx, const char *bytes, size_t length,
252 : jschar *chars, size_t *charsLength);
253 :
254 : extern bool
255 : InflateUTF8StringToBuffer(JSContext *cx, const char *bytes, size_t length,
256 : jschar *chars, size_t *charsLength,
257 : FlationCoding fc = NormalEncoding);
258 :
259 : /* Get number of bytes in the deflated sequence of characters. */
260 : extern size_t
261 : GetDeflatedStringLength(JSContext *cx, const jschar *chars, size_t charsLength);
262 :
263 : /* This function will never fail (return -1) in CESU-8 mode. */
264 : extern size_t
265 : GetDeflatedUTF8StringLength(JSContext *cx, const jschar *chars,
266 : size_t charsLength,
267 : FlationCoding fc = NormalEncoding);
268 :
269 : /*
270 : * Deflate JS chars to bytes into a buffer. 'bytes' must be large enough for
271 : * 'length chars. The buffer is NOT null-terminated. The destination length
272 : * must to be initialized with the buffer size and will contain on return the
273 : * number of copied bytes. Conversion behavior depends on js_CStringsAreUTF8.
274 : */
275 : extern bool
276 : DeflateStringToBuffer(JSContext *cx, const jschar *chars,
277 : size_t charsLength, char *bytes, size_t *length);
278 :
279 : /*
280 : * Same as DeflateStringToBuffer, but treats 'bytes' as UTF-8 or CESU-8.
281 : */
282 : extern bool
283 : DeflateStringToUTF8Buffer(JSContext *cx, const jschar *chars,
284 : size_t charsLength, char *bytes, size_t *length,
285 : FlationCoding fc = NormalEncoding);
286 :
287 : /*
288 : * The String.prototype.replace fast-native entry point is exported for joined
289 : * function optimization in js{interp,tracer}.cpp.
290 : */
291 : extern JSBool
292 : str_replace(JSContext *cx, unsigned argc, js::Value *vp);
293 :
294 : extern JSBool
295 : str_fromCharCode(JSContext *cx, unsigned argc, Value *vp);
296 :
297 : } /* namespace js */
298 :
299 : extern JSBool
300 : js_str_toString(JSContext *cx, unsigned argc, js::Value *vp);
301 :
302 : extern JSBool
303 : js_str_charAt(JSContext *cx, unsigned argc, js::Value *vp);
304 :
305 : extern JSBool
306 : js_str_charCodeAt(JSContext *cx, unsigned argc, js::Value *vp);
307 :
308 : /*
309 : * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at
310 : * least 6 bytes long. Return the number of UTF-8 bytes of data written.
311 : */
312 : extern int
313 : js_OneUcs4ToUtf8Char(uint8_t *utf8Buffer, uint32_t ucs4Char);
314 :
315 : namespace js {
316 :
317 : extern size_t
318 : PutEscapedStringImpl(char *buffer, size_t size, FILE *fp, JSLinearString *str, uint32_t quote);
319 :
320 : /*
321 : * Write str into buffer escaping any non-printable or non-ASCII character
322 : * using \escapes for JS string literals.
323 : * Guarantees that a NUL is at the end of the buffer unless size is 0. Returns
324 : * the length of the written output, NOT including the NUL. Thus, a return
325 : * value of size or more means that the output was truncated. If buffer
326 : * is null, just returns the length of the output. If quote is not 0, it must
327 : * be a single or double quote character that will quote the output.
328 : */
329 : inline size_t
330 436519 : PutEscapedString(char *buffer, size_t size, JSLinearString *str, uint32_t quote)
331 : {
332 436519 : size_t n = PutEscapedStringImpl(buffer, size, NULL, str, quote);
333 :
334 : /* PutEscapedStringImpl can only fail with a file. */
335 436519 : JS_ASSERT(n != size_t(-1));
336 436519 : return n;
337 : }
338 :
339 : /*
340 : * Write str into file escaping any non-printable or non-ASCII character.
341 : * If quote is not 0, it must be a single or double quote character that
342 : * will quote the output.
343 : */
344 : inline bool
345 0 : FileEscapedString(FILE *fp, JSLinearString *str, uint32_t quote)
346 : {
347 0 : return PutEscapedStringImpl(NULL, 0, fp, str, quote) != size_t(-1);
348 : }
349 :
350 : JSBool
351 : str_match(JSContext *cx, unsigned argc, Value *vp);
352 :
353 : JSBool
354 : str_search(JSContext *cx, unsigned argc, Value *vp);
355 :
356 : JSBool
357 : str_split(JSContext *cx, unsigned argc, Value *vp);
358 :
359 : } /* namespace js */
360 :
361 : extern JSBool
362 : js_String(JSContext *cx, unsigned argc, js::Value *vp);
363 :
364 : #endif /* jsstr_h___ */
|