195 #ifndef INCLUDED_SimpleIni_h 196 #define INCLUDED_SimpleIni_h 198 #if defined(_MSC_VER) && (_MSC_VER >= 1020) 212 # pragma warning (push) 213 # pragma warning (disable: 4127 4503 4702 4786) 224 #ifdef SI_SUPPORT_IOSTREAMS 226 #endif // SI_SUPPORT_IOSTREAMS 232 # define SI_ASSERT(x) assert(x) 234 # define SI_ASSERT(x) 248 #define SI_UTF8_SIGNATURE "\xEF\xBB\xBF" 251 # define SI_NEWLINE_A "\r\n" 252 # define SI_NEWLINE_W L"\r\n" 254 # define SI_NEWLINE_A "\n" 255 # define SI_NEWLINE_W L"\n" 258 #if defined(SI_CONVERT_ICU) 259 # include <unicode/ustring.h> 263 # define SI_HAS_WIDE_FILE 264 # define SI_WCHAR_T wchar_t 265 #elif defined(SI_CONVERT_ICU) 266 # define SI_HAS_WIDE_FILE 267 # define SI_WCHAR_T UChar 294 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
297 typedef SI_CHAR SI_CHAR_T;
301 const SI_CHAR *pItem;
302 const SI_CHAR *pComment;
305 Entry(
const SI_CHAR *a_pszItem = NULL,
int a_nOrder = 0)
310 Entry(
const SI_CHAR *a_pszItem,
const SI_CHAR *a_pszComment,
int a_nOrder)
312 , pComment(a_pszComment)
320 pComment = rhs.pComment;
325 #if defined(_MSC_VER) && _MSC_VER <= 1200 327 bool operator<(
const Entry &rhs)
const {
330 bool operator>(
const Entry &rhs)
const {
337 bool operator()(
const Entry &lhs,
const Entry &rhs)
const {
338 const static SI_STRLESS isLess = SI_STRLESS();
339 return isLess(lhs.pItem, rhs.pItem);
345 bool operator()(
const Entry &lhs,
const Entry &rhs)
const {
346 if (lhs.nOrder != rhs.nOrder) {
347 return lhs.nOrder < rhs.nOrder;
350 return KeyOrder()(lhs.pItem, rhs.pItem);
356 typedef std::multimap<Entry, const SI_CHAR *, typename Entry::KeyOrder>
TKeyVal;
359 typedef std::map<Entry, TKeyVal, typename Entry::KeyOrder>
TSection;
373 virtual void Write(
const char *a_pBuf) = 0;
384 void Write(
const char *a_pBuf) {
385 fputs(a_pBuf, m_file);
394 std::string &m_string;
396 StringWriter(std::string &a_string) : m_string(a_string) { }
397 void Write(
const char *a_pBuf) {
398 m_string.append(a_pBuf);
405 #ifdef SI_SUPPORT_IOSTREAMS 408 std::ostream &m_ostream;
410 StreamWriter(std::ostream &a_ostream) : m_ostream(a_ostream) { }
411 void Write(
const char *a_pBuf) {
415 StreamWriter(
const StreamWriter &);
416 StreamWriter &operator=(
const StreamWriter &);
418 #endif // SI_SUPPORT_IOSTREAMS 425 Converter(
bool a_bStoreIsUtf8) : SI_CONVERTER(a_bStoreIsUtf8) {
426 m_scratch.resize(1024);
432 m_scratch = rhs.m_scratch;
435 bool ConvertToStore(
const SI_CHAR *a_pszString) {
436 size_t uLen = SI_CONVERTER::SizeToStore(a_pszString);
438 if (uLen == (
size_t)(-1)) {
442 while (uLen > m_scratch.size()) {
443 m_scratch.resize(m_scratch.size() * 2);
446 return SI_CONVERTER::ConvertToStore(
448 const_cast<char *>(m_scratch.data()),
452 return m_scratch.data();
455 std::string m_scratch;
468 bool a_bIsUtf8 =
false,
469 bool a_bMultiKey =
false,
470 bool a_bMultiLine =
false 481 return m_data.empty();
503 m_bStoreIsUtf8 = a_bIsUtf8;
509 return m_bStoreIsUtf8;
531 m_bAllowMultiKey = a_bAllowMultiKey;
536 return m_bAllowMultiKey;
547 m_bAllowMultiLine = a_bAllowMultiLine;
552 return m_bAllowMultiLine;
562 m_bSpaces = a_bSpaces;
583 const char *a_pszFile
586 #ifdef SI_HAS_WIDE_FILE 594 const SI_WCHAR_T *a_pwszFile
596 #endif // SI_HAS_WIDE_FILE 609 #ifdef SI_SUPPORT_IOSTREAMS 617 std::istream &a_istream
619 #endif // SI_SUPPORT_IOSTREAMS 627 SI_Error
LoadData(
const std::string &a_strData) {
628 return LoadData(a_strData.c_str(), a_strData.size());
660 const char *a_pszFile,
661 bool a_bAddSignature =
true 664 #ifdef SI_HAS_WIDE_FILE 676 const SI_WCHAR_T *a_pwszFile,
677 bool a_bAddSignature =
true 695 bool a_bAddSignature =
false 730 OutputWriter &a_oOutput,
731 bool a_bAddSignature =
false 734 #ifdef SI_SUPPORT_IOSTREAMS 747 std::ostream &a_ostream,
748 bool a_bAddSignature =
false 750 StreamWriter writer(a_ostream);
751 return Save(writer, a_bAddSignature);
753 #endif // SI_SUPPORT_IOSTREAMS 767 std::string &a_sBuffer,
768 bool a_bAddSignature =
false 770 StringWriter writer(a_sBuffer);
771 return Save(writer, a_bAddSignature);
793 TNamesDepend &a_names
814 const SI_CHAR *a_pSection,
815 TNamesDepend &a_names
835 const SI_CHAR *a_pSection,
836 const SI_CHAR *a_pKey,
837 TNamesDepend &a_values
850 const SI_CHAR *a_pSection
868 const SI_CHAR *a_pSection
889 const SI_CHAR *a_pSection,
890 const SI_CHAR *a_pKey,
891 const SI_CHAR *a_pDefault = NULL,
892 bool *a_pHasMultiple = NULL
909 const SI_CHAR *a_pSection,
910 const SI_CHAR *a_pKey,
912 bool *a_pHasMultiple = NULL
929 const SI_CHAR *a_pSection,
930 const SI_CHAR *a_pKey,
931 double a_nDefault = 0,
932 bool *a_pHasMultiple = NULL
954 const SI_CHAR *a_pSection,
955 const SI_CHAR *a_pKey,
956 bool a_bDefault =
false,
957 bool *a_pHasMultiple = NULL
990 const SI_CHAR *a_pSection,
991 const SI_CHAR *a_pKey,
992 const SI_CHAR *a_pValue,
993 const SI_CHAR *a_pComment = NULL,
994 bool a_bForceReplace =
false 996 return AddEntry(a_pSection, a_pKey, a_pValue, a_pComment, a_bForceReplace,
true);
1023 const SI_CHAR *a_pSection,
1024 const SI_CHAR *a_pKey,
1026 const SI_CHAR *a_pComment = NULL,
1027 bool a_bUseHex =
false,
1028 bool a_bForceReplace =
false 1052 const SI_CHAR *a_pSection,
1053 const SI_CHAR *a_pKey,
1055 const SI_CHAR *a_pComment = NULL,
1056 bool a_bForceReplace =
false 1080 const SI_CHAR *a_pSection,
1081 const SI_CHAR *a_pKey,
1083 const SI_CHAR *a_pComment = NULL,
1084 bool a_bForceReplace =
false 1106 const SI_CHAR *a_pSection,
1107 const SI_CHAR *a_pKey,
1108 bool a_bRemoveEmpty =
false 1132 const SI_CHAR *a_pSection,
1133 const SI_CHAR *a_pKey,
1134 const SI_CHAR *a_pValue,
1135 bool a_bRemoveEmpty =
false 1148 return Converter(m_bStoreIsUtf8);
1161 SI_Error FindFileComment(
1172 const SI_CHAR *&a_pSection,
1173 const SI_CHAR *&a_pKey,
1174 const SI_CHAR *&a_pVal,
1175 const SI_CHAR *&a_pComment
1201 const SI_CHAR *a_pSection,
1202 const SI_CHAR *a_pKey,
1203 const SI_CHAR *a_pValue,
1204 const SI_CHAR *a_pComment,
1205 bool a_bForceReplace,
1210 inline bool IsSpace(SI_CHAR ch)
const {
1211 return (ch ==
' ' || ch ==
'\t' || ch ==
'\r' || ch ==
'\n');
1215 inline bool IsComment(SI_CHAR ch)
const {
1216 return (ch ==
';' || ch ==
'#');
1221 inline void SkipNewLine(SI_CHAR *&a_pData)
const {
1222 a_pData += (*a_pData ==
'\r' && *(a_pData + 1) ==
'\n') ? 2 : 1;
1226 SI_Error CopyString(
const SI_CHAR *&a_pString);
1229 void DeleteString(
const SI_CHAR *a_pString);
1232 bool IsLess(
const SI_CHAR *a_pLeft,
const SI_CHAR *a_pRight)
const {
1233 const static SI_STRLESS isLess = SI_STRLESS();
1234 return isLess(a_pLeft, a_pRight);
1237 bool IsMultiLineTag(
const SI_CHAR *a_pData)
const;
1238 bool IsMultiLineData(
const SI_CHAR *a_pData)
const;
1239 bool LoadMultiLineText(
1241 const SI_CHAR *&a_pVal,
1242 const SI_CHAR *a_pTagName,
1243 bool a_bAllowBlankLinesInComment =
false 1245 bool IsNewLineChar(SI_CHAR a_c)
const;
1247 bool OutputMultiLineText(
1248 OutputWriter &a_oOutput,
1249 Converter &a_oConverter,
1250 const SI_CHAR *a_pText
1268 const SI_CHAR *m_pFileComment;
1277 TNamesDepend m_strings;
1280 bool m_bStoreIsUtf8;
1283 bool m_bAllowMultiKey;
1286 bool m_bAllowMultiLine;
1301 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1304 bool a_bAllowMultiKey,
1305 bool a_bAllowMultiLine
1309 , m_pFileComment(NULL)
1310 , m_bStoreIsUtf8(a_bIsUtf8)
1311 , m_bAllowMultiKey(a_bAllowMultiKey)
1312 , m_bAllowMultiLine(a_bAllowMultiLine)
1317 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1322 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1329 m_pFileComment = NULL;
1331 if (!m_data.empty()) {
1332 m_data.erase(m_data.begin(), m_data.end());
1336 if (!m_strings.empty()) {
1337 typename TNamesDepend::iterator i = m_strings.begin();
1339 for (; i != m_strings.end(); ++i) {
1340 delete[]
const_cast<SI_CHAR *
>(i->pItem);
1343 m_strings.erase(m_strings.begin(), m_strings.end());
1347 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1350 const char *a_pszFile
1353 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 1354 fopen_s(&fp, a_pszFile,
"rb");
1355 #else // !__STDC_WANT_SECURE_LIB__ 1356 fp = fopen(a_pszFile,
"rb");
1357 #endif // __STDC_WANT_SECURE_LIB__ 1368 #ifdef SI_HAS_WIDE_FILE 1369 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1372 const SI_WCHAR_T *a_pwszFile
1376 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 1377 _wfopen_s(&fp, a_pwszFile, L
"rb");
1378 #else // !__STDC_WANT_SECURE_LIB__ 1379 fp = _wfopen(a_pwszFile, L
"rb");
1380 #endif // __STDC_WANT_SECURE_LIB__ 1389 #else // !_WIN32 (therefore SI_CONVERT_ICU) 1391 u_austrncpy(szFile, a_pwszFile,
sizeof(szFile));
1395 #endif // SI_HAS_WIDE_FILE 1397 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1403 int retval = fseek(a_fpFile, 0, SEEK_END);
1409 long lSize = ftell(a_fpFile);
1420 char *pData =
new (std::nothrow)
char[lSize + 1];
1429 fseek(a_fpFile, 0, SEEK_SET);
1430 size_t uRead = fread(pData,
sizeof(
char), lSize, a_fpFile);
1432 if (uRead != (
size_t) lSize) {
1438 SI_Error rc =
LoadData(pData, uRead);
1443 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1446 const char *a_pData,
1456 if (a_uDataLen >= 3 && memcmp(a_pData, SI_UTF8_SIGNATURE, 3) == 0) {
1459 SI_ASSERT(m_bStoreIsUtf8 || !m_pData);
1463 if (a_uDataLen == 0) {
1468 SI_CONVERTER converter(m_bStoreIsUtf8);
1469 size_t uLen = converter.SizeFromStore(a_pData, a_uDataLen);
1471 if (uLen == (
size_t)(-1)) {
1477 SI_CHAR *pData =
new (std::nothrow) SI_CHAR[uLen + 1];
1483 memset(pData, 0,
sizeof(SI_CHAR) * (uLen + 1));
1486 if (!converter.ConvertFromStore(a_pData, a_uDataLen, pData, uLen)) {
1492 const static SI_CHAR empty = 0;
1493 SI_CHAR *pWork = pData;
1494 const SI_CHAR *pSection = ∅
1495 const SI_CHAR *pItem = NULL;
1496 const SI_CHAR *pVal = NULL;
1497 const SI_CHAR *pComment = NULL;
1501 bool bCopyStrings = (m_pData != NULL);
1505 SI_Error rc = FindFileComment(pWork, bCopyStrings);
1512 while (FindEntry(pWork, pSection, pItem, pVal, pComment)) {
1513 rc = AddEntry(pSection, pItem, pVal, pComment,
false, bCopyStrings);
1525 m_uDataLen = uLen + 1;
1531 #ifdef SI_SUPPORT_IOSTREAMS 1532 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1535 std::istream &a_istream
1537 std::string strData;
1541 a_istream.get(szBuf,
sizeof(szBuf),
'\0');
1542 strData.append(szBuf);
1543 }
while (a_istream.good());
1547 #endif // SI_SUPPORT_IOSTREAMS 1549 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1556 if (m_pFileComment) {
1562 if (!LoadMultiLineText(a_pData, m_pFileComment, NULL,
false)) {
1567 if (a_bCopyStrings) {
1568 SI_Error rc = CopyString(m_pFileComment);
1578 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1582 const SI_CHAR *&a_pSection,
1583 const SI_CHAR *&a_pKey,
1584 const SI_CHAR *&a_pVal,
1585 const SI_CHAR *&a_pComment
1589 SI_CHAR *pTrail = NULL;
1593 while (*a_pData && IsSpace(*a_pData)) {
1603 if (IsComment(*a_pData)) {
1604 LoadMultiLineText(a_pData, a_pComment, NULL,
true);
1609 if (*a_pData ==
'[') {
1613 while (*a_pData && IsSpace(*a_pData)) {
1619 a_pSection = a_pData;
1621 while (*a_pData && *a_pData !=
']' && !IsNewLineChar(*a_pData)) {
1626 if (*a_pData !=
']') {
1631 pTrail = a_pData - 1;
1633 while (pTrail >= a_pSection && IsSpace(*pTrail)) {
1643 while (*a_pData && !IsNewLineChar(*a_pData)) {
1656 while (*a_pData && *a_pData !=
'=' && !IsNewLineChar(*a_pData)) {
1661 if (*a_pData !=
'=') {
1666 if (a_pKey == a_pData) {
1667 while (*a_pData && !IsNewLineChar(*a_pData)) {
1675 pTrail = a_pData - 1;
1677 while (pTrail >= a_pKey && IsSpace(*pTrail)) {
1687 while (*a_pData && !IsNewLineChar(*a_pData) && IsSpace(*a_pData)) {
1694 while (*a_pData && !IsNewLineChar(*a_pData)) {
1699 pTrail = a_pData - 1;
1702 SkipNewLine(a_pData);
1705 while (pTrail >= a_pVal && IsSpace(*pTrail)) {
1713 if (m_bAllowMultiLine && IsMultiLineTag(a_pVal)) {
1715 const SI_CHAR *pTagName = a_pVal + 3;
1716 return LoadMultiLineText(a_pData, a_pVal, pTagName);
1726 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1729 const SI_CHAR *a_pVal
1732 if (*a_pVal++ !=
'<') {
1736 if (*a_pVal++ !=
'<') {
1740 if (*a_pVal++ !=
'<') {
1747 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1750 const SI_CHAR *a_pData
1763 if (IsSpace(*a_pData)) {
1769 if (IsNewLineChar(*a_pData)) {
1777 if (IsSpace(*--a_pData)) {
1784 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1789 return (a_c ==
'\n' || a_c ==
'\r');
1792 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1796 const SI_CHAR *&a_pVal,
1797 const SI_CHAR *a_pTagName,
1798 bool a_bAllowBlankLinesInComment
1808 SI_CHAR *pDataLine = a_pData;
1817 SI_CHAR cEndOfLineChar = *a_pData;
1822 if (!a_pTagName && !IsComment(*a_pData)) {
1824 if (!a_bAllowBlankLinesInComment) {
1831 SI_CHAR *pCurr = a_pData;
1834 while (IsSpace(*pCurr)) {
1835 if (IsNewLineChar(*pCurr)) {
1845 if (IsComment(*pCurr)) {
1846 for (; nNewLines > 0; --nNewLines) {
1847 *pDataLine++ =
'\n';
1859 pCurrLine = a_pData;
1861 while (*a_pData && !IsNewLineChar(*a_pData)) {
1866 if (pDataLine < pCurrLine) {
1867 size_t nLen = (size_t)(a_pData - pCurrLine);
1868 memmove(pDataLine, pCurrLine, nLen *
sizeof(SI_CHAR));
1869 pDataLine[nLen] =
'\0';
1873 cEndOfLineChar = *a_pData;
1880 (!IsLess(pDataLine, a_pTagName) && !IsLess(a_pTagName, pDataLine))) {
1886 if (!cEndOfLineChar) {
1892 pDataLine += (a_pData - pCurrLine);
1893 *a_pData = cEndOfLineChar;
1894 SkipNewLine(a_pData);
1895 *pDataLine++ =
'\n';
1899 if (a_pVal == a_pData) {
1908 *--pDataLine =
'\0';
1912 if (a_pTagName && cEndOfLineChar) {
1913 SI_ASSERT(IsNewLineChar(cEndOfLineChar));
1914 *a_pData = cEndOfLineChar;
1915 SkipNewLine(a_pData);
1921 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1924 const SI_CHAR *&a_pString
1928 if (
sizeof(SI_CHAR) ==
sizeof(
char)) {
1929 uLen = strlen((
const char *)a_pString);
1930 }
else if (
sizeof(SI_CHAR) ==
sizeof(
wchar_t)) {
1931 uLen = wcslen((
const wchar_t *)a_pString);
1933 for (; a_pString[uLen]; ++uLen) ;
1937 SI_CHAR *pCopy =
new (std::nothrow) SI_CHAR[uLen];
1943 memcpy(pCopy, a_pString,
sizeof(SI_CHAR)*uLen);
1944 m_strings.push_back(pCopy);
1949 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1952 const SI_CHAR *a_pSection,
1953 const SI_CHAR *a_pKey,
1954 const SI_CHAR *a_pValue,
1955 const SI_CHAR *a_pComment,
1956 bool a_bForceReplace,
1960 bool bInserted =
false;
1962 SI_ASSERT(!a_pComment || IsComment(*a_pComment));
1966 if (a_bCopyStrings && a_pComment) {
1967 rc = CopyString(a_pComment);
1975 typename TSection::iterator iSection = m_data.find(a_pSection);
1977 if (iSection == m_data.end()) {
1980 if (a_bCopyStrings) {
1981 rc = CopyString(a_pSection);
1989 Entry oSection(a_pSection, ++m_nOrder);
1991 if (a_pComment && (!a_pKey || !a_pValue)) {
1992 oSection.pComment = a_pComment;
1995 typename TSection::value_type oEntry(oSection,
TKeyVal());
1996 typedef typename TSection::iterator SectionIterator;
1997 std::pair<SectionIterator, bool> i = m_data.insert(oEntry);
2002 if (!a_pKey || !a_pValue) {
2004 return bInserted ? SI_INSERTED : SI_UPDATED;
2008 TKeyVal &keyval = iSection->second;
2009 typename TKeyVal::iterator iKey = keyval.find(a_pKey);
2013 int nLoadOrder = ++m_nOrder;
2015 if (iKey != keyval.end() && m_bAllowMultiKey && a_bForceReplace) {
2016 const SI_CHAR *pComment = NULL;
2018 while (iKey != keyval.end() && !IsLess(a_pKey, iKey->first.pItem)) {
2019 if (iKey->first.nOrder < nLoadOrder) {
2020 nLoadOrder = iKey->first.nOrder;
2021 pComment = iKey->first.pComment;
2028 DeleteString(a_pComment);
2029 a_pComment = pComment;
2030 CopyString(a_pComment);
2033 Delete(a_pSection, a_pKey);
2034 iKey = keyval.end();
2038 bool bForceCreateNewKey = m_bAllowMultiKey && !a_bForceReplace;
2040 if (a_bCopyStrings) {
2041 if (bForceCreateNewKey || iKey == keyval.end()) {
2045 rc = CopyString(a_pKey);
2053 rc = CopyString(a_pValue);
2061 if (iKey == keyval.end() || bForceCreateNewKey) {
2062 Entry oKey(a_pKey, nLoadOrder);
2065 oKey.pComment = a_pComment;
2068 typename TKeyVal::value_type oEntry(oKey, static_cast<const SI_CHAR *>(NULL));
2069 iKey = keyval.insert(oEntry);
2073 iKey->second = a_pValue;
2074 return bInserted ? SI_INSERTED : SI_UPDATED;
2077 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2080 const SI_CHAR *a_pSection,
2081 const SI_CHAR *a_pKey,
2082 const SI_CHAR *a_pDefault,
2083 bool *a_pHasMultiple
2085 if (a_pHasMultiple) {
2086 *a_pHasMultiple =
false;
2089 if (!a_pSection || !a_pKey) {
2093 typename TSection::const_iterator iSection = m_data.find(a_pSection);
2095 if (iSection == m_data.end()) {
2099 typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey);
2101 if (iKeyVal == iSection->second.end()) {
2106 if (m_bAllowMultiKey && a_pHasMultiple) {
2107 typename TKeyVal::const_iterator iTemp = iKeyVal;
2109 if (++iTemp != iSection->second.end()) {
2110 if (!IsLess(a_pKey, iTemp->first.pItem)) {
2111 *a_pHasMultiple =
true;
2116 return iKeyVal->second;
2119 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2122 const SI_CHAR *a_pSection,
2123 const SI_CHAR *a_pKey,
2125 bool *a_pHasMultiple
2128 const SI_CHAR *pszValue =
GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple);
2130 if (!pszValue || !*pszValue) {
2135 char szValue[64] = { 0 };
2136 SI_CONVERTER c(m_bStoreIsUtf8);
2138 if (!c.ConvertToStore(pszValue, szValue,
sizeof(szValue))) {
2143 long nValue = a_nDefault;
2144 char *pszSuffix = szValue;
2146 if (szValue[0] ==
'0' && (szValue[1] ==
'x' || szValue[1] ==
'X')) {
2151 nValue = strtol(&szValue[2], &pszSuffix, 16);
2153 nValue = strtol(szValue, &pszSuffix, 10);
2164 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2167 const SI_CHAR *a_pSection,
2168 const SI_CHAR *a_pKey,
2170 const SI_CHAR *a_pComment,
2172 bool a_bForceReplace
2175 if (!a_pSection || !a_pKey) {
2181 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 2182 sprintf_s(szInput, a_bUseHex ?
"0x%lx" :
"%ld", a_nValue);
2183 #else // !__STDC_WANT_SECURE_LIB__ 2184 sprintf(szInput, a_bUseHex ?
"0x%lx" :
"%ld", a_nValue);
2185 #endif // __STDC_WANT_SECURE_LIB__ 2188 SI_CHAR szOutput[64];
2189 SI_CONVERTER c(m_bStoreIsUtf8);
2190 c.ConvertFromStore(szInput, strlen(szInput) + 1,
2191 szOutput,
sizeof(szOutput) /
sizeof(SI_CHAR));
2194 return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace,
true);
2197 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2200 const SI_CHAR *a_pSection,
2201 const SI_CHAR *a_pKey,
2203 bool *a_pHasMultiple
2206 const SI_CHAR *pszValue =
GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple);
2208 if (!pszValue || !*pszValue) {
2213 char szValue[64] = { 0 };
2214 SI_CONVERTER c(m_bStoreIsUtf8);
2216 if (!c.ConvertToStore(pszValue, szValue,
sizeof(szValue))) {
2220 char *pszSuffix = NULL;
2221 double nValue = strtod(szValue, &pszSuffix);
2224 if (!pszSuffix || *pszSuffix) {
2231 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2234 const SI_CHAR *a_pSection,
2235 const SI_CHAR *a_pKey,
2237 const SI_CHAR *a_pComment,
2238 bool a_bForceReplace
2241 if (!a_pSection || !a_pKey) {
2247 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 2248 sprintf_s(szInput,
"%f", a_nValue);
2249 #else // !__STDC_WANT_SECURE_LIB__ 2250 sprintf(szInput,
"%f", a_nValue);
2251 #endif // __STDC_WANT_SECURE_LIB__ 2254 SI_CHAR szOutput[64];
2255 SI_CONVERTER c(m_bStoreIsUtf8);
2256 c.ConvertFromStore(szInput, strlen(szInput) + 1,
2257 szOutput,
sizeof(szOutput) /
sizeof(SI_CHAR));
2260 return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace,
true);
2263 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2266 const SI_CHAR *a_pSection,
2267 const SI_CHAR *a_pKey,
2269 bool *a_pHasMultiple
2272 const SI_CHAR *pszValue =
GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple);
2274 if (!pszValue || !*pszValue) {
2279 switch (pszValue[0]) {
2296 if (pszValue[1] ==
'n' || pszValue[1] ==
'N') {
2300 if (pszValue[1] ==
'f' || pszValue[1] ==
'F') {
2311 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2314 const SI_CHAR *a_pSection,
2315 const SI_CHAR *a_pKey,
2317 const SI_CHAR *a_pComment,
2318 bool a_bForceReplace
2321 if (!a_pSection || !a_pKey) {
2326 const char *pszInput = a_bValue ?
"true" :
"false";
2329 SI_CHAR szOutput[64];
2330 SI_CONVERTER c(m_bStoreIsUtf8);
2331 c.ConvertFromStore(pszInput, strlen(pszInput) + 1,
2332 szOutput,
sizeof(szOutput) /
sizeof(SI_CHAR));
2335 return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace,
true);
2338 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2341 const SI_CHAR *a_pSection,
2342 const SI_CHAR *a_pKey,
2347 if (!a_pSection || !a_pKey) {
2351 typename TSection::const_iterator iSection = m_data.find(a_pSection);
2353 if (iSection == m_data.end()) {
2357 typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey);
2359 if (iKeyVal == iSection->second.end()) {
2364 a_values.push_back(
Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder));
2366 if (m_bAllowMultiKey) {
2369 while (iKeyVal != iSection->second.end() && !IsLess(a_pKey, iKeyVal->first.pItem)) {
2370 a_values.push_back(
Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder));
2378 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2381 const SI_CHAR *a_pSection
2387 typename TSection::const_iterator iSection = m_data.find(a_pSection);
2389 if (iSection == m_data.end()) {
2393 const TKeyVal §ion = iSection->second;
2397 if (!m_bAllowMultiKey || section.empty()) {
2398 return (
int) section.size();
2403 const SI_CHAR *pLastKey = NULL;
2404 typename TKeyVal::const_iterator iKeyVal = section.begin();
2406 for (
int n = 0; iKeyVal != section.end(); ++iKeyVal, ++n) {
2407 if (!pLastKey || IsLess(pLastKey, iKeyVal->first.pItem)) {
2409 pLastKey = iKeyVal->first.pItem;
2416 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2419 const SI_CHAR *a_pSection
2422 typename TSection::const_iterator i = m_data.find(a_pSection);
2424 if (i != m_data.end()) {
2425 return &(i->second);
2432 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2438 typename TSection::const_iterator i = m_data.begin();
2440 for (
int n = 0; i != m_data.end(); ++i, ++n) {
2441 a_names.push_back(i->first);
2445 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2448 const SI_CHAR *a_pSection,
2457 typename TSection::const_iterator iSection = m_data.find(a_pSection);
2459 if (iSection == m_data.end()) {
2463 const TKeyVal §ion = iSection->second;
2464 const SI_CHAR *pLastKey = NULL;
2465 typename TKeyVal::const_iterator iKeyVal = section.begin();
2467 for (
int n = 0; iKeyVal != section.end(); ++iKeyVal, ++n) {
2468 if (!pLastKey || IsLess(pLastKey, iKeyVal->first.pItem)) {
2469 a_names.push_back(iKeyVal->first);
2470 pLastKey = iKeyVal->first.pItem;
2477 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2480 const char *a_pszFile,
2481 bool a_bAddSignature
2484 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 2485 fopen_s(&fp, a_pszFile,
"wb");
2486 #else // !__STDC_WANT_SECURE_LIB__ 2487 fp = fopen(a_pszFile,
"wb");
2488 #endif // __STDC_WANT_SECURE_LIB__ 2494 SI_Error rc =
SaveFile(fp, a_bAddSignature);
2499 #ifdef SI_HAS_WIDE_FILE 2500 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2503 const SI_WCHAR_T *a_pwszFile,
2504 bool a_bAddSignature
2508 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 2509 _wfopen_s(&fp, a_pwszFile, L
"wb");
2510 #else // !__STDC_WANT_SECURE_LIB__ 2511 fp = _wfopen(a_pwszFile, L
"wb");
2512 #endif // __STDC_WANT_SECURE_LIB__ 2518 SI_Error rc =
SaveFile(fp, a_bAddSignature);
2521 #else // !_WIN32 (therefore SI_CONVERT_ICU) 2523 u_austrncpy(szFile, a_pwszFile,
sizeof(szFile));
2524 return SaveFile(szFile, a_bAddSignature);
2527 #endif // SI_HAS_WIDE_FILE 2529 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2533 bool a_bAddSignature
2536 return Save(writer, a_bAddSignature);
2539 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2543 bool a_bAddSignature
2548 if (m_bStoreIsUtf8 && a_bAddSignature) {
2549 a_oOutput.Write(SI_UTF8_SIGNATURE);
2555 #if defined(_MSC_VER) && _MSC_VER <= 1200 2557 #elif defined(__BORLANDC__) 2564 bool bNeedNewLine =
false;
2566 if (m_pFileComment) {
2567 if (!OutputMultiLineText(a_oOutput, convert, m_pFileComment)) {
2571 bNeedNewLine =
true;
2575 typename TNamesDepend::const_iterator iSection = oSections.begin();
2577 for (; iSection != oSections.end(); ++iSection) {
2579 if (iSection->pComment) {
2581 a_oOutput.Write(SI_NEWLINE_A);
2582 a_oOutput.Write(SI_NEWLINE_A);
2585 if (!OutputMultiLineText(a_oOutput, convert, iSection->pComment)) {
2589 bNeedNewLine =
false;
2593 a_oOutput.Write(SI_NEWLINE_A);
2594 a_oOutput.Write(SI_NEWLINE_A);
2595 bNeedNewLine =
false;
2599 if (*iSection->pItem) {
2600 if (!convert.ConvertToStore(iSection->pItem)) {
2604 a_oOutput.Write(
"[");
2605 a_oOutput.Write(convert.Data());
2606 a_oOutput.Write(
"]");
2607 a_oOutput.Write(SI_NEWLINE_A);
2613 #if defined(_MSC_VER) && _MSC_VER <= 1200 2615 #elif defined(__BORLANDC__) 2622 typename TNamesDepend::const_iterator iKey = oKeys.begin();
2624 for (; iKey != oKeys.end(); ++iKey) {
2629 typename TNamesDepend::const_iterator iValue = oValues.begin();
2631 for (; iValue != oValues.end(); ++iValue) {
2633 if (iValue->pComment) {
2634 a_oOutput.Write(SI_NEWLINE_A);
2636 if (!OutputMultiLineText(a_oOutput, convert, iValue->pComment)) {
2642 if (!convert.ConvertToStore(iKey->pItem)) {
2646 a_oOutput.Write(convert.Data());
2649 if (!convert.ConvertToStore(iValue->pItem)) {
2653 a_oOutput.Write(m_bSpaces ?
" = " :
"=");
2655 if (m_bAllowMultiLine && IsMultiLineData(iValue->pItem)) {
2658 a_oOutput.Write(
"<<<END_OF_TEXT" SI_NEWLINE_A);
2660 if (!OutputMultiLineText(a_oOutput, convert, iValue->pItem)) {
2664 a_oOutput.Write(
"END_OF_TEXT");
2666 a_oOutput.Write(convert.Data());
2669 a_oOutput.Write(SI_NEWLINE_A);
2673 bNeedNewLine =
true;
2679 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2684 const SI_CHAR *a_pText
2686 const SI_CHAR *pEndOfLine;
2687 SI_CHAR cEndOfLineChar = *a_pText;
2689 while (cEndOfLineChar) {
2691 pEndOfLine = a_pText;
2693 for (; *pEndOfLine && *pEndOfLine !=
'\n'; ++pEndOfLine) ;
2695 cEndOfLineChar = *pEndOfLine;
2698 *
const_cast<SI_CHAR *
>(pEndOfLine) = 0;
2700 if (!a_oConverter.ConvertToStore(a_pText)) {
2704 *
const_cast<SI_CHAR *
>(pEndOfLine) = cEndOfLineChar;
2705 a_pText += (pEndOfLine - a_pText) + 1;
2706 a_oOutput.Write(a_oConverter.Data());
2707 a_oOutput.Write(SI_NEWLINE_A);
2713 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2716 const SI_CHAR *a_pSection,
2717 const SI_CHAR *a_pKey,
2720 return DeleteValue(a_pSection, a_pKey, NULL, a_bRemoveEmpty);
2723 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2726 const SI_CHAR *a_pSection,
2727 const SI_CHAR *a_pKey,
2728 const SI_CHAR *a_pValue,
2735 typename TSection::iterator iSection = m_data.find(a_pSection);
2737 if (iSection == m_data.end()) {
2743 typename TKeyVal::iterator iKeyVal = iSection->second.find(a_pKey);
2745 if (iKeyVal == iSection->second.end()) {
2749 const static SI_STRLESS isLess = SI_STRLESS();
2752 typename TKeyVal::iterator iDelete;
2753 bool bDeleted =
false;
2756 iDelete = iKeyVal++;
2758 if (a_pValue == NULL ||
2759 (isLess(a_pValue, iDelete->second) ==
false &&
2760 isLess(iDelete->second, a_pValue) ==
false)) {
2761 DeleteString(iDelete->first.pItem);
2762 DeleteString(iDelete->second);
2763 iSection->second.erase(iDelete);
2766 }
while (iKeyVal != iSection->second.end()
2767 && !IsLess(a_pKey, iKeyVal->first.pItem));
2776 if (!a_bRemoveEmpty || !iSection->second.empty()) {
2782 typename TKeyVal::iterator iKeyVal = iSection->second.begin();
2784 for (; iKeyVal != iSection->second.end(); ++iKeyVal) {
2785 DeleteString(iKeyVal->first.pItem);
2786 DeleteString(iKeyVal->second);
2791 DeleteString(iSection->first.pItem);
2792 m_data.erase(iSection);
2797 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2800 const SI_CHAR *a_pString
2805 if (a_pString < m_pData || a_pString >= m_pData + m_uDataLen) {
2806 typename TNamesDepend::iterator i = m_strings.begin();
2808 for (; i != m_strings.end(); ++i) {
2809 if (a_pString == i->pItem) {
2810 delete[]
const_cast<SI_CHAR *
>(i->pItem);
2832 #if !defined(SI_CONVERT_GENERIC) && !defined(SI_CONVERT_WIN32) && !defined(SI_CONVERT_ICU) 2834 # define SI_CONVERT_WIN32 2836 # define SI_CONVERT_GENERIC 2845 template<
class SI_CHAR>
2847 bool operator()(
const SI_CHAR *pLeft,
const SI_CHAR *pRight)
const {
2850 for (; *pLeft && *pRight; ++pLeft, ++pRight) {
2851 cmp = (long) * pLeft - (
long) * pRight;
2858 return *pRight != 0;
2868 template<
class SI_CHAR>
2870 inline SI_CHAR locase(SI_CHAR ch)
const {
2871 return (ch < 'A' || ch >
'Z') ? ch : (ch -
'A' +
'a');
2873 bool operator()(
const SI_CHAR *pLeft,
const SI_CHAR *pRight)
const {
2876 for (; *pLeft && *pRight; ++pLeft, ++pRight) {
2877 cmp = (long) locase(*pLeft) - (long) locase(*pRight);
2884 return *pRight != 0;
2891 template<
class SI_CHAR>
2893 bool m_bStoreIsUtf8;
2897 SI_ConvertA(
bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { }
2904 m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8;
2922 const char *a_pInputData,
2923 size_t a_uInputDataLen) {
2925 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
2928 return a_uInputDataLen;
2945 const char *a_pInputData,
2946 size_t a_uInputDataLen,
2947 SI_CHAR *a_pOutputData,
2948 size_t a_uOutputDataSize) {
2950 if (a_uInputDataLen > a_uOutputDataSize) {
2954 memcpy(a_pOutputData, a_pInputData, a_uInputDataLen);
2969 const SI_CHAR *a_pInputData) {
2971 return strlen((
const char *)a_pInputData) + 1;
2988 const SI_CHAR *a_pInputData,
2989 char *a_pOutputData,
2990 size_t a_uOutputDataSize) {
2992 size_t uInputLen = strlen((
const char *)a_pInputData) + 1;
2994 if (uInputLen > a_uOutputDataSize) {
2999 memcpy(a_pOutputData, a_pInputData, uInputLen);
3008 #ifdef SI_CONVERT_GENERIC 3010 #define SI_Case SI_GenericCase 3011 #define SI_NoCase SI_GenericNoCase 3014 #include "ConvertUTF.h" 3020 template<
class SI_CHAR>
3022 bool m_bStoreIsUtf8;
3026 SI_ConvertW(
bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { }
3033 m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8;
3051 const char *a_pInputData,
3052 size_t a_uInputDataLen) {
3053 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
3055 if (m_bStoreIsUtf8) {
3059 return a_uInputDataLen;
3062 #if defined(SI_NO_MBSTOWCS_NULL) || (!defined(_MSC_VER) && !defined(_linux)) 3066 return a_uInputDataLen;
3069 return mbstowcs(NULL, a_pInputData, a_uInputDataLen);
3087 const char *a_pInputData,
3088 size_t a_uInputDataLen,
3089 SI_CHAR *a_pOutputData,
3090 size_t a_uOutputDataSize) {
3091 if (m_bStoreIsUtf8) {
3097 ConversionResult retval;
3098 const UTF8 *pUtf8 = (
const UTF8 *) a_pInputData;
3100 if (
sizeof(
wchar_t) ==
sizeof(UTF32)) {
3101 UTF32 *pUtf32 = (UTF32 *) a_pOutputData;
3102 retval = ConvertUTF8toUTF32(
3103 &pUtf8, pUtf8 + a_uInputDataLen,
3104 &pUtf32, pUtf32 + a_uOutputDataSize,
3106 }
else if (
sizeof(
wchar_t) ==
sizeof(UTF16)) {
3107 UTF16 *pUtf16 = (UTF16 *) a_pOutputData;
3108 retval = ConvertUTF8toUTF16(
3109 &pUtf8, pUtf8 + a_uInputDataLen,
3110 &pUtf16, pUtf16 + a_uOutputDataSize,
3114 return retval == conversionOK;
3118 size_t retval = mbstowcs(a_pOutputData,
3119 a_pInputData, a_uOutputDataSize);
3120 return retval != (size_t)(-1);
3134 const SI_CHAR *a_pInputData) {
3135 if (m_bStoreIsUtf8) {
3139 while (a_pInputData[uLen]) {
3143 return (6 * uLen) + 1;
3145 size_t uLen = wcstombs(NULL, a_pInputData, 0);
3147 if (uLen == (
size_t)(-1)) {
3169 const SI_CHAR *a_pInputData,
3170 char *a_pOutputData,
3171 size_t a_uOutputDataSize
3173 if (m_bStoreIsUtf8) {
3175 size_t uInputLen = 0;
3177 while (a_pInputData[uInputLen]) {
3188 ConversionResult retval;
3189 UTF8 *pUtf8 = (UTF8 *) a_pOutputData;
3191 if (
sizeof(
wchar_t) ==
sizeof(UTF32)) {
3192 const UTF32 *pUtf32 = (
const UTF32 *) a_pInputData;
3193 retval = ConvertUTF32toUTF8(
3194 &pUtf32, pUtf32 + uInputLen,
3195 &pUtf8, pUtf8 + a_uOutputDataSize,
3197 }
else if (
sizeof(
wchar_t) ==
sizeof(UTF16)) {
3198 const UTF16 *pUtf16 = (
const UTF16 *) a_pInputData;
3199 retval = ConvertUTF16toUTF8(
3200 &pUtf16, pUtf16 + uInputLen,
3201 &pUtf8, pUtf8 + a_uOutputDataSize,
3205 return retval == conversionOK;
3207 size_t retval = wcstombs(a_pOutputData,
3208 a_pInputData, a_uOutputDataSize);
3209 return retval != (size_t) -1;
3214 #endif // SI_CONVERT_GENERIC 3220 #ifdef SI_CONVERT_ICU 3222 #define SI_Case SI_GenericCase 3223 #define SI_NoCase SI_GenericNoCase 3225 #include <unicode/ucnv.h> 3230 template<
class SI_CHAR>
3232 const char *m_pEncoding;
3233 UConverter *m_pConverter;
3235 SI_ConvertW() : m_pEncoding(NULL), m_pConverter(NULL) { }
3237 SI_ConvertW(
bool a_bStoreIsUtf8) : m_pConverter(NULL) {
3238 m_pEncoding = a_bStoreIsUtf8 ?
"UTF-8" : NULL;
3246 m_pEncoding = rhs.m_pEncoding;
3247 m_pConverter = NULL;
3252 ucnv_close(m_pConverter);
3269 size_t SizeFromStore(
3270 const char *a_pInputData,
3271 size_t a_uInputDataLen) {
3272 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
3276 if (!m_pConverter) {
3277 nError = U_ZERO_ERROR;
3278 m_pConverter = ucnv_open(m_pEncoding, &nError);
3280 if (U_FAILURE(nError)) {
3285 nError = U_ZERO_ERROR;
3286 int32_t nLen = ucnv_toUChars(m_pConverter, NULL, 0,
3287 a_pInputData, (int32_t) a_uInputDataLen, &nError);
3289 if (U_FAILURE(nError) && nError != U_BUFFER_OVERFLOW_ERROR) {
3293 return (
size_t) nLen;
3309 bool ConvertFromStore(
3310 const char *a_pInputData,
3311 size_t a_uInputDataLen,
3312 UChar *a_pOutputData,
3313 size_t a_uOutputDataSize) {
3316 if (!m_pConverter) {
3317 nError = U_ZERO_ERROR;
3318 m_pConverter = ucnv_open(m_pEncoding, &nError);
3320 if (U_FAILURE(nError)) {
3325 nError = U_ZERO_ERROR;
3326 ucnv_toUChars(m_pConverter,
3327 a_pOutputData, (int32_t) a_uOutputDataSize,
3328 a_pInputData, (int32_t) a_uInputDataLen, &nError);
3330 if (U_FAILURE(nError)) {
3348 const UChar *a_pInputData) {
3351 if (!m_pConverter) {
3352 nError = U_ZERO_ERROR;
3353 m_pConverter = ucnv_open(m_pEncoding, &nError);
3355 if (U_FAILURE(nError)) {
3360 nError = U_ZERO_ERROR;
3361 int32_t nLen = ucnv_fromUChars(m_pConverter, NULL, 0,
3362 a_pInputData, -1, &nError);
3364 if (U_FAILURE(nError) && nError != U_BUFFER_OVERFLOW_ERROR) {
3368 return (
size_t) nLen + 1;
3384 bool ConvertToStore(
3385 const UChar *a_pInputData,
3386 char *a_pOutputData,
3387 size_t a_uOutputDataSize) {
3390 if (!m_pConverter) {
3391 nError = U_ZERO_ERROR;
3392 m_pConverter = ucnv_open(m_pEncoding, &nError);
3394 if (U_FAILURE(nError)) {
3399 nError = U_ZERO_ERROR;
3400 ucnv_fromUChars(m_pConverter,
3401 a_pOutputData, (int32_t) a_uOutputDataSize,
3402 a_pInputData, -1, &nError);
3404 if (U_FAILURE(nError)) {
3412 #endif // SI_CONVERT_ICU 3418 #ifdef SI_CONVERT_WIN32 3420 #define SI_Case SI_GenericCase 3429 #include <windows.h> 3431 # define SI_NoCase SI_GenericNoCase 3432 #else // !SI_NO_MBCS 3441 #include <mbstring.h> 3442 template<
class SI_CHAR>
3444 bool operator()(
const SI_CHAR *pLeft,
const SI_CHAR *pRight)
const {
3445 if (
sizeof(SI_CHAR) ==
sizeof(
char)) {
3446 return _mbsicmp((
const unsigned char *)pLeft,
3447 (
const unsigned char *)pRight) < 0;
3450 if (
sizeof(SI_CHAR) ==
sizeof(
wchar_t)) {
3451 return _wcsicmp((
const wchar_t *)pLeft,
3452 (
const wchar_t *)pRight) < 0;
3458 #endif // SI_NO_MBCS 3466 template<
class SI_CHAR>
3473 m_uCodePage = a_bStoreIsUtf8 ? CP_UTF8 : CP_ACP;
3481 m_uCodePage = rhs.m_uCodePage;
3498 size_t SizeFromStore(
3499 const char *a_pInputData,
3500 size_t a_uInputDataLen) {
3501 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
3503 int retval = MultiByteToWideChar(
3505 a_pInputData, (
int) a_uInputDataLen,
3507 return (
size_t)(retval > 0 ? retval : -1);
3523 bool ConvertFromStore(
3524 const char *a_pInputData,
3525 size_t a_uInputDataLen,
3526 SI_CHAR *a_pOutputData,
3527 size_t a_uOutputDataSize) {
3528 int nSize = MultiByteToWideChar(
3530 a_pInputData, (
int) a_uInputDataLen,
3531 (
wchar_t *) a_pOutputData, (
int) a_uOutputDataSize);
3546 const SI_CHAR *a_pInputData) {
3547 int retval = WideCharToMultiByte(
3549 (
const wchar_t *) a_pInputData, -1,
3551 return (
size_t)(retval > 0 ? retval : -1);
3567 bool ConvertToStore(
3568 const SI_CHAR *a_pInputData,
3569 char *a_pOutputData,
3570 size_t a_uOutputDataSize) {
3571 int retval = WideCharToMultiByte(
3573 (
const wchar_t *) a_pInputData, -1,
3574 a_pOutputData, (
int) a_uOutputDataSize, 0, 0);
3579 #endif // SI_CONVERT_WIN32 3591 #if defined(SI_CONVERT_ICU) 3604 # define CSimpleIni CSimpleIniW 3605 # define CSimpleIniCase CSimpleIniCaseW 3606 # define SI_NEWLINE SI_NEWLINE_W 3608 # define CSimpleIni CSimpleIniA 3609 # define CSimpleIniCase CSimpleIniCaseA 3610 # define SI_NEWLINE SI_NEWLINE_A 3614 # pragma warning (pop) 3617 #endif // INCLUDED_SimpleIni_h Definition: SimpleIni.h:2892
void SetSpaces(bool a_bSpaces=true)
Definition: SimpleIni.h:561
bool GetAllKeys(const SI_CHAR *a_pSection, TNamesDepend &a_names) const
Definition: SimpleIni.h:2447
SI_Error SetValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, const SI_CHAR *a_pValue, const SI_CHAR *a_pComment=NULL, bool a_bForceReplace=false)
Definition: SimpleIni.h:986
Definition: SimpleIni.h:2846
Definition: SimpleIni.h:344
void SetMultiLine(bool a_bAllowMultiLine=true)
Definition: SimpleIni.h:546
SI_Error LoadFile(const char *a_pszFile)
Definition: SimpleIni.h:1349
bool GetAllValues(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, TNamesDepend &a_values) const
Definition: SimpleIni.h:2340
double GetDoubleValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, double a_nDefault=0, bool *a_pHasMultiple=NULL) const
Definition: SimpleIni.h:2199
Definition: SimpleIni.h:295
Definition: SimpleIni.h:423
CSimpleIniTempl(bool a_bIsUtf8=false, bool a_bMultiKey=false, bool a_bMultiLine=false)
Definition: SimpleIni.h:1302
SI_Error Save(OutputWriter &a_oOutput, bool a_bAddSignature=false) const
Definition: SimpleIni.h:2541
const SI_CHAR * GetValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, const SI_CHAR *a_pDefault=NULL, bool *a_pHasMultiple=NULL) const
Definition: SimpleIni.h:2079
bool DeleteValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, const SI_CHAR *a_pValue, bool a_bRemoveEmpty=false)
Definition: SimpleIni.h:2725
void GetAllSections(TNamesDepend &a_names) const
Definition: SimpleIni.h:2434
bool GetBoolValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, bool a_bDefault=false, bool *a_pHasMultiple=NULL) const
Definition: SimpleIni.h:2265
Definition: SimpleIni.h:3021
SI_Error SetDoubleValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, double a_nValue, const SI_CHAR *a_pComment=NULL, bool a_bForceReplace=false)
Definition: SimpleIni.h:2233
Definition: SimpleIni.h:380
size_t SizeFromStore(const char *a_pInputData, size_t a_uInputDataLen)
Definition: SimpleIni.h:2921
bool Delete(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, bool a_bRemoveEmpty=false)
Definition: SimpleIni.h:2715
bool IsMultiKey() const
Definition: SimpleIni.h:535
SI_Error SetLongValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, long a_nValue, const SI_CHAR *a_pComment=NULL, bool a_bUseHex=false, bool a_bForceReplace=false)
Definition: SimpleIni.h:2166
Converter GetConverter() const
Definition: SimpleIni.h:1143
size_t SizeToStore(const SI_CHAR *a_pInputData)
Definition: SimpleIni.h:2968
Definition: SimpleIni.h:393
Definition: SimpleIni.h:300
bool UsingSpaces() const
Definition: SimpleIni.h:566
bool ConvertToStore(const SI_CHAR *a_pInputData, char *a_pOutputData, size_t a_uOutputDataSize)
Definition: SimpleIni.h:3168
std::map< Entry, TKeyVal, typename Entry::KeyOrder > TSection
Definition: SimpleIni.h:359
void Reset()
Definition: SimpleIni.h:1324
SI_Error SaveFile(const char *a_pszFile, bool a_bAddSignature=true) const
Definition: SimpleIni.h:2479
Definition: SimpleIni.h:336
SI_Error LoadData(const std::string &a_strData)
Definition: SimpleIni.h:626
const TKeyVal * GetSection(const SI_CHAR *a_pSection) const
Definition: SimpleIni.h:2418
void SetUnicode(bool a_bIsUtf8=true)
Definition: SimpleIni.h:501
void SetMultiKey(bool a_bAllowMultiKey=true)
Definition: SimpleIni.h:530
bool ConvertFromStore(const char *a_pInputData, size_t a_uInputDataLen, SI_CHAR *a_pOutputData, size_t a_uOutputDataSize)
Definition: SimpleIni.h:2944
bool IsMultiLine() const
Definition: SimpleIni.h:551
int GetSectionSize(const SI_CHAR *a_pSection) const
Definition: SimpleIni.h:2380
bool ConvertFromStore(const char *a_pInputData, size_t a_uInputDataLen, SI_CHAR *a_pOutputData, size_t a_uOutputDataSize)
Definition: SimpleIni.h:3086
bool ConvertToStore(const SI_CHAR *a_pInputData, char *a_pOutputData, size_t a_uOutputDataSize)
Definition: SimpleIni.h:2987
bool IsEmpty() const
Definition: SimpleIni.h:480
bool IsUnicode() const
Definition: SimpleIni.h:508
size_t SizeFromStore(const char *a_pInputData, size_t a_uInputDataLen)
Definition: SimpleIni.h:3050
Definition: SimpleIni.h:369
std::list< Entry > TNamesDepend
Definition: SimpleIni.h:364
~CSimpleIniTempl()
Definition: SimpleIni.h:1318
Definition: SimpleIni.h:2869
std::multimap< Entry, const SI_CHAR *, typename Entry::KeyOrder > TKeyVal
Definition: SimpleIni.h:356
long GetLongValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, long a_nDefault=0, bool *a_pHasMultiple=NULL) const
Definition: SimpleIni.h:2121
SI_Error SetBoolValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, bool a_bValue, const SI_CHAR *a_pComment=NULL, bool a_bForceReplace=false)
Definition: SimpleIni.h:2313
size_t SizeToStore(const SI_CHAR *a_pInputData)
Definition: SimpleIni.h:3133