fune/dom/webbrowserpersist/WebBrowserPersistSerializeChild.cpp
Nika Layzell e61507c3a3 Bug 1818305 - Part 1: Add a streamStatus method to nsIOutputStream, r=necko-reviewers,geckoview-reviewers,jesup,emilio,m_kato,devtools-reviewers
This new method can be used to check if the nsIOutputStream has been
closed without having data available to write. It should avoid blocking
to discover this information.

Differential Revision: https://phabricator.services.mozilla.com/D170696
2023-03-15 19:52:33 +00:00

136 lines
4.4 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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/. */
#include "WebBrowserPersistSerializeChild.h"
#include <algorithm>
#include "nsThreadUtils.h"
namespace mozilla {
NS_IMPL_ISUPPORTS(WebBrowserPersistSerializeChild,
nsIWebBrowserPersistWriteCompletion,
nsIWebBrowserPersistURIMap, nsIOutputStream)
WebBrowserPersistSerializeChild::WebBrowserPersistSerializeChild(
const WebBrowserPersistURIMap& aMap)
: mMap(aMap) {}
WebBrowserPersistSerializeChild::~WebBrowserPersistSerializeChild() = default;
NS_IMETHODIMP
WebBrowserPersistSerializeChild::OnFinish(
nsIWebBrowserPersistDocument* aDocument, nsIOutputStream* aStream,
const nsACString& aContentType, nsresult aStatus) {
MOZ_ASSERT(aStream == this);
nsCString contentType(aContentType);
Send__delete__(this, contentType, aStatus);
return NS_OK;
}
NS_IMETHODIMP
WebBrowserPersistSerializeChild::GetNumMappedURIs(uint32_t* aNum) {
*aNum = static_cast<uint32_t>(mMap.mapURIs().Length());
return NS_OK;
}
NS_IMETHODIMP
WebBrowserPersistSerializeChild::GetURIMapping(uint32_t aIndex,
nsACString& aMapFrom,
nsACString& aMapTo) {
if (aIndex >= mMap.mapURIs().Length()) {
return NS_ERROR_INVALID_ARG;
}
aMapFrom = mMap.mapURIs()[aIndex].mapFrom();
aMapTo = mMap.mapURIs()[aIndex].mapTo();
return NS_OK;
}
NS_IMETHODIMP
WebBrowserPersistSerializeChild::GetTargetBaseURI(nsACString& aURI) {
aURI = mMap.targetBaseURI();
return NS_OK;
}
NS_IMETHODIMP
WebBrowserPersistSerializeChild::Close() {
NS_WARNING("WebBrowserPersistSerializeChild::Close()");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
WebBrowserPersistSerializeChild::Flush() {
NS_WARNING("WebBrowserPersistSerializeChild::Flush()");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
WebBrowserPersistSerializeChild::StreamStatus() {
// XXX: This stream doesn't appear to have a closed state.
return NS_OK;
}
NS_IMETHODIMP
WebBrowserPersistSerializeChild::Write(const char* aBuf, uint32_t aCount,
uint32_t* aWritten) {
// Normally an nsIOutputStream would have to be thread-safe, but
// nsDocumentEncoder currently doesn't call this off the main
// thread (which also means it's difficult to test the
// thread-safety code this class doesn't yet have).
//
// This is *not* an NS_ERROR_NOT_IMPLEMENTED, because at this
// point we've probably already misused the non-thread-safe
// refcounting.
MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Fix this class to be thread-safe.");
// Limit the message size to 64k because large messages are
// potentially bad for the latency of other messages on the same channel.
static const uint32_t kMaxWrite = 65536;
// Work around bug 1181433 by sending multiple messages if
// necessary to write the entire aCount bytes, even though
// nsIOutputStream.idl says we're allowed to do a short write.
const char* buf = aBuf;
uint32_t count = aCount;
*aWritten = 0;
while (count > 0) {
uint32_t toWrite = std::min(kMaxWrite, count);
nsTArray<uint8_t> arrayBuf;
// It would be nice if this extra copy could be avoided.
arrayBuf.AppendElements(buf, toWrite);
SendWriteData(std::move(arrayBuf));
*aWritten += toWrite;
buf += toWrite;
count -= toWrite;
}
return NS_OK;
}
NS_IMETHODIMP
WebBrowserPersistSerializeChild::WriteFrom(nsIInputStream* aFrom,
uint32_t aCount,
uint32_t* aWritten) {
NS_WARNING("WebBrowserPersistSerializeChild::WriteFrom()");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
WebBrowserPersistSerializeChild::WriteSegments(nsReadSegmentFun aFun,
void* aCtx, uint32_t aCount,
uint32_t* aWritten) {
NS_WARNING("WebBrowserPersistSerializeChild::WriteSegments()");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
WebBrowserPersistSerializeChild::IsNonBlocking(bool* aNonBlocking) {
// Writes will never fail with NS_BASE_STREAM_WOULD_BLOCK, so:
*aNonBlocking = false;
return NS_OK;
}
} // namespace mozilla