UTF longname followup (#20115)
This commit is contained in:
		| @@ -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,45 +1122,44 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Return if normal file or subdirectory |     // Post-process normal file or subdirectory longname, if any | ||||||
|     if (DIR_IS_FILE_OR_SUBDIR(dir)) { |     if (DIR_IS_FILE_OR_SUBDIR(dir)) { | ||||||
|       #if ENABLED(UTF_FILENAME_SUPPORT) |       #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) | ||||||
|           #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)) { |  | ||||||
|           uint16_t idx = i * 2; // This is fixed as FAT LFN always contain UTF-16LE encoding |  | ||||||
|  |  | ||||||
|           uint16_t utf16_ch = longFilename[idx] | (longFilename[idx + 1] << 8); |         // Is there a long filename to decode? | ||||||
|           if (0xD800 == (utf16_ch & 0xF800))                                    // Surrogate pair - encode as '_' |         if (longFilename) { | ||||||
|             longFilename[currentPos++] = '_'; |           // Reset n to the start of the long name | ||||||
|           else if (0 == (utf16_ch & 0xFF80))                                    // Encode as 1-byte utf-8 char |           n = 0; | ||||||
|             longFilename[currentPos++] = utf16_ch & 0x007F; |           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 & 0xF800)) {                                  // Encode as 2-byte utf-8 char |             uint16_t utf16_ch = longFilename[idx] | (longFilename[idx + 1] << 8); | ||||||
|             longFilename[currentPos++] = 0xC0 | ((utf16_ch >> 6) & 0x1F); |             if (0xD800 == (utf16_ch & 0xF800))                                    // Surrogate pair - encode as '_' | ||||||
|             longFilename[currentPos++] = 0x80 | (utf16_ch & 0x3F); |               longFilename[n++] = '_'; | ||||||
|           } |             else if (0 == (utf16_ch & 0xFF80))                                    // Encode as 1-byte UTF-8 char | ||||||
|           else { |               longFilename[n++] = utf16_ch & 0x007F; | ||||||
|             #if LONG_FILENAME_CHARSIZE > 2                                      // Encode as 3-byte utf-8 char |             else if (0 == (utf16_ch & 0xF800)) {                                  // Encode as 2-byte UTF-8 char | ||||||
|               longFilename[currentPos++] = 0xE0 | ((utf16_ch >> 12) & 0x0F); |               longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x1F); | ||||||
|               longFilename[currentPos++] = 0xC0 | ((utf16_ch >> 6) & 0x3F); |               longFilename[n++] = 0x80 | ( utf16_ch       & 0x3F); | ||||||
|               longFilename[currentPos++] = 0xC0 | (utf16_ch & 0x3F); |             } | ||||||
|             #else                                                               // Encode as '_' |             else { | ||||||
|               longFilename[currentPos++] = '_'; |               #if LONG_FILENAME_CHARSIZE > 2                                      // Encode as 3-byte UTF-8 char | ||||||
|             #endif |                 longFilename[n++] = 0xE0 | ((utf16_ch >> 12) & 0x0F); | ||||||
|           } |                 longFilename[n++] = 0xC0 | ((utf16_ch >>  6) & 0x3F); | ||||||
|  |                 longFilename[n++] = 0xC0 | ( utf16_ch        & 0x3F); | ||||||
|           if (0 == utf16_ch) break; // End of filename |               #else                                                               // Encode as '_' | ||||||
|         } |                 longFilename[n++] = '_'; | ||||||
|         return currentPos; |               #endif | ||||||
|       #else |             } | ||||||
|         return n; |             if (0 == utf16_ch) break; // End of filename | ||||||
|  |           } // idx | ||||||
|  |         } // longFilename | ||||||
|       #endif |       #endif | ||||||
|     } |       return n; | ||||||
|  |     } // DIR_IS_FILE_OR_SUBDIR | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user