Mercurial > code
changeset 591:3547fc5afba2
Base64: move to bitbucket
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 31 Aug 2016 18:35:39 +0200 |
parents | 3058eaa603e6 |
children | 2bd11ea63822 |
files | CMakeLists.txt modules/base64/CMakeLists.txt modules/base64/base64.hpp modules/base64/doc/mainpage.cpp modules/base64/test/main.cpp |
diffstat | 5 files changed, 0 insertions(+), 504 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Tue Aug 30 13:03:38 2016 +0200 +++ b/CMakeLists.txt Wed Aug 31 18:35:39 2016 +0200 @@ -49,7 +49,6 @@ ) endif () -add_subdirectory(modules/base64) add_subdirectory(modules/dynlib) add_subdirectory(modules/elapsed-timer) add_subdirectory(modules/fs)
--- a/modules/base64/CMakeLists.txt Tue Aug 30 13:03:38 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -# -# CMakeLists.txt -- code building for common code -# -# Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - -code_define_module( - NAME base64 - SOURCES base64.hpp -)
--- a/modules/base64/base64.hpp Tue Aug 30 13:03:38 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,242 +0,0 @@ -/* - * base64.hpp -- base64 encoding and decoding - * - * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef BASE64_HPP -#define BASE64_HPP - -/** - * \file base64.hpp - * \brief Base64 encoding and decoding. - * \author David Demelier <markand@malikania.fr> - */ - -/** - * \page Base64 Base64 - * \brief Base64 encoding and decoding. - * - * The %base64 library let you encode and decode %base64 data from std::string - * and iterators. - * - * ## Encoding - * - * You can encode like this: - * - * ````cpp - * std::string b64 = base64::encode("Hello world!"); - * ```` - * - * ## Decoding - * - * And you can decode like this: - * - * ```` - * try { - * std::string text = base64::decode(msg); - * } catch (const std::exception &ex) { - * std::cerr << ex.what() << std::endl; - * } - * ```` - */ - -#include <cassert> -#include <cctype> -#include <stdexcept> -#include <string> - -/** - * \brief main %base64 namespace. - */ -namespace base64 { - -/** - * Check if the character is a %base64 character, A-Za-z0-9 and +/. - * - * \param ch the character to test - * \return true if valid - */ -inline bool isBase64(char ch) noexcept -{ - return std::isalnum(ch) != 0 || ch == '+' || ch == '/'; -} - -/** - * Check if the given character is a valid character in %base64 string, - * including '='. - * - * \param ch the character - * \return true if the character is valid - */ -inline bool isValid(char ch) noexcept -{ - return isBase64(ch) || ch == '='; -} - -/** - * Get the %base64 character from the 6-bits value. - * - * \pre value must be valid (< 64) - * \param value the value - * \return the %base64 character for value - */ -inline char lookup(unsigned char value) noexcept -{ - static const char *table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - assert(value < 64); - - return table[value]; -} - -/** - * Get the integer value from the %base64 character. - * - * \pre isBase64(ch) - * \param ch the %base64 character - * \return the integer value for the %base64 character ch - * ```` - * auto b64 = base64::rlookup('D') // 3 - * ```` - */ -inline unsigned char rlookup(char ch) noexcept -{ - assert(isBase64(ch)); - - if (ch >= '0' && ch <= '9') - return static_cast<unsigned char>(ch + 4); - if (ch >= 'A' && ch <= 'Z') - return static_cast<unsigned char>(ch - 65); - if (ch >= 'a' && ch <= 'z') - return static_cast<unsigned char>(ch - 71); - - return (ch == '+') ? 62U : 63U; -} - -/** - * Encode the input to the output. - * - * Requirements: - * - **InputIt** must be [InputIterator](http://en.cppreference.com/w/cpp/concept/InputIterator) - * - **OutputIt** must be [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator) - * - * \param input the beginning - * \param end the end of the data - * \param output the output destination - * \return output - */ -template <typename InputIt, typename OutputIt> -OutputIt encode(InputIt input, InputIt end, OutputIt output) -{ - while (input != end) { - char inputbuf[3] = { 0, 0, 0 }; - int count; - - for (count = 0; count < 3 && input != end; ++count) - inputbuf[count] = *input++; - - *output++ = lookup(inputbuf[0] >> 2 & 0x3f); - *output++ = lookup((inputbuf[0] << 4 & 0x3f) | (inputbuf[1] >> 4 & 0x0f)); - *output++ = (count < 2) ? '=' : lookup((inputbuf[1] << 2 & 0x3c) | (inputbuf[2] >> 6 & 0x03)); - *output++ = (count < 3) ? '=' : lookup(inputbuf[2] & 0x3f); - } - - return output; -} - -/** - * Decode the input to the output. - * - * Requirements: - * - **InputIt** must be [InputIterator](http://en.cppreference.com/w/cpp/concept/InputIterator) - * - **OutputIt** must be [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator) - * - * \param input the beginning - * \param end the end of the data - * \param output the output destination - * \return output - * \throw std::invalid_argument on bad %base64 string - */ -template <typename InputIt, typename OutputIt> -OutputIt decode(InputIt input, InputIt end, OutputIt output) -{ - while (input != end) { - char inputbuf[4] = { -1, -1, -1, -1 }; - int count; - - for (count = 0; count < 4 && input != end; ++count) { - // Check if the character is valid and get its value. - if ((*input == '=' && count <= 1) || !isValid(*input)) - throw std::invalid_argument("invalid base64 string"); - if (isBase64(*input)) - inputbuf[count] = static_cast<char>(rlookup(*input)); - - input++; - } - - if (count != 4) - throw std::invalid_argument("truncated string"); - - *output++ = static_cast<char>(((inputbuf[0] << 2) & 0xfc) | ((inputbuf[1] >> 4) & 0x03)); - - if (inputbuf[2] != -1) - *output++ = static_cast<char>(((inputbuf[1] << 4) & 0xf0) | ((inputbuf[2] >> 2) & 0x0f)); - if (inputbuf[3] != -1) { - // "XY=Z" is not allowed. - if (inputbuf[2] == -1) - throw std::invalid_argument("invalid base64 string"); - - *output++ = static_cast<char>(((inputbuf[2] << 6) & 0xc0) | (inputbuf[3] & 0x3f)); - } - } - - return output; -} - -/** - * Encode a string. - * - * \param input the input string - * \return the %base64 formatted string - */ -inline std::string encode(const std::string &input) -{ - std::string result; - - encode(input.begin(), input.end(), std::back_inserter(result)); - - return result; -} - -/** - * Decode a string. - * - * \param input the %base64 formatted string - * \return the original string - * \throw std::invalid_argument on bad %base64 string - */ -inline std::string decode(const std::string &input) -{ - std::string result; - - decode(input.begin(), input.end(), std::back_inserter(result)); - - return result; -} - -} // !base64 - -#endif // !BASE64_HPP
--- a/modules/base64/doc/mainpage.cpp Tue Aug 30 13:03:38 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/** - * \mainpage - * - * Welcome to the %base64 library. - * - * ## Introduction - * - * This code allows you to encode and decode %base64 data in C++ as easy as possible. - * - * ## Installation - * - * Just copy the file base64.hpp and add it to your project. - * - * ## Overview - * - * ```` - * #include "base64.hpp" - * - * int main(void) - * { - * base64::encode("Hello World!"); - * - * return 0; - * } - * ```` - */
--- a/modules/base64/test/main.cpp Tue Aug 30 13:03:38 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +0,0 @@ -/* - * main.cpp -- main test file for base64 - * - * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <gtest/gtest.h> - -#include <base64.hpp> - -TEST(Lookup, lookup) -{ - ASSERT_EQ('A', base64::lookup(0b000000)); - ASSERT_EQ('B', base64::lookup(0b000001)); - ASSERT_EQ('C', base64::lookup(0b000010)); - ASSERT_EQ('D', base64::lookup(0b000011)); - ASSERT_EQ('E', base64::lookup(0b000100)); - ASSERT_EQ('F', base64::lookup(0b000101)); - ASSERT_EQ('G', base64::lookup(0b000110)); - ASSERT_EQ('H', base64::lookup(0b000111)); - ASSERT_EQ('I', base64::lookup(0b001000)); - ASSERT_EQ('J', base64::lookup(0b001001)); - ASSERT_EQ('K', base64::lookup(0b001010)); - ASSERT_EQ('L', base64::lookup(0b001011)); - ASSERT_EQ('M', base64::lookup(0b001100)); - ASSERT_EQ('N', base64::lookup(0b001101)); - ASSERT_EQ('O', base64::lookup(0b001110)); - ASSERT_EQ('P', base64::lookup(0b001111)); - ASSERT_EQ('Q', base64::lookup(0b010000)); - ASSERT_EQ('R', base64::lookup(0b010001)); - ASSERT_EQ('S', base64::lookup(0b010010)); - ASSERT_EQ('T', base64::lookup(0b010011)); - ASSERT_EQ('U', base64::lookup(0b010100)); - ASSERT_EQ('V', base64::lookup(0b010101)); - ASSERT_EQ('W', base64::lookup(0b010110)); - ASSERT_EQ('X', base64::lookup(0b010111)); - ASSERT_EQ('Y', base64::lookup(0b011000)); - ASSERT_EQ('Z', base64::lookup(0b011001)); - ASSERT_EQ('a', base64::lookup(0b011010)); - ASSERT_EQ('b', base64::lookup(0b011011)); - ASSERT_EQ('c', base64::lookup(0b011100)); - ASSERT_EQ('d', base64::lookup(0b011101)); - ASSERT_EQ('e', base64::lookup(0b011110)); - ASSERT_EQ('f', base64::lookup(0b011111)); - ASSERT_EQ('g', base64::lookup(0b100000)); - ASSERT_EQ('h', base64::lookup(0b100001)); - ASSERT_EQ('i', base64::lookup(0b100010)); - ASSERT_EQ('j', base64::lookup(0b100011)); - ASSERT_EQ('k', base64::lookup(0b100100)); - ASSERT_EQ('l', base64::lookup(0b100101)); - ASSERT_EQ('m', base64::lookup(0b100110)); - ASSERT_EQ('n', base64::lookup(0b100111)); - ASSERT_EQ('o', base64::lookup(0b101000)); - ASSERT_EQ('p', base64::lookup(0b101001)); - ASSERT_EQ('q', base64::lookup(0b101010)); - ASSERT_EQ('r', base64::lookup(0b101011)); - ASSERT_EQ('s', base64::lookup(0b101100)); - ASSERT_EQ('t', base64::lookup(0b101101)); - ASSERT_EQ('u', base64::lookup(0b101110)); - ASSERT_EQ('v', base64::lookup(0b101111)); - ASSERT_EQ('w', base64::lookup(0b110000)); - ASSERT_EQ('x', base64::lookup(0b110001)); - ASSERT_EQ('y', base64::lookup(0b110010)); - ASSERT_EQ('z', base64::lookup(0b110011)); - ASSERT_EQ('0', base64::lookup(0b110100)); - ASSERT_EQ('1', base64::lookup(0b110101)); - ASSERT_EQ('2', base64::lookup(0b110110)); - ASSERT_EQ('3', base64::lookup(0b110111)); - ASSERT_EQ('4', base64::lookup(0b111000)); - ASSERT_EQ('5', base64::lookup(0b111001)); - ASSERT_EQ('6', base64::lookup(0b111010)); - ASSERT_EQ('7', base64::lookup(0b111011)); - ASSERT_EQ('8', base64::lookup(0b111100)); - ASSERT_EQ('9', base64::lookup(0b111101)); - ASSERT_EQ('+', base64::lookup(0b111110)); - ASSERT_EQ('/', base64::lookup(0b111111)); -} - -TEST(Lookup, rlookup) -{ - ASSERT_EQ(0b000000U, base64::rlookup('A')); - ASSERT_EQ(0b000001U, base64::rlookup('B')); - ASSERT_EQ(0b000010U, base64::rlookup('C')); - ASSERT_EQ(0b000011U, base64::rlookup('D')); - ASSERT_EQ(0b000100U, base64::rlookup('E')); - ASSERT_EQ(0b000101U, base64::rlookup('F')); - ASSERT_EQ(0b000110U, base64::rlookup('G')); - ASSERT_EQ(0b000111U, base64::rlookup('H')); - ASSERT_EQ(0b001000U, base64::rlookup('I')); - ASSERT_EQ(0b001001U, base64::rlookup('J')); - ASSERT_EQ(0b001010U, base64::rlookup('K')); - ASSERT_EQ(0b001011U, base64::rlookup('L')); - ASSERT_EQ(0b001100U, base64::rlookup('M')); - ASSERT_EQ(0b001101U, base64::rlookup('N')); - ASSERT_EQ(0b001110U, base64::rlookup('O')); - ASSERT_EQ(0b001111U, base64::rlookup('P')); - ASSERT_EQ(0b010000U, base64::rlookup('Q')); - ASSERT_EQ(0b010001U, base64::rlookup('R')); - ASSERT_EQ(0b010010U, base64::rlookup('S')); - ASSERT_EQ(0b010011U, base64::rlookup('T')); - ASSERT_EQ(0b010100U, base64::rlookup('U')); - ASSERT_EQ(0b010101U, base64::rlookup('V')); - ASSERT_EQ(0b010110U, base64::rlookup('W')); - ASSERT_EQ(0b010111U, base64::rlookup('X')); - ASSERT_EQ(0b011000U, base64::rlookup('Y')); - ASSERT_EQ(0b011001U, base64::rlookup('Z')); - ASSERT_EQ(0b011010U, base64::rlookup('a')); - ASSERT_EQ(0b011011U, base64::rlookup('b')); - ASSERT_EQ(0b011100U, base64::rlookup('c')); - ASSERT_EQ(0b011101U, base64::rlookup('d')); - ASSERT_EQ(0b011110U, base64::rlookup('e')); - ASSERT_EQ(0b011111U, base64::rlookup('f')); - ASSERT_EQ(0b100000U, base64::rlookup('g')); - ASSERT_EQ(0b100001U, base64::rlookup('h')); - ASSERT_EQ(0b100010U, base64::rlookup('i')); - ASSERT_EQ(0b100011U, base64::rlookup('j')); - ASSERT_EQ(0b100100U, base64::rlookup('k')); - ASSERT_EQ(0b100101U, base64::rlookup('l')); - ASSERT_EQ(0b100110U, base64::rlookup('m')); - ASSERT_EQ(0b100111U, base64::rlookup('n')); - ASSERT_EQ(0b101000U, base64::rlookup('o')); - ASSERT_EQ(0b101001U, base64::rlookup('p')); - ASSERT_EQ(0b101010U, base64::rlookup('q')); - ASSERT_EQ(0b101011U, base64::rlookup('r')); - ASSERT_EQ(0b101100U, base64::rlookup('s')); - ASSERT_EQ(0b101101U, base64::rlookup('t')); - ASSERT_EQ(0b101110U, base64::rlookup('u')); - ASSERT_EQ(0b101111U, base64::rlookup('v')); - ASSERT_EQ(0b110000U, base64::rlookup('w')); - ASSERT_EQ(0b110001U, base64::rlookup('x')); - ASSERT_EQ(0b110010U, base64::rlookup('y')); - ASSERT_EQ(0b110011U, base64::rlookup('z')); - ASSERT_EQ(0b110100U, base64::rlookup('0')); - ASSERT_EQ(0b110101U, base64::rlookup('1')); - ASSERT_EQ(0b110110U, base64::rlookup('2')); - ASSERT_EQ(0b110111U, base64::rlookup('3')); - ASSERT_EQ(0b111000U, base64::rlookup('4')); - ASSERT_EQ(0b111001U, base64::rlookup('5')); - ASSERT_EQ(0b111010U, base64::rlookup('6')); - ASSERT_EQ(0b111011U, base64::rlookup('7')); - ASSERT_EQ(0b111100U, base64::rlookup('8')); - ASSERT_EQ(0b111101U, base64::rlookup('9')); - ASSERT_EQ(0b111110U, base64::rlookup('+')); - ASSERT_EQ(0b111111U, base64::rlookup('/')); -} - -TEST(Encode, basic) -{ - ASSERT_EQ("YQ==", base64::encode("a")); - ASSERT_EQ("YWI=", base64::encode("ab")); - ASSERT_EQ("YWJj", base64::encode("abc")); - ASSERT_EQ("aGVsbG8=", base64::encode("hello")); - ASSERT_EQ("dGhpcyBpcyBhIGxvbmcgc2VudGVuY2U=", base64::encode("this is a long sentence")); -} - -TEST(Decode, basic) -{ - ASSERT_EQ("a", base64::decode("YQ==")); - ASSERT_EQ("ab", base64::decode("YWI=")); - ASSERT_EQ("abc", base64::decode("YWJj")); - ASSERT_EQ("hello", base64::decode("aGVsbG8=")); - ASSERT_EQ("this is a long sentence", base64::decode("dGhpcyBpcyBhIGxvbmcgc2VudGVuY2U=")); - ASSERT_EQ("Welcome to our server dude", base64::decode("V2VsY29tZSB0byBvdXIgc2VydmVyIGR1ZGU=")); -} - -TEST(Failure, truncated) -{ - ASSERT_THROW(base64::decode("YW="), std::invalid_argument); -} - -TEST(Failure, invalid) -{ - ASSERT_THROW(base64::decode("?!"), std::invalid_argument); -} - -TEST(Failure, wrong1) -{ - ASSERT_THROW(base64::decode("=ABC"), std::invalid_argument); -} - -TEST(Failure, wrong2) -{ - ASSERT_THROW(base64::decode("A=BC"), std::invalid_argument); -} - -TEST(Failure, wrong3) -{ - ASSERT_THROW(base64::decode("==BC"), std::invalid_argument); -} - -TEST(Failure, wrong4) -{ - ASSERT_THROW(base64::decode("AB=C"), std::invalid_argument); -} - -int main(int argc, char **argv) -{ - testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -}