Skip to content

Commit

Permalink
add base64 encode/decode to Utils::
Browse files Browse the repository at this point in the history
  • Loading branch information
hobu committed Mar 15, 2012
1 parent 897461c commit ab7c62a
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 1 deletion.
5 changes: 4 additions & 1 deletion include/pdal/Utils.hpp
Expand Up @@ -46,6 +46,7 @@
#include <limits>
#include <cstring>
#include <sstream>
#include <vector>

#include <boost/filesystem.hpp>
#include <boost/algorithm/string/erase.hpp>
Expand Down Expand Up @@ -161,7 +162,9 @@ class PDAL_DLL Utils
static std::string generate_tempfile();

static void* getDLLSymbol( std::string const& library, std::string const& name);

static std::string base64_encode(std::vector<boost::uint8_t> const& bytes);
static std::vector<boost::uint8_t> base64_decode(std::string const& input);

private:
template<typename T>
static inline char* as_buffer(T& data)
Expand Down
140 changes: 140 additions & 0 deletions src/Utils.cpp
Expand Up @@ -36,6 +36,7 @@

#include <cassert>
#include <cstdlib>
#include <cctype>

#ifdef PDAL_COMPILER_MSVC
# pragma warning(disable: 4127) // conditional expression is constant
Expand Down Expand Up @@ -279,4 +280,143 @@ void* Utils::getDLLSymbol(std::string const& library, std::string const& name)
}










std::string Utils::base64_encode(std::vector<boost::uint8_t> const& bytes)
{

/*
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/

unsigned char const* bytes_to_encode = &bytes.front();

unsigned int in_len = bytes.size();

const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string ret;
int i = 0;
int j = 0;
boost::uint8_t char_array_3[3];
boost::uint8_t char_array_4[4];

while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;

for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}

if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;

for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];

while((i++ < 3))
ret += '=';
}

return ret;

}

std::vector<boost::uint8_t> Utils::base64_decode(std::string const& encoded_string)
{
const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::vector<boost::uint8_t> ret;

while (in_len-- &&
( encoded_string[in_] != '=') &&
(isalnum(encoded_string[in_]) || (encoded_string[in_] == '+') || (encoded_string[in_] == '/'))
)
{
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (i = 0; (i < 3); i++)
ret.push_back( char_array_3[i]);
i = 0;
}
}

if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;

for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (j = 0; (j < i - 1); j++) ret.push_back( char_array_3[i]);
}

return ret;
}


} // namespace pdal
24 changes: 24 additions & 0 deletions test/unit/UtilsTest.cpp
Expand Up @@ -39,6 +39,8 @@

#include <pdal/Range.hpp>

#include <vector>

using namespace pdal;

BOOST_AUTO_TEST_SUITE(UtilsTest)
Expand Down Expand Up @@ -155,4 +157,26 @@ BOOST_AUTO_TEST_CASE(test_field_read_write)
}


BOOST_AUTO_TEST_CASE(test_base64)
{
std::vector<boost::uint8_t> data;
for(int i=0;i<100;i++) data.push_back(i);

std::string encoded = Utils::base64_encode(data);
std::vector<boost::uint8_t> decoded = Utils::base64_decode(encoded);

boost::uint32_t size(0);
for (std::vector<boost::uint8_t>::size_type i = 0; i < decoded.size(); ++i)
{
size = size + decoded[i];
}

BOOST_CHECK_EQUAL(size, 4950u);


return;
}



BOOST_AUTO_TEST_SUITE_END()

0 comments on commit ab7c62a

Please sign in to comment.