void AppendPrettyDescriptor(constchar* descriptor, std::string* result) { // Count the number of '['s to get the dimensionality. constchar* c = descriptor;
size_t dim = 0; while (*c == '[') {
dim++;
c++;
}
// Reference or primitive? if (*c == 'L') { // "[[La/b/C;" -> "a.b.C[][]".
std::string_view stripped = std::string_view(c + 1); // Skip the 'L'... if (stripped.ends_with(';')) {
stripped.remove_suffix(1u); // ...and remove the semicolon.
} // At this point, `stripped` is of the form "fully/qualified/Type". // Append it to the `*result` and replace all '/'s with '.' in place.
size_t old_size = result->size();
*result += stripped;
std::replace(result->begin() + old_size, result->end(), '/', '.');
} else { // "[[B" -> "byte[][]".
std::string_view pretty_primitive; switch (*c) { case'B':
pretty_primitive = "byte"; break; case'C':
pretty_primitive = "char"; break; case'D':
pretty_primitive = "double"; break; case'F':
pretty_primitive = "float"; break; case'I':
pretty_primitive = "int"; break; case'J':
pretty_primitive = "long"; break; case'S':
pretty_primitive = "short"; break; case'Z':
pretty_primitive = "boolean"; break; case'V':
pretty_primitive = "void"; break; // Used when decoding return types. default: result->append(descriptor); return;
}
result->append(pretty_primitive);
}
// Finally, add 'dim' "[]" pairs: for (size_t i = 0; i < dim; ++i) {
result->append("[]");
}
}
// Helper for IsValidPartOfMemberNameUtf8(); do not call directly.
COLD_ATTR staticbool IsValidPartOfMemberNameUtf8Slow(constchar** pUtf8Ptr) { /* *It'samultibyteencodedcharacter.Decodeitandanalyze.We *acceptanythingthatisn't: *-animproperlyencodedlowvalue *-animpropersurrogatepair *-anencoded'\0' *-aC1controlcharacterU+0080..U+009f *-aformatcharacterU+200b..U+200f,U+2028..U+202e *-aspecialcharacterU+fff0..U+ffff *PriortoDEXformatversion040,wealsoexcludedsomeoftheUnicode *spacecharacters: *-U+00a0,U+2000..U+200a,U+202f *Thisisallspecifiedinthedexformatdocument.
*/
const uint32_t pair = GetUtf16FromUtf8(pUtf8Ptr); const uint16_t leading = GetLeadingUtf16Char(pair);
// We have a surrogate pair resulting from a valid 4 byte UTF sequence. // No further checks are necessary because 4 byte sequences span code // points [U+10000, U+1FFFFF], which are valid codepoints in a dex // identifier. Furthermore, GetUtf16FromUtf8 guarantees that each of // the surrogate halves are valid and well formed in this instance. if (GetTrailingUtf16Char(pair) != 0) { returntrue;
}
// We've encountered a one, two or three byte UTF-8 sequence. The // three byte UTF-8 sequence could be one half of a surrogate pair. switch (leading >> 8) { case0x00: // It's in the range that has C1 control characters. return (leading >= 0x00a0); case0xd8: case0xd9: case0xda: case0xdb:
{ // We found a three byte sequence encoding one half of a surrogate. // Look for the other half. const uint32_t pair2 = GetUtf16FromUtf8(pUtf8Ptr); const uint16_t trailing = GetLeadingUtf16Char(pair2);
return (GetTrailingUtf16Char(pair2) == 0) && (0xdc00 <= trailing && trailing <= 0xdfff);
} case0xdc: case0xdd: case0xde: case0xdf: // It's a trailing surrogate, which is not valid at this point. returnfalse; case0x20: case0xff: // It's in the range that has format characters and specials. switch (leading & 0xfff8) { case0x2008: return (leading <= 0x200a); case0x2028: return (leading == 0x202f); case0xfff0: case0xfff8: returnfalse;
} returntrue; default: returntrue;
}
}
/* Return whether the pointed-at modified-UTF-8 encoded character is *validaspartofamembername,updatingthepointertopointpast *theconsumedcharacter.ThiswillconsumetwoencodedUTF-16code *pointsifthecharacterisencodedasasurrogatepair.Also,if *thisfunctionreturnsfalse,thenthegivenpointermayonlyhave *beenpartiallyadvanced.
*/
ALWAYS_INLINE staticbool IsValidPartOfMemberNameUtf8(constchar** pUtf8Ptr) {
uint8_t c = (uint8_t) **pUtf8Ptr; if (LIKELY(c <= 0x7f)) { // It's low-ascii, so check the table.
uint32_t wordIdx = c >> 5;
uint32_t bitIdx = c & 0x1f;
(*pUtf8Ptr)++; return (DEX_MEMBER_VALID_LOW_ASCII[wordIdx] & (1 << bitIdx)) != 0;
}
// It's a multibyte encoded character. Call a non-inline function // for the heavy lifting. return IsValidPartOfMemberNameUtf8Slow(pUtf8Ptr);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.