1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "gtest/gtest.h"
7 #include "mozilla/Base64.h"
8 #include "mozilla/gtest/MozAssertions.h"
10 #include "nsIInputStream.h"
11 #include "nsStringStream.h"
16 // An input stream whose ReadSegments method calls aWriter with writes of size
17 // aStep from the provided aInput in order to test edge-cases related to small
19 class TestStream final
: public nsIInputStream
{
23 TestStream(const nsACString
& aInput
, uint32_t aStep
)
24 : mInput(aInput
), mStep(aStep
) {}
26 NS_IMETHOD
Close() override
{ MOZ_CRASH("This should not be called"); }
28 NS_IMETHOD
Available(uint64_t* aLength
) override
{
29 *aLength
= mInput
.Length() - mPos
;
33 NS_IMETHOD
StreamStatus() override
{ return NS_OK
; }
35 NS_IMETHOD
Read(char* aBuffer
, uint32_t aCount
,
36 uint32_t* aReadCount
) override
{
37 MOZ_CRASH("This should not be called");
40 NS_IMETHOD
ReadSegments(nsWriteSegmentFun aWriter
, void* aClosure
,
41 uint32_t aCount
, uint32_t* aResult
) override
{
44 if (mPos
== mInput
.Length()) {
49 uint32_t amt
= std::min(mStep
, (uint32_t)(mInput
.Length() - mPos
));
53 aWriter(this, aClosure
, mInput
.get() + mPos
, *aResult
, amt
, &read
);
54 if (NS_WARN_IF(NS_FAILED(rv
))) {
66 NS_IMETHOD
IsNonBlocking(bool* aNonBlocking
) override
{
72 ~TestStream() = default;
79 NS_IMPL_ISUPPORTS(TestStream
, nsIInputStream
)
81 // Test the base64 encoder with writer buffer sizes between 1 byte and the
82 // entire length of "Hello World!" in order to exercise various edge cases.
83 TEST(TestBase64Stream
, Run
)
86 input
.AssignLiteral("Hello World!");
88 for (uint32_t step
= 1; step
<= input
.Length(); ++step
) {
89 RefPtr
<TestStream
> ts
= new TestStream(input
, step
);
91 nsAutoString encodedData
;
92 nsresult rv
= Base64EncodeInputStream(ts
, encodedData
, input
.Length());
93 ASSERT_NS_SUCCEEDED(rv
);
95 EXPECT_TRUE(encodedData
.EqualsLiteral("SGVsbG8gV29ybGQh"));
99 TEST(TestBase64Stream
, VaryingCount
)
102 input
.AssignLiteral("Hello World!");
104 std::pair
<size_t, nsCString
> tests
[] = {
105 {0, "SGVsbG8gV29ybGQh"_ns
}, {1, "SA=="_ns
},
106 {5, "SGVsbG8="_ns
}, {11, "SGVsbG8gV29ybGQ="_ns
},
107 {12, "SGVsbG8gV29ybGQh"_ns
}, {13, "SGVsbG8gV29ybGQh"_ns
},
110 for (auto& [count
, expected
] : tests
) {
111 nsCOMPtr
<nsIInputStream
> is
;
112 nsresult rv
= NS_NewCStringInputStream(getter_AddRefs(is
), input
);
113 ASSERT_NS_SUCCEEDED(rv
);
115 nsAutoCString encodedData
;
116 rv
= Base64EncodeInputStream(is
, encodedData
, count
);
117 ASSERT_NS_SUCCEEDED(rv
);
118 EXPECT_EQ(encodedData
, expected
) << "count: " << count
;
123 } // namespace mozilla