From 8e55b6ef2289286c43efc8e41b8bc2a41b2255d6 Mon Sep 17 00:00:00 2001 From: LRFLEW Date: Sun, 5 Mar 2017 14:45:05 -0600 Subject: [PATCH] Make the INI keys case insensitive --- OpenRCT2.xcodeproj/project.pbxproj | 12 ++++----- src/openrct2/config/IniReader.cpp | 42 +++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index ec486286f2..2cf84296cc 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -726,11 +726,11 @@ D429FF411E36ABCD009342A6 /* tile_inspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tile_inspector.h; sourceTree = ""; }; D42E33751E5C27D600D630AF /* Config.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Config.cpp; sourceTree = ""; }; D42E33761E5C27D600D630AF /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; - D42E33771E5C27D600D630AF /* ConfigEnum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigEnum.h; sourceTree = ""; }; + D42E33771E5C27D600D630AF /* ConfigEnum.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ConfigEnum.hpp; sourceTree = ""; }; D42E33781E5C27D600D630AF /* IniReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IniReader.cpp; sourceTree = ""; }; - D42E33791E5C27D600D630AF /* IniReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IniReader.h; sourceTree = ""; }; + D42E33791E5C27D600D630AF /* IniReader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = IniReader.hpp; sourceTree = ""; }; D42E337A1E5C27D600D630AF /* IniWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IniWriter.cpp; sourceTree = ""; }; - D42E337B1E5C27D600D630AF /* IniWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IniWriter.h; sourceTree = ""; }; + D42E337B1E5C27D600D630AF /* IniWriter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = IniWriter.hpp; sourceTree = ""; }; D42E337C1E5C27D600D630AF /* KeyboardShortcuts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardShortcuts.cpp; sourceTree = ""; }; D433A4FA1E4A861F00D9A6DF /* SawyerChunk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SawyerChunk.cpp; path = rct12/SawyerChunk.cpp; sourceTree = ""; }; D433A4FB1E4A861F00D9A6DF /* SawyerChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SawyerChunk.h; path = rct12/SawyerChunk.h; sourceTree = ""; }; @@ -1622,11 +1622,11 @@ children = ( D42E33751E5C27D600D630AF /* Config.cpp */, D42E33761E5C27D600D630AF /* Config.h */, - D42E33771E5C27D600D630AF /* ConfigEnum.h */, + D42E33771E5C27D600D630AF /* ConfigEnum.hpp */, D42E33781E5C27D600D630AF /* IniReader.cpp */, - D42E33791E5C27D600D630AF /* IniReader.h */, + D42E33791E5C27D600D630AF /* IniReader.hpp */, D42E337A1E5C27D600D630AF /* IniWriter.cpp */, - D42E337B1E5C27D600D630AF /* IniWriter.h */, + D42E337B1E5C27D600D630AF /* IniWriter.hpp */, D42E337C1E5C27D600D630AF /* KeyboardShortcuts.cpp */, ); path = config; diff --git a/src/openrct2/config/IniReader.cpp b/src/openrct2/config/IniReader.cpp index 4f0e67ed9c..de6ae2a35d 100644 --- a/src/openrct2/config/IniReader.cpp +++ b/src/openrct2/config/IniReader.cpp @@ -14,6 +14,7 @@ *****************************************************************************/ #pragma endregion +#include #include #include #include @@ -57,13 +58,46 @@ struct LineRange } }; +struct StringIHash +{ + std::size_t operator()(const std::string &s) const + { + typedef std::char_traits Traits; + std::size_t seed = 0; + for (const char &c : s) + { + const Traits::int_type value = std::toupper(Traits::to_int_type(c)); + // Simple Hash Combine as used by Boost.Functional/Hash + seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2); + } + return seed; + } +}; + +struct StringICmp +{ + bool operator()(const std::string &a, const std::string &b) const + { + typedef std::char_traits Traits; + if (a.size() != b.size()) return false; + const char *s1 = a.data(), *s2 = b.data(); + for (std::size_t i = a.size(); i > 0; --i, ++s1, ++s2) + { + const int c1 = std::toupper(Traits::to_int_type(*s1)); + const int c2 = std::toupper(Traits::to_int_type(*s1)); + if (c1 != c2) return false; + } + return true; + } +}; + class IniReader final : public IIniReader { private: - std::vector _buffer; - std::vector _lines; - std::unordered_map _sections; - std::unordered_map _values; + std::vector _buffer; + std::vector _lines; + std::unordered_map _sections; + std::unordered_map _values; public: IniReader(IStream * stream)