Bug 1659674 - Change BulkWrite to return mozilla::Result. r=froydnj

Differential Revision: https://phabricator.services.mozilla.com/D87419
This commit is contained in:
Simon Giesecke 2020-08-21 09:54:48 +00:00
parent 5a605fed3d
commit f77f8fd84c
13 changed files with 73 additions and 72 deletions

View File

@ -8280,12 +8280,13 @@ class StringBuilder {
if (!mLength.isValid()) {
return false;
}
nsresult rv;
BulkAppender appender(aOut.BulkWrite(mLength.value(), 0, true, rv));
if (NS_FAILED(rv)) {
auto appenderOrErr = aOut.BulkWrite(mLength.value(), 0, true);
if (appenderOrErr.isErr()) {
return false;
}
BulkAppender appender{appenderOrErr.unwrap()};
for (StringBuilder* current = this; current;
current = current->mNext.get()) {
uint32_t len = current->mUnits.Length();

View File

@ -297,13 +297,14 @@ inline bool AssignJSString(JSContext* cx, T& dest, JSString* s) {
// Shouldn't really matter, but worth being safe.
const bool kAllowShrinking = true;
nsresult rv;
auto handle = dest.BulkWrite(bufLen.value(), 0, kAllowShrinking, rv);
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
auto handleOrErr = dest.BulkWrite(bufLen.value(), 0, kAllowShrinking);
if (MOZ_UNLIKELY(handleOrErr.isErr())) {
JS_ReportOutOfMemory(cx);
return false;
}
auto handle = handleOrErr.unwrap();
auto maybe = JS_EncodeStringToUTF8BufferPartial(cx, s, handle.AsSpan());
if (MOZ_UNLIKELY(!maybe)) {
JS_ReportOutOfMemory(cx);

View File

@ -89,15 +89,13 @@ struct FakeString {
return mozilla::Span{BeginWriting(), Length()};
}
mozilla::BulkWriteHandle<CharT> BulkWrite(size_type aCapacity,
size_type aPrefixToPreserve,
bool aAllowShrinking,
nsresult& aRv) {
mozilla::Result<mozilla::BulkWriteHandle<CharT>, nsresult> BulkWrite(
size_type aCapacity, size_type aPrefixToPreserve, bool aAllowShrinking) {
MOZ_ASSERT(!mDataInitialized);
InitData(mStorage, 0);
mDataFlags |= DataFlags::INLINE;
return ToAStringPtr()->BulkWrite(aCapacity, aPrefixToPreserve,
aAllowShrinking, aRv);
aAllowShrinking);
}
// Reserve space to write aLength chars, not including null-terminator.

View File

@ -518,13 +518,13 @@ nsresult XMLHttpRequestMainThread::AppendToResponseText(
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv;
BulkWriteHandle<char16_t> handle =
helper.BulkWrite(destBufferLen.value(), rv);
if (NS_FAILED(rv)) {
return rv;
auto handleOrErr = helper.BulkWrite(destBufferLen.value());
if (handleOrErr.isErr()) {
return handleOrErr.unwrapErr();
}
auto handle = handleOrErr.unwrap();
uint32_t result;
size_t read;
size_t written;

View File

@ -28,9 +28,9 @@ class XMLHttpRequestStringBuffer final {
uint32_t UnsafeLength() const { return mData.Length(); }
mozilla::BulkWriteHandle<char16_t> UnsafeBulkWrite(uint32_t aCapacity,
nsresult& aRv) {
return mData.BulkWrite(aCapacity, UnsafeLength(), false, aRv);
mozilla::Result<mozilla::BulkWriteHandle<char16_t>, nsresult> UnsafeBulkWrite(
uint32_t aCapacity) {
return mData.BulkWrite(aCapacity, UnsafeLength(), false);
}
void Append(const nsAString& aString) {
@ -168,9 +168,9 @@ uint32_t XMLHttpRequestStringWriterHelper::Length() const {
return mBuffer->UnsafeLength();
}
mozilla::BulkWriteHandle<char16_t> XMLHttpRequestStringWriterHelper::BulkWrite(
uint32_t aCapacity, nsresult& aRv) {
return mBuffer->UnsafeBulkWrite(aCapacity, aRv);
mozilla::Result<mozilla::BulkWriteHandle<char16_t>, nsresult>
XMLHttpRequestStringWriterHelper::BulkWrite(uint32_t aCapacity) {
return mBuffer->UnsafeBulkWrite(aCapacity);
}
// ---------------------------------------------------------------------------

View File

@ -67,8 +67,8 @@ class MOZ_STACK_CLASS XMLHttpRequestStringWriterHelper final {
*/
uint32_t Length() const;
mozilla::BulkWriteHandle<char16_t> BulkWrite(uint32_t aCapacity,
nsresult& aRv);
mozilla::Result<mozilla::BulkWriteHandle<char16_t>, nsresult> BulkWrite(
uint32_t aCapacity);
private:
XMLHttpRequestStringWriterHelper(const XMLHttpRequestStringWriterHelper&) =

View File

@ -831,11 +831,11 @@ TransactionObserver::OnDataAvailable(nsIRequest* aRequest,
uint32_t oldLen = mWKResponse.Length();
uint64_t newLen = aCount + oldLen;
if (newLen < MAX_WK) {
nsresult rv;
auto handle = mWKResponse.BulkWrite(newLen, oldLen, false, rv);
if (NS_FAILED(rv)) {
return rv;
auto handleOrErr = mWKResponse.BulkWrite(newLen, oldLen, false);
if (handleOrErr.isErr()) {
return handleOrErr.unwrapErr();
}
auto handle = handleOrErr.unwrap();
uint32_t amtRead;
if (NS_SUCCEEDED(
aStream->Read(handle.Elements() + oldLen, aCount, &amtRead))) {

View File

@ -49,10 +49,12 @@ struct ProfileBufferEntryReader::Deserializer<nsTString<CHAR>> {
static nsTString<CHAR> Read(ProfileBufferEntryReader& aER) {
const Length length = aER.ReadULEB128<Length>();
nsTString<CHAR> s;
nsresult rv;
// BulkWrite is the most efficient way to copy bytes into the target string.
auto writer = s.BulkWrite(length, 0, true, rv);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
auto writerOrErr = s.BulkWrite(length, 0, true);
MOZ_RELEASE_ASSERT(!writerOrErr.isErr());
auto writer = writerOrErr.unwrap();
aER.ReadBytes(writer.Elements(), length * sizeof(CHAR));
writer.Finish(length, true);
return s;
@ -94,10 +96,11 @@ struct ProfileBufferEntryReader::Deserializer<nsTAutoStringN<CHAR, N>> {
static nsTAutoStringN<CHAR, N> Read(ProfileBufferEntryReader& aER) {
const auto length = aER.ReadULEB128<Length>();
nsTAutoStringN<CHAR, N> s;
nsresult rv;
// BulkWrite is the most efficient way to copy bytes into the target string.
auto writer = s.BulkWrite(length, 0, true, rv);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
auto writerOrErr = s.BulkWrite(length, 0, true);
MOZ_RELEASE_ASSERT(!writerOrErr.isErr());
auto writer = writerOrErr.unwrap();
aER.ReadBytes(writer.Elements(), length * sizeof(CHAR));
writer.Finish(length, true);
return s;

View File

@ -391,12 +391,13 @@ static nsresult Base64EncodeHelper(const T* const aBinary,
}
const uint32_t base64Len = base64LenOrErr.inspect();
nsresult rv;
auto handle = aBase64.BulkWrite(base64Len, prefixLen, false, rv);
if (NS_FAILED(rv)) {
return rv;
auto handleOrErr = aBase64.BulkWrite(base64Len, prefixLen, false);
if (handleOrErr.isErr()) {
return handleOrErr.unwrapErr();
}
auto handle = handleOrErr.unwrap();
Encode(aBinary, aBinaryLen, handle.Elements() + prefixLen);
handle.Finish(base64Len, false);
return NS_OK;
@ -587,17 +588,18 @@ static nsresult Base64DecodeString(const T& aBase64, T& aBinary) {
uint32_t binaryLen = ((aBase64.Length() * 3) / 4);
nsresult rv;
auto handle = aBinary.BulkWrite(binaryLen, 0, false, rv);
if (NS_FAILED(rv)) {
auto handleOrErr = aBinary.BulkWrite(binaryLen, 0, false);
if (handleOrErr.isErr()) {
// Must not touch the handle if failing here, but we
// already truncated the string at the top, so it's
// unchanged.
return rv;
return handleOrErr.unwrapErr();
}
rv = Base64DecodeHelper(aBase64.BeginReading(), aBase64.Length(),
handle.Elements(), &binaryLen);
auto handle = handleOrErr.unwrap();
nsresult rv = Base64DecodeHelper(aBase64.BeginReading(), aBase64.Length(),
handle.Elements(), &binaryLen);
if (NS_FAILED(rv)) {
// Retruncate to match old semantics of this method.
handle.Finish(0, true);
@ -715,12 +717,13 @@ nsresult Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary,
}
const uint32_t base64Len = base64LenOrErr.inspect();
nsresult rv;
auto handle = aBase64.BulkWrite(base64Len, 0, false, rv);
if (NS_FAILED(rv)) {
return rv;
auto handleOrErr = aBase64.BulkWrite(base64Len, 0, false);
if (handleOrErr.isErr()) {
return handleOrErr.unwrapErr();
}
auto handle = handleOrErr.unwrap();
char* base64 = handle.Elements();
uint32_t index = 0;

View File

@ -573,7 +573,7 @@ void nsStorageInputStream::SerializeInternal(InputStreamParams& aParams,
*aSizeUsed = 0;
uint64_t remaining = 0;
nsresult rv = Available(&remaining);
DebugOnly<nsresult> rv = Available(&remaining);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (remaining >= aMaxSize) {
@ -589,8 +589,10 @@ void nsStorageInputStream::SerializeInternal(InputStreamParams& aParams,
rv = Tell(&offset);
MOZ_ASSERT(NS_SUCCEEDED(rv));
auto handle = combined.BulkWrite(remaining, 0, false, rv);
MOZ_ASSERT(NS_SUCCEEDED(rv));
auto handleOrErr = combined.BulkWrite(remaining, 0, false);
MOZ_ASSERT(!handleOrErr.isErr());
auto handle = handleOrErr.unwrap();
uint32_t numRead = 0;

View File

@ -9,6 +9,7 @@
#include "mozilla/MathAlgorithms.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Printf.h"
#include "mozilla/ResultExtensions.h"
#include "nsASCIIMask.h"
@ -63,15 +64,13 @@ inline const nsTAutoString<T>* AsAutoString(const nsTSubstring<T>* aStr) {
}
template <typename T>
mozilla::BulkWriteHandle<T> nsTSubstring<T>::BulkWrite(
size_type aCapacity, size_type aPrefixToPreserve, bool aAllowShrinking,
nsresult& aRv) {
mozilla::Result<mozilla::BulkWriteHandle<T>, nsresult>
nsTSubstring<T>::BulkWrite(size_type aCapacity, size_type aPrefixToPreserve,
bool aAllowShrinking) {
auto r = StartBulkWriteImpl(aCapacity, aPrefixToPreserve, aAllowShrinking);
if (MOZ_UNLIKELY(r.isErr())) {
aRv = r.unwrapErr();
return mozilla::BulkWriteHandle<T>(nullptr, 0);
return r.propagateErr();
}
aRv = NS_OK;
return mozilla::BulkWriteHandle<T>(this, r.unwrap());
}

View File

@ -1191,11 +1191,6 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr<T> {
* performed when the string is already mutable and the requested
* capacity is smaller than the current capacity.
*
* aRv takes a reference to an nsresult that will be set to
* NS_OK on success or to NS_ERROR_OUT_OF_MEMORY on failure,
* because mozilla::Result cannot wrap move-only types at
* this time.
*
* If this method returns successfully, you must not access
* the string except through the returned BulkWriteHandle
* until either the BulkWriteHandle goes out of scope or
@ -1211,10 +1206,8 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr<T> {
* content has been written, which results in a
* cache-friendly linear write pattern.
*/
mozilla::BulkWriteHandle<T> NS_FASTCALL BulkWrite(size_type aCapacity,
size_type aPrefixToPreserve,
bool aAllowShrinking,
nsresult& aRv);
mozilla::Result<mozilla::BulkWriteHandle<T>, nsresult> NS_FASTCALL BulkWrite(
size_type aCapacity, size_type aPrefixToPreserve, bool aAllowShrinking);
/**
* THIS IS NOT REALLY A PUBLIC METHOD! DO NOT CALL FROM OUTSIDE

View File

@ -1388,12 +1388,14 @@ TEST_F(Strings, legacy_set_length_semantics) {
#endif
TEST_F(Strings, bulk_write) {
nsresult rv;
nsCString s;
const char* ptrTwoThousand;
{
auto handle = s.BulkWrite(500, 0, true, rv);
EXPECT_EQ(rv, NS_OK);
auto handleOrErr = s.BulkWrite(500, 0, true);
EXPECT_TRUE(handleOrErr.isOk());
auto handle = handleOrErr.unwrap();
auto span = handle.AsSpan();
for (auto&& c : span) {
c = 'a';
@ -1418,11 +1420,10 @@ TEST_F(Strings, bulk_write) {
}
TEST_F(Strings, bulk_write_fail) {
nsresult rv;
nsCString s;
{
auto handle = s.BulkWrite(500, 0, true, rv);
EXPECT_EQ(rv, NS_OK);
auto handleOrErr = s.BulkWrite(500, 0, true);
EXPECT_TRUE(handleOrErr.isOk());
}
EXPECT_EQ(s.Length(), 3U);
EXPECT_TRUE(s.Equals(u8"\uFFFD"));