PageRenderTime 97ms CodeModel.GetById 40ms app.highlight 24ms RepoModel.GetById 26ms app.codeStats 1ms

/js/lib/Socket.IO-node/support/expresso/deps/jscoverage/js/jsstr.h

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
C++ Header | 662 lines | 318 code | 99 blank | 245 comment | 42 complexity | 81d3efe739ae057c74a8e7d55413056b MD5 | raw file
  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 * JS string type implementation.
 44 *
 45 * A JS string is a counted array of unicode characters.  To support handoff
 46 * of API client memory, the chars are allocated separately from the length,
 47 * necessitating a pointer after the count, to form a separately allocated
 48 * string descriptor.  String descriptors are GC'ed, while their chars are
 49 * allocated from the malloc heap.
 50 */
 51#include <ctype.h>
 52#include "jspubtd.h"
 53#include "jsprvtd.h"
 54
 55JS_BEGIN_EXTERN_C
 56
 57/*
 58 * The GC-thing "string" type.
 59 *
 60 * When the JSSTRFLAG_DEPENDENT bit of the length field is unset, the u.chars
 61 * field points to a flat character array owned by its GC-thing descriptor.
 62 * The array is terminated at index length by a zero character and the size of
 63 * the array in bytes is (length + 1) * sizeof(jschar). The terminator is
 64 * purely a backstop, in case the chars pointer flows out to native code that
 65 * requires \u0000 termination.
 66 *
 67 * A flat string with JSSTRFLAG_MUTABLE set means that the string is accessible
 68 * only from one thread and it is possible to turn it into a dependent string
 69 * of the same length to optimize js_ConcatStrings. It is also possible to grow
 70 * such a string, but extreme care must be taken to ensure that no other code
 71 * relies on the original length of the string.
 72 *
 73 * A flat string with JSSTRFLAG_ATOMIZED set means that the string is hashed as
 74 * an atom. This flag is used to avoid re-hashing the already-atomized string.
 75 *
 76 * When JSSTRFLAG_DEPENDENT is set, the string depends on characters of another
 77 * string strongly referenced by the u.base field. The base member may point to
 78 * another dependent string if JSSTRING_CHARS has not been called yet.
 79 *
 80 * JSSTRFLAG_PREFIX determines the kind of the dependent string. When the flag
 81 * is unset, the length field encodes both starting position relative to the
 82 * base string and the number of characters in the dependent string, see
 83 * JSSTRDEP_START_MASK and JSSTRDEP_LENGTH_MASK macros below for details.
 84 *
 85 * When JSSTRFLAG_PREFIX is set, the dependent string is a prefix of the base
 86 * string. The number of characters in the prefix is encoded using all non-flag
 87 * bits of the length field and spans the same 0 .. SIZE_T_MAX/4 range as the
 88 * length of the flat string.
 89 *
 90 * NB: Always use the JSSTRING_LENGTH and JSSTRING_CHARS accessor macros.
 91 */
 92struct JSString {
 93    size_t          length;
 94    union {
 95        jschar      *chars;
 96        JSString    *base;
 97    } u;
 98};
 99
100/*
101 * Definitions for flags stored in the high order bits of JSString.length.
102 * JSSTRFLAG_PREFIX and JSSTRFLAG_MUTABLE are two aliases for the same value.
103 * JSSTRFLAG_PREFIX should be used only if JSSTRFLAG_DEPENDENT is set and
104 * JSSTRFLAG_MUTABLE should be used only if the string is flat.
105 * JSSTRFLAG_ATOMIZED is used only with the flat immutable strings.
106 */
107#define JSSTRFLAG_DEPENDENT         JSSTRING_BIT(JS_BITS_PER_WORD - 1)
108#define JSSTRFLAG_PREFIX            JSSTRING_BIT(JS_BITS_PER_WORD - 2)
109#define JSSTRFLAG_MUTABLE           JSSTRFLAG_PREFIX
110#define JSSTRFLAG_ATOMIZED          JSSTRING_BIT(JS_BITS_PER_WORD - 3)
111
112#define JSSTRING_LENGTH_BITS        (JS_BITS_PER_WORD - 3)
113#define JSSTRING_LENGTH_MASK        JSSTRING_BITMASK(JSSTRING_LENGTH_BITS)
114
115/* Universal JSString type inquiry and accessor macros. */
116#define JSSTRING_BIT(n)             ((size_t)1 << (n))
117#define JSSTRING_BITMASK(n)         (JSSTRING_BIT(n) - 1)
118#define JSSTRING_HAS_FLAG(str,flg)  ((str)->length & (flg))
119#define JSSTRING_IS_DEPENDENT(str)  JSSTRING_HAS_FLAG(str, JSSTRFLAG_DEPENDENT)
120#define JSSTRING_IS_FLAT(str)       (!JSSTRING_IS_DEPENDENT(str))
121#define JSSTRING_IS_MUTABLE(str)    (((str)->length & (JSSTRFLAG_DEPENDENT |  \
122                                                       JSSTRFLAG_MUTABLE)) == \
123                                     JSSTRFLAG_MUTABLE)
124#define JSSTRING_IS_ATOMIZED(str)   (((str)->length & (JSSTRFLAG_DEPENDENT |  \
125                                                       JSSTRFLAG_ATOMIZED)) ==\
126                                     JSSTRFLAG_ATOMIZED)
127
128#define JSSTRING_CHARS(str)         (JSSTRING_IS_DEPENDENT(str)               \
129                                     ? JSSTRDEP_CHARS(str)                    \
130                                     : JSFLATSTR_CHARS(str))
131#define JSSTRING_LENGTH(str)        (JSSTRING_IS_DEPENDENT(str)               \
132                                     ? JSSTRDEP_LENGTH(str)                   \
133                                     : JSFLATSTR_LENGTH(str))
134
135#define JSSTRING_CHARS_AND_LENGTH(str, chars_, length_)                       \
136    ((void)(JSSTRING_IS_DEPENDENT(str)                                        \
137            ? ((length_) = JSSTRDEP_LENGTH(str),                              \
138               (chars_) = JSSTRDEP_CHARS(str))                                \
139            : ((length_) = JSFLATSTR_LENGTH(str),                             \
140               (chars_) = JSFLATSTR_CHARS(str))))
141
142#define JSSTRING_CHARS_AND_END(str, chars_, end)                              \
143    ((void)((end) = JSSTRING_IS_DEPENDENT(str)                                \
144                  ? JSSTRDEP_LENGTH(str) + ((chars_) = JSSTRDEP_CHARS(str))   \
145                  : JSFLATSTR_LENGTH(str) + ((chars_) = JSFLATSTR_CHARS(str))))
146
147/* Specific flat string initializer and accessor macros. */
148#define JSFLATSTR_INIT(str, chars_, length_)                                  \
149    ((void)(JS_ASSERT(((length_) & ~JSSTRING_LENGTH_MASK) == 0),              \
150            (str)->length = (length_), (str)->u.chars = (chars_)))
151
152#define JSFLATSTR_LENGTH(str)                                                 \
153    (JS_ASSERT(JSSTRING_IS_FLAT(str)), (str)->length & JSSTRING_LENGTH_MASK)
154
155#define JSFLATSTR_CHARS(str)                                                  \
156    (JS_ASSERT(JSSTRING_IS_FLAT(str)), (str)->u.chars)
157
158/*
159 * Macros to manipulate atomized and mutable flags of flat strings. It is safe
160 * to use these without extra locking due to the following properties:
161 *
162 *   * We do not have a macro like JSFLATSTR_CLEAR_ATOMIZED as a string
163 *     remains atomized until the GC collects it.
164 *
165 *   * A thread may call JSFLATSTR_SET_MUTABLE only when it is the only thread
166 *     accessing the string until a later call to JSFLATSTR_CLEAR_MUTABLE.
167 *
168 *   * Multiple threads can call JSFLATSTR_CLEAR_MUTABLE but the macro
169 *     actually clears the mutable flag only when the flag is set -- in which
170 *     case only one thread can access the string (see previous property).
171 *
172 * Thus, when multiple threads access the string, JSFLATSTR_SET_ATOMIZED is
173 * the only macro that can update the length field of the string by changing
174 * the mutable bit from 0 to 1. We call the macro only after the string has
175 * been hashed. When some threads in js_ValueToStringId see that the flag is
176 * set, it knows that the string was atomized.
177 *
178 * On the other hand, if the thread sees that the flag is unset, it could be
179 * seeing a stale value when another thread has just atomized the string and
180 * set the flag. But this can lead only to an extra call to js_AtomizeString.
181 * This function would find that the string was already hashed and return it
182 * with the atomized bit set.
183 */
184#define JSFLATSTR_SET_ATOMIZED(str)                                           \
185    ((void)(JS_ASSERT(JSSTRING_IS_FLAT(str) && !JSSTRING_IS_MUTABLE(str)),    \
186            (str)->length |= JSSTRFLAG_ATOMIZED))
187
188#define JSFLATSTR_SET_MUTABLE(str)                                            \
189    ((void)(JS_ASSERT(JSSTRING_IS_FLAT(str) && !JSSTRING_IS_ATOMIZED(str)),   \
190            (str)->length |= JSSTRFLAG_MUTABLE))
191
192#define JSFLATSTR_CLEAR_MUTABLE(str)                                          \
193    ((void)(JS_ASSERT(JSSTRING_IS_FLAT(str)),                                 \
194            JSSTRING_HAS_FLAG(str, JSSTRFLAG_MUTABLE) &&                      \
195            ((str)->length &= ~JSSTRFLAG_MUTABLE)))
196
197/* Specific dependent string shift/mask accessor and mutator macros. */
198#define JSSTRDEP_START_BITS         (JSSTRING_LENGTH_BITS-JSSTRDEP_LENGTH_BITS)
199#define JSSTRDEP_START_SHIFT        JSSTRDEP_LENGTH_BITS
200#define JSSTRDEP_START_MASK         JSSTRING_BITMASK(JSSTRDEP_START_BITS)
201#define JSSTRDEP_LENGTH_BITS        (JSSTRING_LENGTH_BITS / 2)
202#define JSSTRDEP_LENGTH_MASK        JSSTRING_BITMASK(JSSTRDEP_LENGTH_BITS)
203
204#define JSSTRDEP_IS_PREFIX(str)     JSSTRING_HAS_FLAG(str, JSSTRFLAG_PREFIX)
205
206#define JSSTRDEP_START(str)         (JSSTRDEP_IS_PREFIX(str) ? 0              \
207                                     : (((str)->length                        \
208                                         >> JSSTRDEP_START_SHIFT)             \
209                                        & JSSTRDEP_START_MASK))
210#define JSSTRDEP_LENGTH(str)        ((str)->length                            \
211                                     & (JSSTRDEP_IS_PREFIX(str)               \
212                                        ? JSSTRING_LENGTH_MASK                \
213                                        : JSSTRDEP_LENGTH_MASK))
214
215#define JSSTRDEP_INIT(str,bstr,off,len)                                       \
216    ((str)->length = JSSTRFLAG_DEPENDENT                                      \
217                   | ((off) << JSSTRDEP_START_SHIFT)                          \
218                   | (len),                                                   \
219     (str)->u.base = (bstr))
220
221#define JSPREFIX_INIT(str,bstr,len)                                           \
222    ((str)->length = JSSTRFLAG_DEPENDENT | JSSTRFLAG_PREFIX | (len),          \
223     (str)->u.base = (bstr))
224
225#define JSSTRDEP_BASE(str)          ((str)->u.base)
226#define JSPREFIX_BASE(str)          JSSTRDEP_BASE(str)
227#define JSPREFIX_SET_BASE(str,bstr) ((str)->u.base = (bstr))
228
229#define JSSTRDEP_CHARS(str)                                                   \
230    (JSSTRING_IS_DEPENDENT(JSSTRDEP_BASE(str))                                \
231     ? js_GetDependentStringChars(str)                                        \
232     : JSFLATSTR_CHARS(JSSTRDEP_BASE(str)) + JSSTRDEP_START(str))
233
234extern size_t
235js_MinimizeDependentStrings(JSString *str, int level, JSString **basep);
236
237extern jschar *
238js_GetDependentStringChars(JSString *str);
239
240extern const jschar *
241js_GetStringChars(JSContext *cx, JSString *str);
242
243extern JSString * JS_FASTCALL
244js_ConcatStrings(JSContext *cx, JSString *left, JSString *right);
245
246extern const jschar *
247js_UndependString(JSContext *cx, JSString *str);
248
249extern JSBool
250js_MakeStringImmutable(JSContext *cx, JSString *str);
251
252extern JSString* JS_FASTCALL
253js_toLowerCase(JSContext *cx, JSString *str);
254
255extern JSString* JS_FASTCALL
256js_toUpperCase(JSContext *cx, JSString *str);
257
258typedef struct JSCharBuffer {
259    size_t          length;
260    jschar          *chars;
261} JSCharBuffer;
262
263struct JSSubString {
264    size_t          length;
265    const jschar    *chars;
266};
267
268extern jschar      js_empty_ucstr[];
269extern JSSubString js_EmptySubString;
270
271/* Unicode character attribute lookup tables. */
272extern const uint8 js_X[];
273extern const uint8 js_Y[];
274extern const uint32 js_A[];
275
276/* Enumerated Unicode general category types. */
277typedef enum JSCharType {
278    JSCT_UNASSIGNED             = 0,
279    JSCT_UPPERCASE_LETTER       = 1,
280    JSCT_LOWERCASE_LETTER       = 2,
281    JSCT_TITLECASE_LETTER       = 3,
282    JSCT_MODIFIER_LETTER        = 4,
283    JSCT_OTHER_LETTER           = 5,
284    JSCT_NON_SPACING_MARK       = 6,
285    JSCT_ENCLOSING_MARK         = 7,
286    JSCT_COMBINING_SPACING_MARK = 8,
287    JSCT_DECIMAL_DIGIT_NUMBER   = 9,
288    JSCT_LETTER_NUMBER          = 10,
289    JSCT_OTHER_NUMBER           = 11,
290    JSCT_SPACE_SEPARATOR        = 12,
291    JSCT_LINE_SEPARATOR         = 13,
292    JSCT_PARAGRAPH_SEPARATOR    = 14,
293    JSCT_CONTROL                = 15,
294    JSCT_FORMAT                 = 16,
295    JSCT_PRIVATE_USE            = 18,
296    JSCT_SURROGATE              = 19,
297    JSCT_DASH_PUNCTUATION       = 20,
298    JSCT_START_PUNCTUATION      = 21,
299    JSCT_END_PUNCTUATION        = 22,
300    JSCT_CONNECTOR_PUNCTUATION  = 23,
301    JSCT_OTHER_PUNCTUATION      = 24,
302    JSCT_MATH_SYMBOL            = 25,
303    JSCT_CURRENCY_SYMBOL        = 26,
304    JSCT_MODIFIER_SYMBOL        = 27,
305    JSCT_OTHER_SYMBOL           = 28
306} JSCharType;
307
308/* Character classifying and mapping macros, based on java.lang.Character. */
309#define JS_CCODE(c)     (js_A[js_Y[(js_X[(uint16)(c)>>6]<<6)|((c)&0x3F)]])
310#define JS_CTYPE(c)     (JS_CCODE(c) & 0x1F)
311
312#define JS_ISALPHA(c)   ((((1 << JSCT_UPPERCASE_LETTER) |                     \
313                           (1 << JSCT_LOWERCASE_LETTER) |                     \
314                           (1 << JSCT_TITLECASE_LETTER) |                     \
315                           (1 << JSCT_MODIFIER_LETTER) |                      \
316                           (1 << JSCT_OTHER_LETTER))                          \
317                          >> JS_CTYPE(c)) & 1)
318
319#define JS_ISALNUM(c)   ((((1 << JSCT_UPPERCASE_LETTER) |                     \
320                           (1 << JSCT_LOWERCASE_LETTER) |                     \
321                           (1 << JSCT_TITLECASE_LETTER) |                     \
322                           (1 << JSCT_MODIFIER_LETTER) |                      \
323                           (1 << JSCT_OTHER_LETTER) |                         \
324                           (1 << JSCT_DECIMAL_DIGIT_NUMBER))                  \
325                          >> JS_CTYPE(c)) & 1)
326
327/* A unicode letter, suitable for use in an identifier. */
328#define JS_ISLETTER(c)   ((((1 << JSCT_UPPERCASE_LETTER) |                    \
329                            (1 << JSCT_LOWERCASE_LETTER) |                    \
330                            (1 << JSCT_TITLECASE_LETTER) |                    \
331                            (1 << JSCT_MODIFIER_LETTER) |                     \
332                            (1 << JSCT_OTHER_LETTER) |                        \
333                            (1 << JSCT_LETTER_NUMBER))                        \
334                           >> JS_CTYPE(c)) & 1)
335
336/*
337 * 'IdentifierPart' from ECMA grammar, is Unicode letter or combining mark or
338 * digit or connector punctuation.
339 */
340#define JS_ISIDPART(c)  ((((1 << JSCT_UPPERCASE_LETTER) |                     \
341                           (1 << JSCT_LOWERCASE_LETTER) |                     \
342                           (1 << JSCT_TITLECASE_LETTER) |                     \
343                           (1 << JSCT_MODIFIER_LETTER) |                      \
344                           (1 << JSCT_OTHER_LETTER) |                         \
345                           (1 << JSCT_LETTER_NUMBER) |                        \
346                           (1 << JSCT_NON_SPACING_MARK) |                     \
347                           (1 << JSCT_COMBINING_SPACING_MARK) |               \
348                           (1 << JSCT_DECIMAL_DIGIT_NUMBER) |                 \
349                           (1 << JSCT_CONNECTOR_PUNCTUATION))                 \
350                          >> JS_CTYPE(c)) & 1)
351
352/* Unicode control-format characters, ignored in input */
353#define JS_ISFORMAT(c) (((1 << JSCT_FORMAT) >> JS_CTYPE(c)) & 1)
354
355/*
356 * Per ECMA-262 15.10.2.6, these characters are the only ones that make up a
357 * "word", as far as a RegExp is concerned.  If we want a Unicode-friendlier
358 * definition of "word", we should rename this macro to something regexp-y.
359 */
360#define JS_ISWORD(c)    ((c) < 128 && (isalnum(c) || (c) == '_'))
361
362#define JS_ISIDSTART(c) (JS_ISLETTER(c) || (c) == '_' || (c) == '$')
363#define JS_ISIDENT(c)   (JS_ISIDPART(c) || (c) == '_' || (c) == '$')
364
365#define JS_ISXMLSPACE(c)        ((c) == ' ' || (c) == '\t' || (c) == '\r' ||  \
366                                 (c) == '\n')
367#define JS_ISXMLNSSTART(c)      ((JS_CCODE(c) & 0x00000100) || (c) == '_')
368#define JS_ISXMLNS(c)           ((JS_CCODE(c) & 0x00000080) || (c) == '.' ||  \
369                                 (c) == '-' || (c) == '_')
370#define JS_ISXMLNAMESTART(c)    (JS_ISXMLNSSTART(c) || (c) == ':')
371#define JS_ISXMLNAME(c)         (JS_ISXMLNS(c) || (c) == ':')
372
373#define JS_ISDIGIT(c)   (JS_CTYPE(c) == JSCT_DECIMAL_DIGIT_NUMBER)
374
375/* XXXbe unify on A/X/Y tbls, avoid ctype.h? */
376/* XXXbe fs, etc. ? */
377#define JS_ISSPACE(c)   ((JS_CCODE(c) & 0x00070000) == 0x00040000)
378#define JS_ISPRINT(c)   ((c) < 128 && isprint(c))
379
380#define JS_ISUPPER(c)   (JS_CTYPE(c) == JSCT_UPPERCASE_LETTER)
381#define JS_ISLOWER(c)   (JS_CTYPE(c) == JSCT_LOWERCASE_LETTER)
382
383#define JS_TOUPPER(c)   ((jschar) ((JS_CCODE(c) & 0x00100000)                 \
384                                   ? (c) - ((int32)JS_CCODE(c) >> 22)         \
385                                   : (c)))
386#define JS_TOLOWER(c)   ((jschar) ((JS_CCODE(c) & 0x00200000)                 \
387                                   ? (c) + ((int32)JS_CCODE(c) >> 22)         \
388                                   : (c)))
389
390/*
391 * Shorthands for ASCII (7-bit) decimal and hex conversion.
392 * Manually inline isdigit for performance; MSVC doesn't do this for us.
393 */
394#define JS7_ISDEC(c)    ((((unsigned)(c)) - '0') <= 9)
395#define JS7_UNDEC(c)    ((c) - '0')
396#define JS7_ISHEX(c)    ((c) < 128 && isxdigit(c))
397#define JS7_UNHEX(c)    (uintN)(JS7_ISDEC(c) ? (c) - '0' : 10 + tolower(c) - 'a')
398#define JS7_ISLET(c)    ((c) < 128 && isalpha(c))
399
400/* Initialize per-runtime string state for the first context in the runtime. */
401extern JSBool
402js_InitRuntimeStringState(JSContext *cx);
403
404extern JSBool
405js_InitDeflatedStringCache(JSRuntime *rt);
406
407/*
408 * Maximum character code for which we will create a pinned unit string on
409 * demand -- see JSRuntime.unitStrings in jscntxt.h.
410 */
411#define UNIT_STRING_LIMIT 256U
412
413/*
414 * Get the independent string containing only character code at index in str
415 * (backstopped with a zero character as usual for independent strings).
416 */
417extern JSString *
418js_GetUnitString(JSContext *cx, JSString *str, size_t index);
419
420/*
421 * Get the independent string containing only the character code c, which must
422 * be less than UNIT_STRING_LIMIT.
423 */
424extern JSString *
425js_GetUnitStringForChar(JSContext *cx, jschar c);
426
427extern void
428js_FinishUnitStrings(JSRuntime *rt);
429
430extern void
431js_FinishRuntimeStringState(JSContext *cx);
432
433extern void
434js_FinishDeflatedStringCache(JSRuntime *rt);
435
436/* Initialize the String class, returning its prototype object. */
437extern JSClass js_StringClass;
438
439extern JSObject *
440js_InitStringClass(JSContext *cx, JSObject *obj);
441
442extern const char js_escape_str[];
443extern const char js_unescape_str[];
444extern const char js_uneval_str[];
445extern const char js_decodeURI_str[];
446extern const char js_encodeURI_str[];
447extern const char js_decodeURIComponent_str[];
448extern const char js_encodeURIComponent_str[];
449
450/* GC-allocate a string descriptor for the given malloc-allocated chars. */
451extern JSString *
452js_NewString(JSContext *cx, jschar *chars, size_t length);
453
454extern JSString *
455js_NewDependentString(JSContext *cx, JSString *base, size_t start,
456                      size_t length);
457
458/* Copy a counted string and GC-allocate a descriptor for it. */
459extern JSString *
460js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n);
461
462/* Copy a C string and GC-allocate a descriptor for it. */
463extern JSString *
464js_NewStringCopyZ(JSContext *cx, const jschar *s);
465
466/*
467 * Free the chars held by str when it is finalized by the GC. When type is
468 * less then zero, it denotes an internal string. Otherwise it denotes the
469 * type of the external string allocated with JS_NewExternalString.
470 *
471 * This function always needs rt but can live with null cx.
472 */
473extern void
474js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx);
475
476/*
477 * Convert a value to a printable C string.
478 */
479typedef JSString *(*JSValueToStringFun)(JSContext *cx, jsval v);
480
481extern JS_FRIEND_API(const char *)
482js_ValueToPrintable(JSContext *cx, jsval v, JSValueToStringFun v2sfun);
483
484#define js_ValueToPrintableString(cx,v) \
485    js_ValueToPrintable(cx, v, js_ValueToString)
486
487#define js_ValueToPrintableSource(cx,v) \
488    js_ValueToPrintable(cx, v, js_ValueToSource)
489
490/*
491 * Convert a value to a string, returning null after reporting an error,
492 * otherwise returning a new string reference.
493 */
494extern JS_FRIEND_API(JSString *)
495js_ValueToString(JSContext *cx, jsval v);
496
497/*
498 * Convert a value to its source expression, returning null after reporting
499 * an error, otherwise returning a new string reference.
500 */
501extern JS_FRIEND_API(JSString *)
502js_ValueToSource(JSContext *cx, jsval v);
503
504/*
505 * Compute a hash function from str. The caller can call this function even if
506 * str is not a GC-allocated thing.
507 */
508extern uint32
509js_HashString(JSString *str);
510
511/*
512 * Test if strings are equal. The caller can call the function even if str1
513 * or str2 are not GC-allocated things.
514 */
515extern JSBool JS_FASTCALL
516js_EqualStrings(JSString *str1, JSString *str2);
517
518/*
519 * Return less than, equal to, or greater than zero depending on whether
520 * str1 is less than, equal to, or greater than str2.
521 */
522extern int32 JS_FASTCALL
523js_CompareStrings(JSString *str1, JSString *str2);
524
525/*
526 * Boyer-Moore-Horspool superlinear search for pat:patlen in text:textlen.
527 * The patlen argument must be positive and no greater than BMH_PATLEN_MAX.
528 * The start argument tells where in text to begin the search.
529 *
530 * Return the index of pat in text, or -1 if not found.
531 */
532#define BMH_CHARSET_SIZE 256    /* ISO-Latin-1 */
533#define BMH_PATLEN_MAX   255    /* skip table element is uint8 */
534
535#define BMH_BAD_PATTERN  (-2)   /* return value if pat is not ISO-Latin-1 */
536
537extern jsint
538js_BoyerMooreHorspool(const jschar *text, jsint textlen,
539                      const jschar *pat, jsint patlen,
540                      jsint start);
541
542extern size_t
543js_strlen(const jschar *s);
544
545extern jschar *
546js_strchr(const jschar *s, jschar c);
547
548extern jschar *
549js_strchr_limit(const jschar *s, jschar c, const jschar *limit);
550
551#define js_strncpy(t, s, n)     memcpy((t), (s), (n) * sizeof(jschar))
552
553/*
554 * Return s advanced past any Unicode white space characters.
555 */
556extern const jschar *
557js_SkipWhiteSpace(const jschar *s, const jschar *end);
558
559/*
560 * Inflate bytes to JS chars and vice versa.  Report out of memory via cx
561 * and return null on error, otherwise return the jschar or byte vector that
562 * was JS_malloc'ed. length is updated with the length of the new string in jschars.
563 */
564extern jschar *
565js_InflateString(JSContext *cx, const char *bytes, size_t *length);
566
567extern char *
568js_DeflateString(JSContext *cx, const jschar *chars, size_t length);
569
570/*
571 * Inflate bytes to JS chars into a buffer. 'chars' must be large enough for
572 * 'length' jschars. The buffer is NOT null-terminated. The destination length
573 * must be be initialized with the buffer size and will contain on return the
574 * number of copied chars.
575 */
576extern JSBool
577js_InflateStringToBuffer(JSContext* cx, const char *bytes, size_t length,
578                         jschar *chars, size_t* charsLength);
579
580/*
581 * Get number of bytes in the deflated sequence of characters.
582 */
583extern size_t
584js_GetDeflatedStringLength(JSContext *cx, const jschar *chars,
585                           size_t charsLength);
586
587/*
588 * Deflate JS chars to bytes into a buffer. 'bytes' must be large enough for
589 * 'length chars. The buffer is NOT null-terminated. The destination length
590 * must to be initialized with the buffer size and will contain on return the
591 * number of copied bytes.
592 */
593extern JSBool
594js_DeflateStringToBuffer(JSContext* cx, const jschar *chars,
595                         size_t charsLength, char *bytes, size_t* length);
596
597/*
598 * Associate bytes with str in the deflated string cache, returning true on
599 * successful association, false on out of memory.
600 */
601extern JSBool
602js_SetStringBytes(JSContext *cx, JSString *str, char *bytes, size_t length);
603
604/*
605 * Find or create a deflated string cache entry for str that contains its
606 * characters chopped from Unicode code points into bytes.
607 */
608extern const char *
609js_GetStringBytes(JSContext *cx, JSString *str);
610
611/* Remove a deflated string cache entry associated with str if any. */
612extern void
613js_PurgeDeflatedStringCache(JSRuntime *rt, JSString *str);
614
615/* Export a few natives and a helper to other files in SpiderMonkey. */
616extern JSBool
617js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
618              jsval *rval);
619
620extern JSBool
621js_StringMatchHelper(JSContext *cx, uintN argc, jsval *vp, jsbytecode *pc);
622
623extern JSBool
624js_StringReplaceHelper(JSContext *cx, uintN argc, JSObject *lambda,
625                       JSString *repstr, jsval *vp);
626
627/*
628 * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at
629 * least 6 bytes long.  Return the number of UTF-8 bytes of data written.
630 */
631extern int
632js_OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char);
633
634/*
635 * Write str into buffer escaping any non-printable or non-ASCII character.
636 * Guarantees that a NUL is at the end of the buffer. Returns the length of
637 * the written output, NOT including the NUL. If buffer is null, just returns
638 * the length of the output. If quote is not 0, it must be a single or double
639 * quote character that will quote the output.
640 *
641 * The function is only defined for debug builds.
642*/
643#define js_PutEscapedString(buffer, bufferSize, str, quote)                   \
644    js_PutEscapedStringImpl(buffer, bufferSize, NULL, str, quote)
645
646/*
647 * Write str into file escaping any non-printable or non-ASCII character.
648 * Returns the number of bytes written to file. If quote is not 0, it must
649 * be a single or double quote character that will quote the output.
650 *
651 * The function is only defined for debug builds.
652*/
653#define js_FileEscapedString(file, str, quote)                                \
654    (JS_ASSERT(file), js_PutEscapedStringImpl(NULL, 0, file, str, quote))
655
656extern JS_FRIEND_API(size_t)
657js_PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp,
658                        JSString *str, uint32 quote);
659
660JS_END_EXTERN_C
661
662#endif /* jsstr_h___ */