xpcom/tests/TestBase64.cpp

changeset 0
6474c204b198
     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 +}

mercurial