Просмотр исходного кода

Rewritten base64::decode and base64::encode

Tatsuhiro Tsujikawa 14 лет назад
Родитель
Сommit
d45d854926
11 измененных файлов с 216 добавлено и 391 удалено
  1. 10 10
      src/HttpRequest.cc
  2. 1 1
      src/HttpResponse.cc
  3. 1 2
      src/HttpServer.cc
  4. 1 1
      src/Makefile.am
  5. 6 2
      src/RpcMethodImpl.cc
  6. 2 1
      src/XmlRpcRequestParserStateImpl.cc
  7. 0 208
      src/base64.cc
  8. 132 48
      src/base64.h
  9. 2 2
      src/json.cc
  10. 57 114
      test/Base64Test.cc
  11. 4 2
      test/JsonTest.cc

+ 10 - 10
src/HttpRequest.cc

@@ -219,10 +219,10 @@ std::string HttpRequest::createRequest()
     builtinHds.push_back(getProxyAuthString());
   }
   if(authConfig_) {
-    builtinHds.push_back
-      (std::make_pair("Authorization:",
-                      strconcat("Basic ",
-                                Base64::encode(authConfig_->getAuthText()))));
+    std::string authText = authConfig_->getAuthText();
+    std::string val = "Basic ";
+    val += base64::encode(authText.begin(), authText.end());
+    builtinHds.push_back(std::make_pair("Authorization:", val));
   }
   if(getPreviousURI().size()) {
     builtinHds.push_back(std::make_pair("Referer:", getPreviousURI()));
@@ -298,12 +298,12 @@ std::string HttpRequest::createProxyRequest() const
 
 std::pair<std::string, std::string> HttpRequest::getProxyAuthString() const
 {
-  return std::make_pair
-    ("Proxy-Authorization:",
-     strconcat("Basic ",
-               Base64::encode(strconcat(proxyRequest_->getUsername(),
-                                        ":",
-                                        proxyRequest_->getPassword()))));
+  std::string authText = proxyRequest_->getUsername();
+  authText += ':';
+  authText += proxyRequest_->getPassword();
+  std::string val = "Basic ";
+  val += base64::encode(authText.begin(), authText.end());
+  return std::make_pair("Proxy-Authorization:", val);
 }
 
 void HttpRequest::enableContentEncoding()

+ 1 - 1
src/HttpResponse.cc

@@ -416,7 +416,7 @@ void HttpResponse::getDigest(std::vector<Checksum>& result) const
         break;
       }
       util::lowercase(hashType);
-      digest = Base64::decode(digest);
+      digest = base64::decode(digest.begin(), digest.end());
       if(!MessageDigest::supports(hashType) ||
          MessageDigest::getDigestLength(hashType) != digest.size()) {
         continue;

+ 1 - 2
src/HttpServer.cc

@@ -225,8 +225,7 @@ bool HttpServer::authenticate()
                   A2_AUTHMETHOD, vend(A2_AUTHMETHOD)-1)) {
     return false;
   }
-  std::string userpass = Base64::decode(std::string(p.second.first,
-                                                    p.second.second));
+  std::string userpass = base64::decode(p.second.first, p.second.second);
   std::pair<Sip, Sip> up;
   util::divide(up, userpass.begin(), userpass.end(), ':');
   return util::streq(up.first.first, up.first.second,

+ 1 - 1
src/Makefile.am

@@ -48,7 +48,7 @@ SRCS =  Socket.h\
 	DefaultDiskWriterFactory.cc DefaultDiskWriterFactory.h\
 	File.cc File.h\
 	Option.cc Option.h\
-	base64.cc base64.h\
+	base64.h\
 	base32.cc base32.h\
 	LogFactory.cc LogFactory.h\
 	TimerA2.cc TimerA2.h\

+ 6 - 2
src/RpcMethodImpl.cc

@@ -271,7 +271,9 @@ SharedHandle<ValueBase> AddTorrentRpcMethod::process
 
   SharedHandle<String> tempTorrentParam;
   if(req.jsonRpc) {
-    tempTorrentParam = String::g(Base64::decode(torrentParam->s()));
+    tempTorrentParam = String::g
+      (base64::decode(torrentParam->s().begin(),
+                      torrentParam->s().end()));
     torrentParam = tempTorrentParam.get();
   }
   std::vector<std::string> uris;
@@ -317,7 +319,9 @@ SharedHandle<ValueBase> AddMetalinkRpcMethod::process
 
   SharedHandle<String> tempMetalinkParam;
   if(req.jsonRpc) {
-    tempMetalinkParam = String::g(Base64::decode(metalinkParam->s()));
+    tempMetalinkParam = String::g
+      (base64::decode(metalinkParam->s().begin(),
+                      metalinkParam->s().end()));
     metalinkParam = tempMetalinkParam.get();
   }
   SharedHandle<Option> requestOption(new Option(*e->getOption()));

+ 2 - 1
src/XmlRpcRequestParserStateImpl.cc

@@ -238,7 +238,8 @@ void Base64XmlRpcRequestParserState::endElement
  const std::string& name,
  const std::string& characters)
 {
-  stm->setCurrentFrameValue(String::g(Base64::decode(characters)));
+  stm->setCurrentFrameValue
+    (String::g(base64::decode(characters.begin(), characters.end())));
 }
 
 // StructXmlRpcRequestParserState

+ 0 - 208
src/base64.cc

@@ -1,208 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#include "base64.h"
-
-namespace aria2 {
-
-namespace {
-const char CHAR_TABLE[] = {
-  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
-  'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
-  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
-  'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
-  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
-  'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
-  'w', 'x', 'y', 'z', '0', '1', '2', '3',
-  '4', '5', '6', '7', '8', '9', '+', '/',
-};
-} // namespace
-
-namespace {
-const int INDEX_TABLE[] = {
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 
-  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, 
-  -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 
-  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, 
-  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 
-  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-} // namespace
-
-void Base64::encode(unsigned char*& result, size_t& rlength,
-                    const unsigned char* src, size_t slength)
-{
-  if(slength == 0) {
-    rlength = 0;
-    return;
-  }
-  size_t trituple = (slength+2)/3;
-  int r = slength%3;
-  rlength = trituple*4;
-  result = new unsigned char[rlength];
-
-  unsigned char* p = result;
-  const unsigned char* s = src;
-  const unsigned char* smax = s+slength-r;
-  while(s != smax) {
-    int n = *s++ << 16;
-    n += *s++ << 8;
-    n += *s++;
-    *p++ = CHAR_TABLE[n >> 18];
-    *p++ = CHAR_TABLE[n >> 12&0x3fu];
-    *p++ = CHAR_TABLE[n >> 6&0x3fu];
-    *p++ = CHAR_TABLE[n&0x3fu];
-  }
-  if(r == 2) {
-    int n = *s++ << 16;
-    n += *s++ << 8;
-    *p++ = CHAR_TABLE[n >> 18];
-    *p++ = CHAR_TABLE[n >> 12&0x3fu];
-    *p++ = CHAR_TABLE[n >> 6&0x3fu];
-    *p++ = '=';
-  } else if(r == 1) {
-    int n = *s++ << 16;
-    *p++ = CHAR_TABLE[n >> 18];
-    *p++ = CHAR_TABLE[n >> 12&0x3fu];
-    *p++ = '=';
-    *p++ = '=';
-  }
-}
-
-void Base64::removeNonBase64Chars(unsigned char*& nsrc,
-                                  size_t& nlength,
-                                  const unsigned char* src,
-                                  size_t slength)
-{
-  unsigned char* temp = new unsigned char[slength];
-  const unsigned char* end = src+slength;
-  size_t n = 0;
-  for(const unsigned char*s = src; s != end; ++s) {
-    if(INDEX_TABLE[*s] != -1 || *s == '=') {
-      *(temp+n++) = *s;
-    }
-  }
-  nlength = n;
-  nsrc = temp;
-}
-
-void Base64::decode(unsigned char*& result, size_t& rlength,
-                    const unsigned char* src, size_t slength)
-{
-  if(slength == 0) {
-    rlength = 0;
-    return;
-  }
-  unsigned char* nsrc;
-  size_t nlength;
-  removeNonBase64Chars(nsrc, nlength, src, slength);
-
-  if(nlength%4 != 0) {
-    delete [] nsrc;
-    rlength = 0;
-    return;
-  }
-
-  size_t quadtuple = nlength/4;
-  size_t len;
-  if(nsrc[nlength-1] == '=') {
-    if(nsrc[nlength-2] == '=') {
-      len = nlength-2;
-    } else {
-      len = nlength-1;
-    }
-  } else {
-    len = nlength;
-  }
-  rlength = len-quadtuple;
-  result = new unsigned char[rlength];
-  int r = len%4;
-
-  unsigned char* p = result;
-  const unsigned char* s = nsrc;
-  const unsigned char* smax = s+len-r;
-  while(s != smax) {
-    int n = INDEX_TABLE[*s++] << 18;
-    n += INDEX_TABLE[*s++] << 12;
-    n += INDEX_TABLE[*s++] << 6;
-    n += INDEX_TABLE[*s++];
-    *p++ = n >> 16;
-    *p++ = n >> 8&0xffu;
-    *p++ = n&0xffu;
-  }
-  if(r == 2) {
-    int n = INDEX_TABLE[*s++] << 18;
-    n += INDEX_TABLE[*s++] << 12;
-    *p++ = n >> 16;
-  } else if(r == 3) {
-    int n = INDEX_TABLE[*s++] << 18;
-    n += INDEX_TABLE[*s++] << 12;
-    n += INDEX_TABLE[*s++] << 6;
-    *p++ = n >> 16;
-    *p++ = n >> 8&0xffu;
-  }
-  delete [] nsrc;
-}
-
-std::string Base64::encode(const std::string& s)
-{
-  unsigned char* buf = 0;
-  size_t len;
-  encode(buf, len, s.c_str(), s.size());
-  std::string r(&buf[0], &buf[len]);
-  delete [] buf;
-  return r;
-}
-
-std::string Base64::decode(const std::string& s)
-{
-  unsigned char* buf = 0;
-  size_t len;
-  decode(buf, len, s.c_str(), s.size());
-  std::string r(&buf[0], &buf[len]);
-  delete [] buf;
-  return r;
-}
-
-} // namespace aria2

+ 132 - 48
src/base64.h

@@ -2,7 +2,7 @@
 /*
  * aria2 - The high speed download utility
  *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ * Copyright (C) 2011 Tatsuhiro Tsujikawa
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,63 +34,147 @@
 /* copyright --> */
 #ifndef D_BASE64_H
 #define D_BASE64_H
+
 #include <string>
 
 namespace aria2 {
 
-class Base64
-{
-private:
-  /**
-   * Removes non base64 chars(including '=') from src, and results are
-   * stored in nsrc and its length is stored in nlength.
-   * Caller must delete nsrc.
-   */
-  static void removeNonBase64Chars(unsigned char*& nsrc, size_t& nlength,
-                                   const unsigned char* src, size_t slength);
-
-public:
-  /**
-   * Encods src whose length is slength into base64 encoded data
-   * and stores them to result.
-   * result is allocated in this function and the length is stored to rlength.
-   * If slength is equal to 0, then return with rlength set to 0 and result
-   * is left untouched.
-   * A caller must deallocate the memory used by result.
-   */
-  static void encode(unsigned char*& result, size_t& rlength,
-                     const unsigned char* src, size_t slength);
+namespace base64 {
 
-  static void encode(unsigned char*& result, size_t& rlength,
-                     const char* src, size_t slength)
-  {
-    encode(result, rlength, reinterpret_cast<const unsigned char*>(src),
-           slength);
+template<typename InputIterator>
+std::string encode(InputIterator first, InputIterator last)
+{
+  static const char CHAR_TABLE[] = {
+    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+    'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+    'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+    'w', 'x', 'y', 'z', '0', '1', '2', '3',
+    '4', '5', '6', '7', '8', '9', '+', '/',
+  };
+  std::string res;
+  size_t len = last-first;
+  if(len == 0) {
+    return res;
   }
+  size_t r = len%3;
+  InputIterator j = last-r;
+  while(first != j) {
+    int n = static_cast<unsigned char>(*first++) << 16;
+    n += static_cast<unsigned char>(*first++) << 8;
+    n += static_cast<unsigned char>(*first++);
+    res += CHAR_TABLE[n >> 18];
+    res += CHAR_TABLE[(n >> 12) & 0x3fu];
+    res += CHAR_TABLE[(n >> 6) & 0x3fu];
+    res += CHAR_TABLE[n & 0x3fu];
+  }
+  if(r == 2) {
+    int n = static_cast<unsigned char>(*first++) << 16;
+    n += static_cast<unsigned char>(*first++) << 8;
+    res += CHAR_TABLE[n >> 18];
+    res += CHAR_TABLE[(n >> 12) & 0x3fu];
+    res += CHAR_TABLE[(n >> 6) & 0x3fu];
+    res += '=';
+  } else if(r == 1) {
+    int n = static_cast<unsigned char>(*first++) << 16;
+    res += CHAR_TABLE[n >> 18];
+    res += CHAR_TABLE[(n >> 12) & 0x3fu];
+    res += '=';
+    res += '=';
+  }
+  return res;
+}
 
-  static std::string encode(const std::string& s);
-
-  /**
-   * Dencods base64 encoded src whose length is slength and stores them to
-   * result.
-   * result is allocated in this function and the length is stored to rlength.
-   * If slength is equal to 0 or is not multiple of 4, then return with rlength
-   * set to 0 and result is left untouched.
-   * The function removes non-base64 characters before decoding.
-   * A caller must deallocate the memory used by result.
-   */
-  static void decode(unsigned char*& result, size_t& rlength,
-                     const unsigned char* src, size_t slength);
+template<typename InputIterator>
+InputIterator getNext
+(InputIterator first,
+ InputIterator last,
+ const int* tbl)
+{
+  for(; first != last; ++first) {
+    if(tbl[static_cast<size_t>(*first)] != -1 || *first == '=') {
+      break;
+    }
+  }
+  return first;
+}
 
-  static void decode(unsigned char*& result, size_t& rlength,
-                     const char* src, size_t slength)
-  {
-    decode(result, rlength, reinterpret_cast<const unsigned char*>(src),
-           slength);
+template<typename InputIterator>
+std::string decode(InputIterator first, InputIterator last)
+{
+  static const int INDEX_TABLE[] = {
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+  };
+  std::string res;
+  InputIterator k[5];
+  int eq = 0;
+  for(; first != last;) {
+    for(int i = 1; i <= 4; ++i) {
+      k[i] = getNext(first, last, INDEX_TABLE);
+      if(k[i] == last) {
+        res.clear();
+        return res;
+      } else if(*k[i] == '=' && eq == 0) {
+        eq = i;
+      }
+      first = k[i]+1;
+    }
+    if(eq) {
+      break;
+    }
+    int n = (INDEX_TABLE[static_cast<unsigned char>(*k[1])] << 18)+
+      (INDEX_TABLE[static_cast<unsigned char>(*k[2])] << 12)+
+      (INDEX_TABLE[static_cast<unsigned char>(*k[3])] << 6)+
+      INDEX_TABLE[static_cast<unsigned char>(*k[4])];
+    res += n >> 16;
+    res += n >> 8 & 0xffu;
+    res += n & 0xffu;
+  }
+  if(eq) {
+    if(eq <= 2) {
+      res.clear();
+      return res;
+    } else {
+      for(int i = eq; i <= 4; ++i) {
+        if(*k[i] != '=') {
+          res.clear();
+          return res;
+        }
+      }
+      if(eq == 3) {
+        int n = (INDEX_TABLE[static_cast<unsigned char>(*k[1])] << 18)+
+          (INDEX_TABLE[static_cast<unsigned char>(*k[2])] << 12);
+        res += n >> 16;
+      } else if(eq == 4) {
+        int n = (INDEX_TABLE[static_cast<unsigned char>(*k[1])] << 18)+
+          (INDEX_TABLE[static_cast<unsigned char>(*k[2])] << 12)+
+          (INDEX_TABLE[static_cast<unsigned char>(*k[3])] << 6);
+        res += n >> 16;
+        res += n >> 8 & 0xffu;
+      }
+    }
   }
+  return res;
+}
 
-  static std::string decode(const std::string& s);
-};
+} // namespace base64
 
 } // namespace aria2
 

+ 2 - 2
src/json.cc

@@ -646,8 +646,8 @@ decodeGetParams(const std::string& query)
         callback.assign((*i).first+13, (*i).second);
       }
     }
-    std::string jsonParam =
-      Base64::decode(util::percentDecode(params.first, params.second));
+    std::string decparam = util::percentDecode(params.first, params.second);
+    std::string jsonParam = base64::decode(decparam.begin(), decparam.end());
     if(method.first == method.second && id.first == id.second) {
       // Assume batch call.
       jsonRequest = jsonParam;

+ 57 - 114
test/Base64Test.cc

@@ -8,8 +8,6 @@ class Base64Test:public CppUnit::TestFixture {
   CPPUNIT_TEST_SUITE(Base64Test);
   CPPUNIT_TEST(testEncode);
   CPPUNIT_TEST(testDecode);
-  CPPUNIT_TEST(testEncode_string);
-  CPPUNIT_TEST(testDecode_string);
   CPPUNIT_TEST(testLongString);
   CPPUNIT_TEST_SUITE_END();
 private:
@@ -20,8 +18,6 @@ public:
 
   void testEncode();
   void testDecode();
-  void testEncode_string();
-  void testDecode_string();
   void testLongString();
 };
 
@@ -29,125 +25,72 @@ public:
 CPPUNIT_TEST_SUITE_REGISTRATION( Base64Test );
 
 void Base64Test::testEncode() {
-  unsigned char* buf = 0;
-  size_t len;
-  std::string s1 = "Hello World!";
-  Base64::encode(buf, len, s1.c_str(), s1.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("SGVsbG8gV29ybGQh"), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  std::string s2 = "Hello World";
-  Base64::encode(buf, len, s2.c_str(), s2.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("SGVsbG8gV29ybGQ="), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  std::string s3 = "Hello Worl";
-  Base64::encode(buf, len, s3.c_str(), s3.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("SGVsbG8gV29ybA=="), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  std::string s4 = "Man";
-  Base64::encode(buf, len, s4.c_str(), s4.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("TWFu"), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  std::string s5 = "M";
-  Base64::encode(buf, len, s5.c_str(), s5.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("TQ=="), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  buf = 0;
-  std::string s6 = "";
-  Base64::encode(buf, len, s6.c_str(), s6.size());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(&buf[0], &buf[len]));
-  CPPUNIT_ASSERT_EQUAL((size_t)0, len);
-  CPPUNIT_ASSERT(0 == buf);
-
-  {
-    const char temp[] = { -1 };
-    Base64::encode(buf, len, temp, 1);
-    CPPUNIT_ASSERT_EQUAL(std::string("/w=="), std::string(&buf[0], &buf[len]));
-    delete [] buf;
-  }
-}
+  std::string s = "Hello World!";
+  CPPUNIT_ASSERT_EQUAL(std::string("SGVsbG8gV29ybGQh"),
+                       base64::encode(s.begin(), s.end()));
 
-void Base64Test::testEncode_string()
-{
-  std::string s1 = "Hello World!";
-  CPPUNIT_ASSERT_EQUAL(std::string("SGVsbG8gV29ybGQh"), Base64::encode(s1));
+  s = "Hello World";
+  CPPUNIT_ASSERT_EQUAL(std::string("SGVsbG8gV29ybGQ="),
+                       base64::encode(s.begin(), s.end()));
+
+  s = "Hello Worl";
+  CPPUNIT_ASSERT_EQUAL(std::string("SGVsbG8gV29ybA=="),
+                       base64::encode(s.begin(), s.end()));
 
-  std::string s2 = "";
-  CPPUNIT_ASSERT_EQUAL(std::string(""), Base64::encode(s2));
+  s = "Man";
+  CPPUNIT_ASSERT_EQUAL(std::string("TWFu"), base64::encode(s.begin(), s.end()));
 
+  s = "M";
+  CPPUNIT_ASSERT_EQUAL(std::string("TQ=="), base64::encode(s.begin(), s.end()));
 
-  
+  s = "";
+  CPPUNIT_ASSERT_EQUAL(std::string(), base64::encode(s.begin(), s.end()));
+
+  s.assign(1, (char)-1);
+  base64::encode(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(std::string("/w=="), base64::encode(s.begin(), s.end()));
+
+  s.assign(2, (char)-1);
+  base64::encode(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(std::string("//8="), base64::encode(s.begin(), s.end()));
+
+  s.assign(3, (char)-1);
+  base64::encode(s.begin(), s.end());
+  CPPUNIT_ASSERT_EQUAL(std::string("////"), base64::encode(s.begin(), s.end()));
 }
 
 void Base64Test::testDecode()
 {
-  unsigned char* buf;
-  size_t len;
-
-  std::string s1 = "SGVsbG8gV29ybGQh";
-  Base64::decode(buf, len, s1.c_str(), s1.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("Hello World!"), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  std::string s2 = "SGVsbG8gV29ybGQ=";
-  Base64::decode(buf, len, s2.c_str(), s2.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("Hello World"), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  std::string s3 = "SGVsbG8gV29ybA==";
-  Base64::decode(buf, len, s3.c_str(), s3.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("Hello Worl"), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  std::string s4 = "TWFu";
-  Base64::decode(buf, len, s4.c_str(), s4.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("Man"), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  std::string s5 = "TQ==";
-  Base64::decode(buf, len, s5.c_str(), s5.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("M"), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  buf = 0;
-  std::string s6 = "";
-  Base64::decode(buf, len, s6.c_str(), s6.size());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(&buf[0], &buf[len]));
-  CPPUNIT_ASSERT_EQUAL((size_t)0, len);
-  CPPUNIT_ASSERT(!buf);
-
-  std::string s7 = "SGVsbG8\ngV2*9ybGQ=";
-  Base64::decode(buf, len, s7.c_str(), s7.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("Hello World"), std::string(&buf[0], &buf[len]));
-  delete [] buf;
-
-  buf = 0;
-  std::string s8 = "SGVsbG8\ngV2*9ybGQ";
-  Base64::decode(buf, len, s8.c_str(), s8.size());
-  CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(&buf[0], &buf[len]));
-  CPPUNIT_ASSERT_EQUAL((size_t)0, len);
-  CPPUNIT_ASSERT(!buf);
-
-  {
-    std::string s = "/w==";
-    Base64::decode(buf, len, s.c_str(), s.size());
-    CPPUNIT_ASSERT_EQUAL((unsigned char)-1, buf[0]);
-    delete [] buf;
-  }
+  std::string s = "SGVsbG8gV29ybGQh";
+  CPPUNIT_ASSERT_EQUAL(std::string("Hello World!"),
+                       base64::decode(s.begin(), s.end()));
 
-}
+  s = "SGVsbG8gV29ybGQ=";
+  CPPUNIT_ASSERT_EQUAL(std::string("Hello World"),
+                       base64::decode(s.begin(), s.end()));
 
-void Base64Test::testDecode_string()
-{
-  std::string s1 = "SGVsbG8gV29ybGQh";
-  CPPUNIT_ASSERT_EQUAL(std::string("Hello World!"), Base64::decode(s1));
+  s = "SGVsbG8gV29ybA==";
+  CPPUNIT_ASSERT_EQUAL(std::string("Hello Worl"),
+                       base64::decode(s.begin(), s.end()));
+
+  s = "TWFu";
+  CPPUNIT_ASSERT_EQUAL(std::string("Man"), base64::decode(s.begin(), s.end()));
+
+  s = "TQ==";
+  CPPUNIT_ASSERT_EQUAL(std::string("M"), base64::decode(s.begin(), s.end()));
+
+  s = "";
+  CPPUNIT_ASSERT_EQUAL(std::string(""), base64::decode(s.begin(), s.end()));
+
+  s = "SGVsbG8\ngV2*9ybGQ=";
+  CPPUNIT_ASSERT_EQUAL(std::string("Hello World"),
+                       base64::decode(s.begin(), s.end()));
+
+  s = "SGVsbG8\ngV2*9ybGQ";
+  CPPUNIT_ASSERT_EQUAL(std::string(""), base64::decode(s.begin(), s.end()));
 
-  std::string s2 = "";
-  CPPUNIT_ASSERT_EQUAL(std::string(""), Base64::decode(s2));
+  s = "/w==";
+  CPPUNIT_ASSERT_EQUAL(std::string(1, -1), base64::decode(s.begin(), s.end()));
 }
 
 void Base64Test::testLongString()
@@ -217,8 +160,8 @@ void Base64Test::testLongString()
     " * files in the program, then also delete it here.\n"
     " */\n"
     "/* copyright --> */\n";
-  CPPUNIT_ASSERT_EQUAL(d, Base64::decode(s));  
-  CPPUNIT_ASSERT_EQUAL(s, Base64::encode(d));  
+  CPPUNIT_ASSERT_EQUAL(d, base64::decode(s.begin(), s.end()));
+  CPPUNIT_ASSERT_EQUAL(s, base64::encode(d.begin(), d.end()));
 }
 
 } // namespace aria2

+ 4 - 2
test/JsonTest.cc

@@ -456,7 +456,8 @@ void JsonTest::testEncode()
 void JsonTest::testDecodeGetParams()
 {
   {
-    std::string param = util::percentEncode(Base64::encode("[1,2,3]"));
+    std::string s = "[1,2,3]";
+    std::string param = util::percentEncode(base64::encode(s.begin(), s.end()));
     std::string query = "?params=";
     query += param;
     query += '&';
@@ -471,8 +472,9 @@ void JsonTest::testDecodeGetParams()
     CPPUNIT_ASSERT_EQUAL(std::string("cb"), gparam.callback);
   }
   {
+    std::string s = "[{}]";
     std::string query = "?params=";
-    query += util::percentEncode(Base64::encode("[{}]"));
+    query += util::percentEncode(base64::encode(s.begin(), s.end()));
     query += '&';
     query += "jsoncallback=cb";
     json::JsonGetParam gparam = json::decodeGetParams(query);