Bug 1024774 - Part 2: Implement a google::protobuf::ZeroCopyOutputStream wrapper

around nsIOutputStream; r=jimb
This commit is contained in:
Nick Fitzgerald 2015-04-22 11:09:54 -07:00
Родитель 5f8c8f100a
Коммит 26904e13ea
3 изменённых файлов: 174 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,99 @@
/* -*- 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"
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())
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,
"Must back up a positive number 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

Просмотреть файл

@ -0,0 +1,70 @@
/* -*- 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/. */
#ifndef mozilla_devtools_ZeroCopyNSIOutputStream__
#define mozilla_devtools_ZeroCopyNSIOutputStream__
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/common.h>
#include "nsCOMPtr.h"
#include "nsIOutputStream.h"
namespace mozilla {
namespace devtools {
// A `google::protobuf::io::ZeroCopyOutputStream` implementation that uses an
// `nsIOutputStream` under the covers.
//
// This class will automatically write and flush its data to the
// `nsIOutputStream` in its destructor, but if you care whether that call
// succeeds or fails, then you should call the `flush` method yourself. Errors
// will be logged, however.
class MOZ_STACK_CLASS ZeroCopyNSIOutputStream
: public ::google::protobuf::io::ZeroCopyOutputStream
{
static const int BUFFER_SIZE = 8192;
// The nsIOutputStream we are streaming to.
nsCOMPtr<nsIOutputStream> &out;
// The buffer we write data to before passing it to the output stream.
char buffer[BUFFER_SIZE];
// The status of writing to the underlying output stream.
nsresult result_;
// The number of bytes in the buffer that have been used thus far.
int amountUsed;
// Excluding the amount of the buffer currently used (which hasn't been
// written and flushed yet), this is the number of bytes written to the output
// stream.
int64_t writtenCount;
// Write the internal buffer to the output stream and flush it.
nsresult writeBuffer();
public:
explicit ZeroCopyNSIOutputStream(nsCOMPtr<nsIOutputStream> &out);
nsresult flush() { return writeBuffer(); }
// Return true if writing to the underlying output stream ever failed.
bool failed() const { return NS_FAILED(result_); }
nsresult result() const { return result_; }
// ZeroCopyOutputStream Interface
virtual ~ZeroCopyNSIOutputStream() override;
virtual bool Next(void **data, int *size) override;
virtual void BackUp(int count) override;
virtual ::google::protobuf::int64 ByteCount() const override;
};
} // namespace devtools
} // namespace mozilla
#endif // mozilla_devtools_ZeroCopyNSIOutputStream__

Просмотреть файл

@ -14,8 +14,13 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'jsinspector'
EXPORTS.mozilla.devtools += [
'ZeroCopyNSIOutputStream.h',
]
SOURCES += [
'nsJSInspector.cpp',
'ZeroCopyNSIOutputStream.cpp',
]
FINAL_LIBRARY = 'xul'