194 #ifndef INCLUDED_SimpleIni_h 195 #define INCLUDED_SimpleIni_h 197 #if defined(_MSC_VER) && (_MSC_VER >= 1020) 211 # pragma warning (push) 212 # pragma warning (disable: 4127 4503 4702 4786) 222 #ifdef SI_SUPPORT_IOSTREAMS 224 #endif // SI_SUPPORT_IOSTREAMS 230 # define SI_ASSERT(x) assert(x) 232 # define SI_ASSERT(x) 246 #define SI_UTF8_SIGNATURE "\xEF\xBB\xBF" 249 # define SI_NEWLINE_A "\r\n" 250 # define SI_NEWLINE_W L"\r\n" 252 # define SI_NEWLINE_A "\n" 253 # define SI_NEWLINE_W L"\n" 256 #if defined(SI_CONVERT_ICU) 257 # include <unicode/ustring.h> 261 # define SI_HAS_WIDE_FILE 262 # define SI_WCHAR_T wchar_t 263 #elif defined(SI_CONVERT_ICU) 264 # define SI_HAS_WIDE_FILE 265 # define SI_WCHAR_T UChar 292 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
302 Entry(
const SI_CHAR * a_pszItem = NULL,
int a_nOrder = 0)
307 Entry(
const SI_CHAR * a_pszItem,
const SI_CHAR * a_pszComment,
int a_nOrder)
309 , pComment(a_pszComment)
320 #if defined(_MSC_VER) && _MSC_VER <= 1200 323 bool operator>(
const Entry & rhs)
const {
return LoadOrder()(rhs, *
this); }
327 struct KeyOrder : std::binary_function<Entry, Entry, bool> {
329 const static SI_STRLESS isLess = SI_STRLESS();
335 struct LoadOrder : std::binary_function<Entry, Entry, bool> {
346 typedef std::multimap<Entry,const SI_CHAR *,typename Entry::KeyOrder>
TKeyVal;
349 typedef std::map<Entry,TKeyVal,typename Entry::KeyOrder>
TSection;
363 virtual void Write(
const char * a_pBuf) = 0;
375 fputs(a_pBuf, m_file);
388 m_string.append(a_pBuf);
395 #ifdef SI_SUPPORT_IOSTREAMS 398 std::ostream & m_ostream;
400 StreamWriter(std::ostream & a_ostream) : m_ostream(a_ostream) { }
401 void Write(
const char * a_pBuf) {
405 StreamWriter(
const StreamWriter &);
406 StreamWriter &
operator=(
const StreamWriter &);
408 #endif // SI_SUPPORT_IOSTREAMS 415 Converter(
bool a_bStoreIsUtf8) : SI_CONVERTER(a_bStoreIsUtf8) {
416 m_scratch.resize(1024);
424 size_t uLen = SI_CONVERTER::SizeToStore(a_pszString);
425 if (uLen == (
size_t)(-1)) {
428 while (uLen > m_scratch.size()) {
429 m_scratch.resize(m_scratch.size() * 2);
431 return SI_CONVERTER::ConvertToStore(
433 const_cast<char*>(m_scratch.data()),
436 const char *
Data() {
return m_scratch.data(); }
451 bool a_bIsUtf8 =
false,
452 bool a_bMultiKey =
false,
453 bool a_bMultiLine =
false 554 const char * a_pszFile
557 #ifdef SI_HAS_WIDE_FILE 565 const SI_WCHAR_T * a_pwszFile
567 #endif // SI_HAS_WIDE_FILE 580 #ifdef SI_SUPPORT_IOSTREAMS 588 std::istream & a_istream
590 #endif // SI_SUPPORT_IOSTREAMS 599 return LoadData(a_strData.c_str(), a_strData.size());
610 const char * a_pData,
631 const char * a_pszFile,
632 bool a_bAddSignature =
true 635 #ifdef SI_HAS_WIDE_FILE 647 const SI_WCHAR_T * a_pwszFile,
648 bool a_bAddSignature =
true 666 bool a_bAddSignature =
false 702 bool a_bAddSignature =
false 705 #ifdef SI_SUPPORT_IOSTREAMS 718 std::ostream & a_ostream,
719 bool a_bAddSignature =
false 722 StreamWriter writer(a_ostream);
723 return Save(writer, a_bAddSignature);
725 #endif // SI_SUPPORT_IOSTREAMS 739 std::string & a_sBuffer,
740 bool a_bAddSignature =
false 744 return Save(writer, a_bAddSignature);
766 TNamesDepend & a_names
787 const SI_CHAR * a_pSection,
788 TNamesDepend & a_names
808 const SI_CHAR * a_pSection,
809 const SI_CHAR * a_pKey,
810 TNamesDepend & a_values
823 const SI_CHAR * a_pSection
841 const SI_CHAR * a_pSection
862 const SI_CHAR * a_pSection,
863 const SI_CHAR * a_pKey,
864 const SI_CHAR * a_pDefault =
NULL,
865 bool * a_pHasMultiple =
NULL 882 const SI_CHAR * a_pSection,
883 const SI_CHAR * a_pKey,
885 bool * a_pHasMultiple =
NULL 902 const SI_CHAR * a_pSection,
903 const SI_CHAR * a_pKey,
904 double a_nDefault = 0,
905 bool * a_pHasMultiple =
NULL 927 const SI_CHAR * a_pSection,
928 const SI_CHAR * a_pKey,
929 bool a_bDefault =
false,
930 bool * a_pHasMultiple =
NULL 963 const SI_CHAR * a_pSection,
964 const SI_CHAR * a_pKey,
965 const SI_CHAR * a_pValue,
966 const SI_CHAR * a_pComment =
NULL,
967 bool a_bForceReplace =
false 970 return AddEntry(a_pSection, a_pKey, a_pValue, a_pComment, a_bForceReplace,
true);
997 const SI_CHAR * a_pSection,
998 const SI_CHAR * a_pKey,
1000 const SI_CHAR * a_pComment =
NULL,
1001 bool a_bUseHex =
false,
1002 bool a_bForceReplace =
false 1026 const SI_CHAR * a_pSection,
1027 const SI_CHAR * a_pKey,
1029 const SI_CHAR * a_pComment =
NULL,
1030 bool a_bForceReplace =
false 1054 const SI_CHAR * a_pSection,
1055 const SI_CHAR * a_pKey,
1057 const SI_CHAR * a_pComment =
NULL,
1058 bool a_bForceReplace =
false 1080 const SI_CHAR * a_pSection,
1081 const SI_CHAR * a_pKey,
1082 bool a_bRemoveEmpty =
false 1119 const SI_CHAR *& a_pSection,
1120 const SI_CHAR *& a_pKey,
1121 const SI_CHAR *& a_pVal,
1122 const SI_CHAR *& a_pComment
1148 const SI_CHAR * a_pSection,
1149 const SI_CHAR * a_pKey,
1150 const SI_CHAR * a_pValue,
1151 const SI_CHAR * a_pComment,
1152 bool a_bForceReplace,
1157 inline bool IsSpace(SI_CHAR ch)
const {
1158 return (ch ==
' ' || ch ==
'\t' || ch ==
'\r' || ch ==
'\n');
1162 inline bool IsComment(SI_CHAR ch)
const {
1163 return (ch ==
';' || ch ==
'#');
1168 inline void SkipNewLine(SI_CHAR *& a_pData)
const {
1169 a_pData += (*a_pData ==
'\r' && *(a_pData+1) ==
'\n') ? 2 : 1;
1179 bool IsLess(
const SI_CHAR * a_pLeft,
const SI_CHAR * a_pRight)
const {
1180 const static SI_STRLESS isLess = SI_STRLESS();
1181 return isLess(a_pLeft, a_pRight);
1188 const SI_CHAR *& a_pVal,
1189 const SI_CHAR * a_pTagName,
1190 bool a_bAllowBlankLinesInComment =
false 1197 const SI_CHAR * a_pText
1248 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1251 bool a_bAllowMultiKey,
1252 bool a_bAllowMultiLine
1264 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1270 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1285 typename TNamesDepend::iterator i =
m_strings.begin();
1287 delete[]
const_cast<SI_CHAR*
>(i->pItem);
1293 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1296 const char * a_pszFile
1300 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 1301 fopen_s(&fp, a_pszFile,
"rb");
1302 #else // !__STDC_WANT_SECURE_LIB__ 1303 fp = fopen(a_pszFile,
"rb");
1304 #endif // __STDC_WANT_SECURE_LIB__ 1313 #ifdef SI_HAS_WIDE_FILE 1314 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1317 const SI_WCHAR_T * a_pwszFile
1322 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 1323 _wfopen_s(&fp, a_pwszFile, L
"rb");
1324 #else // !__STDC_WANT_SECURE_LIB__ 1325 fp = _wfopen(a_pwszFile, L
"rb");
1326 #endif // __STDC_WANT_SECURE_LIB__ 1331 #else // !_WIN32 (therefore SI_CONVERT_ICU) 1333 u_austrncpy(szFile, a_pwszFile,
sizeof(szFile));
1337 #endif // SI_HAS_WIDE_FILE 1339 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1346 int retval = fseek(a_fpFile, 0, SEEK_END);
1350 long lSize = ftell(a_fpFile);
1357 char * pData =
new char[lSize];
1361 fseek(a_fpFile, 0, SEEK_SET);
1362 size_t uRead = fread(pData,
sizeof(
char), lSize, a_fpFile);
1363 if (uRead != (
size_t) lSize) {
1374 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1377 const char * a_pData,
1383 if (a_uDataLen == 0) {
1396 size_t uLen = converter.SizeFromStore(a_pData, a_uDataLen);
1397 if (uLen == (
size_t)(-1)) {
1403 SI_CHAR * pData =
new SI_CHAR[uLen+1];
1407 memset(pData, 0,
sizeof(SI_CHAR)*(uLen+1));
1410 if (!converter.ConvertFromStore(a_pData, a_uDataLen, pData, uLen)) {
1416 const static SI_CHAR empty = 0;
1417 SI_CHAR * pWork = pData;
1418 const SI_CHAR * pSection = ∅
1419 const SI_CHAR * pItem =
NULL;
1420 const SI_CHAR * pVal =
NULL;
1421 const SI_CHAR * pComment =
NULL;
1430 if (rc < 0)
return rc;
1433 while (
FindEntry(pWork, pSection, pItem, pVal, pComment)) {
1434 rc =
AddEntry(pSection, pItem, pVal, pComment,
false, bCopyStrings);
1435 if (rc < 0)
return rc;
1450 #ifdef SI_SUPPORT_IOSTREAMS 1451 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1454 std::istream & a_istream
1457 std::string strData;
1460 a_istream.get(szBuf,
sizeof(szBuf),
'\0');
1461 strData.append(szBuf);
1463 while (a_istream.good());
1466 #endif // SI_SUPPORT_IOSTREAMS 1468 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1487 if (a_bCopyStrings) {
1489 if (rc < 0)
return rc;
1495 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1499 const SI_CHAR *& a_pSection,
1500 const SI_CHAR *& a_pKey,
1501 const SI_CHAR *& a_pVal,
1502 const SI_CHAR *& a_pComment
1507 SI_CHAR * pTrail =
NULL;
1510 while (*a_pData &&
IsSpace(*a_pData)) {
1525 if (*a_pData ==
'[') {
1528 while (*a_pData &&
IsSpace(*a_pData)) {
1534 a_pSection = a_pData;
1535 while (*a_pData && *a_pData !=
']' && !
IsNewLineChar(*a_pData)) {
1540 if (*a_pData !=
']') {
1545 pTrail = a_pData - 1;
1546 while (pTrail >= a_pSection &&
IsSpace(*pTrail)) {
1566 while (*a_pData && *a_pData !=
'=' && !
IsNewLineChar(*a_pData)) {
1571 if (*a_pData !=
'=') {
1576 if (a_pKey == a_pData) {
1584 pTrail = a_pData - 1;
1585 while (pTrail >= a_pKey &&
IsSpace(*pTrail)) {
1604 pTrail = a_pData - 1;
1608 while (pTrail >= a_pVal &&
IsSpace(*pTrail)) {
1617 const SI_CHAR * pTagName = a_pVal + 3;
1628 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1631 const SI_CHAR * a_pVal
1635 if (*a_pVal++ !=
'<')
return false;
1636 if (*a_pVal++ !=
'<')
return false;
1637 if (*a_pVal++ !=
'<')
return false;
1641 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1644 const SI_CHAR * a_pData
1678 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1684 return (a_c ==
'\n' || a_c ==
'\r');
1687 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1691 const SI_CHAR *& a_pVal,
1692 const SI_CHAR * a_pTagName,
1693 bool a_bAllowBlankLinesInComment
1704 SI_CHAR * pDataLine = a_pData;
1705 SI_CHAR * pCurrLine;
1713 SI_CHAR cEndOfLineChar = *a_pData;
1717 if (!a_pTagName && !
IsComment(*a_pData)) {
1719 if (!a_bAllowBlankLinesInComment) {
1726 SI_CHAR * pCurr = a_pData;
1741 for (; nNewLines > 0; --nNewLines) *pDataLine++ =
'\n';
1751 pCurrLine = a_pData;
1755 if (pDataLine < pCurrLine) {
1756 size_t nLen = (size_t) (a_pData - pCurrLine);
1757 memmove(pDataLine, pCurrLine, nLen *
sizeof(SI_CHAR));
1758 pDataLine[nLen] =
'\0';
1762 cEndOfLineChar = *a_pData;
1769 (!
IsLess(pDataLine, a_pTagName) && !
IsLess(a_pTagName, pDataLine)))
1776 if (!cEndOfLineChar) {
1782 pDataLine += (a_pData - pCurrLine);
1783 *a_pData = cEndOfLineChar;
1785 *pDataLine++ =
'\n';
1789 if (a_pVal == a_pData) {
1798 *--pDataLine =
'\0';
1802 if (a_pTagName && cEndOfLineChar) {
1804 *a_pData = cEndOfLineChar;
1811 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1814 const SI_CHAR *& a_pString
1818 if (
sizeof(SI_CHAR) ==
sizeof(
char)) {
1819 uLen = strlen((
const char *)a_pString);
1821 else if (
sizeof(SI_CHAR) ==
sizeof(
wchar_t)) {
1822 uLen = wcslen((
const wchar_t *)a_pString);
1825 for ( ; a_pString[uLen]; ++uLen) ;
1828 SI_CHAR * pCopy =
new SI_CHAR[uLen];
1832 memcpy(pCopy, a_pString,
sizeof(SI_CHAR)*uLen);
1838 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1841 const SI_CHAR * a_pSection,
1842 const SI_CHAR * a_pKey,
1843 const SI_CHAR * a_pValue,
1844 const SI_CHAR * a_pComment,
1845 bool a_bForceReplace,
1850 bool bInserted =
false;
1856 if (a_bCopyStrings && a_pComment) {
1858 if (rc < 0)
return rc;
1862 typename TSection::iterator iSection =
m_data.find(a_pSection);
1863 if (iSection ==
m_data.end()) {
1866 if (a_bCopyStrings) {
1868 if (rc < 0)
return rc;
1873 if (a_pComment && (!a_pKey || !a_pValue)) {
1877 typename TSection::value_type oEntry(oSection,
TKeyVal());
1878 typedef typename TSection::iterator SectionIterator;
1879 std::pair<SectionIterator,bool> i =
m_data.insert(oEntry);
1883 if (!a_pKey || !a_pValue) {
1889 TKeyVal & keyval = iSection->second;
1890 typename TKeyVal::iterator iKey = keyval.find(a_pKey);
1896 const SI_CHAR * pComment =
NULL;
1897 while (iKey != keyval.end() && !
IsLess(a_pKey, iKey->first.pItem)) {
1898 if (iKey->first.nOrder < nLoadOrder) {
1899 nLoadOrder = iKey->first.nOrder;
1900 pComment = iKey->first.pComment;
1906 a_pComment = pComment;
1909 Delete(a_pSection, a_pKey);
1910 iKey = keyval.end();
1915 if (a_bCopyStrings) {
1916 if (bForceCreateNewKey || iKey == keyval.end()) {
1921 if (rc < 0)
return rc;
1926 if (rc < 0)
return rc;
1930 if (iKey == keyval.end() || bForceCreateNewKey) {
1931 Entry oKey(a_pKey, nLoadOrder);
1935 typename TKeyVal::value_type oEntry(oKey, static_cast<const SI_CHAR *>(
NULL));
1936 iKey = keyval.insert(oEntry);
1939 iKey->second = a_pValue;
1943 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1946 const SI_CHAR * a_pSection,
1947 const SI_CHAR * a_pKey,
1948 const SI_CHAR * a_pDefault,
1949 bool * a_pHasMultiple
1952 if (a_pHasMultiple) {
1953 *a_pHasMultiple =
false;
1955 if (!a_pSection || !a_pKey) {
1958 typename TSection::const_iterator iSection =
m_data.find(a_pSection);
1959 if (iSection ==
m_data.end()) {
1962 typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey);
1963 if (iKeyVal == iSection->second.end()) {
1969 typename TKeyVal::const_iterator iTemp = iKeyVal;
1970 if (++iTemp != iSection->second.end()) {
1971 if (!
IsLess(a_pKey, iTemp->first.pItem)) {
1972 *a_pHasMultiple =
true;
1977 return iKeyVal->second;
1980 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1983 const SI_CHAR * a_pSection,
1984 const SI_CHAR * a_pKey,
1986 bool * a_pHasMultiple
1990 const SI_CHAR * pszValue =
GetValue(a_pSection, a_pKey,
NULL, a_pHasMultiple);
1991 if (!pszValue || !*pszValue)
return a_nDefault;
1994 char szValue[64] = { 0 };
1996 if (!c.ConvertToStore(pszValue, szValue,
sizeof(szValue))) {
2001 long nValue = a_nDefault;
2002 char * pszSuffix = szValue;
2003 if (szValue[0] ==
'0' && (szValue[1] ==
'x' || szValue[1] ==
'X')) {
2004 if (!szValue[2])
return a_nDefault;
2005 nValue = strtol(&szValue[2], &pszSuffix, 16);
2008 nValue = strtol(szValue, &pszSuffix, 10);
2019 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2022 const SI_CHAR * a_pSection,
2023 const SI_CHAR * a_pKey,
2025 const SI_CHAR * a_pComment,
2027 bool a_bForceReplace
2031 if (!a_pSection || !a_pKey)
return SI_FAIL;
2035 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 2036 sprintf_s(szInput, a_bUseHex ?
"0x%lx" :
"%ld", a_nValue);
2037 #else // !__STDC_WANT_SECURE_LIB__ 2038 sprintf(szInput, a_bUseHex ?
"0x%lx" :
"%ld", a_nValue);
2039 #endif // __STDC_WANT_SECURE_LIB__ 2042 SI_CHAR szOutput[64];
2044 c.ConvertFromStore(szInput, strlen(szInput) + 1,
2045 szOutput,
sizeof(szOutput) /
sizeof(SI_CHAR));
2048 return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace,
true);
2051 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2054 const SI_CHAR * a_pSection,
2055 const SI_CHAR * a_pKey,
2057 bool * a_pHasMultiple
2061 const SI_CHAR * pszValue =
GetValue(a_pSection, a_pKey,
NULL, a_pHasMultiple);
2062 if (!pszValue || !*pszValue)
return a_nDefault;
2065 char szValue[64] = { 0 };
2067 if (!c.ConvertToStore(pszValue, szValue,
sizeof(szValue))) {
2071 char * pszSuffix =
NULL;
2072 double nValue = strtod(szValue, &pszSuffix);
2075 if (!pszSuffix || *pszSuffix) {
2082 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2085 const SI_CHAR * a_pSection,
2086 const SI_CHAR * a_pKey,
2088 const SI_CHAR * a_pComment,
2089 bool a_bForceReplace
2093 if (!a_pSection || !a_pKey)
return SI_FAIL;
2097 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 2098 sprintf_s(szInput,
"%f", a_nValue);
2099 #else // !__STDC_WANT_SECURE_LIB__ 2100 sprintf(szInput,
"%f", a_nValue);
2101 #endif // __STDC_WANT_SECURE_LIB__ 2104 SI_CHAR szOutput[64];
2106 c.ConvertFromStore(szInput, strlen(szInput) + 1,
2107 szOutput,
sizeof(szOutput) /
sizeof(SI_CHAR));
2110 return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace,
true);
2113 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2116 const SI_CHAR * a_pSection,
2117 const SI_CHAR * a_pKey,
2119 bool * a_pHasMultiple
2123 const SI_CHAR * pszValue =
GetValue(a_pSection, a_pKey,
NULL, a_pHasMultiple);
2124 if (!pszValue || !*pszValue)
return a_bDefault;
2127 switch (pszValue[0]) {
2139 if (pszValue[1] ==
'n' || pszValue[1] ==
'N')
return true;
2140 if (pszValue[1] ==
'f' || pszValue[1] ==
'F')
return false;
2148 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2151 const SI_CHAR * a_pSection,
2152 const SI_CHAR * a_pKey,
2154 const SI_CHAR * a_pComment,
2155 bool a_bForceReplace
2159 if (!a_pSection || !a_pKey)
return SI_FAIL;
2162 const char * pszInput = a_bValue ?
"true" :
"false";
2165 SI_CHAR szOutput[64];
2167 c.ConvertFromStore(pszInput, strlen(pszInput) + 1,
2168 szOutput,
sizeof(szOutput) /
sizeof(SI_CHAR));
2171 return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace,
true);
2174 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2177 const SI_CHAR * a_pSection,
2178 const SI_CHAR * a_pKey,
2184 if (!a_pSection || !a_pKey) {
2187 typename TSection::const_iterator iSection =
m_data.find(a_pSection);
2188 if (iSection ==
m_data.end()) {
2191 typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey);
2192 if (iKeyVal == iSection->second.end()) {
2197 a_values.push_back(
Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder));
2200 while (iKeyVal != iSection->second.end() && !
IsLess(a_pKey, iKeyVal->first.pItem)) {
2201 a_values.push_back(
Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder));
2209 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2212 const SI_CHAR * a_pSection
2219 typename TSection::const_iterator iSection =
m_data.find(a_pSection);
2220 if (iSection ==
m_data.end()) {
2223 const TKeyVal & section = iSection->second;
2228 return (
int) section.size();
2233 const SI_CHAR * pLastKey =
NULL;
2234 typename TKeyVal::const_iterator iKeyVal = section.begin();
2235 for (
int n = 0; iKeyVal != section.end(); ++iKeyVal, ++n) {
2236 if (!pLastKey ||
IsLess(pLastKey, iKeyVal->first.pItem)) {
2238 pLastKey = iKeyVal->first.pItem;
2244 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2247 const SI_CHAR * a_pSection
2251 typename TSection::const_iterator i =
m_data.find(a_pSection);
2253 return &(i->second);
2259 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2266 typename TSection::const_iterator i =
m_data.begin();
2267 for (
int n = 0; i !=
m_data.end(); ++i, ++n ) {
2268 a_names.push_back(i->first);
2272 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2275 const SI_CHAR * a_pSection,
2285 typename TSection::const_iterator iSection =
m_data.find(a_pSection);
2286 if (iSection ==
m_data.end()) {
2290 const TKeyVal & section = iSection->second;
2291 const SI_CHAR * pLastKey =
NULL;
2292 typename TKeyVal::const_iterator iKeyVal = section.begin();
2293 for (
int n = 0; iKeyVal != section.end(); ++iKeyVal, ++n ) {
2294 if (!pLastKey ||
IsLess(pLastKey, iKeyVal->first.pItem)) {
2295 a_names.push_back(iKeyVal->first);
2296 pLastKey = iKeyVal->first.pItem;
2303 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2306 const char * a_pszFile,
2307 bool a_bAddSignature
2311 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 2312 fopen_s(&fp, a_pszFile,
"wb");
2313 #else // !__STDC_WANT_SECURE_LIB__ 2314 fp = fopen(a_pszFile,
"wb");
2315 #endif // __STDC_WANT_SECURE_LIB__ 2322 #ifdef SI_HAS_WIDE_FILE 2323 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2326 const SI_WCHAR_T * a_pwszFile,
2327 bool a_bAddSignature
2332 #if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE 2333 _wfopen_s(&fp, a_pwszFile, L
"wb");
2334 #else // !__STDC_WANT_SECURE_LIB__ 2335 fp = _wfopen(a_pwszFile, L
"wb");
2336 #endif // __STDC_WANT_SECURE_LIB__ 2341 #else // !_WIN32 (therefore SI_CONVERT_ICU) 2343 u_austrncpy(szFile, a_pwszFile,
sizeof(szFile));
2344 return SaveFile(szFile, a_bAddSignature);
2347 #endif // SI_HAS_WIDE_FILE 2349 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2353 bool a_bAddSignature
2357 return Save(writer, a_bAddSignature);
2360 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2364 bool a_bAddSignature
2377 #if defined(_MSC_VER) && _MSC_VER <= 1200 2379 #elif defined(__BORLANDC__) 2386 bool bNeedNewLine =
false;
2391 bNeedNewLine =
true;
2395 typename TNamesDepend::const_iterator iSection = oSections.begin();
2396 for ( ; iSection != oSections.end(); ++iSection ) {
2398 if (iSection->pComment) {
2406 bNeedNewLine =
false;
2412 bNeedNewLine =
false;
2416 if (*iSection->pItem) {
2420 a_oOutput.
Write(
"[");
2422 a_oOutput.
Write(
"]");
2429 #if defined(_MSC_VER) && _MSC_VER <= 1200 2431 #elif defined(__BORLANDC__) 2438 typename TNamesDepend::const_iterator iKey = oKeys.begin();
2439 for ( ; iKey != oKeys.end(); ++iKey) {
2444 typename TNamesDepend::const_iterator iValue = oValues.begin();
2445 for ( ; iValue != oValues.end(); ++iValue) {
2447 if (iValue->pComment) {
2472 a_oOutput.
Write(
"END_OF_TEXT");
2481 bNeedNewLine =
true;
2487 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2492 const SI_CHAR * a_pText
2495 const SI_CHAR * pEndOfLine;
2496 SI_CHAR cEndOfLineChar = *a_pText;
2497 while (cEndOfLineChar) {
2499 pEndOfLine = a_pText;
2500 for (; *pEndOfLine && *pEndOfLine !=
'\n'; ++pEndOfLine) ;
2501 cEndOfLineChar = *pEndOfLine;
2504 *
const_cast<SI_CHAR*
>(pEndOfLine) = 0;
2508 *
const_cast<SI_CHAR*
>(pEndOfLine) = cEndOfLineChar;
2509 a_pText += (pEndOfLine - a_pText) + 1;
2516 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2519 const SI_CHAR * a_pSection,
2520 const SI_CHAR * a_pKey,
2528 typename TSection::iterator iSection =
m_data.find(a_pSection);
2529 if (iSection ==
m_data.end()) {
2535 typename TKeyVal::iterator iKeyVal = iSection->second.find(a_pKey);
2536 if (iKeyVal == iSection->second.end()) {
2541 typename TKeyVal::iterator iDelete;
2543 iDelete = iKeyVal++;
2547 iSection->second.erase(iDelete);
2549 while (iKeyVal != iSection->second.end()
2550 && !
IsLess(a_pKey, iKeyVal->first.pItem));
2555 if (!a_bRemoveEmpty || !iSection->second.empty()) {
2562 typename TKeyVal::iterator iKeyVal = iSection->second.begin();
2563 for ( ; iKeyVal != iSection->second.end(); ++iKeyVal) {
2576 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2579 const SI_CHAR * a_pString
2586 typename TNamesDepend::iterator i =
m_strings.begin();
2588 if (a_pString == i->pItem) {
2589 delete[]
const_cast<SI_CHAR*
>(i->pItem);
2611 #if !defined(SI_CONVERT_GENERIC) && !defined(SI_CONVERT_WIN32) && !defined(SI_CONVERT_ICU) 2613 # define SI_CONVERT_WIN32 2615 # define SI_CONVERT_GENERIC 2624 template<
class SI_CHAR>
2626 bool operator()(
const SI_CHAR * pLeft,
const SI_CHAR * pRight)
const {
2628 for ( ;*pLeft && *pRight; ++pLeft, ++pRight) {
2629 cmp = (long) *pLeft - (
long) *pRight;
2634 return *pRight != 0;
2644 template<
class SI_CHAR>
2647 return (ch < 'A' || ch >
'Z') ? ch : (ch -
'A' +
'a');
2649 bool operator()(
const SI_CHAR * pLeft,
const SI_CHAR * pRight)
const {
2651 for ( ;*pLeft && *pRight; ++pLeft, ++pRight) {
2652 cmp = (long) locase(*pLeft) - (long) locase(*pRight);
2657 return *pRight != 0;
2664 template<
class SI_CHAR>
2693 const char * a_pInputData,
2694 size_t a_uInputDataLen)
2697 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
2700 return a_uInputDataLen;
2717 const char * a_pInputData,
2718 size_t a_uInputDataLen,
2719 SI_CHAR * a_pOutputData,
2720 size_t a_uOutputDataSize)
2723 if (a_uInputDataLen > a_uOutputDataSize) {
2726 memcpy(a_pOutputData, a_pInputData, a_uInputDataLen);
2741 const SI_CHAR * a_pInputData)
2744 return strlen((
const char *)a_pInputData) + 1;
2761 const SI_CHAR * a_pInputData,
2762 char * a_pOutputData,
2763 size_t a_uOutputDataSize)
2766 size_t uInputLen = strlen((
const char *)a_pInputData) + 1;
2767 if (uInputLen > a_uOutputDataSize) {
2772 memcpy(a_pOutputData, a_pInputData, uInputLen);
2781 #ifdef SI_CONVERT_GENERIC 2783 #define SI_Case SI_GenericCase 2784 #define SI_NoCase SI_GenericNoCase 2793 template<
class SI_CHAR>
2822 const char * a_pInputData,
2823 size_t a_uInputDataLen)
2825 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
2827 if (m_bStoreIsUtf8) {
2831 return a_uInputDataLen;
2834 return mbstowcs(
NULL, a_pInputData, a_uInputDataLen);
2852 const char * a_pInputData,
2853 size_t a_uInputDataLen,
2854 SI_CHAR * a_pOutputData,
2855 size_t a_uOutputDataSize)
2857 if (m_bStoreIsUtf8) {
2864 const UTF8 * pUtf8 = (
const UTF8 *) a_pInputData;
2865 if (
sizeof(
wchar_t) ==
sizeof(
UTF32)) {
2868 &pUtf8, pUtf8 + a_uInputDataLen,
2869 &pUtf32, pUtf32 + a_uOutputDataSize,
2872 else if (
sizeof(
wchar_t) ==
sizeof(
UTF16)) {
2875 &pUtf8, pUtf8 + a_uInputDataLen,
2876 &pUtf16, pUtf16 + a_uOutputDataSize,
2882 size_t retval = mbstowcs(a_pOutputData,
2883 a_pInputData, a_uOutputDataSize);
2884 return retval != (size_t)(-1);
2899 const SI_CHAR * a_pInputData)
2901 if (m_bStoreIsUtf8) {
2904 while (a_pInputData[uLen]) {
2907 return (6 * uLen) + 1;
2910 size_t uLen = wcstombs(
NULL, a_pInputData, 0);
2911 if (uLen == (
size_t)(-1)) {
2932 const SI_CHAR * a_pInputData,
2933 char * a_pOutputData,
2934 size_t a_uOutputDataSize
2937 if (m_bStoreIsUtf8) {
2939 size_t uInputLen = 0;
2940 while (a_pInputData[uInputLen]) {
2951 UTF8 * pUtf8 = (
UTF8 *) a_pOutputData;
2952 if (
sizeof(
wchar_t) ==
sizeof(
UTF32)) {
2953 const UTF32 * pUtf32 = (
const UTF32 *) a_pInputData;
2955 &pUtf32, pUtf32 + uInputLen,
2956 &pUtf8, pUtf8 + a_uOutputDataSize,
2959 else if (
sizeof(
wchar_t) ==
sizeof(
UTF16)) {
2960 const UTF16 * pUtf16 = (
const UTF16 *) a_pInputData;
2962 &pUtf16, pUtf16 + uInputLen,
2963 &pUtf8, pUtf8 + a_uOutputDataSize,
2969 size_t retval = wcstombs(a_pOutputData,
2970 a_pInputData, a_uOutputDataSize);
2971 return retval != (size_t) -1;
2976 #endif // SI_CONVERT_GENERIC 2982 #ifdef SI_CONVERT_ICU 2984 #define SI_Case SI_GenericCase 2985 #define SI_NoCase SI_GenericNoCase 2987 #include <unicode/ucnv.h> 2992 template<
class SI_CHAR>
2994 const char * m_pEncoding;
2995 UConverter * m_pConverter;
3000 m_pEncoding = a_bStoreIsUtf8 ?
"UTF-8" :
NULL;
3006 m_pEncoding = rhs.m_pEncoding;
3007 m_pConverter =
NULL;
3010 ~
SI_ConvertW() {
if (m_pConverter) ucnv_close(m_pConverter); }
3025 size_t SizeFromStore(
3026 const char * a_pInputData,
3027 size_t a_uInputDataLen)
3029 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
3033 if (!m_pConverter) {
3034 nError = U_ZERO_ERROR;
3035 m_pConverter = ucnv_open(m_pEncoding, &nError);
3036 if (U_FAILURE(nError)) {
3041 nError = U_ZERO_ERROR;
3042 int32_t nLen = ucnv_toUChars(m_pConverter,
NULL, 0,
3043 a_pInputData, (
int32_t) a_uInputDataLen, &nError);
3044 if (U_FAILURE(nError) && nError != U_BUFFER_OVERFLOW_ERROR) {
3048 return (
size_t) nLen;
3064 bool ConvertFromStore(
3065 const char * a_pInputData,
3066 size_t a_uInputDataLen,
3067 UChar * a_pOutputData,
3068 size_t a_uOutputDataSize)
3072 if (!m_pConverter) {
3073 nError = U_ZERO_ERROR;
3074 m_pConverter = ucnv_open(m_pEncoding, &nError);
3075 if (U_FAILURE(nError)) {
3080 nError = U_ZERO_ERROR;
3081 ucnv_toUChars(m_pConverter,
3082 a_pOutputData, (
int32_t) a_uOutputDataSize,
3083 a_pInputData, (
int32_t) a_uInputDataLen, &nError);
3084 if (U_FAILURE(nError)) {
3102 const UChar * a_pInputData)
3106 if (!m_pConverter) {
3107 nError = U_ZERO_ERROR;
3108 m_pConverter = ucnv_open(m_pEncoding, &nError);
3109 if (U_FAILURE(nError)) {
3114 nError = U_ZERO_ERROR;
3115 int32_t nLen = ucnv_fromUChars(m_pConverter,
NULL, 0,
3116 a_pInputData, -1, &nError);
3117 if (U_FAILURE(nError) && nError != U_BUFFER_OVERFLOW_ERROR) {
3121 return (
size_t) nLen + 1;
3137 bool ConvertToStore(
3138 const UChar * a_pInputData,
3139 char * a_pOutputData,
3140 size_t a_uOutputDataSize)
3144 if (!m_pConverter) {
3145 nError = U_ZERO_ERROR;
3146 m_pConverter = ucnv_open(m_pEncoding, &nError);
3147 if (U_FAILURE(nError)) {
3152 nError = U_ZERO_ERROR;
3153 ucnv_fromUChars(m_pConverter,
3154 a_pOutputData, (
int32_t) a_uOutputDataSize,
3155 a_pInputData, -1, &nError);
3156 if (U_FAILURE(nError)) {
3164 #endif // SI_CONVERT_ICU 3170 #ifdef SI_CONVERT_WIN32 3172 #define SI_Case SI_GenericCase 3181 #include <windows.h> 3183 # define SI_NoCase SI_GenericNoCase 3184 #else // !SI_NO_MBCS 3193 #include <mbstring.h> 3194 template<
class SI_CHAR>
3196 bool operator()(
const SI_CHAR * pLeft,
const SI_CHAR * pRight)
const {
3197 if (
sizeof(SI_CHAR) ==
sizeof(
char)) {
3198 return _mbsicmp((
const unsigned char *)pLeft,
3199 (
const unsigned char *)pRight) < 0;
3201 if (
sizeof(SI_CHAR) ==
sizeof(
wchar_t)) {
3202 return _wcsicmp((
const wchar_t *)pLeft,
3203 (
const wchar_t *)pRight) < 0;
3208 #endif // SI_NO_MBCS 3216 template<
class SI_CHAR>
3223 m_uCodePage = a_bStoreIsUtf8 ? CP_UTF8 : CP_ACP;
3229 m_uCodePage = rhs.m_uCodePage;
3246 size_t SizeFromStore(
3247 const char * a_pInputData,
3248 size_t a_uInputDataLen)
3250 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
3252 int retval = MultiByteToWideChar(
3254 a_pInputData, (
int) a_uInputDataLen,
3256 return (
size_t)(retval > 0 ? retval : -1);
3272 bool ConvertFromStore(
3273 const char * a_pInputData,
3274 size_t a_uInputDataLen,
3275 SI_CHAR * a_pOutputData,
3276 size_t a_uOutputDataSize)
3278 int nSize = MultiByteToWideChar(
3280 a_pInputData, (
int) a_uInputDataLen,
3281 (
wchar_t *) a_pOutputData, (
int) a_uOutputDataSize);
3296 const SI_CHAR * a_pInputData)
3298 int retval = WideCharToMultiByte(
3300 (
const wchar_t *) a_pInputData, -1,
3302 return (
size_t) (retval > 0 ? retval : -1);
3318 bool ConvertToStore(
3319 const SI_CHAR * a_pInputData,
3320 char * a_pOutputData,
3321 size_t a_uOutputDataSize)
3323 int retval = WideCharToMultiByte(
3325 (
const wchar_t *) a_pInputData, -1,
3326 a_pOutputData, (
int) a_uOutputDataSize, 0, 0);
3331 #endif // SI_CONVERT_WIN32 3343 #if defined(SI_CONVERT_ICU) 3356 # define CSimpleIni CSimpleIniW 3357 # define CSimpleIniCase CSimpleIniCaseW 3358 # define SI_NEWLINE SI_NEWLINE_W 3360 # define CSimpleIni CSimpleIniA 3361 # define CSimpleIniCase CSimpleIniCaseA 3362 # define SI_NEWLINE SI_NEWLINE_A 3366 # pragma warning (pop) 3369 #endif // INCLUDED_SimpleIni_h bool ConvertToStore(const SI_CHAR *a_pInputData, char *a_pOutputData, size_t a_uOutputDataSize)
Converter(bool a_bStoreIsUtf8)
bool operator()(const Entry &lhs, const Entry &rhs) const
bool FindEntry(SI_CHAR *&a_pData, const SI_CHAR *&a_pSection, const SI_CHAR *&a_pKey, const SI_CHAR *&a_pVal, const SI_CHAR *&a_pComment) const
SI_ConvertW & operator=(const SI_ConvertW &rhs)
size_t SizeFromStore(const char *a_pInputData, size_t a_uInputDataLen)
bool Delete(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, bool a_bRemoveEmpty=false)
bool operator<(const Node &n1, const Node &n2)
CSimpleIniTempl(bool a_bIsUtf8=false, bool a_bMultiKey=false, bool a_bMultiLine=false)
bool ConvertToStore(const SI_CHAR *a_pszString)
Converter(const Converter &rhs)
const TKeyVal * GetSection(const SI_CHAR *a_pSection) const
bool ConvertFromStore(const char *a_pInputData, size_t a_uInputDataLen, SI_CHAR *a_pOutputData, size_t a_uOutputDataSize)
std::multimap< Entry, const SI_CHAR *, typename Entry::KeyOrder > TKeyVal
void Write(const char *a_pBuf)
double GetDoubleValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, double a_nDefault=0, bool *a_pHasMultiple=NULL) const
SI_ConvertA & operator=(const SI_ConvertA &rhs)
std::list< Entry > TNamesDepend
SI_Error CopyString(const SI_CHAR *&a_pString)
bool operator()(const SI_CHAR *pLeft, const SI_CHAR *pRight) const
StringWriter(std::string &a_string)
bool GetAllKeys(const SI_CHAR *a_pSection, TNamesDepend &a_names) const
A new value was inserted.
SI_Error SaveFile(const char *a_pszFile, bool a_bAddSignature=true) const
Entry(const SI_CHAR *a_pszItem, const SI_CHAR *a_pszComment, int a_nOrder)
CSimpleIniTempl & operator=(const CSimpleIniTempl &)
ConversionResult ConvertUTF8toUTF16(const UTF8 **sourceStart, const UTF8 *sourceEnd, UTF16 **targetStart, UTF16 *targetEnd, ConversionFlags flags)
void GetAllSections(TNamesDepend &a_names) const
std::map< Entry, TKeyVal, typename Entry::KeyOrder > TSection
bool IsMultiLineData(const SI_CHAR *a_pData) const
bool GetAllValues(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, TNamesDepend &a_values) const
bool GetBoolValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, bool a_bDefault=false, bool *a_pHasMultiple=NULL) const
ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, UTF32 **targetStart, UTF32 *targetEnd, ConversionFlags flags)
bool LoadMultiLineText(SI_CHAR *&a_pData, const SI_CHAR *&a_pVal, const SI_CHAR *a_pTagName, bool a_bAllowBlankLinesInComment=false) const
CSimpleIniTempl< wchar_t, SI_Case< wchar_t >, SI_ConvertW< wchar_t > > CSimpleIniCaseW
void SetUnicode(bool a_bIsUtf8=true)
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)
ConversionResult ConvertUTF16toUTF8(const UTF16 **sourceStart, const UTF16 *sourceEnd, UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags)
const SI_CHAR * m_pFileComment
int Write(int fd, const void *buf, unsigned int count)
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)
An existing value was updated.
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)
bool operator()(const Entry &lhs, const Entry &rhs) const
SI_Error LoadData(const std::string &a_strData)
int GetSectionSize(const SI_CHAR *a_pSection) const
SI_ConvertA(bool a_bStoreIsUtf8)
CSimpleIniTempl< char, SI_NoCase< char >, SI_ConvertA< char > > CSimpleIniA
bool ConvertFromStore(const char *a_pInputData, size_t a_uInputDataLen, SI_CHAR *a_pOutputData, size_t a_uOutputDataSize)
bool IsNewLineChar(SI_CHAR a_c) const
Converter & operator=(const Converter &rhs)
void SkipNewLine(SI_CHAR *&a_pData) const
SI_ConvertW(bool a_bStoreIsUtf8)
bool ConvertToStore(const SI_CHAR *a_pInputData, char *a_pOutputData, size_t a_uOutputDataSize)
long GetLongValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, long a_nDefault=0, bool *a_pHasMultiple=NULL) const
size_t SizeToStore(const SI_CHAR *a_pInputData)
SI_ConvertW(const SI_ConvertW &rhs)
bool operator()(const SI_CHAR *pLeft, const SI_CHAR *pRight) const
void DeleteString(const SI_CHAR *a_pString)
void SetSpaces(bool a_bSpaces=true)
SI_Error LoadFile(const char *a_pszFile)
SI_Error AddEntry(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, const SI_CHAR *a_pValue, const SI_CHAR *a_pComment, bool a_bForceReplace, bool a_bCopyStrings)
Converter GetConverter() const
void Write(const char *a_pBuf)
bool IsComment(SI_CHAR ch) const
bool IsMultiLineTag(const SI_CHAR *a_pData) const
bool IsSpace(SI_CHAR ch) const
SI_Error Save(OutputWriter &a_oOutput, bool a_bAddSignature=false) const
size_t SizeToStore(const SI_CHAR *a_pInputData)
Entry & operator=(const Entry &rhs)
Entry(const SI_CHAR *a_pszItem=NULL, int a_nOrder=0)
CSimpleIniTempl< wchar_t, SI_NoCase< wchar_t >, SI_ConvertW< wchar_t > > CSimpleIniW
virtual void Write(const char *a_pBuf)=0
ConversionResult ConvertUTF32toUTF8(const UTF32 **sourceStart, const UTF32 *sourceEnd, UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags)
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)
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
SI_ConvertA(const SI_ConvertA &rhs)
struct FileWriter FileWriter
SI_CHAR locase(SI_CHAR ch) const
#define SI_UTF8_SIGNATURE
void SetMultiLine(bool a_bAllowMultiLine=true)
size_t SizeFromStore(const char *a_pInputData, size_t a_uInputDataLen)
File error (see errno for detail error)
void SetMultiKey(bool a_bAllowMultiKey=true)
bool IsLess(const SI_CHAR *a_pLeft, const SI_CHAR *a_pRight) const
bool OutputMultiLineText(OutputWriter &a_oOutput, Converter &a_oConverter, const SI_CHAR *a_pText) const
CSimpleIniTempl< char, SI_Case< char >, SI_ConvertA< char > > CSimpleIniCaseA
SI_Error FindFileComment(SI_CHAR *&a_pData, bool a_bCopyStrings)