From fbd72fd6bf0f02a13be207c9d61f630c594e3156 Mon Sep 17 00:00:00 2001
From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Date: Mon, 29 Sep 2014 08:34:37 +0000
Subject: Common: Add a helper function to generate a 8.3 filename from a long
 one. Core: Fix the SDMC Directory implementation to make blargSnes work.

---
 src/common/file_util.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

(limited to 'src/common/file_util.cpp')

diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 9292a1cd69..5fd155222d 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -780,6 +780,48 @@ size_t ReadFileToString(bool text_file, const char *filename, std::string &str)
     return file.ReadArray(&str[0], str.size());
 }
 
+/**
+ * Splits the filename into 8.3 format
+ * Loosely implemented following https://en.wikipedia.org/wiki/8.3_filename
+ * @param filename The normal filename to use
+ * @param short_name A 9-char array in which the short name will be written
+ * @param extension A 4-char array in which the extension will be written
+ */
+void SplitFilename83(const std::string& filename, std::array<char, 9>& short_name,
+                     std::array<char, 4>& extension) {
+    const std::string forbidden_characters = ".\"/\\[]:;=, ";
+
+    // On a FAT32 partition, 8.3 names are stored as a 11 bytes array, filled with spaces.
+    short_name = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\0'};
+    extension = {' ', ' ', ' ', '\0'};
+
+    std::string::size_type point = filename.rfind('.');
+    if (point == filename.size() - 1)
+        point = filename.rfind('.', point);
+
+    // Get short name.
+    int j = 0;
+    for (char letter : filename.substr(0, point)) {
+        if (forbidden_characters.find(letter, 0) != std::string::npos)
+            continue;
+        if (j == 8) {
+            // TODO(Link Mauve): also do that for filenames containing a space.
+            // TODO(Link Mauve): handle multiple files having the same short name.
+            short_name[6] = '~';
+            short_name[7] = '1';
+            break;
+        }
+        short_name[j++] = toupper(letter);
+    }
+
+    // Get extension.
+    if (point != std::string::npos) {
+        j = 0;
+        for (char letter : filename.substr(point + 1, 3))
+            extension[j++] = toupper(letter);
+    }
+}
+
 IOFile::IOFile()
     : m_file(NULL), m_good(true)
 {}
-- 
cgit v1.2.3-70-g09d2