/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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 __Helpers_h #define __Helpers_h #include "nsCOMPtr.h" #include "nsIAsyncInputStream.h" #include "nsIAsyncOutputStream.h" #include "nsIInputStreamLength.h" #include "nsString.h" #include "nsStringStream.h" #include "nsTArrayForwardDeclare.h" #include "nsThreadUtils.h" #include class nsIInputStream; class nsIOutputStream; namespace testing { void CreateData(uint32_t aNumBytes, nsTArray& aDataOut); void Write(nsIOutputStream* aStream, const nsTArray& aData, uint32_t aOffset, uint32_t aNumBytes); void WriteAllAndClose(nsIOutputStream* aStream, const nsTArray& aData); void ConsumeAndValidateStream(nsIInputStream* aStream, const nsTArray& aExpectedData); void ConsumeAndValidateStream(nsIInputStream* aStream, const nsACString& aExpectedData); class OutputStreamCallback final : public nsIOutputStreamCallback { public: OutputStreamCallback(); bool Called() const { return mCalled; } private: ~OutputStreamCallback(); bool mCalled; public: NS_DECL_ISUPPORTS NS_DECL_NSIOUTPUTSTREAMCALLBACK }; class InputStreamCallback final : public nsIInputStreamCallback { public: InputStreamCallback(); bool Called() const { return mCalled; } private: ~InputStreamCallback(); bool mCalled; public: NS_DECL_ISUPPORTS NS_DECL_NSIINPUTSTREAMCALLBACK }; class AsyncStringStream final : public nsIAsyncInputStream { nsCOMPtr mStream; public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIINPUTSTREAM NS_DECL_NSIASYNCINPUTSTREAM explicit AsyncStringStream(const nsACString& aBuffer); private: ~AsyncStringStream() = default; void MaybeExecCallback(nsIInputStreamCallback* aCallback, nsIEventTarget* aEventTarget); nsCOMPtr mCallback; nsCOMPtr mCallbackEventTarget; }; // This class implements a simple nsIInputStreamLength stream. class LengthInputStream : public nsIInputStream, public nsIInputStreamLength, public nsIAsyncInputStreamLength { nsCOMPtr mStream; bool mIsInputStreamLength; bool mIsAsyncInputStreamLength; nsresult mLengthRv; bool mNegativeValue; public: NS_DECL_THREADSAFE_ISUPPORTS LengthInputStream(const nsACString& aBuffer, bool aIsInputStreamLength, bool aIsAsyncInputStreamLength, nsresult aLengthRv = NS_OK, bool aNegativeValue = false) : mIsInputStreamLength(aIsInputStreamLength), mIsAsyncInputStreamLength(aIsAsyncInputStreamLength), mLengthRv(aLengthRv), mNegativeValue(aNegativeValue) { NS_NewCStringInputStream(getter_AddRefs(mStream), aBuffer); } NS_IMETHOD Available(uint64_t* aLength) override { return mStream->Available(aLength); } NS_IMETHOD StreamStatus() override { return mStream->StreamStatus(); } NS_IMETHOD Read(char* aBuffer, uint32_t aCount, uint32_t* aReadCount) override { return mStream->Read(aBuffer, aCount, aReadCount); } NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount, uint32_t* aResult) override { return mStream->ReadSegments(aWriter, aClosure, aCount, aResult); } NS_IMETHOD Close() override { return mStream->Close(); } NS_IMETHOD IsNonBlocking(bool* aNonBlocking) override { return mStream->IsNonBlocking(aNonBlocking); } NS_IMETHOD Length(int64_t* aLength) override { if (mNegativeValue) { *aLength = -1; } else { mStream->Available((uint64_t*)aLength); } return mLengthRv; } NS_IMETHOD AsyncLengthWait(nsIInputStreamLengthCallback* aCallback, nsIEventTarget* aEventTarget) override { RefPtr self = this; nsCOMPtr callback = aCallback; nsCOMPtr r = NS_NewRunnableFunction("AsyncLengthWait", [self, callback]() { int64_t length; self->Length(&length); callback->OnInputStreamLengthReady(self, length); }); return aEventTarget->Dispatch(r.forget(), NS_DISPATCH_NORMAL); } protected: virtual ~LengthInputStream() = default; }; class LengthCallback final : public nsIInputStreamLengthCallback { bool mCalled; int64_t mSize; public: NS_DECL_THREADSAFE_ISUPPORTS LengthCallback() : mCalled(false), mSize(0) {} NS_IMETHOD OnInputStreamLengthReady(nsIAsyncInputStreamLength* aStream, int64_t aLength) override { mCalled = true; mSize = aLength; return NS_OK; } bool Called() const { return mCalled; } int64_t Size() const { return mSize; } private: ~LengthCallback() = default; }; } // namespace testing #endif // __Helpers_h