no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / xpcom / io / FixedBufferOutputStream.cpp
blob1c841bb91f0892f2a01301944723af3a4a79018c
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "FixedBufferOutputStream.h"
9 #include "mozilla/RefPtr.h"
10 #include "mozilla/StreamBufferSinkImpl.h"
11 #include "nsStreamUtils.h"
12 #include "nsString.h"
14 namespace mozilla {
16 FixedBufferOutputStream::FixedBufferOutputStream(
17 UniquePtr<StreamBufferSink>&& aSink)
18 : mSink(std::move(aSink)),
19 mMutex("FixedBufferOutputStream::mMutex"),
20 mOffset(0),
21 mWriting(false),
22 mClosed(false) {}
24 // static
25 RefPtr<FixedBufferOutputStream> FixedBufferOutputStream::Create(
26 size_t aLength) {
27 MOZ_ASSERT(aLength);
29 return MakeRefPtr<FixedBufferOutputStream>(MakeUnique<BufferSink>(aLength));
32 // static
33 RefPtr<FixedBufferOutputStream> FixedBufferOutputStream::Create(
34 size_t aLength, const mozilla::fallible_t&) {
35 MOZ_ASSERT(aLength);
37 auto sink = BufferSink::Alloc(aLength);
39 if (NS_WARN_IF(!sink)) {
40 return nullptr;
43 return MakeRefPtr<FixedBufferOutputStream>(std::move(sink));
46 // static
47 RefPtr<FixedBufferOutputStream> FixedBufferOutputStream::Create(
48 mozilla::Span<char> aBuffer) {
49 return MakeRefPtr<FixedBufferOutputStream>(
50 MakeUnique<nsBorrowedSink>(aBuffer));
53 // static
54 RefPtr<FixedBufferOutputStream> FixedBufferOutputStream::Create(
55 UniquePtr<StreamBufferSink>&& aSink) {
56 return MakeRefPtr<FixedBufferOutputStream>(std::move(aSink));
59 nsDependentCSubstring FixedBufferOutputStream::WrittenData() {
60 MutexAutoLock autoLock(mMutex);
62 return mSink->Slice(mOffset);
65 NS_IMPL_ISUPPORTS(FixedBufferOutputStream, nsIOutputStream)
67 NS_IMETHODIMP
68 FixedBufferOutputStream::Close() {
69 MutexAutoLock autoLock(mMutex);
71 if (mWriting) {
72 return NS_ERROR_NOT_AVAILABLE;
75 mClosed = true;
77 return NS_OK;
80 NS_IMETHODIMP
81 FixedBufferOutputStream::Flush() { return NS_OK; }
83 NS_IMETHODIMP
84 FixedBufferOutputStream::StreamStatus() {
85 MutexAutoLock autoLock(mMutex);
86 return mClosed ? NS_BASE_STREAM_CLOSED : NS_OK;
89 NS_IMETHODIMP
90 FixedBufferOutputStream::Write(const char* aBuf, uint32_t aCount,
91 uint32_t* _retval) {
92 return WriteSegments(NS_CopyBufferToSegment, const_cast<char*>(aBuf), aCount,
93 _retval);
96 NS_IMETHODIMP
97 FixedBufferOutputStream::WriteFrom(nsIInputStream* aFromStream, uint32_t aCount,
98 uint32_t* _retval) {
99 return WriteSegments(NS_CopyStreamToSegment, aFromStream, aCount, _retval);
102 NS_IMETHODIMP
103 FixedBufferOutputStream::WriteSegments(nsReadSegmentFun aReader, void* aClosure,
104 uint32_t aCount, uint32_t* _retval) {
105 MOZ_ASSERT(_retval);
107 MutexAutoLock autoLock(mMutex);
109 if (mWriting) {
110 return NS_ERROR_NOT_AVAILABLE;
113 if (mClosed) {
114 return NS_BASE_STREAM_CLOSED;
117 size_t length = mSink->Data().Length();
118 size_t offset = mOffset;
120 MOZ_ASSERT(length >= offset, "Bad stream state!");
122 size_t maxCount = length - offset;
123 if (maxCount == 0) {
124 *_retval = 0;
125 return NS_OK;
128 if (aCount > maxCount) {
129 aCount = maxCount;
132 mWriting = true;
134 nsresult rv;
137 MutexAutoUnlock autoUnlock(mMutex);
139 rv = aReader(this, aClosure, mSink->Data().Elements() + offset, 0, aCount,
140 _retval);
143 mWriting = false;
145 if (NS_SUCCEEDED(rv)) {
146 MOZ_ASSERT(*_retval <= aCount,
147 "Reader should not read more than we asked it to read!");
148 mOffset += *_retval;
151 // As defined in nsIOutputStream.idl, do not pass reader func errors.
152 return NS_OK;
155 NS_IMETHODIMP
156 FixedBufferOutputStream::IsNonBlocking(bool* _retval) {
157 *_retval = true;
158 return NS_OK;
161 } // namespace mozilla