1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/xpconnect/src/XPCString.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,108 @@ 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 +/* 1.11 + * Infrastructure for sharing DOMString data with JSStrings. 1.12 + * 1.13 + * Importing an nsAString into JS: 1.14 + * If possible (GetSharedBufferHandle works) use the external string support in 1.15 + * JS to create a JSString that points to the readable's buffer. We keep a 1.16 + * reference to the buffer handle until the JSString is finalized. 1.17 + * 1.18 + * Exporting a JSString as an nsAReadable: 1.19 + * Wrap the JSString with a root-holding XPCJSReadableStringWrapper, which roots 1.20 + * the string and exposes its buffer via the nsAString interface, as 1.21 + * well as providing refcounting support. 1.22 + */ 1.23 + 1.24 +#include "nscore.h" 1.25 +#include "nsString.h" 1.26 +#include "nsStringBuffer.h" 1.27 +#include "jsapi.h" 1.28 +#include "xpcpublic.h" 1.29 + 1.30 +using namespace JS; 1.31 + 1.32 +// static 1.33 +void 1.34 +XPCStringConvert::FreeZoneCache(JS::Zone *zone) 1.35 +{ 1.36 + // Put the zone user data into an AutoPtr (which will do the cleanup for us), 1.37 + // and null out the user data (which may already be null). 1.38 + nsAutoPtr<ZoneStringCache> cache(static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone))); 1.39 + JS_SetZoneUserData(zone, nullptr); 1.40 +} 1.41 + 1.42 +// static 1.43 +void 1.44 +XPCStringConvert::ClearZoneCache(JS::Zone *zone) 1.45 +{ 1.46 + ZoneStringCache *cache = static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone)); 1.47 + if (cache) { 1.48 + cache->mBuffer = nullptr; 1.49 + cache->mString = nullptr; 1.50 + } 1.51 +} 1.52 + 1.53 +// static 1.54 +void 1.55 +XPCStringConvert::FinalizeLiteral(const JSStringFinalizer *fin, jschar *chars) 1.56 +{ 1.57 +} 1.58 + 1.59 +const JSStringFinalizer XPCStringConvert::sLiteralFinalizer = 1.60 + { XPCStringConvert::FinalizeLiteral }; 1.61 + 1.62 +// static 1.63 +void 1.64 +XPCStringConvert::FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars) 1.65 +{ 1.66 + nsStringBuffer* buf = nsStringBuffer::FromData(chars); 1.67 + buf->Release(); 1.68 +} 1.69 + 1.70 +const JSStringFinalizer XPCStringConvert::sDOMStringFinalizer = 1.71 + { XPCStringConvert::FinalizeDOMString }; 1.72 + 1.73 +// convert a readable to a JSString, copying string data 1.74 +// static 1.75 +bool 1.76 +XPCStringConvert::ReadableToJSVal(JSContext *cx, 1.77 + const nsAString &readable, 1.78 + nsStringBuffer** sharedBuffer, 1.79 + MutableHandleValue vp) 1.80 +{ 1.81 + *sharedBuffer = nullptr; 1.82 + 1.83 + uint32_t length = readable.Length(); 1.84 + 1.85 + if (readable.IsLiteral()) { 1.86 + JSString *str = JS_NewExternalString(cx, 1.87 + static_cast<const jschar*>(readable.BeginReading()), 1.88 + length, &sLiteralFinalizer); 1.89 + if (!str) 1.90 + return false; 1.91 + vp.setString(str); 1.92 + return true; 1.93 + } 1.94 + 1.95 + nsStringBuffer *buf = nsStringBuffer::FromString(readable); 1.96 + if (buf) { 1.97 + bool shared; 1.98 + if (!StringBufferToJSVal(cx, buf, length, vp, &shared)) 1.99 + return false; 1.100 + if (shared) 1.101 + *sharedBuffer = buf; 1.102 + return true; 1.103 + } 1.104 + 1.105 + // blech, have to copy. 1.106 + JSString *str = JS_NewUCStringCopyN(cx, readable.BeginReading(), length); 1.107 + if (!str) 1.108 + return false; 1.109 + vp.setString(str); 1.110 + return true; 1.111 +}