-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix C++ generator to pass Base64 tests (#442)
This patch includes all the changes needed so that we pass the Base64 tests in the SDK.
- Loading branch information
Showing
5 changed files
with
8 additions
and
199 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -457,118 +457,6 @@ def _generate_enum_to_wstring_implementation( | |
) | ||
|
||
|
||
def _generate_base64_encode_definition() -> Stripped: | ||
"""Generate the definition of a stringification of bytes as base64 wstring.""" | ||
function_name = cpp_naming.function_name(Identifier("base64_encode")) | ||
return Stripped( | ||
f"""\ | ||
/** | ||
* Encode the \\p bytes with base64 to a std::wstring. | ||
* | ||
* \\param bytes to be encoded | ||
* \\return base64-encoding of \\p bytes | ||
*/ | ||
std::wstring {function_name}( | ||
{I}const std::vector<std::uint8_t>& bytes | ||
);""" | ||
) | ||
|
||
|
||
def _generate_base64_encode_implementation() -> List[Stripped]: | ||
"""Generate the implementation of a stringification of bytes as base64 wstring.""" | ||
function_name = cpp_naming.function_name(Identifier("base64_encode")) | ||
|
||
wchar_base64_table = cpp_naming.constant_name(Identifier("wchar_base64_table")) | ||
|
||
return [ | ||
Stripped( | ||
"""\ | ||
// The following encoder has been adapted from Jouni Malinen <[email protected]> to work with | ||
// std::wstring. The original source code is available at: | ||
// https://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c""" | ||
), | ||
Stripped( | ||
f"""\ | ||
static const wchar_t {wchar_base64_table}[65]( | ||
{I}L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" | ||
);""" | ||
), | ||
Stripped( | ||
f"""\ | ||
std::wstring {function_name}( | ||
{I}const std::vector<std::uint8_t>& bytes | ||
) {{ | ||
{I}// See: https://cplusplus.com/reference/vector/vector/data/. | ||
{I}// The data is guaranteed to be a continuous block in memory. | ||
{I}const unsigned char* src( | ||
{II}bytes.data() | ||
{I}); | ||
{I}const std::size_t len = bytes.size(); | ||
{I}// 3-byte blocks to 4-byte | ||
{I}const std::size_t olen = 4 * ((len + 2) / 3); | ||
{I}// Integer overflow? | ||
{I}if (olen < len) {{ | ||
{II}throw std::invalid_argument( | ||
{III}common::Concat( | ||
{IIII}"The calculation of the output length overflowed. " | ||
{IIII}"The length was: ", | ||
{IIII}std::to_string(len), | ||
{IIII}", but the output length was calculated as: ", | ||
{IIII}std::to_string(olen) | ||
{III}) | ||
{II}); | ||
{I}}} | ||
{I}std::wstring out_wstring; | ||
{I}out_wstring.resize(olen); | ||
{I}wchar_t* out( | ||
{II}static_cast<wchar_t*>( | ||
{III}&out_wstring[0] | ||
{II}) | ||
{I}); | ||
{I}const unsigned char* end = src + len; | ||
{I}const unsigned char* in = src; | ||
{I}wchar_t* pos = out; | ||
{I}while (end - in >= 3) {{ | ||
{II}*pos++ = {wchar_base64_table}[in[0] >> 2]; | ||
{II}*pos++ = {wchar_base64_table}[((in[0] & 0x03) << 4) | (in[1] >> 4)]; | ||
{II}*pos++ = {wchar_base64_table}[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; | ||
{II}*pos++ = {wchar_base64_table}[in[2] & 0x3f]; | ||
{II}in += 3; | ||
{I}}} | ||
{I}if (end - in) {{ | ||
{II}*pos++ = {wchar_base64_table}[in[0] >> 2]; | ||
{II}if (end - in == 1) {{ | ||
{III}*pos++ = {wchar_base64_table}[(in[0] & 0x03) << 4]; | ||
{III}*pos++ = L'='; | ||
{II}}} else {{ | ||
{III}*pos++ = {wchar_base64_table}[ | ||
{IIII}((in[0] & 0x03) << 4) | (in[1] >> 4) | ||
{III}]; | ||
{III}*pos++ = {wchar_base64_table}[(in[1] & 0x0f) << 2]; | ||
{II}}} | ||
{II}*pos++ = L'='; | ||
{I}}} | ||
{I}return out_wstring; | ||
}}""" | ||
), | ||
] | ||
|
||
|
||
# NOTE (mristin, 2023-07-12): | ||
# The SDK does not use base64-decoding *from* wide strings, so we omit that direction | ||
# here following YAGNI. | ||
|
||
# fmt: off | ||
@ensure( | ||
lambda result: | ||
|
@@ -622,7 +510,6 @@ def generate_header( | |
|
||
blocks.extend( | ||
[ | ||
_generate_base64_encode_definition(), | ||
Stripped( | ||
"""\ | ||
} // namespace wstringification | ||
|
@@ -682,7 +569,6 @@ def generate_implementation( | |
|
||
blocks.extend( | ||
[ | ||
*_generate_base64_encode_implementation(), | ||
cpp_common.generate_namespace_closing(namespace), | ||
cpp_common.WARNING, | ||
] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1511,81 +1511,6 @@ std::wstring to_wstring( | |
} | ||
} | ||
|
||
// The following encoder has been adapted from Jouni Malinen <[email protected]> to work with | ||
// std::wstring. The original source code is available at: | ||
// https://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c | ||
|
||
static const wchar_t kWcharBase64Table[65]( | ||
L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" | ||
); | ||
|
||
std::wstring Base64Encode( | ||
const std::vector<std::uint8_t>& bytes | ||
) { | ||
// See: https://cplusplus.com/reference/vector/vector/data/. | ||
// The data is guaranteed to be a continuous block in memory. | ||
const unsigned char* src( | ||
bytes.data() | ||
); | ||
|
||
const std::size_t len = bytes.size(); | ||
|
||
// 3-byte blocks to 4-byte | ||
const std::size_t olen = 4 * ((len + 2) / 3); | ||
|
||
// Integer overflow? | ||
if (olen < len) { | ||
throw std::invalid_argument( | ||
common::Concat( | ||
"The calculation of the output length overflowed. " | ||
"The length was: ", | ||
std::to_string(len), | ||
", but the output length was calculated as: ", | ||
std::to_string(olen) | ||
) | ||
); | ||
} | ||
|
||
std::wstring out_wstring; | ||
out_wstring.resize(olen); | ||
|
||
wchar_t* out( | ||
static_cast<wchar_t*>( | ||
&out_wstring[0] | ||
) | ||
); | ||
|
||
const unsigned char* end = src + len; | ||
|
||
const unsigned char* in = src; | ||
wchar_t* pos = out; | ||
|
||
while (end - in >= 3) { | ||
*pos++ = kWcharBase64Table[in[0] >> 2]; | ||
*pos++ = kWcharBase64Table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; | ||
*pos++ = kWcharBase64Table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; | ||
*pos++ = kWcharBase64Table[in[2] & 0x3f]; | ||
in += 3; | ||
} | ||
|
||
if (end - in) { | ||
*pos++ = kWcharBase64Table[in[0] >> 2]; | ||
|
||
if (end - in == 1) { | ||
*pos++ = kWcharBase64Table[(in[0] & 0x03) << 4]; | ||
*pos++ = L'='; | ||
} else { | ||
*pos++ = kWcharBase64Table[ | ||
((in[0] & 0x03) << 4) | (in[1] >> 4) | ||
]; | ||
*pos++ = kWcharBase64Table[(in[1] & 0x0f) << 2]; | ||
} | ||
*pos++ = L'='; | ||
} | ||
|
||
return out_wstring; | ||
} | ||
|
||
} // namespace wstringification | ||
} // namespace aas_3_0 | ||
} // namespace aas_core | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters