This commit is contained in:
Scott Lahteine 2020-11-12 22:24:26 -06:00 committed by GitHub
parent 6eee9bbaa9
commit 8008c6c897
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1109,8 +1109,8 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) {
// We can't reconvert to UTF-8 here as UTF-8 is variable-size encoding, but joining LFN blocks // We can't reconvert to UTF-8 here as UTF-8 is variable-size encoding, but joining LFN blocks
// needs static bytes addressing. So here just store full UTF-16LE words to re-convert later. // needs static bytes addressing. So here just store full UTF-16LE words to re-convert later.
uint16_t idx = (n + i) * 2; // This is fixed as FAT LFN always contain UTF-16LE encoding uint16_t idx = (n + i) * 2; // This is fixed as FAT LFN always contain UTF-16LE encoding
longFilename[idx] = utf16_ch & 0xFF; longFilename[idx] = utf16_ch & 0xFF;
longFilename[idx+1] = (utf16_ch >> 8) & 0xFF; longFilename[idx + 1] = (utf16_ch >> 8) & 0xFF;
#else #else
// Replace all multibyte characters to '_' // Replace all multibyte characters to '_'
longFilename[n + i] = (utf16_ch > 0xFF) ? '_' : (utf16_ch & 0xFF); longFilename[n + i] = (utf16_ch > 0xFF) ? '_' : (utf16_ch & 0xFF);
@ -1122,10 +1122,9 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) {
} }
} }
#if ENABLED(UTF_FILENAME_SUPPORT) // Post-process normal file or subdirectory longname, if any
// Return if normal file or subdirectory if (DIR_IS_FILE_OR_SUBDIR(dir)) {
if (DIR_IS_FILE_OR_SUBDIR(dir)) { #if ENABLED(UTF_FILENAME_SUPPORT)
// Convert filename from utf-16 to utf-8 as Marlin expects
#if LONG_FILENAME_CHARSIZE > 2 #if LONG_FILENAME_CHARSIZE > 2
// Add warning for developers for currently not supported 3-byte cases (Conversion series of 2-byte // Add warning for developers for currently not supported 3-byte cases (Conversion series of 2-byte
// codepoints to 3-byte in-place will break the rest of filename) // codepoints to 3-byte in-place will break the rest of filename)
@ -1133,34 +1132,34 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) {
#endif #endif
// Is there a long filename to decode? // Is there a long filename to decode?
if (!longFilename) return n; // sizeof(dir_t) if (longFilename) {
// Reset n to the start of the long name
// Reset n to the start of the long name n = 0;
n = 0; for (uint16_t idx = 0; idx < (LONG_FILENAME_LENGTH) / 2; idx += 2) { // idx is fixed since FAT LFN always contains UTF-16LE encoding
for (uint16_t idx = 0; idx < (LONG_FILENAME_LENGTH) / 2; idx += 2) { // idx is fixed since FAT LFN always contains UTF-16LE encoding uint16_t utf16_ch = longFilename[idx] | (longFilename[idx + 1] << 8);
uint16_t utf16_ch = longFilename[idx] | (longFilename[idx + 1] << 8); if (0xD800 == (utf16_ch & 0xF800)) // Surrogate pair - encode as '_'
if (0xD800 == (utf16_ch & 0xF800)) // Surrogate pair - encode as '_'
longFilename[n++] = '_';
else if (0 == (utf16_ch & 0xFF80)) // Encode as 1-byte UTF-8 char
longFilename[n++] = utf16_ch & 0x007F;
else if (0 == (utf16_ch & 0xF800)) { // Encode as 2-byte UTF-8 char
longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x1F);
longFilename[n++] = 0x80 | ( utf16_ch & 0x3F);
}
else {
#if LONG_FILENAME_CHARSIZE > 2 // Encode as 3-byte UTF-8 char
longFilename[n++] = 0xE0 | ((utf16_ch >> 12) & 0x0F);
longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x3F);
longFilename[n++] = 0xC0 | ( utf16_ch & 0x3F);
#else // Encode as '_'
longFilename[n++] = '_'; longFilename[n++] = '_';
#endif else if (0 == (utf16_ch & 0xFF80)) // Encode as 1-byte UTF-8 char
} longFilename[n++] = utf16_ch & 0x007F;
if (0 == utf16_ch) break; // End of filename else if (0 == (utf16_ch & 0xF800)) { // Encode as 2-byte UTF-8 char
} longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x1F);
return n; longFilename[n++] = 0x80 | ( utf16_ch & 0x3F);
} }
#endif else {
#if LONG_FILENAME_CHARSIZE > 2 // Encode as 3-byte UTF-8 char
longFilename[n++] = 0xE0 | ((utf16_ch >> 12) & 0x0F);
longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x3F);
longFilename[n++] = 0xC0 | ( utf16_ch & 0x3F);
#else // Encode as '_'
longFilename[n++] = '_';
#endif
}
if (0 == utf16_ch) break; // End of filename
} // idx
} // longFilename
#endif
return n;
} // DIR_IS_FILE_OR_SUBDIR
} }
} }