summaryrefslogtreecommitdiffstats
path: root/devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp')
-rw-r--r--devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp100
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 000000000..0c29db7f9
--- /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