Bug 1784812 - Use common JSONWriteFuncs when writing to a string - r=canaltinova,media-playback-reviewers,alwu

Most users of JSONWriter want to fill a string, so instead of having all these
similar implementations, we now have central reusable implementations:
- JSONStringWriteFunc contains a string and writes to it.
- JSONStringRefWriteFunc references a string and writes to it. This is most
  useful when the string already exists somewhere, or needs to be returned from
  a function (so we avoid another conversion when returning).

Depends on D154617

Differential Revision: https://phabricator.services.mozilla.com/D154618
This commit is contained in:
Gerald Squelart 2022-08-16 22:57:49 +00:00
parent 722fbce3cc
commit 253bb5dc48
16 changed files with 125 additions and 185 deletions

View File

@ -9,7 +9,7 @@
#include "DDLogUtils.h"
#include "nsIThread.h"
#include "nsIThreadManager.h"
#include "mozilla/JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
namespace mozilla {
@ -375,12 +375,6 @@ void DDMediaLogs::ProcessBuffer() {
});
}
struct StringWriteFunc : public JSONWriteFunc {
nsCString& mCString;
explicit StringWriteFunc(nsCString& aCString) : mCString(aCString) {}
void Write(const Span<const char>& aStr) override { mCString.Append(aStr); }
};
void DDMediaLogs::FulfillPromises() {
MOZ_ASSERT(!mThread || mThread.get() == NS_GetCurrentThread());
@ -415,8 +409,8 @@ void DDMediaLogs::FulfillPromises() {
continue;
}
nsCString json;
JSONWriter jw{MakeUnique<StringWriteFunc>(json)};
JSONStringWriteFunc json;
JSONWriter jw{json};
jw.Start();
jw.StartArrayProperty("messages");
for (const DDLogMessage& message : log->mMessages) {
@ -485,7 +479,8 @@ void DDMediaLogs::FulfillPromises() {
log->mMessages.IsEmpty());
jw.EndObject();
jw.End();
DDL_DEBUG("RetrieveMessages(%p) ->\n%s", mediaElement, json.get());
DDL_DEBUG("RetrieveMessages(%p) ->\n%s", mediaElement,
json.StringCRef().get());
// This log exists (new messages or not) -> Resolve this promise.
DDL_INFO("Resolving promise for HTMLMediaElement[%p] with messages %" PRImi
@ -495,7 +490,7 @@ void DDMediaLogs::FulfillPromises() {
log->mMessages.IsEmpty()
? 0
: log->mMessages[log->mMessages.Length() - 1].mIndex.Value());
promiseHolder.Resolve(std::move(json), __func__);
promiseHolder.Resolve(std::move(json).StringRRef(), __func__);
// Remove exported messages.
log->mMessages.Clear();

View File

@ -9,7 +9,7 @@
#include "ChromiumCDMProxy.h"
#include "GMPCrashHelper.h"
#include "mozilla/EMEUtils.h"
#include "mozilla/JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
#include "mozilla/Telemetry.h"
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/Document.h"
@ -716,14 +716,6 @@ void MediaKeys::Unbind() {
mElement = nullptr;
}
struct StringWriteFunc : public JSONWriteFunc {
nsString& mString;
explicit StringWriteFunc(nsString& aString) : mString(aString) {}
void Write(const Span<const char>& aStr) override {
mString.Append(NS_ConvertUTF8toUTF16(aStr.data(), aStr.size()));
}
};
void MediaKeys::CheckIsElementCapturePossible() {
MOZ_ASSERT(NS_IsMainThread());
EME_LOG("MediaKeys[%p]::IsElementCapturePossible()", this);
@ -761,11 +753,13 @@ void MediaKeys::CheckIsElementCapturePossible() {
if (mCaptureCheckRequestJson.IsEmpty()) {
// Lazily populate the JSON the first time we need it.
JSONWriter jw{MakeUnique<StringWriteFunc>(mCaptureCheckRequestJson)};
JSONStringWriteFunc json;
JSONWriter jw{json};
jw.Start();
jw.StringProperty("status", "is-capture-possible");
jw.StringProperty("keySystem", NS_ConvertUTF16toUTF8(mKeySystem));
jw.End();
mCaptureCheckRequestJson = NS_ConvertUTF8toUTF16(json.StringCRef());
}
MOZ_DIAGNOSTIC_ASSERT(!mCaptureCheckRequestJson.IsEmpty());

View File

@ -13,7 +13,7 @@
#include "mozilla/Encoding.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/HoldDropJSObjects.h"
#include "mozilla/JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/Preferences.h"
#include "mozilla/StaticPrefs_dom.h"
@ -1315,17 +1315,6 @@ bool Notification::IsInPrivateBrowsing() {
return false;
}
namespace {
struct StringWriteFunc : public JSONWriteFunc {
nsAString& mBuffer; // This struct must not outlive this buffer
explicit StringWriteFunc(nsAString& buffer) : mBuffer(buffer) {}
void Write(const Span<const char>& aStr) override {
mBuffer.Append(NS_ConvertUTF8toUTF16(aStr.data(), aStr.size()));
}
};
} // namespace
void Notification::ShowInternal() {
AssertIsOnMainThread();
MOZ_ASSERT(mTempRef,
@ -1431,9 +1420,8 @@ void Notification::ShowInternal() {
NS_ENSURE_SUCCESS_VOID(rv);
if (isPersistent) {
nsAutoString persistentData;
JSONWriter w(MakeUnique<StringWriteFunc>(persistentData));
JSONStringWriteFunc<nsAutoCString> persistentData;
JSONWriter w(persistentData);
w.Start();
nsAutoString origin;
@ -1448,8 +1436,9 @@ void Notification::ShowInternal() {
w.End();
alertService->ShowPersistentNotification(persistentData, alert,
alertObserver);
alertService->ShowPersistentNotification(
NS_ConvertUTF8toUTF16(persistentData.StringCRef()), alert,
alertObserver);
} else {
alertService->ShowAlert(alert, alertObserver);
}

View File

@ -9,19 +9,13 @@
#include "mozilla/dom/Navigator.h"
#include "mozilla/dom/ReportingHeader.h"
#include "mozilla/dom/ReportDeliver.h"
#include "mozilla/JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
#include "nsIPrincipal.h"
#include "nsIURIMutator.h"
#include "nsString.h"
namespace mozilla::dom {
struct StringWriteFunc : public JSONWriteFunc {
nsCString& mCString;
explicit StringWriteFunc(nsCString& aCString) : mCString(aCString) {}
void Write(const Span<const char>& aStr) override { mCString.Append(aStr); }
};
/* static */
bool CrashReport::Deliver(nsIPrincipal* aPrincipal, bool aIsOOM) {
MOZ_ASSERT(aPrincipal);
@ -47,8 +41,8 @@ bool CrashReport::Deliver(nsIPrincipal* aPrincipal, bool aIsOOM) {
data.mFailures = 0;
data.mEndpointURL = endpoint_url;
nsCString body;
JSONWriter writer{MakeUnique<StringWriteFunc>(body)};
JSONStringWriteFunc body;
JSONWriter writer{body};
writer.Start();
if (aIsOOM) {
@ -56,7 +50,7 @@ bool CrashReport::Deliver(nsIPrincipal* aPrincipal, bool aIsOOM) {
}
writer.End();
data.mReportBodyJSON = body;
data.mReportBodyJSON = std::move(body).StringRRef();
ReportDeliver::Fetch(data);
return true;

View File

@ -4,7 +4,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/dom/EndpointForReportChild.h"
#include "mozilla/dom/Fetch.h"
@ -94,18 +94,10 @@ class ReportFetchHandler final : public PromiseNativeHandler {
NS_IMPL_ISUPPORTS0(ReportFetchHandler)
struct StringWriteFunc final : public JSONWriteFunc {
nsACString&
mBuffer; // The lifetime of the struct must be bound to the buffer
explicit StringWriteFunc(nsACString& aBuffer) : mBuffer(aBuffer) {}
void Write(const Span<const char>& aStr) override { mBuffer.Append(aStr); }
};
class ReportJSONWriter final : public JSONWriter {
public:
explicit ReportJSONWriter(nsACString& aOutput)
: JSONWriter(MakeUnique<StringWriteFunc>(aOutput)) {}
explicit ReportJSONWriter(JSONStringWriteFunc<nsAutoCString>& aOutput)
: JSONWriter(aOutput) {}
void JSONProperty(const Span<const char>& aProperty,
const Span<const char>& aJSON) {
@ -148,7 +140,7 @@ void SendReports(nsTArray<ReportDeliver::ReportData>& aReports,
}
// The body
nsAutoCString body;
JSONStringWriteFunc<nsAutoCString> body;
ReportJSONWriter w(body);
w.StartArrayElement();
@ -170,7 +162,8 @@ void SendReports(nsTArray<ReportDeliver::ReportData>& aReports,
// The body as stream
nsCOMPtr<nsIInputStream> streamBody;
nsresult rv = NS_NewCStringInputStream(getter_AddRefs(streamBody), body);
nsresult rv =
NS_NewCStringInputStream(getter_AddRefs(streamBody), body.StringCRef());
// Headers
IgnoredErrorResult error;
@ -209,7 +202,7 @@ void SendReports(nsTArray<ReportDeliver::ReportData>& aReports,
auto internalRequest = MakeSafeRefPtr<InternalRequest>(uriSpec, uriFragment);
internalRequest->SetMethod("POST"_ns);
internalRequest->SetBody(streamBody, body.Length());
internalRequest->SetBody(streamBody, body.StringCRef().Length());
internalRequest->SetHeaders(internalHeaders);
internalRequest->SetSkipServiceWorker();
// TODO: internalRequest->SetContentPolicyType(TYPE_REPORT);
@ -249,7 +242,7 @@ void ReportDeliver::Record(nsPIDOMWindowInner* aWindow, const nsAString& aType,
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aBody);
nsAutoCString reportBodyJSON;
JSONStringWriteFunc<nsAutoCString> reportBodyJSON;
ReportJSONWriter w(reportBodyJSON);
w.Start();
@ -283,7 +276,7 @@ void ReportDeliver::Record(nsPIDOMWindowInner* aWindow, const nsAString& aType,
data.mGroupName = aGroupName;
data.mURL = aURL;
data.mCreationTime = TimeStamp::Now();
data.mReportBodyJSON = reportBodyJSON;
data.mReportBodyJSON = std::move(reportBodyJSON).StringRRef();
data.mPrincipal = principal;
data.mFailures = 0;

View File

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <fstream>
#include "mozilla/JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
#include "mozilla/ClearOnShutdown.h"
#include "nsIThread.h"
#include "nsString.h"
@ -61,15 +61,6 @@ namespace mozilla::gfx {
namespace {
// This is for controller action file writer.
struct StringWriteFunc : public JSONWriteFunc {
nsACString& mBuffer; // This struct must not outlive this buffer
explicit StringWriteFunc(nsACString& buffer) : mBuffer(buffer) {}
void Write(const Span<const char>& aStr) override { mBuffer.Append(aStr); }
};
class ControllerManifestFile {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ControllerManifestFile)
@ -579,8 +570,8 @@ bool OpenVRSession::SetupContollerActions() {
if (!GenerateTempFileName(controllerAction)) {
return false;
}
nsCString actionData;
JSONWriter actionWriter(MakeUnique<StringWriteFunc>(actionData));
JSONStringWriteFunc actionData;
JSONWriter actionWriter(actionData);
actionWriter.Start();
actionWriter.StringProperty("version",
@ -642,9 +633,8 @@ bool OpenVRSession::SetupContollerActions() {
actionWriter.End();
std::ofstream actionfile(controllerAction.BeginReading());
nsCString actionResult(actionData.get());
if (actionfile.is_open()) {
actionfile << actionResult.get();
actionfile << actionData.StringCRef().get();
actionfile.close();
}
}

View File

@ -6,7 +6,7 @@
#include "RegistrationAnnotator.h"
#include "mozilla/JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
#include "mozilla/mscom/Utils.h"
#include "mozilla/NotNull.h"
#include "nsExceptionHandler.h"
@ -16,22 +16,6 @@
#include <oleauto.h>
namespace {
class CStringWriter final : public mozilla::JSONWriteFunc {
public:
void Write(const mozilla::Span<const char>& aStr) override {
mBuf.Append(aStr);
}
const nsCString& Get() const { return mBuf; }
private:
nsCString mBuf;
};
} // anonymous namespace
namespace mozilla {
namespace mscom {
@ -338,7 +322,8 @@ void AnnotateInterfaceRegistration(REFIID aIid) {
const JSONWriter::CollectionStyle style = JSONWriter::SingleLineStyle;
#endif
JSONWriter json(MakeUnique<CStringWriter>());
JSONStringWriteFunc jsonString;
JSONWriter json(jsonString);
json.Start(style);
@ -358,8 +343,7 @@ void AnnotateInterfaceRegistration(REFIID aIid) {
} else {
annotationKey = CrashReporter::Annotation::InterfaceRegistrationInfoChild;
}
CrashReporter::AnnotateCrashReport(
annotationKey, static_cast<CStringWriter&>(json.WriteFunc()).Get());
CrashReporter::AnnotateCrashReport(annotationKey, jsonString.StringCRef());
}
void AnnotateClassRegistration(REFCLSID aClsid) {
@ -372,7 +356,8 @@ void AnnotateClassRegistration(REFCLSID aClsid) {
nsAutoString strClsid;
GUIDToString(aClsid, strClsid);
JSONWriter json(MakeUnique<CStringWriter>());
JSONStringWriteFunc jsonString;
JSONWriter json(jsonString);
json.Start(style);
@ -393,8 +378,7 @@ void AnnotateClassRegistration(REFCLSID aClsid) {
annotationKey = CrashReporter::Annotation::ClassRegistrationInfoChild;
}
CrashReporter::AnnotateCrashReport(
annotationKey, static_cast<CStringWriter&>(json.WriteFunc()).Get());
CrashReporter::AnnotateCrashReport(annotationKey, jsonString.StringCRef());
}
} // namespace mscom

View File

@ -321,15 +321,6 @@ void UniqueStacks::StreamNonJITFrame(const FrameKey& aFrame) {
}
}
struct CStringWriteFunc : public JSONWriteFunc {
std::string& mBuffer; // The struct must not outlive this buffer
explicit CStringWriteFunc(std::string& aBuffer) : mBuffer(aBuffer) {}
void Write(const Span<const char>& aStr) override {
mBuffer.append(aStr.data(), aStr.size());
}
};
struct ProfileSample {
uint32_t mStack;
double mTime;

View File

@ -8,7 +8,7 @@
#define mozilla_ContentBlockingLog_h
#include "mozilla/ContentBlockingNotifier.h"
#include "mozilla/JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
#include "mozilla/Maybe.h"
#include "mozilla/StaticPrefs_browser.h"
#include "mozilla/Tuple.h"
@ -57,14 +57,6 @@ class ContentBlockingLog final {
typedef nsTArray<OriginEntry> OriginDataTable;
struct StringWriteFunc : public JSONWriteFunc {
nsACString&
mBuffer; // The lifetime of the struct must be bound to the buffer
explicit StringWriteFunc(nsACString& aBuffer) : mBuffer(aBuffer) {}
void Write(const Span<const char>& aStr) override { mBuffer.Append(aStr); }
};
struct Comparator {
public:
bool Equals(const OriginDataTable::value_type& aLeft,
@ -110,7 +102,8 @@ class ContentBlockingLog final {
nsAutoCString Stringify() {
nsAutoCString buffer;
JSONWriter w(MakeUnique<StringWriteFunc>(buffer));
JSONStringRefWriteFunc js(buffer);
JSONWriter w(js);
w.Start();
for (const OriginEntry& entry : mLog) {

View File

@ -7,7 +7,7 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
#include "Database.h"
@ -2061,12 +2061,6 @@ nsresult Database::MigrateV50Up() {
return NS_OK;
}
struct StringWriteFunc : public JSONWriteFunc {
nsCString& mCString;
explicit StringWriteFunc(nsCString& aCString) : mCString(aCString) {}
void Write(const Span<const char>& aStr) override { mCString.Append(aStr); }
};
nsresult Database::MigrateV51Up() {
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = mMainConn->CreateStatement(
@ -2084,8 +2078,8 @@ nsresult Database::MigrateV51Up() {
rv = stmt->BindUTF8StringByName("anno_name"_ns, LAST_USED_ANNO);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString json;
JSONWriter jw{MakeUnique<StringWriteFunc>(json)};
JSONStringWriteFunc<nsAutoCString> json;
JSONWriter jw{json};
jw.StartArrayProperty(nullptr, JSONWriter::SingleLineStyle);
bool hasAtLeastOne = false;
@ -2111,7 +2105,7 @@ nsresult Database::MigrateV51Up() {
rv = stmt->BindUTF8StringByName("key"_ns, LAST_USED_FOLDERS_META_KEY);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->BindUTF8StringByName("value"_ns, json);
rv = stmt->BindUTF8StringByName("value"_ns, json.StringCRef());
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -13,7 +13,7 @@
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/gfx/GPUChild.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
using namespace mozilla::dom;
using namespace mozilla::gfx;
@ -107,15 +107,6 @@ void PerfStats::RecordMeasurementCounterInternal(Metric aMetric,
sSingleton->mRecordedCounts[static_cast<size_t>(aMetric)]++;
}
struct StringWriteFunc : public JSONWriteFunc {
nsCString& mString;
explicit StringWriteFunc(nsCString& aString) : mString(aString) {}
virtual void Write(const Span<const char>& aStr) override {
mString.Append(aStr);
}
};
void AppendJSONStringAsProperty(nsCString& aDest, const char* aPropertyName,
const nsACString& aJSON) {
// We need to manually append into the string here, since JSONWriter has no
@ -166,7 +157,7 @@ static void WriteContentParent(nsCString& aRawString, JSONWriter& aWriter,
}
struct PerfStatsCollector {
PerfStatsCollector() : writer(MakeUnique<StringWriteFunc>(string)) {}
PerfStatsCollector() : writer(MakeUnique<JSONStringRefWriteFunc>(string)) {}
void AppendPerfStats(const nsCString& aString, ContentParent* aParent) {
writer.StartObjectElement();
@ -208,7 +199,8 @@ void PerfStats::ResetCollection() {
void PerfStats::StorePerfStatsInternal(dom::ContentParent* aParent,
const nsACString& aPerfStats) {
nsCString jsonString;
JSONWriter w(MakeUnique<StringWriteFunc>(jsonString));
JSONStringRefWriteFunc jw(jsonString);
JSONWriter w(jw);
// To generate correct JSON here we don't call start and end. That causes
// this to use Single Line mode, sadly.
@ -294,7 +286,8 @@ nsCString PerfStats::CollectLocalPerfStatsJSONInternal() {
nsCString jsonString;
JSONWriter w(MakeUnique<StringWriteFunc>(jsonString));
JSONStringRefWriteFunc jw(jsonString);
JSONWriter w(jw);
w.Start();
{
w.StartArrayProperty("metrics");

View File

@ -17,6 +17,7 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "mozilla/Logging.h"
#include "mozilla/JSONStringWriteFuncs.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/Sprintf.h"
#include "mozilla/StackWalk.h"
@ -485,18 +486,12 @@ static void StreamJITFrame(JSContext* aContext, SpliceableJSONWriter& aWriter,
writer.IntElement(SUBCATEGORY, info.mSubcategoryIndex);
}
struct CStringWriteFunc : public JSONWriteFunc {
nsACString& mBuffer; // The struct must not outlive this buffer
explicit CStringWriteFunc(nsACString& aBuffer) : mBuffer(aBuffer) {}
void Write(const Span<const char>& aStr) override { mBuffer.Append(aStr); }
};
static nsCString JSONForJITFrame(JSContext* aContext,
const JS::ProfiledFrameHandle& aJITFrame,
UniqueJSONStrings& aUniqueStrings) {
nsCString json;
SpliceableJSONWriter writer(MakeUnique<CStringWriteFunc>(json));
JSONStringRefWriteFunc jw(json);
SpliceableJSONWriter writer(jw);
StreamJITFrame(aContext, writer, aUniqueStrings, aJITFrame);
return json;
}

View File

@ -21,6 +21,7 @@
#include "js/Value.h"
#include "json/json.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/JSONStringWriteFuncs.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/Services.h"
#include "mozilla/dom/Promise.h"
@ -299,31 +300,20 @@ nsProfiler::GetProfile(double aSinceTime, char** aProfile) {
return NS_OK;
}
namespace {
struct StringWriteFunc : public JSONWriteFunc {
nsAString& mBuffer; // This struct must not outlive this buffer
explicit StringWriteFunc(nsAString& buffer) : mBuffer(buffer) {}
void Write(const Span<const char>& aStr) override {
mBuffer.Append(NS_ConvertUTF8toUTF16(aStr.data(), aStr.size()));
}
};
} // namespace
NS_IMETHODIMP
nsProfiler::GetSharedLibraries(JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
JS::Rooted<JS::Value> val(aCx);
{
nsString buffer;
JSONWriter w(MakeUnique<StringWriteFunc>(buffer),
JSONWriter::SingleLineStyle);
JSONStringWriteFunc buffer;
JSONWriter w(buffer, JSONWriter::SingleLineStyle);
w.StartArrayElement();
AppendSharedLibraries(w);
w.EndArray();
NS_ConvertUTF8toUTF16 buffer16(buffer.StringCRef());
MOZ_ALWAYS_TRUE(JS_ParseJSON(aCx,
static_cast<const char16_t*>(buffer.get()),
buffer.Length(), &val));
static_cast<const char16_t*>(buffer16.get()),
buffer16.Length(), &val));
}
JS::Rooted<JSObject*> obj(aCx, &val.toObject());
if (!obj) {
@ -338,13 +328,13 @@ nsProfiler::GetActiveConfiguration(JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
JS::Rooted<JS::Value> jsValue(aCx);
{
nsString buffer;
JSONWriter writer(MakeUnique<StringWriteFunc>(buffer),
JSONWriter::SingleLineStyle);
JSONStringWriteFunc buffer;
JSONWriter writer(buffer, JSONWriter::SingleLineStyle);
profiler_write_active_configuration(writer);
NS_ConvertUTF8toUTF16 buffer16(buffer.StringCRef());
MOZ_ALWAYS_TRUE(JS_ParseJSON(aCx,
static_cast<const char16_t*>(buffer.get()),
buffer.Length(), &jsValue));
static_cast<const char16_t*>(buffer16.get()),
buffer16.Length(), &jsValue));
}
if (jsValue.isNull()) {
aResult.setNull();

View File

@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef JSONSTRINGWRITEFUNCS_H
#define JSONSTRINGWRITEFUNCS_H
#include "mozilla/JSONWriter.h"
#include "nsString.h"
#include <type_traits>
namespace mozilla {
// JSONWriteFunc that writes to an owned string.
template <typename StringType = nsCString>
class JSONStringWriteFunc final : public JSONWriteFunc {
static_assert(
!std::is_reference_v<StringType>,
"Use JSONStringRefWriteFunc instead to write to a referenced string");
public:
JSONStringWriteFunc() = default;
void Write(const Span<const char>& aStr) override { mString.Append(aStr); }
const StringType& StringCRef() const { return mString; }
StringType&& StringRRef() && { return std::move(mString); }
private:
StringType mString;
};
// JSONWriteFunc that writes to a given nsACString reference.
class JSONStringRefWriteFunc final : public JSONWriteFunc {
public:
MOZ_IMPLICIT JSONStringRefWriteFunc(nsACString& aString) : mString(aString) {}
void Write(const Span<const char>& aStr) override { mString.Append(aStr); }
const nsACString& StringCRef() const { return mString; }
private:
nsACString& mString;
};
} // namespace mozilla
#endif // JSONSTRINGWRITEFUNCS_H

View File

@ -122,6 +122,7 @@ EXPORTS.mozilla += [
"HoldDropJSObjects.h",
"IntentionalCrash.h",
"JSObjectHolder.h",
"JSONStringWriteFuncs.h",
"Logging.h",
"MemoryInfo.h",
"MemoryMapping.h",

View File

@ -9,20 +9,12 @@
#include "js/JSON.h"
#include "js/RootingAPI.h"
#include "js/Value.h"
#include "JSONWriter.h"
#include "mozilla/JSONStringWriteFuncs.h"
NS_IMPL_ISUPPORTS(nsMacPreferencesReader, nsIMacPreferencesReader)
using namespace mozilla;
struct StringWriteFunc : public JSONWriteFunc {
nsAString& mString;
explicit StringWriteFunc(nsAString& aStr) : mString(aStr) {}
void Write(const Span<const char>& aStr) override {
mString.Append(NS_ConvertUTF8toUTF16(aStr.data(), aStr.size()));
}
};
static void EvaluateDict(JSONWriter* aWriter, NSDictionary<NSString*, id>* aDict);
static void EvaluateArray(JSONWriter* aWriter, NSArray* aArray) {
@ -71,16 +63,16 @@ nsMacPreferencesReader::PoliciesEnabled(bool* aPoliciesEnabled) {
NS_IMETHODIMP
nsMacPreferencesReader::ReadPreferences(JSContext* aCx, JS::MutableHandle<JS::Value> aResult) {
nsAutoString jsonStr;
JSONWriter w(MakeUnique<StringWriteFunc>(jsonStr));
JSONStringWriteFunc<nsAutoCString> jsonStr;
JSONWriter w(jsonStr);
w.Start();
EvaluateDict(&w, [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);
w.End();
auto json = static_cast<const char16_t*>(jsonStr.get());
NS_ConvertUTF8toUTF16 jsonStr16(jsonStr.StringCRef());
JS::RootedValue val(aCx);
MOZ_ALWAYS_TRUE(JS_ParseJSON(aCx, json, jsonStr.Length(), &val));
MOZ_ALWAYS_TRUE(JS_ParseJSON(aCx, jsonStr16.get(), jsonStr16.Length(), &val));
aResult.set(val);
return NS_OK;