From b481ddb3df21e02e16038854ec7d256601717018 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 1 Sep 2016 13:08:18 +0200 Subject: [PATCH] Add cmBase32Encoder class --- Source/CMakeLists.txt | 1 + Source/cmBase32.cxx | 108 ++++++++++++++++++++++++++++++++++++++++++ Source/cmBase32.h | 42 ++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 Source/cmBase32.cxx create mode 100644 Source/cmBase32.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 8c74f6074..6c3ebf5ff 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -166,6 +166,7 @@ endif() # set(SRCS cmArchiveWrite.cxx + cmBase32.cxx cmBootstrapCommands1.cxx cmBootstrapCommands2.cxx cmCacheManager.cxx diff --git a/Source/cmBase32.cxx b/Source/cmBase32.cxx new file mode 100644 index 000000000..ce5c99b13 --- /dev/null +++ b/Source/cmBase32.cxx @@ -0,0 +1,108 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2016 Sebastian Holtermann + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmBase32.h" + +// -- Static functions + +static const unsigned char Base32EncodeTable[33] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + +inline unsigned char Base32EncodeChar(int schar) +{ + return Base32EncodeTable[schar]; +} + +void Base32Encode5(const unsigned char src[5], char dst[8]) +{ + // [0]:5 bits + dst[0] = Base32EncodeChar((src[0] >> 3) & 0x1F); + // [0]:3 bits + [1]:2 bits + dst[1] = Base32EncodeChar(((src[0] << 2) & 0x1C) + ((src[1] >> 6) & 0x03)); + // [1]:5 bits + dst[2] = Base32EncodeChar((src[1] >> 1) & 0x1F); + // [1]:1 bit + [2]:4 bits + dst[3] = Base32EncodeChar(((src[1] << 4) & 0x10) + ((src[2] >> 4) & 0x0F)); + // [2]:4 bits + [3]:1 bit + dst[4] = Base32EncodeChar(((src[2] << 1) & 0x1E) + ((src[3] >> 7) & 0x01)); + // [3]:5 bits + dst[5] = Base32EncodeChar((src[3] >> 2) & 0x1F); + // [3]:2 bits + [4]:3 bit + dst[6] = Base32EncodeChar(((src[3] << 3) & 0x18) + ((src[4] >> 5) & 0x07)); + // [4]:5 bits + dst[7] = Base32EncodeChar((src[4] << 0) & 0x1F); +} + +// -- Class methods + +cmBase32Encoder::cmBase32Encoder() +{ +} + +cmBase32Encoder::~cmBase32Encoder() +{ +} + +std::string cmBase32Encoder::encodeString(const unsigned char* input, + size_t len, bool padding) +{ + std::string res; + + static const size_t blockSize = 5; + static const size_t bufferSize = 8; + char buffer[bufferSize]; + + const unsigned char* end = input + len; + while ((input + blockSize) <= end) { + Base32Encode5(input, buffer); + res.append(buffer, bufferSize); + input += blockSize; + } + + size_t remain(end - input); + if (remain != 0) { + // Temporary source buffer filled up with 0s + unsigned char extended[blockSize]; + for (size_t ii = 0; ii != remain; ++ii) { + extended[ii] = input[ii]; + } + for (size_t ii = remain; ii != blockSize; ++ii) { + extended[ii] = 0; + } + + Base32Encode5(extended, buffer); + size_t numPad(0); + switch (remain) { + case 1: + numPad = 6; + break; + case 2: + numPad = 4; + break; + case 3: + numPad = 3; + break; + case 4: + numPad = 1; + break; + default: + break; + } + res.append(buffer, bufferSize - numPad); + if (padding) { + for (size_t ii = 0; ii != numPad; ++ii) { + res.push_back(paddingChar); + } + } + } + + return res; +} diff --git a/Source/cmBase32.h b/Source/cmBase32.h new file mode 100644 index 000000000..66ff8ba04 --- /dev/null +++ b/Source/cmBase32.h @@ -0,0 +1,42 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2016 Sebastian Holtermann + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmBase32_h +#define cmBase32_h + +#include // IWYU pragma: keep + +#include +#include + +/** \class cmBase32Encoder + * \brief Encodes a byte sequence to a Base32 byte sequence according to + * RFC4648 + * + */ +class cmBase32Encoder +{ +public: + static const char paddingChar = '='; + +public: + cmBase32Encoder(); + ~cmBase32Encoder(); + + // Encodes the given input byte sequence into a string + // @arg input Input data pointer + // @arg len Input data size + // @arg padding Flag to append "=" on demand + std::string encodeString(const unsigned char* input, size_t len, + bool padding = true); +}; + +#endif