--- /dev/null
+/**
+ * Copyright (C) 2016 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE64_DEFAULT_URL_UNPADDED
+#define CPPCODEC_BASE64_DEFAULT_URL_UNPADDED
+
+#include "base64_url_unpadded.hpp"
+
+using base64 = cppcodec::base64_url_unpadded;
+
+#endif // CPPCODEC_BASE64_DEFAULT_URL_UNPADDED
--- /dev/null
+/**
+ * Copyright (C) 2016 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE64_URL_UNPADDED
+#define CPPCODEC_BASE64_URL_UNPADDED
+
+#include "base64_url.hpp"
+
+namespace cppcodec {
+
+namespace detail {
+
+class base64_url_unpadded : public base64_url
+{
+public:
+ template <typename Codec> using codec_impl = stream_codec<Codec, base64_url_unpadded>;
+
+ static inline constexpr bool generates_padding() { return false; }
+ static inline constexpr bool requires_padding() { return false; }
+};
+
+} // namespace detail
+
+using base64_url_unpadded = detail::codec<detail::base64<detail::base64_url_unpadded>>;
+
+} // namespace cppcodec
+
+#endif // CPPCODEC_BASE64_URL_UNPADDED
#include <cppcodec/base32_rfc4648.hpp>
#include <cppcodec/base64_rfc4648.hpp>
#include <cppcodec/base64_url.hpp>
+#include <cppcodec/base64_url_unpadded.hpp>
#include <cppcodec/hex_lower.hpp>
#include <cppcodec/hex_upper.hpp>
#include <stdint.h>
}
}
+TEST_CASE("base64 (unpadded URL-safe)", "[base64][url_unpadded]") {
+ using base64 = cppcodec::base64_url_unpadded;
+
+ SECTION("encoded size calculation") {
+ REQUIRE(base64::encoded_size(0) == 0);
+ REQUIRE(base64::encoded_size(1) == 2);
+ REQUIRE(base64::encoded_size(2) == 3);
+ REQUIRE(base64::encoded_size(3) == 4);
+ REQUIRE(base64::encoded_size(4) == 6);
+ REQUIRE(base64::encoded_size(5) == 7);
+ REQUIRE(base64::encoded_size(6) == 8);
+ REQUIRE(base64::encoded_size(7) == 10);
+ REQUIRE(base64::encoded_size(12) == 16);
+ }
+
+ SECTION("maximum decoded size calculation") {
+ REQUIRE(base64::decoded_max_size(0) == 0);
+ REQUIRE(base64::decoded_max_size(1) == 0);
+ REQUIRE(base64::decoded_max_size(2) == 1);
+ REQUIRE(base64::decoded_max_size(3) == 2);
+ REQUIRE(base64::decoded_max_size(4) == 3);
+ REQUIRE(base64::decoded_max_size(5) == 3);
+ REQUIRE(base64::decoded_max_size(6) == 4);
+ REQUIRE(base64::decoded_max_size(7) == 5);
+ REQUIRE(base64::decoded_max_size(8) == 6);
+ REQUIRE(base64::decoded_max_size(9) == 6);
+ REQUIRE(base64::decoded_max_size(10) == 7);
+ REQUIRE(base64::decoded_max_size(11) == 8);
+ REQUIRE(base64::decoded_max_size(12) == 9);
+ REQUIRE(base64::decoded_max_size(16) == 12);
+ }
+
+ SECTION("encoding data") {
+ REQUIRE(base64::encode(std::vector<uint8_t>()) == "");
+ REQUIRE(base64::encode(std::vector<uint8_t>({0})) == "AA");
+ REQUIRE(base64::encode(std::vector<uint8_t>({0, 0})) == "AAA");
+ REQUIRE(base64::encode(std::vector<uint8_t>({0, 0, 0})) == "AAAA");
+ REQUIRE(base64::encode(std::vector<uint8_t>({0, 0, 0, 0})) == "AAAAAA");
+ REQUIRE(base64::encode(std::vector<uint8_t>({0, 0, 0, 0, 0})) == "AAAAAAA");
+ REQUIRE(base64::encode(std::vector<uint8_t>({0, 0, 0, 0, 0, 0})) == "AAAAAAAA");
+
+ // RFC 4648: 9. Illustrations and Examples, adapted for more special characters
+ REQUIRE(base64::encode(std::vector<uint8_t>({0x14, 0xFB, 0xBF, 0x03, 0xD9, 0x7E})) == "FPu_A9l-");
+ REQUIRE(base64::encode(std::vector<uint8_t>({0x14, 0xFB, 0xBF, 0x03, 0xD9})) == "FPu_A9k");
+ REQUIRE(base64::encode(std::vector<uint8_t>({0x14, 0xFB, 0xBF, 0x03})) == "FPu_Aw");
+
+ // RFC 4648: 10. Test Vectors
+ REQUIRE(base64::encode(std::string("")) == "");
+ REQUIRE(base64::encode(std::string("f")) == "Zg");
+ REQUIRE(base64::encode(std::string("fo")) == "Zm8");
+ REQUIRE(base64::encode(std::string("foo")) == "Zm9v");
+ REQUIRE(base64::encode(std::string("foob")) == "Zm9vYg");
+ REQUIRE(base64::encode(std::string("fooba")) == "Zm9vYmE");
+ REQUIRE(base64::encode(std::string("foobar")) == "Zm9vYmFy");
+
+ // Other test strings.
+ REQUIRE(base64::encode(std::string("123")) == "MTIz");
+ REQUIRE(base64::encode(std::string("ABC")) == "QUJD");
+ REQUIRE(base64::encode(std::string("\xFF\xFF\xFF")) == "____");
+ }
+
+ SECTION("decoding data") {
+ REQUIRE(base64::decode("") == std::vector<uint8_t>());
+ REQUIRE(base64::decode("AA") == std::vector<uint8_t>({0}));
+ REQUIRE(base64::decode("AAA") == std::vector<uint8_t>({0, 0}));
+ REQUIRE(base64::decode("AAAA") == std::vector<uint8_t>({0, 0, 0}));
+ REQUIRE(base64::decode("AAAAAA") == std::vector<uint8_t>({0, 0, 0, 0}));
+ REQUIRE(base64::decode("AAAAAAA") == std::vector<uint8_t>({0, 0, 0, 0, 0}));
+ REQUIRE(base64::decode("AAAAAAAA") == std::vector<uint8_t>({0, 0, 0, 0, 0, 0}));
+
+ // RFC 4648: 9. Illustrations and Examples, adapted for more special characters
+ REQUIRE(base64::decode("FPu_A9l-") == std::vector<uint8_t>({0x14, 0xFB, 0xBF, 0x03, 0xD9, 0x7E}));
+ REQUIRE(base64::decode("FPu_A9k") == std::vector<uint8_t>({0x14, 0xFB, 0xBF, 0x03, 0xD9}));
+ REQUIRE(base64::decode("FPu_Aw") == std::vector<uint8_t>({0x14, 0xFB, 0xBF, 0x03}));
+
+ // RFC 4648: 10. Test Vectors
+ REQUIRE(base64::decode<std::string>("") == "");
+ REQUIRE(base64::decode<std::string>("Zg") == "f");
+ REQUIRE(base64::decode<std::string>("Zg==") == "f");
+ REQUIRE(base64::decode<std::string>("Zm8") == "fo");
+ REQUIRE(base64::decode<std::string>("Zm8=") == "fo");
+ REQUIRE(base64::decode<std::string>("Zm9v") == "foo");
+ REQUIRE(base64::decode<std::string>("Zm9vYg") == "foob");
+ REQUIRE(base64::decode<std::string>("Zm9vYg==") == "foob");
+ REQUIRE(base64::decode<std::string>("Zm9vYmE") == "fooba");
+ REQUIRE(base64::decode<std::string>("Zm9vYmE=") == "fooba");
+ REQUIRE(base64::decode<std::string>("Zm9vYmFy") == "foobar");
+
+ // Other test strings.
+ REQUIRE(base64::decode<std::string>("MTIz") == "123");
+ REQUIRE(base64::decode<std::string>("QUJD") == "ABC");
+ REQUIRE(base64::decode("____") == std::vector<uint8_t>({255, 255, 255}));
+
+ // An invalid number of symbols should throw the right kind of parse_error.
+ REQUIRE_THROWS_AS(base64::decode("A"), cppcodec::invalid_input_length&);
+ REQUIRE_THROWS_AS(base64::decode("AAAAA"), cppcodec::invalid_input_length&);
+
+ // An invalid symbol should throw a symbol error.
+ REQUIRE_THROWS_AS(base64::decode("A&B"), cppcodec::symbol_error&);
+ REQUIRE_THROWS_AS(base64::decode("++"), cppcodec::symbol_error&); // this is not standard base64
+ REQUIRE_THROWS_AS(base64::decode("//"), cppcodec::symbol_error&); // ...ditto
+ }
+}
+
TEST_CASE("base64 (URL-safe)", "[base64][url]") {
using base64 = cppcodec::base64_url;