|
@@ -1109,8 +1109,8 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) {
|
1109
|
1109
|
// We can't reconvert to UTF-8 here as UTF-8 is variable-size encoding, but joining LFN blocks
|
1110
|
1110
|
// needs static bytes addressing. So here just store full UTF-16LE words to re-convert later.
|
1111
|
1111
|
uint16_t idx = (n + i) * 2; // This is fixed as FAT LFN always contain UTF-16LE encoding
|
1112
|
|
- longFilename[idx] = utf16_ch & 0xFF;
|
1113
|
|
- longFilename[idx+1] = (utf16_ch >> 8) & 0xFF;
|
|
1112
|
+ longFilename[idx] = utf16_ch & 0xFF;
|
|
1113
|
+ longFilename[idx + 1] = (utf16_ch >> 8) & 0xFF;
|
1114
|
1114
|
#else
|
1115
|
1115
|
// Replace all multibyte characters to '_'
|
1116
|
1116
|
longFilename[n + i] = (utf16_ch > 0xFF) ? '_' : (utf16_ch & 0xFF);
|
|
@@ -1122,45 +1122,44 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) {
|
1122
|
1122
|
}
|
1123
|
1123
|
}
|
1124
|
1124
|
|
1125
|
|
- // Return if normal file or subdirectory
|
|
1125
|
+ // Post-process normal file or subdirectory longname, if any
|
1126
|
1126
|
if (DIR_IS_FILE_OR_SUBDIR(dir)) {
|
1127
|
1127
|
#if ENABLED(UTF_FILENAME_SUPPORT)
|
1128
|
|
- // Convert filename from utf-16 to utf-8 as Marlin expects
|
1129
|
1128
|
#if LONG_FILENAME_CHARSIZE > 2
|
1130
|
1129
|
// Add warning for developers for currently not supported 3-byte cases (Conversion series of 2-byte
|
1131
|
1130
|
// codepoints to 3-byte in-place will break the rest of filename)
|
1132
|
1131
|
#error "Currently filename re-encoding is done in-place. It may break the remaining chars to use 3-byte codepoints."
|
1133
|
1132
|
#endif
|
1134
|
|
- uint16_t currentPos = 0;
|
1135
|
|
- LOOP_L_N(i, (LONG_FILENAME_LENGTH / 2)) {
|
1136
|
|
- uint16_t idx = i * 2; // This is fixed as FAT LFN always contain UTF-16LE encoding
|
1137
|
|
-
|
1138
|
|
- uint16_t utf16_ch = longFilename[idx] | (longFilename[idx + 1] << 8);
|
1139
|
|
- if (0xD800 == (utf16_ch & 0xF800)) // Surrogate pair - encode as '_'
|
1140
|
|
- longFilename[currentPos++] = '_';
|
1141
|
|
- else if (0 == (utf16_ch & 0xFF80)) // Encode as 1-byte utf-8 char
|
1142
|
|
- longFilename[currentPos++] = utf16_ch & 0x007F;
|
1143
|
|
- else if (0 == (utf16_ch & 0xF800)) { // Encode as 2-byte utf-8 char
|
1144
|
|
- longFilename[currentPos++] = 0xC0 | ((utf16_ch >> 6) & 0x1F);
|
1145
|
|
- longFilename[currentPos++] = 0x80 | (utf16_ch & 0x3F);
|
1146
|
|
- }
|
1147
|
|
- else {
|
1148
|
|
- #if LONG_FILENAME_CHARSIZE > 2 // Encode as 3-byte utf-8 char
|
1149
|
|
- longFilename[currentPos++] = 0xE0 | ((utf16_ch >> 12) & 0x0F);
|
1150
|
|
- longFilename[currentPos++] = 0xC0 | ((utf16_ch >> 6) & 0x3F);
|
1151
|
|
- longFilename[currentPos++] = 0xC0 | (utf16_ch & 0x3F);
|
1152
|
|
- #else // Encode as '_'
|
1153
|
|
- longFilename[currentPos++] = '_';
|
1154
|
|
- #endif
|
1155
|
|
- }
|
1156
|
1133
|
|
1157
|
|
- if (0 == utf16_ch) break; // End of filename
|
1158
|
|
- }
|
1159
|
|
- return currentPos;
|
1160
|
|
- #else
|
1161
|
|
- return n;
|
|
1134
|
+ // Is there a long filename to decode?
|
|
1135
|
+ if (longFilename) {
|
|
1136
|
+ // Reset n to the start of the long name
|
|
1137
|
+ n = 0;
|
|
1138
|
+ for (uint16_t idx = 0; idx < (LONG_FILENAME_LENGTH) / 2; idx += 2) { // idx is fixed since FAT LFN always contains UTF-16LE encoding
|
|
1139
|
+ uint16_t utf16_ch = longFilename[idx] | (longFilename[idx + 1] << 8);
|
|
1140
|
+ if (0xD800 == (utf16_ch & 0xF800)) // Surrogate pair - encode as '_'
|
|
1141
|
+ longFilename[n++] = '_';
|
|
1142
|
+ else if (0 == (utf16_ch & 0xFF80)) // Encode as 1-byte UTF-8 char
|
|
1143
|
+ longFilename[n++] = utf16_ch & 0x007F;
|
|
1144
|
+ else if (0 == (utf16_ch & 0xF800)) { // Encode as 2-byte UTF-8 char
|
|
1145
|
+ longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x1F);
|
|
1146
|
+ longFilename[n++] = 0x80 | ( utf16_ch & 0x3F);
|
|
1147
|
+ }
|
|
1148
|
+ else {
|
|
1149
|
+ #if LONG_FILENAME_CHARSIZE > 2 // Encode as 3-byte UTF-8 char
|
|
1150
|
+ longFilename[n++] = 0xE0 | ((utf16_ch >> 12) & 0x0F);
|
|
1151
|
+ longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x3F);
|
|
1152
|
+ longFilename[n++] = 0xC0 | ( utf16_ch & 0x3F);
|
|
1153
|
+ #else // Encode as '_'
|
|
1154
|
+ longFilename[n++] = '_';
|
|
1155
|
+ #endif
|
|
1156
|
+ }
|
|
1157
|
+ if (0 == utf16_ch) break; // End of filename
|
|
1158
|
+ } // idx
|
|
1159
|
+ } // longFilename
|
1162
|
1160
|
#endif
|
1163
|
|
- }
|
|
1161
|
+ return n;
|
|
1162
|
+ } // DIR_IS_FILE_OR_SUBDIR
|
1164
|
1163
|
}
|
1165
|
1164
|
}
|
1166
|
1165
|
|