214#ifndef INCLUDED_SimpleIni_h
215#define INCLUDED_SimpleIni_h
217#if defined(_MSC_VER) && (_MSC_VER >= 1020)
231# pragma warning (push)
232# pragma warning (disable: 4127 4503 4702 4786)
243#ifdef SI_SUPPORT_IOSTREAMS
251# define SI_ASSERT(x) assert(x)
258constexpr int SI_OK = 0;
259constexpr int SI_UPDATED = 1;
260constexpr int SI_INSERTED = 2;
263constexpr int SI_FAIL = -1;
264constexpr int SI_NOMEM = -2;
265constexpr int SI_FILE = -3;
269constexpr size_t SI_MAX_FILE_SIZE = 1024ULL * 1024ULL * 1024ULL;
271#define SI_UTF8_SIGNATURE "\xEF\xBB\xBF"
274# define SI_NEWLINE_A "\r\n"
275# define SI_NEWLINE_W L"\r\n"
277# define SI_NEWLINE_A "\n"
278# define SI_NEWLINE_W L"\n"
281#if defined(SI_CONVERT_ICU)
282# include <unicode/ustring.h>
286# define SI_HAS_WIDE_FILE
287# define SI_WCHAR_T wchar_t
288#elif defined(SI_CONVERT_ICU)
289# define SI_HAS_WIDE_FILE
290# define SI_WCHAR_T UChar
317template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
321 typedef SI_CHAR SI_CHAR_T;
325 const SI_CHAR * pItem;
326 const SI_CHAR * pComment;
329 Entry(
const SI_CHAR * a_pszItem = NULL,
int a_nOrder = 0)
334 Entry(
const SI_CHAR * a_pszItem,
const SI_CHAR * a_pszComment,
int a_nOrder)
336 , pComment(a_pszComment)
342 pComment = rhs.pComment;
347#if defined(_MSC_VER) && _MSC_VER <= 1200
349 bool operator<(
const Entry & rhs)
const {
return LoadOrder()(*
this, rhs); }
350 bool operator>(
const Entry & rhs)
const {
return LoadOrder()(rhs, *
this); }
355 bool operator()(
const Entry & lhs,
const Entry & rhs)
const {
356 const static SI_STRLESS isLess = SI_STRLESS();
357 return isLess(lhs.pItem, rhs.pItem);
363 bool operator()(
const Entry & lhs,
const Entry & rhs)
const {
364 if (lhs.nOrder != rhs.nOrder) {
365 return lhs.nOrder < rhs.nOrder;
373 typedef std::multimap<Entry,const SI_CHAR *,typename Entry::KeyOrder>
TKeyVal;
376 typedef std::map<Entry,TKeyVal,typename Entry::KeyOrder>
TSection;
390 virtual void Write(
const char * a_pBuf) = 0;
400 FileWriter(FILE * a_file) : m_file(a_file) { }
401 void Write(
const char * a_pBuf) {
402 fputs(a_pBuf, m_file);
411 std::string & m_string;
413 StringWriter(std::string & a_string) : m_string(a_string) { }
414 void Write(
const char * a_pBuf) {
415 m_string.append(a_pBuf);
422#ifdef SI_SUPPORT_IOSTREAMS
425 std::ostream & m_ostream;
427 StreamWriter(std::ostream & a_ostream) : m_ostream(a_ostream) { }
428 void Write(
const char * a_pBuf) {
432 StreamWriter(
const StreamWriter &);
433 StreamWriter & operator=(
const StreamWriter &);
442 Converter(
bool a_bStoreIsUtf8) : SI_CONVERTER(a_bStoreIsUtf8) {
443 m_scratch.resize(1024);
447 m_scratch = rhs.m_scratch;
450 bool ConvertToStore(
const SI_CHAR * a_pszString) {
451 size_t uLen = SI_CONVERTER::SizeToStore(a_pszString);
452 if (uLen == (
size_t)(-1)) {
455 while (uLen > m_scratch.size()) {
456 m_scratch.resize(m_scratch.size() * 2);
458 return SI_CONVERTER::ConvertToStore(
460 const_cast<char*
>(m_scratch.data()),
463 const char * Data() {
return m_scratch.data(); }
465 std::string m_scratch;
478 bool a_bIsUtf8 =
false,
479 bool a_bMultiKey =
false,
480 bool a_bMultiLine =
false
490 bool IsEmpty()
const {
return m_data.empty(); }
510 if (!m_pData) m_bStoreIsUtf8 = a_bIsUtf8;
535 m_bAllowMultiKey = a_bAllowMultiKey;
549 m_bAllowMultiLine = a_bAllowMultiLine;
562 m_bSpaces = a_bSpaces;
574 m_bParseQuotes = a_bParseQuotes;
589 m_bAllowKeyOnly = a_bAllowKeyOnly;
610 const char * a_pszFile
613#ifdef SI_HAS_WIDE_FILE
621 const SI_WCHAR_T * a_pwszFile
636#ifdef SI_SUPPORT_IOSTREAMS
644 std::istream & a_istream
655 return LoadData(a_strData.c_str(), a_strData.size());
666 const char * a_pData,
687 const char * a_pszFile,
688 bool a_bAddSignature =
true
691#ifdef SI_HAS_WIDE_FILE
703 const SI_WCHAR_T * a_pwszFile,
704 bool a_bAddSignature =
true
722 bool a_bAddSignature =
false
757 OutputWriter & a_oOutput,
758 bool a_bAddSignature =
false
761#ifdef SI_SUPPORT_IOSTREAMS
774 std::ostream & a_ostream,
775 bool a_bAddSignature =
false
778 StreamWriter writer(a_ostream);
779 return Save(writer, a_bAddSignature);
795 std::string & a_sBuffer,
796 bool a_bAddSignature =
false
800 return Save(writer, a_bAddSignature);
843 const SI_CHAR * a_pSection,
864 const SI_CHAR * a_pSection,
865 const SI_CHAR * a_pKey,
879 const SI_CHAR * a_pSection
896 const SI_CHAR * a_pSection
901 const SI_CHAR * a_pSection
908 const SI_CHAR * a_pSection,
909 const SI_CHAR * a_pKey
911 return GetValue(a_pSection, a_pKey) != NULL;
932 const SI_CHAR * a_pSection,
933 const SI_CHAR * a_pKey,
934 const SI_CHAR * a_pDefault = NULL,
935 bool * a_pHasMultiple = NULL
952 const SI_CHAR * a_pSection,
953 const SI_CHAR * a_pKey,
955 bool * a_pHasMultiple = NULL
972 const SI_CHAR * a_pSection,
973 const SI_CHAR * a_pKey,
974 double a_nDefault = 0,
975 bool * a_pHasMultiple = NULL
997 const SI_CHAR * a_pSection,
998 const SI_CHAR * a_pKey,
999 bool a_bDefault =
false,
1000 bool * a_pHasMultiple = NULL
1033 const SI_CHAR * a_pSection,
1034 const SI_CHAR * a_pKey,
1035 const SI_CHAR * a_pValue,
1036 const SI_CHAR * a_pComment = NULL,
1037 bool a_bForceReplace =
false
1040 return AddEntry(a_pSection, a_pKey, a_pValue, a_pComment, a_bForceReplace,
true);
1067 const SI_CHAR * a_pSection,
1068 const SI_CHAR * a_pKey,
1070 const SI_CHAR * a_pComment = NULL,
1071 bool a_bUseHex =
false,
1072 bool a_bForceReplace =
false
1096 const SI_CHAR * a_pSection,
1097 const SI_CHAR * a_pKey,
1099 const SI_CHAR * a_pComment = NULL,
1100 bool a_bForceReplace =
false
1124 const SI_CHAR * a_pSection,
1125 const SI_CHAR * a_pKey,
1127 const SI_CHAR * a_pComment = NULL,
1128 bool a_bForceReplace =
false
1150 const SI_CHAR * a_pSection,
1151 const SI_CHAR * a_pKey,
1152 bool a_bRemoveEmpty =
false
1176 const SI_CHAR * a_pSection,
1177 const SI_CHAR * a_pKey,
1178 const SI_CHAR * a_pValue,
1179 bool a_bRemoveEmpty =
false
1205 SI_Error FindFileComment(
1216 const SI_CHAR *& a_pSection,
1217 const SI_CHAR *& a_pKey,
1218 const SI_CHAR *& a_pVal,
1219 const SI_CHAR *& a_pComment
1245 const SI_CHAR * a_pSection,
1246 const SI_CHAR * a_pKey,
1247 const SI_CHAR * a_pValue,
1248 const SI_CHAR * a_pComment,
1249 bool a_bForceReplace,
1254 inline bool IsSpace(SI_CHAR ch)
const {
1255 return (ch ==
' ' || ch ==
'\t' || ch ==
'\r' || ch ==
'\n');
1259 inline bool IsComment(SI_CHAR ch)
const {
1260 return (ch ==
';' || ch ==
'#');
1265 inline void SkipNewLine(SI_CHAR *& a_pData)
const {
1266 a_pData += (*a_pData ==
'\r' && *(a_pData+1) ==
'\n') ? 2 : 1;
1270 SI_Error CopyString(
const SI_CHAR *& a_pString);
1273 void DeleteString(
const SI_CHAR * a_pString);
1276 bool IsLess(
const SI_CHAR * a_pLeft,
const SI_CHAR * a_pRight)
const {
1277 const static SI_STRLESS isLess = SI_STRLESS();
1278 return isLess(a_pLeft, a_pRight);
1281 bool IsMultiLineTag(
const SI_CHAR * a_pData)
const;
1282 bool IsMultiLineData(
const SI_CHAR * a_pData)
const;
1283 bool IsSingleLineQuotedValue(
const SI_CHAR* a_pData)
const;
1284 bool LoadMultiLineText(
1286 const SI_CHAR *& a_pVal,
1287 const SI_CHAR * a_pTagName,
1288 bool a_bAllowBlankLinesInComment =
false
1290 bool IsNewLineChar(SI_CHAR a_c)
const;
1292 bool OutputMultiLineText(
1293 OutputWriter & a_oOutput,
1294 Converter & a_oConverter,
1295 const SI_CHAR * a_pText
1313 const SI_CHAR * m_pFileComment;
1316 const SI_CHAR m_cEmptyString;
1328 bool m_bStoreIsUtf8;
1331 bool m_bAllowMultiKey;
1334 bool m_bAllowMultiLine;
1340 bool m_bParseQuotes;
1343 bool m_bAllowKeyOnly;
1355template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1358 bool a_bAllowMultiKey,
1359 bool a_bAllowMultiLine
1363 , m_pFileComment(NULL)
1365 , m_bStoreIsUtf8(a_bIsUtf8)
1366 , m_bAllowMultiKey(a_bAllowMultiKey)
1367 , m_bAllowMultiLine(a_bAllowMultiLine)
1369 , m_bParseQuotes(false)
1370 , m_bAllowKeyOnly(false)
1374template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1380template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1388 m_pFileComment = NULL;
1389 if (!m_data.empty()) {
1390 m_data.erase(m_data.begin(), m_data.end());
1394 if (!m_strings.empty()) {
1395 typename TNamesDepend::iterator i = m_strings.begin();
1396 for (; i != m_strings.end(); ++i) {
1397 delete[]
const_cast<SI_CHAR*
>(i->pItem);
1399 m_strings.erase(m_strings.begin(), m_strings.end());
1403template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1406 const char * a_pszFile
1410#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE
1411 fopen_s(&fp, a_pszFile,
"rb");
1413 fp = fopen(a_pszFile,
"rb");
1418 SI_Error rc = LoadFile(fp);
1423#ifdef SI_HAS_WIDE_FILE
1424template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1427 const SI_WCHAR_T * a_pwszFile
1432#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE
1433 _wfopen_s(&fp, a_pwszFile, L
"rb");
1435 fp = _wfopen(a_pwszFile, L
"rb");
1437 if (!fp)
return SI_FILE;
1438 SI_Error rc = LoadFile(fp);
1443 u_austrncpy(szFile, a_pwszFile,
sizeof(szFile));
1444 return LoadFile(szFile);
1449template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1456 int retval = fseek(a_fpFile, 0, SEEK_END);
1460 long lSize = ftell(a_fpFile);
1469 if (
static_cast<size_t>(lSize) > SI_MAX_FILE_SIZE) {
1474 char * pData =
new(std::nothrow)
char[
static_cast<size_t>(lSize) + 1];
1481 fseek(a_fpFile, 0, SEEK_SET);
1482 size_t uRead = fread(pData,
sizeof(
char), lSize, a_fpFile);
1483 if (uRead != (
size_t) lSize) {
1489 SI_Error rc = LoadData(pData, uRead);
1494template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1497 const char * a_pData,
1508 if (a_uDataLen >= 3 && memcmp(a_pData, SI_UTF8_SIGNATURE, 3) == 0) {
1511 SI_ASSERT(m_bStoreIsUtf8 || !m_pData);
1515 if (a_uDataLen == 0) {
1520 SI_CONVERTER converter(m_bStoreIsUtf8);
1521 size_t uLen = converter.SizeFromStore(a_pData, a_uDataLen);
1522 if (uLen == (
size_t)(-1)) {
1527 if (uLen >= (SI_MAX_FILE_SIZE /
sizeof(SI_CHAR))) {
1533 SI_CHAR * pData =
new(std::nothrow) SI_CHAR[uLen + 1];
1537 memset(pData, 0,
sizeof(SI_CHAR) * (uLen + 1));
1540 if (!converter.ConvertFromStore(a_pData, a_uDataLen, pData, uLen)) {
1546 const static SI_CHAR empty = 0;
1547 SI_CHAR * pWork = pData;
1548 const SI_CHAR * pSection = ∅
1549 const SI_CHAR * pItem = NULL;
1550 const SI_CHAR * pVal = NULL;
1551 const SI_CHAR * pComment = NULL;
1555 bool bCopyStrings = (m_pData != NULL);
1559 SI_Error rc = FindFileComment(pWork, bCopyStrings);
1560 if (rc < 0)
return rc;
1563 while (FindEntry(pWork, pSection, pItem, pVal, pComment)) {
1564 rc = AddEntry(pSection, pItem, pVal, pComment,
false, bCopyStrings);
1565 if (rc < 0)
return rc;
1574 m_uDataLen = uLen+1;
1580#ifdef SI_SUPPORT_IOSTREAMS
1581template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1584 std::istream & a_istream
1587 std::string strData;
1590 a_istream.get(szBuf,
sizeof(szBuf),
'\0');
1591 strData.append(szBuf);
1593 while (a_istream.good());
1594 return LoadData(strData);
1598template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1606 if (m_pFileComment) {
1612 if (!LoadMultiLineText(a_pData, m_pFileComment, NULL,
false)) {
1617 if (a_bCopyStrings) {
1618 SI_Error rc = CopyString(m_pFileComment);
1619 if (rc < 0)
return rc;
1625template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1629 const SI_CHAR *& a_pSection,
1630 const SI_CHAR *& a_pKey,
1631 const SI_CHAR *& a_pVal,
1632 const SI_CHAR *& a_pComment
1637 bool bHaveValue =
false;
1638 SI_CHAR * pTrail = NULL;
1641 while (*a_pData && IsSpace(*a_pData)) {
1650 if (IsComment(*a_pData)) {
1651 LoadMultiLineText(a_pData, a_pComment, NULL,
true);
1656 if (*a_pData ==
'[') {
1659 while (*a_pData && IsSpace(*a_pData)) {
1665 a_pSection = a_pData;
1666 while (*a_pData && *a_pData !=
']' && !IsNewLineChar(*a_pData)) {
1671 if (*a_pData !=
']') {
1676 pTrail = a_pData - 1;
1677 while (pTrail >= a_pSection && IsSpace(*pTrail)) {
1685 while (*a_pData && !IsNewLineChar(*a_pData)) {
1696 while (*a_pData && *a_pData !=
'=' && !IsNewLineChar(*a_pData)) {
1702 bHaveValue = (*a_pData ==
'=');
1703 if (!bHaveValue && !m_bAllowKeyOnly) {
1708 if (bHaveValue && a_pKey == a_pData) {
1709 while (*a_pData && !IsNewLineChar(*a_pData)) {
1716 pTrail = a_pData - 1;
1717 while (pTrail >= a_pKey && IsSpace(*pTrail)) {
1728 while (*a_pData && !IsNewLineChar(*a_pData) && IsSpace(*a_pData)) {
1734 while (*a_pData && !IsNewLineChar(*a_pData)) {
1739 pTrail = a_pData - 1;
1741 SkipNewLine(a_pData);
1743 while (pTrail >= a_pVal && IsSpace(*pTrail)) {
1750 if (m_bAllowMultiLine && IsMultiLineTag(a_pVal)) {
1752 const SI_CHAR* pTagName = a_pVal + 3;
1753 return LoadMultiLineText(a_pData, a_pVal, pTagName);
1757 if (m_bParseQuotes) {
1759 if (pTrail > a_pVal && *a_pVal ==
'"' && *pTrail ==
'"') {
1768 SkipNewLine(a_pData);
1780template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1783 const SI_CHAR * a_pVal
1787 if (*a_pVal++ !=
'<')
return false;
1788 if (*a_pVal++ !=
'<')
return false;
1789 if (*a_pVal++ !=
'<')
return false;
1793template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1796 const SI_CHAR * a_pData
1810 if (IsSpace(*a_pData)) {
1815 const SI_CHAR * pStart = a_pData;
1817 if (IsNewLineChar(*a_pData)) {
1824 if (a_pData > pStart && IsSpace(*(a_pData - 1))) {
1831template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1834 const SI_CHAR* a_pData
1846 if (IsSpace(*a_pData)) {
1851 const SI_CHAR * pStart = a_pData;
1853 if (IsNewLineChar(*a_pData)) {
1860 if (a_pData > pStart && IsSpace(*(a_pData - 1))) {
1867template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1873 return (a_c ==
'\n' || a_c ==
'\r');
1876template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1880 const SI_CHAR *& a_pVal,
1881 const SI_CHAR * a_pTagName,
1882 bool a_bAllowBlankLinesInComment
1893 SI_CHAR * pDataLine = a_pData;
1894 SI_CHAR * pCurrLine;
1902 SI_CHAR cEndOfLineChar = *a_pData;
1906 if (!a_pTagName && !IsComment(*a_pData)) {
1908 if (!a_bAllowBlankLinesInComment) {
1915 SI_CHAR * pCurr = a_pData;
1917 while (IsSpace(*pCurr)) {
1918 if (IsNewLineChar(*pCurr)) {
1929 if (IsComment(*pCurr)) {
1930 for (; nNewLines > 0; --nNewLines) *pDataLine++ =
'\n';
1940 pCurrLine = a_pData;
1941 while (*a_pData && !IsNewLineChar(*a_pData)) ++a_pData;
1944 if (pDataLine < pCurrLine) {
1945 size_t nLen = (size_t) (a_pData - pCurrLine);
1946 memmove(pDataLine, pCurrLine, nLen *
sizeof(SI_CHAR));
1947 pDataLine[nLen] =
'\0';
1951 cEndOfLineChar = *a_pData;
1959 SI_CHAR* pc = a_pData - 1;
1960 while (pc > pDataLine && IsSpace(*pc)) --pc;
1964 if (!IsLess(pDataLine, a_pTagName) && !IsLess(a_pTagName, pDataLine)) {
1973 if (!cEndOfLineChar) {
1979 pDataLine += (a_pData - pCurrLine);
1980 *a_pData = cEndOfLineChar;
1981 SkipNewLine(a_pData);
1982 *pDataLine++ =
'\n';
1986 if (a_pVal == a_pData) {
1995 *--pDataLine =
'\0';
1999 if (a_pTagName && cEndOfLineChar) {
2000 SI_ASSERT(IsNewLineChar(cEndOfLineChar));
2001 *a_pData = cEndOfLineChar;
2002 SkipNewLine(a_pData);
2008template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2011 const SI_CHAR *& a_pString
2015 if (
sizeof(SI_CHAR) ==
sizeof(
char)) {
2016 uLen = strlen((
const char *)a_pString);
2018 else if (
sizeof(SI_CHAR) ==
sizeof(
wchar_t)) {
2019 uLen = wcslen((
const wchar_t *)a_pString);
2022 for ( ; a_pString[uLen]; ++uLen) ;
2025 SI_CHAR * pCopy =
new(std::nothrow) SI_CHAR[uLen];
2029 memcpy(pCopy, a_pString,
sizeof(SI_CHAR)*uLen);
2030 m_strings.push_back(pCopy);
2035template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2038 const SI_CHAR * a_pSection,
2039 const SI_CHAR * a_pKey,
2040 const SI_CHAR * a_pValue,
2041 const SI_CHAR * a_pComment,
2042 bool a_bForceReplace,
2047 bool bInserted =
false;
2049 SI_ASSERT(!a_pComment || IsComment(*a_pComment));
2053 if (a_bCopyStrings && a_pComment) {
2054 rc = CopyString(a_pComment);
2055 if (rc < 0)
return rc;
2059 typename TSection::iterator iSection = m_data.find(a_pSection);
2060 if (iSection == m_data.end()) {
2063 if (a_bCopyStrings) {
2064 rc = CopyString(a_pSection);
2065 if (rc < 0)
return rc;
2069 Entry oSection(a_pSection, ++m_nOrder);
2070 if (a_pComment && !a_pKey) {
2071 oSection.pComment = a_pComment;
2074 typename TSection::value_type oEntry(oSection, TKeyVal());
2075 typedef typename TSection::iterator SectionIterator;
2076 std::pair<SectionIterator,bool> i = m_data.insert(oEntry);
2082 return bInserted ? SI_INSERTED : SI_UPDATED;
2086 TKeyVal & keyval = iSection->second;
2087 typename TKeyVal::iterator iKey = keyval.find(a_pKey);
2088 bInserted = iKey == keyval.end();
2092 int nLoadOrder = ++m_nOrder;
2093 if (iKey != keyval.end() && m_bAllowMultiKey && a_bForceReplace) {
2094 const SI_CHAR * pComment = NULL;
2095 while (iKey != keyval.end() && !IsLess(a_pKey, iKey->first.pItem)) {
2096 if (iKey->first.nOrder < nLoadOrder) {
2097 nLoadOrder = iKey->first.nOrder;
2098 pComment = iKey->first.pComment;
2103 DeleteString(a_pComment);
2104 a_pComment = pComment;
2105 rc = CopyString(a_pComment);
2106 if (rc < 0)
return rc;
2108 Delete(a_pSection, a_pKey);
2109 iKey = keyval.end();
2114 a_pValue = &m_cEmptyString;
2118 bool bForceCreateNewKey = m_bAllowMultiKey && !a_bForceReplace;
2119 if (a_bCopyStrings) {
2120 if (bForceCreateNewKey || iKey == keyval.end()) {
2124 rc = CopyString(a_pKey);
2125 if (rc < 0)
return rc;
2129 rc = CopyString(a_pValue);
2130 if (rc < 0)
return rc;
2134 if (iKey == keyval.end() || bForceCreateNewKey) {
2135 Entry oKey(a_pKey, nLoadOrder);
2137 oKey.pComment = a_pComment;
2139 typename TKeyVal::value_type oEntry(oKey,
static_cast<const SI_CHAR *
>(NULL));
2140 iKey = keyval.insert(oEntry);
2143 iKey->second = a_pValue;
2144 return bInserted ? SI_INSERTED : SI_UPDATED;
2147template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2150 const SI_CHAR * a_pSection,
2151 const SI_CHAR * a_pKey,
2152 const SI_CHAR * a_pDefault,
2153 bool * a_pHasMultiple
2156 if (a_pHasMultiple) {
2157 *a_pHasMultiple =
false;
2159 if (!a_pSection || !a_pKey) {
2162 typename TSection::const_iterator iSection = m_data.find(a_pSection);
2163 if (iSection == m_data.end()) {
2166 typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey);
2167 if (iKeyVal == iSection->second.end()) {
2172 if (m_bAllowMultiKey && a_pHasMultiple) {
2173 typename TKeyVal::const_iterator iTemp = iKeyVal;
2174 if (++iTemp != iSection->second.end()) {
2175 if (!IsLess(a_pKey, iTemp->first.pItem)) {
2176 *a_pHasMultiple =
true;
2181 return iKeyVal->second;
2184template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2187 const SI_CHAR * a_pSection,
2188 const SI_CHAR * a_pKey,
2190 bool * a_pHasMultiple
2194 const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple);
2195 if (!pszValue || !*pszValue)
return a_nDefault;
2198 char szValue[64] = { 0 };
2199 SI_CONVERTER c(m_bStoreIsUtf8);
2200 if (!c.ConvertToStore(pszValue, szValue,
sizeof(szValue))) {
2205 long nValue = a_nDefault;
2206 char * pszSuffix = szValue;
2207 if (szValue[0] ==
'0' && (szValue[1] ==
'x' || szValue[1] ==
'X')) {
2208 if (!szValue[2])
return a_nDefault;
2209 nValue = strtol(&szValue[2], &pszSuffix, 16);
2212 nValue = strtol(szValue, &pszSuffix, 10);
2223template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2226 const SI_CHAR * a_pSection,
2227 const SI_CHAR * a_pKey,
2229 const SI_CHAR * a_pComment,
2231 bool a_bForceReplace
2235 if (!a_pSection || !a_pKey)
return SI_FAIL;
2239#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE
2240 sprintf_s(szInput, a_bUseHex ?
"0x%lx" :
"%ld", a_nValue);
2242 snprintf(szInput,
sizeof(szInput), a_bUseHex ?
"0x%lx" :
"%ld", a_nValue);
2246 SI_CHAR szOutput[64];
2247 SI_CONVERTER c(m_bStoreIsUtf8);
2248 c.ConvertFromStore(szInput, strlen(szInput) + 1,
2249 szOutput,
sizeof(szOutput) /
sizeof(SI_CHAR));
2252 return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace,
true);
2255template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2258 const SI_CHAR * a_pSection,
2259 const SI_CHAR * a_pKey,
2261 bool * a_pHasMultiple
2265 const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple);
2266 if (!pszValue || !*pszValue)
return a_nDefault;
2269 char szValue[64] = { 0 };
2270 SI_CONVERTER c(m_bStoreIsUtf8);
2271 if (!c.ConvertToStore(pszValue, szValue,
sizeof(szValue))) {
2275 char * pszSuffix = szValue;
2276 double nValue = strtod(szValue, &pszSuffix);
2280 if (pszSuffix == szValue || *pszSuffix) {
2287template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2290 const SI_CHAR * a_pSection,
2291 const SI_CHAR * a_pKey,
2293 const SI_CHAR * a_pComment,
2294 bool a_bForceReplace
2298 if (!a_pSection || !a_pKey)
return SI_FAIL;
2302#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE
2303 sprintf_s(szInput,
"%f", a_nValue);
2305 snprintf(szInput,
sizeof(szInput),
"%f", a_nValue);
2309 SI_CHAR szOutput[64];
2310 SI_CONVERTER c(m_bStoreIsUtf8);
2311 c.ConvertFromStore(szInput, strlen(szInput) + 1,
2312 szOutput,
sizeof(szOutput) /
sizeof(SI_CHAR));
2315 return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace,
true);
2318template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2321 const SI_CHAR * a_pSection,
2322 const SI_CHAR * a_pKey,
2324 bool * a_pHasMultiple
2328 const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple);
2329 if (!pszValue || !*pszValue)
return a_bDefault;
2332 switch (pszValue[0]) {
2344 if (pszValue[1] ==
'n' || pszValue[1] ==
'N')
return true;
2345 if (pszValue[1] ==
'f' || pszValue[1] ==
'F')
return false;
2353template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2356 const SI_CHAR * a_pSection,
2357 const SI_CHAR * a_pKey,
2359 const SI_CHAR * a_pComment,
2360 bool a_bForceReplace
2364 if (!a_pSection || !a_pKey)
return SI_FAIL;
2367 const char * pszInput = a_bValue ?
"true" :
"false";
2370 SI_CHAR szOutput[64];
2371 SI_CONVERTER c(m_bStoreIsUtf8);
2372 c.ConvertFromStore(pszInput, strlen(pszInput) + 1,
2373 szOutput,
sizeof(szOutput) /
sizeof(SI_CHAR));
2376 return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace,
true);
2379template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2382 const SI_CHAR * a_pSection,
2383 const SI_CHAR * a_pKey,
2389 if (!a_pSection || !a_pKey) {
2392 typename TSection::const_iterator iSection = m_data.find(a_pSection);
2393 if (iSection == m_data.end()) {
2396 typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey);
2397 if (iKeyVal == iSection->second.end()) {
2402 a_values.push_back(
Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder));
2403 if (m_bAllowMultiKey) {
2405 while (iKeyVal != iSection->second.end() && !IsLess(a_pKey, iKeyVal->first.pItem)) {
2406 a_values.push_back(
Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder));
2414template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2417 const SI_CHAR * a_pSection
2424 typename TSection::const_iterator iSection = m_data.find(a_pSection);
2425 if (iSection == m_data.end()) {
2428 const TKeyVal & section = iSection->second;
2432 if (!m_bAllowMultiKey || section.empty()) {
2433 return (
int) section.size();
2438 const SI_CHAR * pLastKey = NULL;
2439 typename TKeyVal::const_iterator iKeyVal = section.begin();
2440 for (; iKeyVal != section.end(); ++iKeyVal) {
2441 if (!pLastKey || IsLess(pLastKey, iKeyVal->first.pItem)) {
2443 pLastKey = iKeyVal->first.pItem;
2449template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2452 const SI_CHAR * a_pSection
2456 typename TSection::const_iterator i = m_data.find(a_pSection);
2457 if (i != m_data.end()) {
2458 return &(i->second);
2464template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2471 typename TSection::const_iterator i = m_data.begin();
2472 for (; i != m_data.end(); ++i) {
2473 a_names.push_back(i->first);
2477template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2480 const SI_CHAR * a_pSection,
2490 typename TSection::const_iterator iSection = m_data.find(a_pSection);
2491 if (iSection == m_data.end()) {
2495 const TKeyVal & section = iSection->second;
2496 const SI_CHAR * pLastKey = NULL;
2497 typename TKeyVal::const_iterator iKeyVal = section.begin();
2498 for (; iKeyVal != section.end(); ++iKeyVal) {
2499 if (!pLastKey || IsLess(pLastKey, iKeyVal->first.pItem)) {
2500 a_names.push_back(iKeyVal->first);
2501 pLastKey = iKeyVal->first.pItem;
2508template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2511 const char * a_pszFile,
2512 bool a_bAddSignature
2516#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE
2517 fopen_s(&fp, a_pszFile,
"wb");
2519 fp = fopen(a_pszFile,
"wb");
2521 if (!fp)
return SI_FILE;
2522 SI_Error rc = SaveFile(fp, a_bAddSignature);
2527#ifdef SI_HAS_WIDE_FILE
2528template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2531 const SI_WCHAR_T * a_pwszFile,
2532 bool a_bAddSignature
2537#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE
2538 _wfopen_s(&fp, a_pwszFile, L
"wb");
2540 fp = _wfopen(a_pwszFile, L
"wb");
2542 if (!fp)
return SI_FILE;
2543 SI_Error rc = SaveFile(fp, a_bAddSignature);
2548 u_austrncpy(szFile, a_pwszFile,
sizeof(szFile));
2549 return SaveFile(szFile, a_bAddSignature);
2554template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2558 bool a_bAddSignature
2562 return Save(writer, a_bAddSignature);
2565template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2569 bool a_bAddSignature
2575 if (m_bStoreIsUtf8 && a_bAddSignature) {
2576 a_oOutput.Write(SI_UTF8_SIGNATURE);
2581 GetAllSections(oSections);
2582#if defined(_MSC_VER) && _MSC_VER <= 1200
2584#elif defined(__BORLANDC__)
2592 typename TNamesDepend::iterator is = oSections.begin();
2593 for (; is != oSections.end(); ++is) {
2596 if (is != oSections.begin()) {
2597 oSections.splice(oSections.begin(), oSections, is, std::next(is));
2604 bool bNeedNewLine =
false;
2605 if (m_pFileComment) {
2606 if (!OutputMultiLineText(a_oOutput, convert, m_pFileComment)) {
2609 bNeedNewLine =
true;
2613 typename TNamesDepend::const_iterator iSection = oSections.begin();
2614 for ( ; iSection != oSections.end(); ++iSection ) {
2616 if (iSection->pComment) {
2618 a_oOutput.Write(SI_NEWLINE_A);
2619 a_oOutput.Write(SI_NEWLINE_A);
2621 if (!OutputMultiLineText(a_oOutput, convert, iSection->pComment)) {
2624 bNeedNewLine =
false;
2628 a_oOutput.Write(SI_NEWLINE_A);
2629 a_oOutput.Write(SI_NEWLINE_A);
2630 bNeedNewLine =
false;
2634 if (*iSection->pItem) {
2635 if (!convert.ConvertToStore(iSection->pItem)) {
2638 a_oOutput.Write(
"[");
2639 a_oOutput.Write(convert.Data());
2640 a_oOutput.Write(
"]");
2641 a_oOutput.Write(SI_NEWLINE_A);
2646 GetAllKeys(iSection->pItem, oKeys);
2647#if defined(_MSC_VER) && _MSC_VER <= 1200
2649#elif defined(__BORLANDC__)
2656 typename TNamesDepend::const_iterator iKey = oKeys.begin();
2657 for ( ; iKey != oKeys.end(); ++iKey) {
2660 GetAllValues(iSection->pItem, iKey->pItem, oValues);
2662 typename TNamesDepend::const_iterator iValue = oValues.begin();
2663 for ( ; iValue != oValues.end(); ++iValue) {
2665 if (iValue->pComment) {
2666 a_oOutput.Write(SI_NEWLINE_A);
2667 if (!OutputMultiLineText(a_oOutput, convert, iValue->pComment)) {
2673 if (!convert.ConvertToStore(iKey->pItem)) {
2676 a_oOutput.Write(convert.Data());
2679 if (*iValue->pItem || !m_bAllowKeyOnly) {
2680 if (!convert.ConvertToStore(iValue->pItem)) {
2683 a_oOutput.Write(m_bSpaces ?
" = " :
"=");
2684 if (m_bParseQuotes && IsSingleLineQuotedValue(iValue->pItem)) {
2687 a_oOutput.Write(
"\"");
2688 a_oOutput.Write(convert.Data());
2689 a_oOutput.Write(
"\"");
2691 else if (m_bAllowMultiLine && IsMultiLineData(iValue->pItem)) {
2694 a_oOutput.Write(
"<<<END_OF_TEXT" SI_NEWLINE_A);
2695 if (!OutputMultiLineText(a_oOutput, convert, iValue->pItem)) {
2698 a_oOutput.Write(
"END_OF_TEXT");
2701 a_oOutput.Write(convert.Data());
2704 a_oOutput.Write(SI_NEWLINE_A);
2708 bNeedNewLine =
true;
2714template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2717 OutputWriter & a_oOutput,
2718 Converter & a_oConverter,
2719 const SI_CHAR * a_pText
2722 const SI_CHAR * pEndOfLine;
2723 SI_CHAR cEndOfLineChar = *a_pText;
2724 while (cEndOfLineChar) {
2726 pEndOfLine = a_pText;
2727 for (; *pEndOfLine && *pEndOfLine !=
'\n'; ++pEndOfLine) ;
2728 cEndOfLineChar = *pEndOfLine;
2731 *
const_cast<SI_CHAR*
>(pEndOfLine) = 0;
2732 if (!a_oConverter.ConvertToStore(a_pText)) {
2735 *
const_cast<SI_CHAR*
>(pEndOfLine) = cEndOfLineChar;
2736 a_pText += (pEndOfLine - a_pText) + 1;
2737 a_oOutput.Write(a_oConverter.Data());
2738 a_oOutput.Write(SI_NEWLINE_A);
2743template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2746 const SI_CHAR * a_pSection,
2747 const SI_CHAR * a_pKey,
2751 return DeleteValue(a_pSection, a_pKey, NULL, a_bRemoveEmpty);
2754template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2757 const SI_CHAR * a_pSection,
2758 const SI_CHAR * a_pKey,
2759 const SI_CHAR * a_pValue,
2767 typename TSection::iterator iSection = m_data.find(a_pSection);
2768 if (iSection == m_data.end()) {
2774 typename TKeyVal::iterator iKeyVal = iSection->second.find(a_pKey);
2775 if (iKeyVal == iSection->second.end()) {
2779 const static SI_STRLESS isLess = SI_STRLESS();
2782 typename TKeyVal::iterator iDelete;
2783 bool bDeleted =
false;
2785 iDelete = iKeyVal++;
2787 if(a_pValue == NULL ||
2788 (isLess(a_pValue, iDelete->second) ==
false &&
2789 isLess(iDelete->second, a_pValue) ==
false)) {
2790 DeleteString(iDelete->first.pItem);
2791 DeleteString(iDelete->second);
2792 iSection->second.erase(iDelete);
2796 while (iKeyVal != iSection->second.end()
2797 && !IsLess(a_pKey, iKeyVal->first.pItem));
2806 if (!a_bRemoveEmpty || !iSection->second.empty()) {
2813 typename TKeyVal::iterator iKeyVal = iSection->second.begin();
2814 for ( ; iKeyVal != iSection->second.end(); ++iKeyVal) {
2815 DeleteString(iKeyVal->first.pItem);
2816 DeleteString(iKeyVal->second);
2821 DeleteString(iSection->first.pItem);
2822 m_data.erase(iSection);
2827template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2830 const SI_CHAR * a_pString
2836 if (!m_pData || a_pString < m_pData || a_pString >= m_pData + m_uDataLen) {
2837 typename TNamesDepend::iterator i = m_strings.begin();
2838 for (;i != m_strings.end(); ++i) {
2839 if (a_pString == i->pItem) {
2840 delete[]
const_cast<SI_CHAR*
>(i->pItem);
2866#if !defined(SI_NO_CONVERSION) && !defined(SI_CONVERT_GENERIC) && !defined(SI_CONVERT_WIN32) && !defined(SI_CONVERT_ICU)
2868# define SI_CONVERT_WIN32
2870# define SI_NO_CONVERSION
2879template<
class SI_CHAR>
2881 bool operator()(
const SI_CHAR * pLeft,
const SI_CHAR * pRight)
const {
2883 for ( ;*pLeft && *pRight; ++pLeft, ++pRight) {
2884 cmp = (long) *pLeft - (
long) *pRight;
2889 return *pRight != 0;
2899template<
class SI_CHAR>
2901 inline SI_CHAR locase(SI_CHAR ch)
const {
2902 return (ch <
'A' || ch >
'Z') ? ch : (ch -
'A' +
'a');
2904 bool operator()(
const SI_CHAR * pLeft,
const SI_CHAR * pRight)
const {
2906 for ( ;*pLeft && *pRight; ++pLeft, ++pRight) {
2907 cmp = (long) locase(*pLeft) - (long) locase(*pRight);
2912 return *pRight != 0;
2919template<
class SI_CHAR>
2921 bool m_bStoreIsUtf8;
2925 SI_ConvertA(
bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { }
2930 m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8;
2948 const char * a_pInputData,
2949 size_t a_uInputDataLen)
2952 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
2955 return a_uInputDataLen;
2972 const char * a_pInputData,
2973 size_t a_uInputDataLen,
2974 SI_CHAR * a_pOutputData,
2975 size_t a_uOutputDataSize)
2978 if (a_uInputDataLen > a_uOutputDataSize) {
2981 memcpy(a_pOutputData, a_pInputData, a_uInputDataLen);
2996 const SI_CHAR * a_pInputData)
2999 return strlen((
const char *)a_pInputData) + 1;
3016 const SI_CHAR * a_pInputData,
3017 char * a_pOutputData,
3018 size_t a_uOutputDataSize)
3021 size_t uInputLen = strlen((
const char *)a_pInputData) + 1;
3022 if (uInputLen > a_uOutputDataSize) {
3027 memcpy(a_pOutputData, a_pInputData, uInputLen);
3036#ifdef SI_CONVERT_GENERIC
3038#define SI_Case SI_GenericCase
3039#define SI_NoCase SI_GenericNoCase
3042#include "ConvertUTF.h"
3048template<
class SI_CHAR>
3050 bool m_bStoreIsUtf8;
3054 SI_ConvertW(
bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { }
3057 SI_ConvertW(
const SI_ConvertW & rhs) { operator=(rhs); }
3058 SI_ConvertW & operator=(
const SI_ConvertW & rhs) {
3059 m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8;
3076 size_t SizeFromStore(
3077 const char * a_pInputData,
3078 size_t a_uInputDataLen)
3080 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
3082 if (m_bStoreIsUtf8) {
3086 return a_uInputDataLen;
3090#if defined(_MSC_VER)
3092 errno_t e = mbstowcs_s(&uBufSiz, NULL, 0, a_pInputData, a_uInputDataLen);
3093 return (e == 0) ? uBufSiz : (size_t) -1;
3094#elif !defined(SI_NO_MBSTOWCS_NULL)
3095 return mbstowcs(NULL, a_pInputData, a_uInputDataLen);
3100 return a_uInputDataLen;
3117 bool ConvertFromStore(
3118 const char * a_pInputData,
3119 size_t a_uInputDataLen,
3120 SI_CHAR * a_pOutputData,
3121 size_t a_uOutputDataSize)
3123 if (m_bStoreIsUtf8) {
3129 ConversionResult retval;
3130 const UTF8 * pUtf8 = (
const UTF8 *) a_pInputData;
3131 if (
sizeof(
wchar_t) ==
sizeof(UTF32)) {
3132 UTF32 * pUtf32 = (UTF32 *) a_pOutputData;
3133 retval = ConvertUTF8toUTF32(
3134 &pUtf8, pUtf8 + a_uInputDataLen,
3135 &pUtf32, pUtf32 + a_uOutputDataSize,
3138 else if (
sizeof(
wchar_t) ==
sizeof(UTF16)) {
3139 UTF16 * pUtf16 = (UTF16 *) a_pOutputData;
3140 retval = ConvertUTF8toUTF16(
3141 &pUtf8, pUtf8 + a_uInputDataLen,
3142 &pUtf16, pUtf16 + a_uOutputDataSize,
3145 return retval == conversionOK;
3149#if defined(_MSC_VER)
3151 errno_t e = mbstowcs_s(&uBufSiz,
3152 a_pOutputData, a_uOutputDataSize,
3153 a_pInputData, a_uInputDataLen);
3157 size_t retval = mbstowcs(a_pOutputData,
3158 a_pInputData, a_uOutputDataSize);
3159 return retval != (size_t)(-1);
3174 const SI_CHAR * a_pInputData)
3176 if (m_bStoreIsUtf8) {
3179 while (a_pInputData[uLen]) {
3182 return (6 * uLen) + 1;
3185 size_t uLen = wcstombs(NULL, a_pInputData, 0);
3186 if (uLen == (
size_t)(-1)) {
3206 bool ConvertToStore(
3207 const SI_CHAR * a_pInputData,
3208 char * a_pOutputData,
3209 size_t a_uOutputDataSize
3212 if (m_bStoreIsUtf8) {
3214 size_t uInputLen = 0;
3215 while (a_pInputData[uInputLen]) {
3225 ConversionResult retval;
3226 UTF8 * pUtf8 = (UTF8 *) a_pOutputData;
3227 if (
sizeof(
wchar_t) ==
sizeof(UTF32)) {
3228 const UTF32 * pUtf32 = (
const UTF32 *) a_pInputData;
3229 retval = ConvertUTF32toUTF8(
3230 &pUtf32, pUtf32 + uInputLen,
3231 &pUtf8, pUtf8 + a_uOutputDataSize,
3234 else if (
sizeof(
wchar_t) ==
sizeof(UTF16)) {
3235 const UTF16 * pUtf16 = (
const UTF16 *) a_pInputData;
3236 retval = ConvertUTF16toUTF8(
3237 &pUtf16, pUtf16 + uInputLen,
3238 &pUtf8, pUtf8 + a_uOutputDataSize,
3241 return retval == conversionOK;
3244 size_t retval = wcstombs(a_pOutputData,
3245 a_pInputData, a_uOutputDataSize);
3246 return retval != (size_t) -1;
3257#ifdef SI_CONVERT_ICU
3259#define SI_Case SI_GenericCase
3260#define SI_NoCase SI_GenericNoCase
3262#include <unicode/ucnv.h>
3267template<
class SI_CHAR>
3269 const char * m_pEncoding;
3270 UConverter * m_pConverter;
3272 SI_ConvertW() : m_pEncoding(NULL), m_pConverter(NULL) { }
3274 SI_ConvertW(
bool a_bStoreIsUtf8) : m_pConverter(NULL) {
3275 m_pEncoding = a_bStoreIsUtf8 ?
"UTF-8" : NULL;
3279 SI_ConvertW(
const SI_ConvertW & rhs) { operator=(rhs); }
3280 SI_ConvertW & operator=(
const SI_ConvertW & rhs) {
3281 m_pEncoding = rhs.m_pEncoding;
3282 m_pConverter = NULL;
3285 ~SI_ConvertW() {
if (m_pConverter) ucnv_close(m_pConverter); }
3300 size_t SizeFromStore(
3301 const char * a_pInputData,
3302 size_t a_uInputDataLen)
3304 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
3308 if (!m_pConverter) {
3309 nError = U_ZERO_ERROR;
3310 m_pConverter = ucnv_open(m_pEncoding, &nError);
3311 if (U_FAILURE(nError)) {
3316 nError = U_ZERO_ERROR;
3317 int32_t nLen = ucnv_toUChars(m_pConverter, NULL, 0,
3318 a_pInputData, (int32_t) a_uInputDataLen, &nError);
3319 if (U_FAILURE(nError) && nError != U_BUFFER_OVERFLOW_ERROR) {
3323 return (
size_t) nLen;
3339 bool ConvertFromStore(
3340 const char * a_pInputData,
3341 size_t a_uInputDataLen,
3342 UChar * a_pOutputData,
3343 size_t a_uOutputDataSize)
3347 if (!m_pConverter) {
3348 nError = U_ZERO_ERROR;
3349 m_pConverter = ucnv_open(m_pEncoding, &nError);
3350 if (U_FAILURE(nError)) {
3355 nError = U_ZERO_ERROR;
3356 ucnv_toUChars(m_pConverter,
3357 a_pOutputData, (int32_t) a_uOutputDataSize,
3358 a_pInputData, (int32_t) a_uInputDataLen, &nError);
3359 if (U_FAILURE(nError)) {
3377 const UChar * a_pInputData)
3381 if (!m_pConverter) {
3382 nError = U_ZERO_ERROR;
3383 m_pConverter = ucnv_open(m_pEncoding, &nError);
3384 if (U_FAILURE(nError)) {
3389 nError = U_ZERO_ERROR;
3390 int32_t nLen = ucnv_fromUChars(m_pConverter, NULL, 0,
3391 a_pInputData, -1, &nError);
3392 if (U_FAILURE(nError) && nError != U_BUFFER_OVERFLOW_ERROR) {
3396 return (
size_t) nLen + 1;
3412 bool ConvertToStore(
3413 const UChar * a_pInputData,
3414 char * a_pOutputData,
3415 size_t a_uOutputDataSize)
3419 if (!m_pConverter) {
3420 nError = U_ZERO_ERROR;
3421 m_pConverter = ucnv_open(m_pEncoding, &nError);
3422 if (U_FAILURE(nError)) {
3427 nError = U_ZERO_ERROR;
3428 ucnv_fromUChars(m_pConverter,
3429 a_pOutputData, (int32_t) a_uOutputDataSize,
3430 a_pInputData, -1, &nError);
3431 if (U_FAILURE(nError)) {
3445#ifdef SI_CONVERT_WIN32
3447#define SI_Case SI_GenericCase
3458# define SI_NoCase SI_GenericNoCase
3468#include <mbstring.h>
3469template<
class SI_CHAR>
3471 bool operator()(
const SI_CHAR * pLeft,
const SI_CHAR * pRight)
const {
3472 if (
sizeof(SI_CHAR) ==
sizeof(
char)) {
3473 return _mbsicmp((
const unsigned char *)pLeft,
3474 (
const unsigned char *)pRight) < 0;
3476 if (
sizeof(SI_CHAR) ==
sizeof(
wchar_t)) {
3477 return _wcsicmp((
const wchar_t *)pLeft,
3478 (
const wchar_t *)pRight) < 0;
3491template<
class SI_CHAR>
3521 size_t SizeFromStore(
3547 bool ConvertFromStore(
3593 bool ConvertToStore(
3613#ifdef SI_NO_CONVERSION
3615#define SI_Case SI_GenericCase
3616#define SI_NoCase SI_GenericNoCase
3631#if defined(SI_NO_CONVERSION)
3634# define CSimpleIni CSimpleIniA
3635# define CSimpleIniCase CSimpleIniCaseA
3636# define SI_NEWLINE SI_NEWLINE_A
3638# if defined(SI_CONVERT_ICU)
3651# define CSimpleIni CSimpleIniW
3652# define CSimpleIniCase CSimpleIniCaseW
3653# define SI_NEWLINE SI_NEWLINE_W
3655# define CSimpleIni CSimpleIniA
3656# define CSimpleIniCase CSimpleIniCaseA
3657# define SI_NEWLINE SI_NEWLINE_A
3662# pragma warning (pop)
Definition SimpleIni.h:440
Definition SimpleIni.h:397
Definition SimpleIni.h:386
Definition SimpleIni.h:410
Definition SimpleIni.h:319
bool DeleteValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, const SI_CHAR *a_pValue, bool a_bRemoveEmpty=false)
Definition SimpleIni.h:2756
bool GetAllKeys(const SI_CHAR *a_pSection, TNamesDepend &a_names) const
Definition SimpleIni.h:2479
int GetSectionSize(const SI_CHAR *a_pSection) const
Definition SimpleIni.h:2416
void SetAllowKeyOnly(bool a_bAllowKeyOnly=true)
Definition SimpleIni.h:588
SI_Error LoadData(const std::string &a_strData)
Definition SimpleIni.h:654
bool UsingQuotes() const
Definition SimpleIni.h:578
std::map< Entry, TKeyVal, typename Entry::KeyOrder > TSection
Definition SimpleIni.h:376
std::list< Entry > TNamesDepend
Definition SimpleIni.h:381
bool IsUnicode() const
Definition SimpleIni.h:514
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:2355
bool IsMultiKey() const
Definition SimpleIni.h:539
Converter GetConverter() const
Definition SimpleIni.h:1191
bool IsEmpty() const
Definition SimpleIni.h:490
const TKeyVal * GetSection(const SI_CHAR *a_pSection) const
Definition SimpleIni.h:2451
SI_Error Save(OutputWriter &a_oOutput, bool a_bAddSignature=false) const
Definition SimpleIni.h:2567
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:2149
bool GetBoolValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, bool a_bDefault=false, bool *a_pHasMultiple=NULL) const
Definition SimpleIni.h:2320
long GetLongValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, long a_nDefault=0, bool *a_pHasMultiple=NULL) const
Definition SimpleIni.h:2186
void GetAllSections(TNamesDepend &a_names) const
Definition SimpleIni.h:2466
void Reset()
Definition SimpleIni.h:1382
~CSimpleIniTempl()
Definition SimpleIni.h:1375
bool UsingSpaces() const
Definition SimpleIni.h:566
SI_Error Save(std::string &a_sBuffer, bool a_bAddSignature=false) const
Definition SimpleIni.h:794
bool KeyExists(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey) const
Definition SimpleIni.h:907
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:1032
bool SectionExists(const SI_CHAR *a_pSection) const
Definition SimpleIni.h:900
bool Delete(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, bool a_bRemoveEmpty=false)
Definition SimpleIni.h:2745
void SetMultiLine(bool a_bAllowMultiLine=true)
Definition SimpleIni.h:548
void SetQuotes(bool a_bParseQuotes=true)
Definition SimpleIni.h:573
void SetUnicode(bool a_bIsUtf8=true)
Definition SimpleIni.h:509
double GetDoubleValue(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, double a_nDefault=0, bool *a_pHasMultiple=NULL) const
Definition SimpleIni.h:2257
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:2225
void SetMultiKey(bool a_bAllowMultiKey=true)
Definition SimpleIni.h:534
bool GetAllValues(const SI_CHAR *a_pSection, const SI_CHAR *a_pKey, TNamesDepend &a_values) const
Definition SimpleIni.h:2381
void SetSpaces(bool a_bSpaces=true)
Definition SimpleIni.h:561
std::multimap< Entry, const SI_CHAR *, typename Entry::KeyOrder > TKeyVal
Definition SimpleIni.h:373
SI_Error LoadFile(const char *a_pszFile)
Definition SimpleIni.h:1405
bool GetAllowKeyOnly() const
Definition SimpleIni.h:593
SI_Error SaveFile(const char *a_pszFile, bool a_bAddSignature=true) const
Definition SimpleIni.h:2510
CSimpleIniTempl(bool a_bIsUtf8=false, bool a_bMultiKey=false, bool a_bMultiLine=false)
Definition SimpleIni.h:1356
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:2289
bool IsMultiLine() const
Definition SimpleIni.h:553
Definition SimpleIni.h:2920
bool ConvertToStore(const SI_CHAR *a_pInputData, char *a_pOutputData, size_t a_uOutputDataSize)
Definition SimpleIni.h:3015
size_t SizeFromStore(const char *a_pInputData, size_t a_uInputDataLen)
Definition SimpleIni.h:2947
size_t SizeToStore(const SI_CHAR *a_pInputData)
Definition SimpleIni.h:2995
bool ConvertFromStore(const char *a_pInputData, size_t a_uInputDataLen, SI_CHAR *a_pOutputData, size_t a_uOutputDataSize)
Definition SimpleIni.h:2971
Definition SimpleIni.h:354
Definition SimpleIni.h:362
Definition SimpleIni.h:324
Definition SimpleIni.h:2880
Definition SimpleIni.h:2900