Sync DrDump crash handler with TortoiseSVN codebase
[TortoiseGit.git] / ext / CrashServer / CrashHandler / SendRpt / IniFile.cpp
blob55ab5516867fee9e33e3cd19277efa0f779875a1
1 #include "StdAfx.h"
2 #include "IniFile.h"
3 #include "utils.h"
5 IniFile::IniFile(const wchar_t* path)
7 CHandle file(CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0));
8 if (file == INVALID_HANDLE_VALUE)
9 throw std::runtime_error("ini file not found");
11 DWORD size = GetFileSize(file, NULL);
12 std::vector<BYTE> data(size);
14 if (!ReadFile(file, data.data(), (DWORD)data.size(), &size, NULL))
15 throw std::runtime_error("failed to read ini file");
17 Parse(data.data(), size);
20 IniFile::IniFile(HMODULE hImage, DWORD resId)
22 auto data = ExtractDataFromResource(hImage, resId);
23 Parse(data.first, data.second);
26 const wchar_t* GetEol(const wchar_t* p, const wchar_t* end)
28 while (p < end && *p != L'\n')
29 ++p;
30 return p;
33 void IniFile::Parse(LPCVOID data, size_t size)
35 LPCWSTR begin = (LPCWSTR)data;
36 LPCWSTR end = begin + size / sizeof(*begin);
38 if (*begin == 0xFEFF)
39 ++begin;
41 Section* currentSection = nullptr;
42 CString* varToAppend = nullptr;
44 while (1)
46 const wchar_t* eol = GetEol(begin, end);
47 if (begin >= eol)
48 break;
50 CStringW line(begin, int(eol - begin));
51 begin = eol + 1;
53 line.Trim(L" \t\r\n");
55 if (varToAppend)
57 bool appendNext = line.Right(1) == L"\\";
58 if (appendNext)
59 line.Delete(line.GetLength() - 1);
60 *varToAppend += line;
61 if (!appendNext)
62 varToAppend = nullptr;
63 continue;
66 if (line.IsEmpty() || line[0] == L';')
67 continue;
69 if (line[0] == L'[' && line[line.GetLength() - 1] == L']')
71 currentSection = &m_sections[line.Trim(L"[]")];
72 continue;
75 if (!currentSection)
76 continue;
78 int equalPos = line.Find(L'=');
79 if (equalPos == -1 || equalPos == 0)
80 continue;
81 CStringW var = line.Left(equalPos);
82 CStringW text = line.Mid(equalPos + 1);
83 if (text.Right(1) == L"\\")
85 text.Delete(text.GetLength() - 1);
86 varToAppend = &(*currentSection)[var];
89 (*currentSection)[var] = text;
93 CStringW IniFile::GetString(const wchar_t* section, const wchar_t* variable)
95 auto sec = m_sections.find(section);
96 if (sec != m_sections.end())
98 auto var = sec->second.find(variable);
99 if (var != sec->second.end())
100 return var->second;
102 return CStringW();