diff options
Diffstat (limited to 'devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp')
-rw-r--r-- | devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp b/devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp new file mode 100644 index 0000000000..0c29db7f90 --- /dev/null +++ b/devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 2; 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 "mozilla/devtools/ZeroCopyNSIOutputStream.h" + +#include "mozilla/DebugOnly.h" +#include "mozilla/Unused.h" + +namespace mozilla { +namespace devtools { + +ZeroCopyNSIOutputStream::ZeroCopyNSIOutputStream(nsCOMPtr<nsIOutputStream>& out) + : out(out) + , result_(NS_OK) + , amountUsed(0) + , writtenCount(0) +{ + DebugOnly<bool> nonBlocking = false; + MOZ_ASSERT(out->IsNonBlocking(&nonBlocking) == NS_OK); + MOZ_ASSERT(!nonBlocking); +} + +ZeroCopyNSIOutputStream::~ZeroCopyNSIOutputStream() +{ + if (!failed()) + Unused << NS_WARN_IF(NS_FAILED(writeBuffer())); +} + +nsresult +ZeroCopyNSIOutputStream::writeBuffer() +{ + if (failed()) + return result_; + + if (amountUsed == 0) + return NS_OK; + + int32_t amountWritten = 0; + while (amountWritten < amountUsed) { + uint32_t justWritten = 0; + + result_ = out->Write(buffer + amountWritten, + amountUsed - amountWritten, + &justWritten); + if (NS_WARN_IF(NS_FAILED(result_))) + return result_; + + amountWritten += justWritten; + } + + writtenCount += amountUsed; + amountUsed = 0; + return NS_OK; +} + +// ZeroCopyOutputStream Interface + +bool +ZeroCopyNSIOutputStream::Next(void** data, int* size) +{ + MOZ_ASSERT(data != nullptr); + MOZ_ASSERT(size != nullptr); + + if (failed()) + return false; + + if (amountUsed == BUFFER_SIZE) { + if (NS_FAILED(writeBuffer())) + return false; + } + + *data = buffer + amountUsed; + *size = BUFFER_SIZE - amountUsed; + amountUsed = BUFFER_SIZE; + return true; +} + +void +ZeroCopyNSIOutputStream::BackUp(int count) +{ + MOZ_ASSERT(count >= 0, + "Cannot back up a negative amount of bytes."); + MOZ_ASSERT(amountUsed == BUFFER_SIZE, + "Can only call BackUp directly after calling Next."); + MOZ_ASSERT(count <= amountUsed, + "Can't back up further than we've given out."); + + amountUsed -= count; +} + +::google::protobuf::int64 +ZeroCopyNSIOutputStream::ByteCount() const +{ + return writtenCount + amountUsed; +} + +} // namespace devtools +} // namespace mozilla |