Skip to content

Commit

Permalink
Add String::ascii creator functions, to parse a char buffer as ASCII.
Browse files Browse the repository at this point in the history
The function will log errors if any characters above value 127 are found.
  • Loading branch information
Ivorforce committed Jan 9, 2025
1 parent edb8339 commit 5022418
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
6 changes: 4 additions & 2 deletions core/io/plist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,14 +383,16 @@ void PListNode::store_text(String &p_stream, uint8_t p_indent) const {
p_stream += String("\t").repeat(p_indent);
p_stream += "<data>\n";
p_stream += String("\t").repeat(p_indent);
p_stream += String(data_string.get_data()) + "\n";
// Data should be Base64 (i.e. ASCII only).
p_stream += String::ascii(data_string) + "\n";
p_stream += String("\t").repeat(p_indent);
p_stream += "</data>\n";
} break;
case PList::PLNodeType::PL_NODE_TYPE_DATE: {
p_stream += String("\t").repeat(p_indent);
p_stream += "<date>";
p_stream += String(data_string.get_data());
// Data should be ISO 8601 (i.e. ASCII only).
p_stream += String::ascii(data_string);
p_stream += "</date>\n";
} break;
case PList::PLNodeType::PL_NODE_TYPE_STRING: {
Expand Down
28 changes: 28 additions & 0 deletions core/string/ustring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,34 @@ CharString String::ascii(bool p_allow_extended) const {
return cs;
}

Error String::parse_ascii(const StrRange<char> &p_range) {
if (p_range.len == 0) {
resize(0);
return OK;
}

resize(p_range.len + 1); // Include \0

const char *src = p_range.c_str;
const char *end = src + p_range.len;
char32_t *dst = ptrw();
bool decode_failed = false;

for (; src < end; ++src, ++dst) {
// If char is int8_t, a set sign bit will be reinterpreted as 256 - val implicitly.
const uint8_t chr = *src;
if (chr > 127) {
print_unicode_error(vformat("Invalid ASCII codepoint (%x)", (uint32_t)chr), true);
decode_failed = true;
*dst = _replacement_char;
} else {
*dst = chr;
}
}
*dst = _null;
return decode_failed ? ERR_INVALID_DATA : OK;
}

String String::utf8(const char *p_utf8, int p_len) {
String ret;
ret.parse_utf8(p_utf8, p_len);
Expand Down
9 changes: 9 additions & 0 deletions core/string/ustring.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,15 @@ class String {
char32_t unicode_at(int p_idx) const;

CharString ascii(bool p_allow_extended = false) const;
// Parse an ascii string.
// If any character is > 127, an error will be logged, and 0xfffd will be inserted.
Error parse_ascii(const StrRange<char> &p_range);
static String ascii(const StrRange<char> &p_range) {
String s;
s.parse_ascii(p_range);
return s;
}

CharString utf8() const;
Error parse_utf8(const char *p_utf8, int p_len = -1, bool p_skip_cr = false);
Error parse_utf8(const StrRange<char> p_range, bool p_skip_cr = false) {
Expand Down

0 comments on commit 5022418

Please sign in to comment.