From 7649e5d58fc1ecef42d77e68ea2b482cff48d5b7 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 22 Sep 2024 15:10:54 +0200 Subject: [PATCH] chore: generalize base64 usage --- src/Crypto/Impl/Base64.cpp | 49 +++++++++++++++++++ src/Crypto/Impl/Base64.h | 12 +++++ .../XModel/Gltf/Internal/GltfBuffer.cpp | 15 ++---- src/ObjWriting/XModel/Gltf/GltfTextOutput.cpp | 11 ++--- 4 files changed, 71 insertions(+), 16 deletions(-) create mode 100644 src/Crypto/Impl/Base64.cpp create mode 100644 src/Crypto/Impl/Base64.h diff --git a/src/Crypto/Impl/Base64.cpp b/src/Crypto/Impl/Base64.cpp new file mode 100644 index 00000000..f4400d6a --- /dev/null +++ b/src/Crypto/Impl/Base64.cpp @@ -0,0 +1,49 @@ +#include "Base64.h" + +#define LTC_NO_PROTOTYPES +#include + +namespace base64 +{ + std::string EncodeBase64(const void* inputData, const size_t inputLength) + { + const auto base64BufferSize = GetBase64EncodeOutputLength(inputLength); + + std::string output(base64BufferSize, '\0'); + const auto outLength = base64BufferSize + 1u; + + const auto result = EncodeBase64(inputData, inputLength, output.data(), outLength); + assert(result); + + return output; + } + + bool EncodeBase64(const void* inputData, const size_t inputLength, void* outputBuffer, const size_t outputBufferSize) + { + unsigned long outLength = outputBufferSize; + const auto result = base64_encode(static_cast(inputData), inputLength, static_cast(outputBuffer), &outLength); + return result == CRYPT_OK; + } + + size_t GetBase64EncodeOutputLength(const size_t inputLength) + { + return 4u * ((inputLength + 2u) / 3u); + } + + size_t DecodeBase64(const void* base64Data, const size_t inputLength, void* outputBuffer, const size_t outputBufferSize) + { + unsigned long outLength = GetBase64DecodeOutputLength(inputLength); + if (outLength > outputBufferSize) + return 0u; + + const auto result = base64_decode(static_cast(base64Data), inputLength, static_cast(outputBuffer), &outLength); + assert(result == CRYPT_OK); + + return static_cast(outLength); + } + + size_t GetBase64DecodeOutputLength(const size_t inputLength) + { + return inputLength / 4u; + } +} // namespace base64 diff --git a/src/Crypto/Impl/Base64.h b/src/Crypto/Impl/Base64.h new file mode 100644 index 00000000..1e1ec51d --- /dev/null +++ b/src/Crypto/Impl/Base64.h @@ -0,0 +1,12 @@ +#pragma once +#include + +namespace base64 +{ + std::string EncodeBase64(const void* inputData, size_t inputLength); + bool EncodeBase64(const void* inputData, size_t inputLength, void* outputBuffer, size_t outputBufferSize); + size_t GetBase64EncodeOutputLength(size_t inputLength); + + size_t DecodeBase64(const void* base64Data, size_t inputLength, void* outputBuffer, size_t outputBufferSize); + size_t GetBase64DecodeOutputLength(size_t inputLength); +} // namespace base64 diff --git a/src/ObjLoading/XModel/Gltf/Internal/GltfBuffer.cpp b/src/ObjLoading/XModel/Gltf/Internal/GltfBuffer.cpp index 95ec99a1..a0edf7f0 100644 --- a/src/ObjLoading/XModel/Gltf/Internal/GltfBuffer.cpp +++ b/src/ObjLoading/XModel/Gltf/Internal/GltfBuffer.cpp @@ -1,14 +1,12 @@ #include "GltfBuffer.h" +#include "Impl/Base64.h" #include "XModel/Gltf/GltfConstants.h" #include #include #include -#define LTC_NO_PROTOTYPES -#include - using namespace gltf; EmbeddedBuffer::EmbeddedBuffer(const void* data, const size_t dataSize) @@ -51,15 +49,12 @@ bool DataUriBuffer::ReadDataFromUri(const std::string& uri) return false; const auto base64DataLength = uri.size() - URI_PREFIX_LENGTH; + m_data_size = base64::GetBase64DecodeOutputLength(base64DataLength); + m_data = std::make_unique(m_data_size); - unsigned long outLength = base64DataLength / 4u; - m_data = std::make_unique(outLength); - const auto result = base64_decode(&uri[URI_PREFIX_LENGTH], base64DataLength, m_data.get(), &outLength); - m_data_size = static_cast(outLength); + m_data_size = base64::DecodeBase64(&uri[URI_PREFIX_LENGTH], base64DataLength, m_data.get(), m_data_size); - assert(result == CRYPT_OK); - - return false; + return m_data_size > 0; } bool DataUriBuffer::ReadData(void* dest, const size_t offset, const size_t count) const diff --git a/src/ObjWriting/XModel/Gltf/GltfTextOutput.cpp b/src/ObjWriting/XModel/Gltf/GltfTextOutput.cpp index effb524a..49afebd6 100644 --- a/src/ObjWriting/XModel/Gltf/GltfTextOutput.cpp +++ b/src/ObjWriting/XModel/Gltf/GltfTextOutput.cpp @@ -6,6 +6,8 @@ #include #define LTC_NO_PROTOTYPES +#include "Impl/Base64.h" + #include using namespace gltf; @@ -17,18 +19,15 @@ TextOutput::TextOutput(std::ostream& stream) std::optional TextOutput::CreateBufferUri(const void* buffer, const size_t bufferSize) const { - const auto base64Length = 4u * ((bufferSize + 2u) / 3u); + const auto base64Length = base64::GetBase64EncodeOutputLength(bufferSize); const auto base64BufferSize = URI_PREFIX_LENGTH + base64Length; std::string output(base64BufferSize, '\0'); std::memcpy(output.data(), GLTF_DATA_URI_PREFIX, URI_PREFIX_LENGTH); - unsigned long outLength = base64Length + 1u; - const auto result = base64_encode(static_cast(buffer), bufferSize, &output[URI_PREFIX_LENGTH], &outLength); - - assert(result == CRYPT_OK); - assert(outLength == base64Length); + auto result = base64::EncodeBase64(buffer, bufferSize, &output[URI_PREFIX_LENGTH], base64Length + 1u); + assert(result); return output; }