Skip to content

Commit

Permalink
Modularised the library into a module
Browse files Browse the repository at this point in the history
  • Loading branch information
matheusgomes28 committed Jan 27, 2024
1 parent 432c944 commit a4dc119
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 233 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN On)


if(NOT WIN32 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
if (NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "/opt/${PROJECT_NAME}")
Expand Down
11 changes: 7 additions & 4 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@
"generator": "Ninja",
"cacheVariables": {
"CMAKE_C_COMPILER": "clang-17",
"CMAKE_CXX_COMPILER": "clang++-17",
"CMAKE_CXX_FLAGS_INIT": "$env{CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -pedantic"
"CMAKE_CXX_COMPILER": "clang++-17",
"CMAKE_CXX_FLAGS_INIT": "$env{CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -pedantic",
"CMAKE_CXX_SCAN_FOR_MODULES": true,
"CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS": "/usr/bin/clang-scan-deps-17"
}
},
{
Expand All @@ -60,16 +62,17 @@
{
"name": "vs2022",
"hidden": true,
"generator": "Visual Studio 17 2022",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_CXX_FLAGS_INIT": "$env{CMAKE_CXX_FLAGS_INIT} $env{CMAKE_CXX_FLAGS} /W4 /WX /EHsc"
}
},
{
"name": "vs2022-shared",
"hidden": true,
"generator": "Visual Studio 17 2022",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_CXX_COMPILER": "cl.exe",
"CMAKE_CXX_FLAGS_INIT": "$env{CMAKE_CXX_FLAGS_INIT} $env{CMAKE_CXX_FLAGS} /W4 /WX /EHsc",
"BUILD_SHARED_LIBS": true
}
Expand Down
10 changes: 6 additions & 4 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ stages:
parameters:
jobName: ubuntu_build_x86_64_debug
buildType: Debug
cmakePreset: unix-deb
cmakePreset: unix-deb-ninja
cmakeExtraArgs: -DBUILD_DOCS="On"
containerName: ubuntu18.04-gcc11-conan2-doxygen1.9.6
artifactName: UbuntuDebugBuild
Expand All @@ -61,7 +61,8 @@ stages:
cmakePreset: unix-deb-ninja
containerName: ubuntu18.04-gcc11-conan2-doxygen1.9.6
artifactName: UbuntuClangDebugBuild
compiler: clang
cxx: clang++
cc: clang
compilerStd: 20
compilerLibCxx: libstdc++11
compilerVersion: 17
Expand All @@ -70,7 +71,7 @@ stages:
parameters:
jobName: ubuntu_build_x86_64_release
buildType: Release
cmakePreset: unix-rel
cmakePreset: unix-rel-ninja
containerName: ubuntu18.04-gcc11-conan2-doxygen1.9.6
artifactName: UbuntuReleaseBuild

Expand All @@ -81,7 +82,8 @@ stages:
cmakePreset: unix-rel-ninja
containerName: ubuntu18.04-gcc11-conan2-doxygen1.9.6
artifactName: UbuntuClangReleaseBuild
compiler: clang
cxx: clang++
cc: clang
compilerStd: 20
compilerLibCxx: libstdc++11
compilerVersion: 17
Expand Down
17 changes: 8 additions & 9 deletions base64pp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ set(BASE64PP_SOURCES
set(BASE64PP_INCLUDE_DIR
${CMAKE_CURRENT_LIST_DIR}/include)

add_library(base64pp base64pp.cpp)
add_library(base64pp)
target_sources(base64pp
PUBLIC
FILE_SET CXX_MODULES FILES
base64pp.cpp
)

# Extra modules stuff
target_include_directories(base64pp PUBLIC ${BASE64PP_INCLUDE_DIR})

include(GenerateExportHeader)
set(BASE64PP_EXPORT_FILE "${CMAKE_CURRENT_LIST_DIR}/include/base64pp")
generate_export_header(base64pp EXPORT_FILE_NAME "${BASE64PP_INCLUDE_DIR}/base64pp/base64pp_export.h")

file(GLOB BASE64PP_PUBLIC_HEADERS ${BASE64PP_INCLUDE_DIR}/**/*.h)
set_target_properties(base64pp
PROPERTIES PUBLIC_HEADER "${BASE64PP_PUBLIC_HEADERS}")

include(GNUInstallDirs)
install(TARGETS base64pp)

# Generate PKG-Config
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/base64pp.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/base64pp.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/base64pp.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")

144 changes: 79 additions & 65 deletions base64pp/base64pp.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module;

#include <algorithm>
#include <array>
#include <base64pp/base64pp.h>
#include <cstdint>
#include <iterator>
#include <optional>
Expand All @@ -9,80 +10,82 @@
#include <string_view>
#include <vector>

namespace
export module base64pp;

std::array<char, 64> constexpr encode_table{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', '+', '/'};

std::array<std::uint8_t, 256> constexpr decode_table{0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x3E, 0x64, 0x64, 0x64, 0x3F, 0x34,
0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x00, 0x01, 0x02,
0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64};

std::array<char, 4> encode_tripplet(std::uint8_t a, std::uint8_t b, std::uint8_t c)
{
std::array<char, 64> constexpr encode_table{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', '+', '/'};

std::array<std::uint8_t, 256> constexpr decode_table{0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x3E, 0x64, 0x64,
0x64, 0x3F, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x1A, 0x1B, 0x1C,
0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
0x2F, 0x30, 0x31, 0x32, 0x33, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64};

std::array<char, 4> encode_tripplet(std::uint8_t a, std::uint8_t b, std::uint8_t c)
{
std::uint32_t const concat_bits = (a << 16) | (b << 8) | c;
std::uint32_t const concat_bits = (a << 16) | (b << 8) | c;

auto const b64_char1 = encode_table[(concat_bits >> 18) & 0b0011'1111];
auto const b64_char2 = encode_table[(concat_bits >> 12) & 0b0011'1111];
auto const b64_char3 = encode_table[(concat_bits >> 6) & 0b0011'1111];
auto const b64_char4 = encode_table[concat_bits & 0b0011'1111];
return {b64_char1, b64_char2, b64_char3, b64_char4};
}
auto const b64_char1 = encode_table[(concat_bits >> 18) & 0b0011'1111];
auto const b64_char2 = encode_table[(concat_bits >> 12) & 0b0011'1111];
auto const b64_char3 = encode_table[(concat_bits >> 6) & 0b0011'1111];
auto const b64_char4 = encode_table[concat_bits & 0b0011'1111];
return {b64_char1, b64_char2, b64_char3, b64_char4};
}

inline bool is_valid_base64_char(char c)
inline bool is_valid_base64_char(char c)
{
auto const decode_byte = decode_table[c];
return decode_byte != 0x64;
}

inline bool is_valid_base64_str(std::string_view const encoded_str)
{
if ((encoded_str.size() % 4) == 1)
{
auto const decode_byte = decode_table[c];
return decode_byte != 0x64;
return false;
}

inline bool is_valid_base64_str(std::string_view const encoded_str)
if (!std::all_of(begin(encoded_str), end(encoded_str) - 2, [](char c) { return is_valid_base64_char(c); }))
{
if ((encoded_str.size() % 4) == 1)
{
return false;
}

if (!std::all_of(begin(encoded_str), end(encoded_str) - 2, [](char c) { return is_valid_base64_char(c); }))
{
return false;
}

auto const last = rbegin(encoded_str);
if (!is_valid_base64_char(*next(last)))
{
return (*next(last) == '=') && (*last == '=');
}

return is_valid_base64_char(*last) || (*last == '=');
return false;
}

std::array<std::uint8_t, 3> decode_quad(char a, char b, char c, char d)
auto const last = rbegin(encoded_str);
if (!is_valid_base64_char(*next(last)))
{
std::uint32_t const concat_bytes =
(decode_table[a] << 18) | (decode_table[b] << 12) | (decode_table[c] << 6) | decode_table[d];

std::uint8_t const byte1 = (concat_bytes >> 16) & 0b1111'1111;
std::uint8_t const byte2 = (concat_bytes >> 8) & 0b1111'1111;
std::uint8_t const byte3 = concat_bytes & 0b1111'1111;
return {byte1, byte2, byte3};
return (*next(last) == '=') && (*last == '=');
}
} // namespace

std::string base64pp::encode(std::span<std::uint8_t const> input)
return is_valid_base64_char(*last) || (*last == '=');
}

std::array<std::uint8_t, 3> decode_quad(char a, char b, char c, char d)
{
std::uint32_t const concat_bytes =
(decode_table[a] << 18) | (decode_table[b] << 12) | (decode_table[c] << 6) | decode_table[d];

std::uint8_t const byte1 = (concat_bytes >> 16) & 0b1111'1111;
std::uint8_t const byte2 = (concat_bytes >> 8) & 0b1111'1111;
std::uint8_t const byte3 = concat_bytes & 0b1111'1111;
return {byte1, byte2, byte3};
}

//! @brief This function will encode a blob of data into a base64
//! string.
//! @param input - a span pointing to a binary blob to encode.
//! @return a base64 string containing the encoded data.
export std::string encode(std::span<std::uint8_t const> input)
{
auto const size = input.size();
auto const full_tripples = size / 3;
Expand Down Expand Up @@ -120,12 +123,23 @@ std::string base64pp::encode(std::span<std::uint8_t const> input)
return output;
}

std::string base64pp::encode_str(std::string_view input)
//! @brief Overload of the encode function for string_view. This converts
//! the string input to a span and calls the conventional `encode`.
//! @param input - a string_view to be encoded into base64.
//! @return a base64 string containing the encoded string.
export std::string encode_str(std::string_view input)
{
return encode({reinterpret_cast<std::uint8_t const*>(input.data()), input.size()});
}

std::optional<std::vector<std::uint8_t>> base64pp::decode(std::string_view encoded_str)
//! @brief Decodes a base64 encoded string, returning an optional
//! blob. If the decoding fails, it returns std::nullopt
//! @param encoded_str - the base64 encoded string
//! @return an optional containing a valid blob of data, if
//! decoding was successful. Otherwise, returns std::nullopt
//! @note this function accepts unpadded strings, if they are valid
//! otherwise. It rejects odd-sized unpadded strings.
export std::optional<std::vector<std::uint8_t>> decode(std::string_view encoded_str)
{
if (encoded_str.size() == 0)
{
Expand Down
41 changes: 0 additions & 41 deletions base64pp/include/base64pp/base64pp.h

This file was deleted.

67 changes: 0 additions & 67 deletions conan/conanfile.py

This file was deleted.

Loading

0 comments on commit a4dc119

Please sign in to comment.