js/xpconnect/src/XPCString.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:a3d678638984
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set ts=8 sts=4 et sw=4 tw=99: */
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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /*
8 * Infrastructure for sharing DOMString data with JSStrings.
9 *
10 * Importing an nsAString into JS:
11 * If possible (GetSharedBufferHandle works) use the external string support in
12 * JS to create a JSString that points to the readable's buffer. We keep a
13 * reference to the buffer handle until the JSString is finalized.
14 *
15 * Exporting a JSString as an nsAReadable:
16 * Wrap the JSString with a root-holding XPCJSReadableStringWrapper, which roots
17 * the string and exposes its buffer via the nsAString interface, as
18 * well as providing refcounting support.
19 */
20
21 #include "nscore.h"
22 #include "nsString.h"
23 #include "nsStringBuffer.h"
24 #include "jsapi.h"
25 #include "xpcpublic.h"
26
27 using namespace JS;
28
29 // static
30 void
31 XPCStringConvert::FreeZoneCache(JS::Zone *zone)
32 {
33 // Put the zone user data into an AutoPtr (which will do the cleanup for us),
34 // and null out the user data (which may already be null).
35 nsAutoPtr<ZoneStringCache> cache(static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone)));
36 JS_SetZoneUserData(zone, nullptr);
37 }
38
39 // static
40 void
41 XPCStringConvert::ClearZoneCache(JS::Zone *zone)
42 {
43 ZoneStringCache *cache = static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone));
44 if (cache) {
45 cache->mBuffer = nullptr;
46 cache->mString = nullptr;
47 }
48 }
49
50 // static
51 void
52 XPCStringConvert::FinalizeLiteral(const JSStringFinalizer *fin, jschar *chars)
53 {
54 }
55
56 const JSStringFinalizer XPCStringConvert::sLiteralFinalizer =
57 { XPCStringConvert::FinalizeLiteral };
58
59 // static
60 void
61 XPCStringConvert::FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars)
62 {
63 nsStringBuffer* buf = nsStringBuffer::FromData(chars);
64 buf->Release();
65 }
66
67 const JSStringFinalizer XPCStringConvert::sDOMStringFinalizer =
68 { XPCStringConvert::FinalizeDOMString };
69
70 // convert a readable to a JSString, copying string data
71 // static
72 bool
73 XPCStringConvert::ReadableToJSVal(JSContext *cx,
74 const nsAString &readable,
75 nsStringBuffer** sharedBuffer,
76 MutableHandleValue vp)
77 {
78 *sharedBuffer = nullptr;
79
80 uint32_t length = readable.Length();
81
82 if (readable.IsLiteral()) {
83 JSString *str = JS_NewExternalString(cx,
84 static_cast<const jschar*>(readable.BeginReading()),
85 length, &sLiteralFinalizer);
86 if (!str)
87 return false;
88 vp.setString(str);
89 return true;
90 }
91
92 nsStringBuffer *buf = nsStringBuffer::FromString(readable);
93 if (buf) {
94 bool shared;
95 if (!StringBufferToJSVal(cx, buf, length, vp, &shared))
96 return false;
97 if (shared)
98 *sharedBuffer = buf;
99 return true;
100 }
101
102 // blech, have to copy.
103 JSString *str = JS_NewUCStringCopyN(cx, readable.BeginReading(), length);
104 if (!str)
105 return false;
106 vp.setString(str);
107 return true;
108 }

mercurial