1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : *
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 file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "vm/StringBuffer.h"
8 :
9 : #include "jsobjinlines.h"
10 :
11 : #include "vm/String-inl.h"
12 :
13 : using namespace js;
14 :
15 : jschar *
16 155735 : StringBuffer::extractWellSized()
17 : {
18 155735 : size_t capacity = cb.capacity();
19 155735 : size_t length = cb.length();
20 :
21 155735 : jschar *buf = cb.extractRawBuffer();
22 155735 : if (!buf)
23 0 : return NULL;
24 :
25 : /* For medium/big buffers, avoid wasting more than 1/4 of the memory. */
26 155735 : JS_ASSERT(capacity >= length);
27 155735 : if (length > CharBuffer::sMaxInlineStorage && capacity - length > length / 4) {
28 17884 : size_t bytes = sizeof(jschar) * (length + 1);
29 17884 : JSContext *cx = context();
30 17884 : jschar *tmp = (jschar *)cx->realloc_(buf, bytes);
31 17884 : if (!tmp) {
32 0 : cx->free_(buf);
33 0 : return NULL;
34 : }
35 17884 : buf = tmp;
36 : }
37 :
38 155735 : return buf;
39 : }
40 :
41 : JSFixedString *
42 321072 : StringBuffer::finishString()
43 : {
44 321072 : JSContext *cx = context();
45 321072 : if (cb.empty())
46 77455 : return cx->runtime->atomState.emptyAtom;
47 :
48 243617 : size_t length = cb.length();
49 243617 : if (!JSString::validateLength(cx, length))
50 0 : return NULL;
51 :
52 : JS_STATIC_ASSERT(JSShortString::MAX_SHORT_LENGTH < CharBuffer::InlineLength);
53 243617 : if (JSShortString::lengthFits(length))
54 87882 : return NewShortString(cx, cb.begin(), length);
55 :
56 155735 : if (!cb.append('\0'))
57 0 : return NULL;
58 :
59 155735 : jschar *buf = extractWellSized();
60 155735 : if (!buf)
61 0 : return NULL;
62 :
63 155735 : JSFixedString *str = js_NewString(cx, buf, length);
64 155735 : if (!str)
65 0 : cx->free_(buf);
66 155735 : return str;
67 : }
68 :
69 : JSAtom *
70 453 : StringBuffer::finishAtom()
71 : {
72 453 : JSContext *cx = context();
73 :
74 453 : size_t length = cb.length();
75 453 : if (length == 0)
76 0 : return cx->runtime->atomState.emptyAtom;
77 :
78 453 : JSAtom *atom = js_AtomizeChars(cx, cb.begin(), length);
79 453 : cb.clear();
80 453 : return atom;
81 : }
82 :
83 : bool
84 210374 : js::ValueToStringBufferSlow(JSContext *cx, const Value &arg, StringBuffer &sb)
85 : {
86 210374 : Value v = arg;
87 210374 : if (!ToPrimitive(cx, JSTYPE_STRING, &v))
88 9 : return false;
89 :
90 210365 : if (v.isString())
91 873 : return sb.append(v.toString());
92 209492 : if (v.isNumber())
93 161630 : return NumberValueToStringBuffer(cx, v, sb);
94 47862 : if (v.isBoolean())
95 47826 : return BooleanToStringBuffer(cx, v.toBoolean(), sb);
96 36 : if (v.isNull())
97 0 : return sb.append(cx->runtime->atomState.nullAtom);
98 36 : JS_ASSERT(v.isUndefined());
99 36 : return sb.append(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
100 : }
|