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 : #include "vm/StringBuffer-inl.h"
13 :
14 : using namespace js;
15 :
16 : jschar *
17 271607 : StringBuffer::extractWellSized()
18 : {
19 271607 : size_t capacity = cb.capacity();
20 271607 : size_t length = cb.length();
21 :
22 271607 : jschar *buf = cb.extractRawBuffer();
23 271607 : if (!buf)
24 0 : return NULL;
25 :
26 : /* For medium/big buffers, avoid wasting more than 1/4 of the memory. */
27 271607 : JS_ASSERT(capacity >= length);
28 271607 : if (length > CharBuffer::sMaxInlineStorage && capacity - length > length / 4) {
29 51586 : size_t bytes = sizeof(jschar) * (length + 1);
30 51586 : JSContext *cx = context();
31 51586 : jschar *tmp = (jschar *)cx->realloc_(buf, bytes);
32 51586 : if (!tmp) {
33 0 : cx->free_(buf);
34 0 : return NULL;
35 : }
36 51586 : buf = tmp;
37 : }
38 :
39 271607 : return buf;
40 : }
41 :
42 : JSFixedString *
43 466440 : StringBuffer::finishString()
44 : {
45 466440 : JSContext *cx = context();
46 466440 : if (cb.empty())
47 80640 : return cx->runtime->atomState.emptyAtom;
48 :
49 385800 : size_t length = cb.length();
50 385800 : if (!checkLength(length))
51 0 : return NULL;
52 :
53 : JS_STATIC_ASSERT(JSShortString::MAX_SHORT_LENGTH < CharBuffer::InlineLength);
54 385800 : if (JSShortString::lengthFits(length))
55 114193 : return NewShortString(cx, cb.begin(), length);
56 :
57 271607 : if (!cb.append('\0'))
58 0 : return NULL;
59 :
60 271607 : jschar *buf = extractWellSized();
61 271607 : if (!buf)
62 0 : return NULL;
63 :
64 271607 : JSFixedString *str = js_NewString(cx, buf, length);
65 271607 : if (!str)
66 0 : cx->free_(buf);
67 271607 : return str;
68 : }
69 :
70 : JSAtom *
71 3920 : StringBuffer::finishAtom()
72 : {
73 3920 : JSContext *cx = context();
74 :
75 3920 : size_t length = cb.length();
76 3920 : if (length == 0)
77 0 : return cx->runtime->atomState.emptyAtom;
78 :
79 3920 : JSAtom *atom = js_AtomizeChars(cx, cb.begin(), length);
80 3920 : cb.clear();
81 3920 : return atom;
82 : }
83 :
84 : bool
85 692608 : js::ValueToStringBufferSlow(JSContext *cx, const Value &arg, StringBuffer &sb)
86 : {
87 692608 : Value v = arg;
88 692608 : if (!ToPrimitive(cx, JSTYPE_STRING, &v))
89 9 : return false;
90 :
91 692599 : if (v.isString())
92 1213 : return sb.append(v.toString());
93 691386 : if (v.isNumber())
94 643475 : return NumberValueToStringBuffer(cx, v, sb);
95 47911 : if (v.isBoolean())
96 47875 : return BooleanToStringBuffer(cx, v.toBoolean(), sb);
97 36 : if (v.isNull())
98 0 : return sb.append(cx->runtime->atomState.nullAtom);
99 36 : JS_ASSERT(v.isUndefined());
100 36 : return sb.append(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
101 : }
|