js/src/jsstr.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial