1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jsstr.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,373 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef jsstr_h 1.11 +#define jsstr_h 1.12 + 1.13 +#include "mozilla/HashFunctions.h" 1.14 +#include "mozilla/PodOperations.h" 1.15 + 1.16 +#include "jsutil.h" 1.17 +#include "NamespaceImports.h" 1.18 + 1.19 +#include "gc/Rooting.h" 1.20 +#include "js/RootingAPI.h" 1.21 +#include "vm/Unicode.h" 1.22 + 1.23 +class JSAutoByteString; 1.24 +class JSFlatString; 1.25 +class JSLinearString; 1.26 + 1.27 +namespace js { 1.28 + 1.29 +class StringBuffer; 1.30 + 1.31 +class MutatingRopeSegmentRange; 1.32 + 1.33 +template <AllowGC allowGC> 1.34 +extern JSString * 1.35 +ConcatStrings(ThreadSafeContext *cx, 1.36 + typename MaybeRooted<JSString*, allowGC>::HandleType left, 1.37 + typename MaybeRooted<JSString*, allowGC>::HandleType right); 1.38 + 1.39 +// Return s advanced past any Unicode white space characters. 1.40 +static inline const jschar * 1.41 +SkipSpace(const jschar *s, const jschar *end) 1.42 +{ 1.43 + JS_ASSERT(s <= end); 1.44 + 1.45 + while (s < end && unicode::IsSpace(*s)) 1.46 + s++; 1.47 + 1.48 + return s; 1.49 +} 1.50 + 1.51 +// Return less than, equal to, or greater than zero depending on whether 1.52 +// s1 is less than, equal to, or greater than s2. 1.53 +inline int32_t 1.54 +CompareChars(const jschar *s1, size_t l1, const jschar *s2, size_t l2) 1.55 +{ 1.56 + size_t n = Min(l1, l2); 1.57 + for (size_t i = 0; i < n; i++) { 1.58 + if (int32_t cmp = s1[i] - s2[i]) 1.59 + return cmp; 1.60 + } 1.61 + 1.62 + return (int32_t)(l1 - l2); 1.63 +} 1.64 + 1.65 +} /* namespace js */ 1.66 + 1.67 +extern JSString * JS_FASTCALL 1.68 +js_toLowerCase(JSContext *cx, JSString *str); 1.69 + 1.70 +extern JSString * JS_FASTCALL 1.71 +js_toUpperCase(JSContext *cx, JSString *str); 1.72 + 1.73 +struct JSSubString { 1.74 + size_t length; 1.75 + const jschar *chars; 1.76 +}; 1.77 + 1.78 +extern const jschar js_empty_ucstr[]; 1.79 +extern const JSSubString js_EmptySubString; 1.80 + 1.81 +/* 1.82 + * Shorthands for ASCII (7-bit) decimal and hex conversion. 1.83 + * Manually inline isdigit for performance; MSVC doesn't do this for us. 1.84 + */ 1.85 +#define JS7_ISDEC(c) ((((unsigned)(c)) - '0') <= 9) 1.86 +#define JS7_UNDEC(c) ((c) - '0') 1.87 +#define JS7_ISHEX(c) ((c) < 128 && isxdigit(c)) 1.88 +#define JS7_UNHEX(c) (unsigned)(JS7_ISDEC(c) ? (c) - '0' : 10 + tolower(c) - 'a') 1.89 +#define JS7_ISLET(c) ((c) < 128 && isalpha(c)) 1.90 + 1.91 +/* Initialize the String class, returning its prototype object. */ 1.92 +extern JSObject * 1.93 +js_InitStringClass(JSContext *cx, js::HandleObject obj); 1.94 + 1.95 +extern const char js_escape_str[]; 1.96 +extern const char js_unescape_str[]; 1.97 +extern const char js_uneval_str[]; 1.98 +extern const char js_decodeURI_str[]; 1.99 +extern const char js_encodeURI_str[]; 1.100 +extern const char js_decodeURIComponent_str[]; 1.101 +extern const char js_encodeURIComponent_str[]; 1.102 + 1.103 +/* GC-allocate a string descriptor for the given malloc-allocated chars. */ 1.104 +template <js::AllowGC allowGC> 1.105 +extern JSFlatString * 1.106 +js_NewString(js::ThreadSafeContext *cx, jschar *chars, size_t length); 1.107 + 1.108 +extern JSLinearString * 1.109 +js_NewDependentString(JSContext *cx, JSString *base, size_t start, size_t length); 1.110 + 1.111 +/* Copy a counted string and GC-allocate a descriptor for it. */ 1.112 +template <js::AllowGC allowGC> 1.113 +extern JSFlatString * 1.114 +js_NewStringCopyN(js::ExclusiveContext *cx, const jschar *s, size_t n); 1.115 + 1.116 +template <js::AllowGC allowGC> 1.117 +extern JSFlatString * 1.118 +js_NewStringCopyN(js::ThreadSafeContext *cx, const char *s, size_t n); 1.119 + 1.120 +/* Copy a C string and GC-allocate a descriptor for it. */ 1.121 +template <js::AllowGC allowGC> 1.122 +extern JSFlatString * 1.123 +js_NewStringCopyZ(js::ExclusiveContext *cx, const jschar *s); 1.124 + 1.125 +template <js::AllowGC allowGC> 1.126 +extern JSFlatString * 1.127 +js_NewStringCopyZ(js::ThreadSafeContext *cx, const char *s); 1.128 + 1.129 +/* 1.130 + * Convert a value to a printable C string. 1.131 + */ 1.132 +extern const char * 1.133 +js_ValueToPrintable(JSContext *cx, const js::Value &, 1.134 + JSAutoByteString *bytes, bool asSource = false); 1.135 + 1.136 +namespace js { 1.137 + 1.138 +/* 1.139 + * Convert a non-string value to a string, returning null after reporting an 1.140 + * error, otherwise returning a new string reference. 1.141 + */ 1.142 +template <AllowGC allowGC> 1.143 +extern JSString * 1.144 +ToStringSlow(ExclusiveContext *cx, typename MaybeRooted<Value, allowGC>::HandleType arg); 1.145 + 1.146 +/* 1.147 + * Convert the given value to a string. This method includes an inline 1.148 + * fast-path for the case where the value is already a string; if the value is 1.149 + * known not to be a string, use ToStringSlow instead. 1.150 + */ 1.151 +template <AllowGC allowGC> 1.152 +static MOZ_ALWAYS_INLINE JSString * 1.153 +ToString(JSContext *cx, JS::HandleValue v) 1.154 +{ 1.155 + if (v.isString()) 1.156 + return v.toString(); 1.157 + return ToStringSlow<allowGC>(cx, v); 1.158 +} 1.159 + 1.160 +/* 1.161 + * This function implements E-262-3 section 9.8, toString. Convert the given 1.162 + * value to a string of jschars appended to the given buffer. On error, the 1.163 + * passed buffer may have partial results appended. 1.164 + */ 1.165 +inline bool 1.166 +ValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb); 1.167 + 1.168 +/* 1.169 + * Convert a value to its source expression, returning null after reporting 1.170 + * an error, otherwise returning a new string reference. 1.171 + */ 1.172 +extern JSString * 1.173 +ValueToSource(JSContext *cx, HandleValue v); 1.174 + 1.175 +/* 1.176 + * Convert a JSString to its source expression; returns null after reporting an 1.177 + * error, otherwise returns a new string reference. No Handle needed since the 1.178 + * input is dead after the GC. 1.179 + */ 1.180 +extern JSString * 1.181 +StringToSource(JSContext *cx, JSString *str); 1.182 + 1.183 +/* 1.184 + * Test if strings are equal. The caller can call the function even if str1 1.185 + * or str2 are not GC-allocated things. 1.186 + */ 1.187 +extern bool 1.188 +EqualStrings(JSContext *cx, JSString *str1, JSString *str2, bool *result); 1.189 + 1.190 +/* Use the infallible method instead! */ 1.191 +extern bool 1.192 +EqualStrings(JSContext *cx, JSLinearString *str1, JSLinearString *str2, bool *result) MOZ_DELETE; 1.193 + 1.194 +/* EqualStrings is infallible on linear strings. */ 1.195 +extern bool 1.196 +EqualStrings(JSLinearString *str1, JSLinearString *str2); 1.197 + 1.198 +/* 1.199 + * Return less than, equal to, or greater than zero depending on whether 1.200 + * str1 is less than, equal to, or greater than str2. 1.201 + */ 1.202 +extern bool 1.203 +CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result); 1.204 + 1.205 +extern int32_t 1.206 +CompareAtoms(JSAtom *atom1, JSAtom *atom2); 1.207 + 1.208 +/* 1.209 + * Return true if the string matches the given sequence of ASCII bytes. 1.210 + */ 1.211 +extern bool 1.212 +StringEqualsAscii(JSLinearString *str, const char *asciiBytes); 1.213 + 1.214 +/* Return true if the string contains a pattern anywhere inside it. */ 1.215 +extern bool 1.216 +StringHasPattern(const jschar *text, uint32_t textlen, 1.217 + const jschar *pat, uint32_t patlen); 1.218 + 1.219 +} /* namespace js */ 1.220 + 1.221 +extern size_t 1.222 +js_strlen(const jschar *s); 1.223 + 1.224 +extern int32_t 1.225 +js_strcmp(const jschar *lhs, const jschar *rhs); 1.226 + 1.227 +extern jschar * 1.228 +js_strchr_limit(const jschar *s, jschar c, const jschar *limit); 1.229 + 1.230 +static MOZ_ALWAYS_INLINE void 1.231 +js_strncpy(jschar *dst, const jschar *src, size_t nelem) 1.232 +{ 1.233 + return mozilla::PodCopy(dst, src, nelem); 1.234 +} 1.235 + 1.236 +extern jschar * 1.237 +js_strdup(js::ThreadSafeContext *cx, const jschar *s); 1.238 + 1.239 +namespace js { 1.240 + 1.241 +/* 1.242 + * Inflate bytes in ASCII encoding to jschars. Return null on error, otherwise 1.243 + * return the jschar that was malloc'ed. length is updated to the length of the 1.244 + * new string (in jschars). A null char is appended, but it is not included in 1.245 + * the length. 1.246 + */ 1.247 +extern jschar * 1.248 +InflateString(ThreadSafeContext *cx, const char *bytes, size_t *length); 1.249 + 1.250 +/* 1.251 + * Inflate bytes to JS chars in an existing buffer. 'dst' must be large 1.252 + * enough for 'srclen' jschars. The buffer is NOT null-terminated. 1.253 + */ 1.254 +inline void 1.255 +InflateStringToBuffer(const char *src, size_t srclen, jschar *dst) 1.256 +{ 1.257 + for (size_t i = 0; i < srclen; i++) 1.258 + dst[i] = (unsigned char) src[i]; 1.259 +} 1.260 + 1.261 +/* 1.262 + * Deflate JS chars to bytes into a buffer. 'bytes' must be large enough for 1.263 + * 'length chars. The buffer is NOT null-terminated. The destination length 1.264 + * must to be initialized with the buffer size and will contain on return the 1.265 + * number of copied bytes. 1.266 + */ 1.267 +extern bool 1.268 +DeflateStringToBuffer(JSContext *maybecx, const jschar *chars, 1.269 + size_t charsLength, char *bytes, size_t *length); 1.270 + 1.271 +/* 1.272 + * The String.prototype.replace fast-native entry point is exported for joined 1.273 + * function optimization in js{interp,tracer}.cpp. 1.274 + */ 1.275 +extern bool 1.276 +str_replace(JSContext *cx, unsigned argc, js::Value *vp); 1.277 + 1.278 +extern bool 1.279 +str_fromCharCode(JSContext *cx, unsigned argc, Value *vp); 1.280 + 1.281 +} /* namespace js */ 1.282 + 1.283 +extern bool 1.284 +js_str_toString(JSContext *cx, unsigned argc, js::Value *vp); 1.285 + 1.286 +extern bool 1.287 +js_str_charAt(JSContext *cx, unsigned argc, js::Value *vp); 1.288 + 1.289 +extern bool 1.290 +js_str_charCodeAt(JSContext *cx, unsigned argc, js::Value *vp); 1.291 + 1.292 +/* 1.293 + * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at 1.294 + * least 6 bytes long. Return the number of UTF-8 bytes of data written. 1.295 + */ 1.296 +extern int 1.297 +js_OneUcs4ToUtf8Char(uint8_t *utf8Buffer, uint32_t ucs4Char); 1.298 + 1.299 +namespace js { 1.300 + 1.301 +extern size_t 1.302 +PutEscapedStringImpl(char *buffer, size_t size, FILE *fp, JSLinearString *str, uint32_t quote); 1.303 + 1.304 +extern size_t 1.305 +PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, const jschar *chars, 1.306 + size_t length, uint32_t quote); 1.307 + 1.308 +/* 1.309 + * Write str into buffer escaping any non-printable or non-ASCII character 1.310 + * using \escapes for JS string literals. 1.311 + * Guarantees that a NUL is at the end of the buffer unless size is 0. Returns 1.312 + * the length of the written output, NOT including the NUL. Thus, a return 1.313 + * value of size or more means that the output was truncated. If buffer 1.314 + * is null, just returns the length of the output. If quote is not 0, it must 1.315 + * be a single or double quote character that will quote the output. 1.316 +*/ 1.317 +inline size_t 1.318 +PutEscapedString(char *buffer, size_t size, JSLinearString *str, uint32_t quote) 1.319 +{ 1.320 + size_t n = PutEscapedStringImpl(buffer, size, nullptr, str, quote); 1.321 + 1.322 + /* PutEscapedStringImpl can only fail with a file. */ 1.323 + JS_ASSERT(n != size_t(-1)); 1.324 + return n; 1.325 +} 1.326 + 1.327 +inline size_t 1.328 +PutEscapedString(char *buffer, size_t bufferSize, const jschar *chars, size_t length, uint32_t quote) 1.329 +{ 1.330 + size_t n = PutEscapedStringImpl(buffer, bufferSize, nullptr, chars, length, quote); 1.331 + 1.332 + /* PutEscapedStringImpl can only fail with a file. */ 1.333 + JS_ASSERT(n != size_t(-1)); 1.334 + return n; 1.335 +} 1.336 + 1.337 +/* 1.338 + * Write str into file escaping any non-printable or non-ASCII character. 1.339 + * If quote is not 0, it must be a single or double quote character that 1.340 + * will quote the output. 1.341 +*/ 1.342 +inline bool 1.343 +FileEscapedString(FILE *fp, JSLinearString *str, uint32_t quote) 1.344 +{ 1.345 + return PutEscapedStringImpl(nullptr, 0, fp, str, quote) != size_t(-1); 1.346 +} 1.347 + 1.348 +bool 1.349 +str_match(JSContext *cx, unsigned argc, Value *vp); 1.350 + 1.351 +bool 1.352 +str_search(JSContext *cx, unsigned argc, Value *vp); 1.353 + 1.354 +bool 1.355 +str_split(JSContext *cx, unsigned argc, Value *vp); 1.356 + 1.357 +JSObject * 1.358 +str_split_string(JSContext *cx, HandleTypeObject type, HandleString str, HandleString sep); 1.359 + 1.360 +bool 1.361 +str_resolve(JSContext *cx, HandleObject obj, HandleId id, MutableHandleObject objp); 1.362 + 1.363 +bool 1.364 +str_replace_regexp_raw(JSContext *cx, HandleString string, HandleObject regexp, 1.365 + HandleString replacement, MutableHandleValue rval); 1.366 + 1.367 +bool 1.368 +str_replace_string_raw(JSContext *cx, HandleString string, HandleString pattern, 1.369 + HandleString replacement, MutableHandleValue rval); 1.370 + 1.371 +} /* namespace js */ 1.372 + 1.373 +extern bool 1.374 +js_String(JSContext *cx, unsigned argc, js::Value *vp); 1.375 + 1.376 +#endif /* jsstr_h */