view C++/modules/Base64/base64.cpp @ 485:898d8b29a4f1

Switch to lowercase filenames
author David Demelier <markand@malikania.fr>
date Thu, 12 Nov 2015 21:53:36 +0100
parents C++/modules/Base64/Base64.cpp@65b567c8de54
children
line wrap: on
line source

/*
 * Base64.cpp -- base64 encoding and decoding
 *
 * Copyright (c) 2013-2015 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 <cassert>
#include <iterator>
#include <sstream>
#include <unordered_map>

#include "base64.h"

namespace base64 {

namespace {

const std::string table{"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"};

const std::unordered_map<unsigned char, unsigned int> rtable{
	{ 'A', 0  },
	{ 'B', 1  },
	{ 'C', 2  },
	{ 'D', 3  },
	{ 'E', 4  },
	{ 'F', 5  },
	{ 'G', 6  },
	{ 'H', 7  },
	{ 'I', 8  },
	{ 'J', 9  },
	{ 'K', 10 },
	{ 'L', 11 },
	{ 'M', 12 },
	{ 'N', 13 },
	{ 'O', 14 },
	{ 'P', 15 },
	{ 'Q', 16 },
	{ 'R', 17 },
	{ 'S', 18 },
	{ 'T', 19 },
	{ 'U', 20 },
	{ 'V', 21 },
	{ 'W', 22 },
	{ 'X', 23 },
	{ 'Y', 24 },
	{ 'Z', 25 },
	{ 'a', 26 },
	{ 'b', 27 },
	{ 'c', 28 },
	{ 'd', 29 },
	{ 'e', 30 },
	{ 'f', 31 },
	{ 'g', 32 },
	{ 'h', 33 },
	{ 'i', 34 },
	{ 'j', 35 },
	{ 'k', 36 },
	{ 'l', 37 },
	{ 'm', 38 },
	{ 'n', 39 },
	{ 'o', 40 },
	{ 'p', 41 },
	{ 'q', 42 },
	{ 'r', 43 },
	{ 's', 44 },
	{ 't', 45 },
	{ 'u', 46 },
	{ 'v', 47 },
	{ 'w', 48 },
	{ 'x', 49 },
	{ 'y', 50 },
	{ 'z', 51 },
	{ '0', 52 },
	{ '1', 53 },
	{ '2', 54 },
	{ '3', 55 },
	{ '4', 56 },
	{ '5', 57 },
	{ '6', 58 },
	{ '7', 59 },
	{ '8', 60 },
	{ '9', 61 },
	{ '+', 62 },
	{ '/', 63 }
};

} // !namespace

unsigned char lookup(unsigned int value) noexcept
{
	assert(value < 64);

	return table[value];
}

unsigned int rlookup(unsigned char ch)
{
	assert(rtable.count(ch) != 0 && ch != '=');

	return rtable.at(ch);
}

bool isValid(unsigned char ch) noexcept
{
	return ch == '=' || rtable.count(ch);
}

std::string encode(const std::string &input)
{
	std::string result;
	std::istringstream iss(input, std::istringstream::in);

	encode(std::istreambuf_iterator<char>(iss), std::istreambuf_iterator<char>(), std::back_inserter(result));

	return result;
}

std::string decode(const std::string &input)
{
	std::string result;
	std::istringstream iss(input, std::istringstream::in);

	decode(std::istreambuf_iterator<char>(iss), std::istreambuf_iterator<char>(), std::back_inserter(result));

	return result;
}

} // !base64