Final touches

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

View file

@ -1122,47 +1122,45 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) {
} }
} }
// Return if normal file or subdirectory #if ENABLED(UTF_FILENAME_SUPPORT)
if (DIR_IS_FILE_OR_SUBDIR(dir)) { // Return if normal file or subdirectory
#if ENABLED(UTF_FILENAME_SUPPORT) if (DIR_IS_FILE_OR_SUBDIR(dir)) {
if (longFilename) { // Convert filename from utf-16 to utf-8 as Marlin expects
// 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) #error "Currently filename re-encoding is done in-place. It may break the remaining chars to use 3-byte codepoints."
#error "Currently filename re-encoding is done in-place. It may break the remaining chars to use 3-byte codepoints." #endif
#endif
uint16_t currentPos = 0;
LOOP_L_N(i, (LONG_FILENAME_LENGTH / 2)) { // Is there a long filename to decode?
uint16_t idx = i * 2; // This is fixed as FAT LFN always contain UTF-16LE encoding if (!longFilename) return n; // sizeof(dir_t)
uint16_t utf16_ch = longFilename[idx] | (longFilename[idx + 1] << 8); // Reset n to the start of the long name
if (0xD800 == (utf16_ch & 0xF800)) // Surrogate pair - encode as '_' n = 0;
longFilename[currentPos++] = '_'; for (uint16_t idx = 0; idx < (LONG_FILENAME_LENGTH) / 2; idx += 2) { // idx is fixed since FAT LFN always contains UTF-16LE encoding
else if (0 == (utf16_ch & 0xFF80)) // Encode as 1-byte utf-8 char uint16_t utf16_ch = longFilename[idx] | (longFilename[idx + 1] << 8);
longFilename[currentPos++] = utf16_ch & 0x007F; if (0xD800 == (utf16_ch & 0xF800)) // Surrogate pair - encode as '_'
else if (0 == (utf16_ch & 0xF800)) { // Encode as 2-byte utf-8 char longFilename[n++] = '_';
longFilename[currentPos++] = 0xC0 | ((utf16_ch >> 6) & 0x1F); else if (0 == (utf16_ch & 0xFF80)) // Encode as 1-byte UTF-8 char
longFilename[currentPos++] = 0x80 | (utf16_ch & 0x3F); longFilename[n++] = utf16_ch & 0x007F;
} else if (0 == (utf16_ch & 0xF800)) { // Encode as 2-byte UTF-8 char
else { longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x1F);
#if LONG_FILENAME_CHARSIZE > 2 // Encode as 3-byte utf-8 char longFilename[n++] = 0x80 | ( utf16_ch & 0x3F);
longFilename[currentPos++] = 0xE0 | ((utf16_ch >> 12) & 0x0F);
longFilename[currentPos++] = 0xC0 | ((utf16_ch >> 6) & 0x3F);
longFilename[currentPos++] = 0xC0 | (utf16_ch & 0x3F);
#else // Encode as '_'
longFilename[currentPos++] = '_';
#endif
}
if (0 == utf16_ch) break; // End of filename
} }
n = currentPos; 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
} }
#endif return n;
return n; }
} #endif
} }
} }