Skip to content

Commit 3e36069

Browse files
authored
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.
1 parent 256cc8a commit 3e36069

File tree

5 files changed

+8
-199
lines changed

5 files changed

+8
-199
lines changed

aas_core_codegen/cpp/stringification/_generate.py

+4
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,10 @@ def _generate_base64_decode_implementation() -> List[Stripped]:
638638
> {function_name}(
639639
{I}const std::string& text
640640
) {{
641+
{I}if (text.empty()) {{
642+
{II}return std::vector<std::uint8_t>();
643+
{I}}}
644+
641645
{I}const std::size_t len = text.size();
642646
{I}std::size_t len_wo_pad = len;
643647

aas_core_codegen/cpp/wstringification/_generate.py

-114
Original file line numberDiff line numberDiff line change
@@ -457,118 +457,6 @@ def _generate_enum_to_wstring_implementation(
457457
)
458458

459459

460-
def _generate_base64_encode_definition() -> Stripped:
461-
"""Generate the definition of a stringification of bytes as base64 wstring."""
462-
function_name = cpp_naming.function_name(Identifier("base64_encode"))
463-
return Stripped(
464-
f"""\
465-
/**
466-
* Encode the \\p bytes with base64 to a std::wstring.
467-
*
468-
* \\param bytes to be encoded
469-
* \\return base64-encoding of \\p bytes
470-
*/
471-
std::wstring {function_name}(
472-
{I}const std::vector<std::uint8_t>& bytes
473-
);"""
474-
)
475-
476-
477-
def _generate_base64_encode_implementation() -> List[Stripped]:
478-
"""Generate the implementation of a stringification of bytes as base64 wstring."""
479-
function_name = cpp_naming.function_name(Identifier("base64_encode"))
480-
481-
wchar_base64_table = cpp_naming.constant_name(Identifier("wchar_base64_table"))
482-
483-
return [
484-
Stripped(
485-
"""\
486-
// The following encoder has been adapted from Jouni Malinen <j@w1.fi> to work with
487-
// std::wstring. The original source code is available at:
488-
// https://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c"""
489-
),
490-
Stripped(
491-
f"""\
492-
static const wchar_t {wchar_base64_table}[65](
493-
{I}L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
494-
);"""
495-
),
496-
Stripped(
497-
f"""\
498-
std::wstring {function_name}(
499-
{I}const std::vector<std::uint8_t>& bytes
500-
) {{
501-
{I}// See: https://cplusplus.com/reference/vector/vector/data/.
502-
{I}// The data is guaranteed to be a continuous block in memory.
503-
{I}const unsigned char* src(
504-
{II}bytes.data()
505-
{I});
506-
507-
{I}const std::size_t len = bytes.size();
508-
509-
{I}// 3-byte blocks to 4-byte
510-
{I}const std::size_t olen = 4 * ((len + 2) / 3);
511-
512-
{I}// Integer overflow?
513-
{I}if (olen < len) {{
514-
{II}throw std::invalid_argument(
515-
{III}common::Concat(
516-
{IIII}"The calculation of the output length overflowed. "
517-
{IIII}"The length was: ",
518-
{IIII}std::to_string(len),
519-
{IIII}", but the output length was calculated as: ",
520-
{IIII}std::to_string(olen)
521-
{III})
522-
{II});
523-
{I}}}
524-
525-
{I}std::wstring out_wstring;
526-
{I}out_wstring.resize(olen);
527-
528-
{I}wchar_t* out(
529-
{II}static_cast<wchar_t*>(
530-
{III}&out_wstring[0]
531-
{II})
532-
{I});
533-
534-
{I}const unsigned char* end = src + len;
535-
536-
{I}const unsigned char* in = src;
537-
{I}wchar_t* pos = out;
538-
539-
{I}while (end - in >= 3) {{
540-
{II}*pos++ = {wchar_base64_table}[in[0] >> 2];
541-
{II}*pos++ = {wchar_base64_table}[((in[0] & 0x03) << 4) | (in[1] >> 4)];
542-
{II}*pos++ = {wchar_base64_table}[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
543-
{II}*pos++ = {wchar_base64_table}[in[2] & 0x3f];
544-
{II}in += 3;
545-
{I}}}
546-
547-
{I}if (end - in) {{
548-
{II}*pos++ = {wchar_base64_table}[in[0] >> 2];
549-
550-
{II}if (end - in == 1) {{
551-
{III}*pos++ = {wchar_base64_table}[(in[0] & 0x03) << 4];
552-
{III}*pos++ = L'=';
553-
{II}}} else {{
554-
{III}*pos++ = {wchar_base64_table}[
555-
{IIII}((in[0] & 0x03) << 4) | (in[1] >> 4)
556-
{III}];
557-
{III}*pos++ = {wchar_base64_table}[(in[1] & 0x0f) << 2];
558-
{II}}}
559-
{II}*pos++ = L'=';
560-
{I}}}
561-
562-
{I}return out_wstring;
563-
}}"""
564-
),
565-
]
566-
567-
568-
# NOTE (mristin, 2023-07-12):
569-
# The SDK does not use base64-decoding *from* wide strings, so we omit that direction
570-
# here following YAGNI.
571-
572460
# fmt: off
573461
@ensure(
574462
lambda result:
@@ -622,7 +510,6 @@ def generate_header(
622510

623511
blocks.extend(
624512
[
625-
_generate_base64_encode_definition(),
626513
Stripped(
627514
"""\
628515
} // namespace wstringification
@@ -682,7 +569,6 @@ def generate_implementation(
682569

683570
blocks.extend(
684571
[
685-
*_generate_base64_encode_implementation(),
686572
cpp_common.generate_namespace_closing(namespace),
687573
cpp_common.WARNING,
688574
]

test_data/cpp/test_main/aas_core_meta.v3/expected_output/stringification.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1610,6 +1610,10 @@ common::expected<
16101610
> Base64Decode(
16111611
const std::string& text
16121612
) {
1613+
if (text.empty()) {
1614+
return std::vector<std::uint8_t>();
1615+
}
1616+
16131617
const std::size_t len = text.size();
16141618
std::size_t len_wo_pad = len;
16151619

test_data/cpp/test_main/aas_core_meta.v3/expected_output/wstringification.cpp

-75
Original file line numberDiff line numberDiff line change
@@ -1511,81 +1511,6 @@ std::wstring to_wstring(
15111511
}
15121512
}
15131513

1514-
// The following encoder has been adapted from Jouni Malinen <j@w1.fi> to work with
1515-
// std::wstring. The original source code is available at:
1516-
// https://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c
1517-
1518-
static const wchar_t kWcharBase64Table[65](
1519-
L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
1520-
);
1521-
1522-
std::wstring Base64Encode(
1523-
const std::vector<std::uint8_t>& bytes
1524-
) {
1525-
// See: https://cplusplus.com/reference/vector/vector/data/.
1526-
// The data is guaranteed to be a continuous block in memory.
1527-
const unsigned char* src(
1528-
bytes.data()
1529-
);
1530-
1531-
const std::size_t len = bytes.size();
1532-
1533-
// 3-byte blocks to 4-byte
1534-
const std::size_t olen = 4 * ((len + 2) / 3);
1535-
1536-
// Integer overflow?
1537-
if (olen < len) {
1538-
throw std::invalid_argument(
1539-
common::Concat(
1540-
"The calculation of the output length overflowed. "
1541-
"The length was: ",
1542-
std::to_string(len),
1543-
", but the output length was calculated as: ",
1544-
std::to_string(olen)
1545-
)
1546-
);
1547-
}
1548-
1549-
std::wstring out_wstring;
1550-
out_wstring.resize(olen);
1551-
1552-
wchar_t* out(
1553-
static_cast<wchar_t*>(
1554-
&out_wstring[0]
1555-
)
1556-
);
1557-
1558-
const unsigned char* end = src + len;
1559-
1560-
const unsigned char* in = src;
1561-
wchar_t* pos = out;
1562-
1563-
while (end - in >= 3) {
1564-
*pos++ = kWcharBase64Table[in[0] >> 2];
1565-
*pos++ = kWcharBase64Table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
1566-
*pos++ = kWcharBase64Table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
1567-
*pos++ = kWcharBase64Table[in[2] & 0x3f];
1568-
in += 3;
1569-
}
1570-
1571-
if (end - in) {
1572-
*pos++ = kWcharBase64Table[in[0] >> 2];
1573-
1574-
if (end - in == 1) {
1575-
*pos++ = kWcharBase64Table[(in[0] & 0x03) << 4];
1576-
*pos++ = L'=';
1577-
} else {
1578-
*pos++ = kWcharBase64Table[
1579-
((in[0] & 0x03) << 4) | (in[1] >> 4)
1580-
];
1581-
*pos++ = kWcharBase64Table[(in[1] & 0x0f) << 2];
1582-
}
1583-
*pos++ = L'=';
1584-
}
1585-
1586-
return out_wstring;
1587-
}
1588-
15891514
} // namespace wstringification
15901515
} // namespace aas_3_0
15911516
} // namespace aas_core

test_data/cpp/test_main/aas_core_meta.v3/expected_output/wstringification.hpp

-10
Original file line numberDiff line numberDiff line change
@@ -438,16 +438,6 @@ std::wstring to_wstring(
438438
types::DataTypeIec61360 literal
439439
);
440440

441-
/**
442-
* Encode the \p bytes with base64 to a std::wstring.
443-
*
444-
* \param bytes to be encoded
445-
* \return base64-encoding of \p bytes
446-
*/
447-
std::wstring Base64Encode(
448-
const std::vector<std::uint8_t>& bytes
449-
);
450-
451441
} // namespace wstringification
452442
/**@}*/
453443

0 commit comments

Comments
 (0)