summaryrefslogtreecommitdiff
path: root/Source/Core/Common/SettingsHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/Common/SettingsHandler.cpp')
-rw-r--r--Source/Core/Common/SettingsHandler.cpp44
1 files changed, 27 insertions, 17 deletions
diff --git a/Source/Core/Common/SettingsHandler.cpp b/Source/Core/Common/SettingsHandler.cpp
index d01e50c00c..fbdff41302 100644
--- a/Source/Core/Common/SettingsHandler.cpp
+++ b/Source/Core/Common/SettingsHandler.cpp
@@ -6,6 +6,7 @@
#include "Common/SettingsHandler.h"
+#include <algorithm>
#include <cstddef>
#include <ctime>
#include <iomanip>
@@ -79,12 +80,10 @@ void SettingsHandler::Decrypt()
m_key = (m_key >> 31) | (m_key << 1);
}
- // Decryption done. Now get rid of all CR in the output.
- // The decoded file is supposed to contain Windows line endings
- // (CR-LF), but sometimes also contains CR-LF-LF endings which
- // confuse the parsing code, so let's just get rid of all CR
- // line endings.
-
+ // The decoded data normally uses CRLF line endings, but occasionally
+ // (see the comment in WriteLine), lines can be separated by CRLFLF.
+ // To handle this, we remove every CR and treat LF as the line ending.
+ // (We ignore empty lines.)
decoded.erase(std::remove(decoded.begin(), decoded.end(), '\x0d'), decoded.end());
}
@@ -96,22 +95,33 @@ void SettingsHandler::Reset()
m_buffer = {};
}
-void SettingsHandler::AddSetting(std::string_view key, std::string_view value)
+void SettingsHandler::AddSetting(const std::string& key, const std::string& value)
{
- for (const char& c : key)
- {
- WriteByte(c);
- }
+ WriteLine(key + '=' + value + "\r\n");
+}
- WriteByte('=');
+void SettingsHandler::WriteLine(const std::string& str)
+{
+ const u32 old_position = m_position;
+ const u32 old_key = m_key;
- for (const char& c : value)
- {
+ // Encode and write the line
+ for (char c : str)
WriteByte(c);
- }
- WriteByte(13);
- WriteByte(10);
+ // If the encoded data contains a null byte, Nintendo's decoder will stop at that null byte
+ // instead of decoding all the data. To avoid this: If the data we just wrote contains
+ // a null byte, add an LF right before the line to prod the values into being different,
+ // just like Nintendo does. Due to the chosen key, LF itself never encodes into a null byte.
+ const auto begin = m_buffer.cbegin() + old_position;
+ const auto end = m_buffer.cbegin() + m_position;
+ if (std::find(begin, end, 0) != end)
+ {
+ m_key = old_key;
+ m_position = old_position;
+ WriteByte('\n');
+ WriteLine(str);
+ }
}
void SettingsHandler::WriteByte(u8 b)