1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/tests/TestBase64.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,305 @@ 1.4 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "TestHarness.h" 1.10 + 1.11 +#include "mozilla/Attributes.h" 1.12 +#include "nsIScriptableBase64Encoder.h" 1.13 +#include "nsIInputStream.h" 1.14 +#include "nsAutoPtr.h" 1.15 +#include "nsStringAPI.h" 1.16 +#include <wchar.h> 1.17 + 1.18 +struct Chunk { 1.19 + Chunk(uint32_t l, const char* c) 1.20 + : mLength(l), mData(c) 1.21 + {} 1.22 + 1.23 + uint32_t mLength; 1.24 + const char* mData; 1.25 +}; 1.26 + 1.27 +struct Test { 1.28 + Test(Chunk* c, const char* r) 1.29 + : mChunks(c), mResult(r) 1.30 + {} 1.31 + 1.32 + Chunk* mChunks; 1.33 + const char* mResult; 1.34 +}; 1.35 + 1.36 +static Chunk kTest1Chunks[] = 1.37 +{ 1.38 + Chunk(9, "Hello sir"), 1.39 + Chunk(0, nullptr) 1.40 +}; 1.41 + 1.42 +static Chunk kTest2Chunks[] = 1.43 +{ 1.44 + Chunk(3, "Hel"), 1.45 + Chunk(3, "lo "), 1.46 + Chunk(3, "sir"), 1.47 + Chunk(0, nullptr) 1.48 +}; 1.49 + 1.50 +static Chunk kTest3Chunks[] = 1.51 +{ 1.52 + Chunk(1, "I"), 1.53 + Chunk(0, nullptr) 1.54 +}; 1.55 + 1.56 +static Chunk kTest4Chunks[] = 1.57 +{ 1.58 + Chunk(2, "Hi"), 1.59 + Chunk(0, nullptr) 1.60 +}; 1.61 + 1.62 +static Chunk kTest5Chunks[] = 1.63 +{ 1.64 + Chunk(1, "B"), 1.65 + Chunk(2, "ob"), 1.66 + Chunk(0, nullptr) 1.67 +}; 1.68 + 1.69 +static Chunk kTest6Chunks[] = 1.70 +{ 1.71 + Chunk(2, "Bo"), 1.72 + Chunk(1, "b"), 1.73 + Chunk(0, nullptr) 1.74 +}; 1.75 + 1.76 +static Chunk kTest7Chunks[] = 1.77 +{ 1.78 + Chunk(1, "F"), // Carry over 1 1.79 + Chunk(4, "iref"), // Carry over 2 1.80 + Chunk(2, "ox"), // 1 1.81 + Chunk(4, " is "), // 2 1.82 + Chunk(2, "aw"), // 1 1.83 + Chunk(4, "esom"), // 2 1.84 + Chunk(2, "e!"), 1.85 + Chunk(0, nullptr) 1.86 +}; 1.87 + 1.88 +static Chunk kTest8Chunks[] = 1.89 +{ 1.90 + Chunk(5, "ALL T"), 1.91 + Chunk(1, "H"), 1.92 + Chunk(4, "ESE "), 1.93 + Chunk(2, "WO"), 1.94 + Chunk(21, "RLDS ARE YOURS EXCEPT"), 1.95 + Chunk(9, " EUROPA. "), 1.96 + Chunk(25, "ATTEMPT NO LANDING THERE."), 1.97 + Chunk(0, nullptr) 1.98 +}; 1.99 + 1.100 +static Test kTests[] = 1.101 + { 1.102 + // Test 1, test a simple round string in one chunk 1.103 + Test( 1.104 + kTest1Chunks, 1.105 + "SGVsbG8gc2ly" 1.106 + ), 1.107 + // Test 2, test a simple round string split into round chunks 1.108 + Test( 1.109 + kTest2Chunks, 1.110 + "SGVsbG8gc2ly" 1.111 + ), 1.112 + // Test 3, test a single chunk that's 2 short 1.113 + Test( 1.114 + kTest3Chunks, 1.115 + "SQ==" 1.116 + ), 1.117 + // Test 4, test a single chunk that's 1 short 1.118 + Test( 1.119 + kTest4Chunks, 1.120 + "SGk=" 1.121 + ), 1.122 + // Test 5, test a single chunk that's 2 short, followed by a chunk of 2 1.123 + Test( 1.124 + kTest5Chunks, 1.125 + "Qm9i" 1.126 + ), 1.127 + // Test 6, test a single chunk that's 1 short, followed by a chunk of 1 1.128 + Test( 1.129 + kTest6Chunks, 1.130 + "Qm9i" 1.131 + ), 1.132 + // Test 7, test alternating carryovers 1.133 + Test( 1.134 + kTest7Chunks, 1.135 + "RmlyZWZveCBpcyBhd2Vzb21lIQ==" 1.136 + ), 1.137 + // Test 8, test a longish string 1.138 + Test( 1.139 + kTest8Chunks, 1.140 + "QUxMIFRIRVNFIFdPUkxEUyBBUkUgWU9VUlMgRVhDRVBUIEVVUk9QQS4gQVRURU1QVCBOTyBMQU5ESU5HIFRIRVJFLg==" 1.141 + ), 1.142 + // Terminator 1.143 + Test( 1.144 + nullptr, 1.145 + nullptr 1.146 + ) 1.147 + }; 1.148 + 1.149 +class FakeInputStream MOZ_FINAL : public nsIInputStream 1.150 +{ 1.151 +public: 1.152 + 1.153 + FakeInputStream() 1.154 + : mTestNumber(0), 1.155 + mTest(&kTests[0]), 1.156 + mChunk(&mTest->mChunks[0]), 1.157 + mClosed(false) 1.158 + {} 1.159 + 1.160 + NS_DECL_ISUPPORTS 1.161 + NS_DECL_NSIINPUTSTREAM 1.162 + 1.163 + void Reset(); 1.164 + bool NextTest(); 1.165 + bool CheckTest(nsACString& aResult); 1.166 + bool CheckTest(nsAString& aResult); 1.167 +private: 1.168 + uint32_t mTestNumber; 1.169 + const Test* mTest; 1.170 + const Chunk* mChunk; 1.171 + bool mClosed; 1.172 +}; 1.173 + 1.174 +NS_IMPL_ISUPPORTS(FakeInputStream, nsIInputStream) 1.175 + 1.176 +NS_IMETHODIMP 1.177 +FakeInputStream::Close() 1.178 +{ 1.179 + mClosed = true; 1.180 + return NS_OK; 1.181 +} 1.182 + 1.183 +NS_IMETHODIMP 1.184 +FakeInputStream::Available(uint64_t* aAvailable) 1.185 +{ 1.186 + *aAvailable = 0; 1.187 + 1.188 + if (mClosed) 1.189 + return NS_BASE_STREAM_CLOSED; 1.190 + 1.191 + const Chunk* chunk = mChunk; 1.192 + while (chunk->mLength) { 1.193 + *aAvailable += chunk->mLength; 1.194 + chunk++; 1.195 + } 1.196 + 1.197 + return NS_OK; 1.198 +} 1.199 + 1.200 +NS_IMETHODIMP 1.201 +FakeInputStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aOut) 1.202 +{ 1.203 + return NS_ERROR_NOT_IMPLEMENTED; 1.204 +} 1.205 + 1.206 +NS_IMETHODIMP 1.207 +FakeInputStream::ReadSegments(nsWriteSegmentFun aWriter, 1.208 + void* aClosure, 1.209 + uint32_t aCount, 1.210 + uint32_t* aRead) 1.211 +{ 1.212 + *aRead = 0; 1.213 + 1.214 + if (mClosed) 1.215 + return NS_BASE_STREAM_CLOSED; 1.216 + 1.217 + while (mChunk->mLength) { 1.218 + uint32_t written = 0; 1.219 + 1.220 + nsresult rv = (*aWriter)(this, aClosure, mChunk->mData, 1.221 + *aRead, mChunk->mLength, &written); 1.222 + 1.223 + *aRead += written; 1.224 + NS_ENSURE_SUCCESS(rv, rv); 1.225 + 1.226 + mChunk++; 1.227 + } 1.228 + 1.229 + return NS_OK; 1.230 +} 1.231 + 1.232 +NS_IMETHODIMP 1.233 +FakeInputStream::IsNonBlocking(bool* aIsBlocking) 1.234 +{ 1.235 + *aIsBlocking = false; 1.236 + return NS_OK; 1.237 +} 1.238 + 1.239 +void 1.240 +FakeInputStream::Reset() 1.241 +{ 1.242 + mClosed = false; 1.243 + mChunk = &mTest->mChunks[0]; 1.244 +} 1.245 + 1.246 +bool 1.247 +FakeInputStream::NextTest() 1.248 +{ 1.249 + mTestNumber++; 1.250 + mTest = &kTests[mTestNumber]; 1.251 + mChunk = &mTest->mChunks[0]; 1.252 + mClosed = false; 1.253 + 1.254 + return mTest->mChunks ? true : false; 1.255 +} 1.256 + 1.257 +bool 1.258 +FakeInputStream::CheckTest(nsACString& aResult) 1.259 +{ 1.260 + return !strcmp(aResult.BeginReading(), mTest->mResult) ? true : false; 1.261 +} 1.262 + 1.263 +#ifdef XP_WIN 1.264 +static inline int NS_tstrcmp(char16ptr_t x, char16ptr_t y) { 1.265 + return wcscmp(x, y); 1.266 +} 1.267 +#else 1.268 +#define NS_tstrcmp strcmp 1.269 +#endif 1.270 + 1.271 +bool 1.272 +FakeInputStream::CheckTest(nsAString& aResult) 1.273 +{ 1.274 + return !NS_tstrcmp(aResult.BeginReading(), 1.275 + NS_ConvertASCIItoUTF16(mTest->mResult).BeginReading()) 1.276 + ? true : false; 1.277 +} 1.278 + 1.279 +int main(int argc, char** argv) 1.280 +{ 1.281 + ScopedXPCOM xpcom("Base64"); 1.282 + NS_ENSURE_FALSE(xpcom.failed(), 1); 1.283 + 1.284 + nsCOMPtr<nsIScriptableBase64Encoder> encoder = 1.285 + do_CreateInstance("@mozilla.org/scriptablebase64encoder;1"); 1.286 + NS_ENSURE_TRUE(encoder, 1); 1.287 + 1.288 + nsRefPtr<FakeInputStream> stream = new FakeInputStream(); 1.289 + do { 1.290 + nsString wideString; 1.291 + nsCString string; 1.292 + 1.293 + nsresult rv; 1.294 + rv = encoder->EncodeToString(stream, 0, wideString); 1.295 + NS_ENSURE_SUCCESS(rv, 1); 1.296 + 1.297 + stream->Reset(); 1.298 + 1.299 + rv = encoder->EncodeToCString(stream, 0, string); 1.300 + NS_ENSURE_SUCCESS(rv, 1); 1.301 + 1.302 + if (!stream->CheckTest(wideString) || !stream->CheckTest(string)) 1.303 + fail("Failed to convert properly\n"); 1.304 + 1.305 + } while (stream->NextTest()); 1.306 + 1.307 + return 0; 1.308 +}