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>
298 const SI_CHAR * pItem;
299 const SI_CHAR * pComment;
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)
312 Entry(
const Entry & rhs) {
operator=(rhs); }
315 pComment = rhs.pComment;
320 #if defined(_MSC_VER) && _MSC_VER <= 1200
322 bool operator<(
const Entry & rhs)
const {
return LoadOrder()(*
this, rhs); }
323 bool operator>(
const Entry & rhs)
const {
return LoadOrder()(rhs, *
this); }
327 struct KeyOrder : std::binary_function<Entry, Entry, bool> {
328 bool operator()(
const Entry & lhs,
const Entry & rhs)
const {
329 const static SI_STRLESS isLess = SI_STRLESS();
330 return isLess(lhs.pItem, rhs.pItem);
335 struct LoadOrder : std::binary_function<Entry, Entry, bool> {
336 bool operator()(
const Entry & lhs,
const Entry & rhs)
const {
337 if (lhs.nOrder != rhs.nOrder) {
338 return lhs.nOrder < rhs.nOrder;
340 return KeyOrder()(lhs.pItem, rhs.pItem);
346 typedef std::multimap<Entry,const SI_CHAR *,typename Entry::KeyOrder>
TKeyVal;
349 typedef std::map<Entry,TKeyVal,typename Entry::KeyOrder>
TSection;
362 virtual ~OutputWriter() { }
363 virtual void Write(
const char * a_pBuf) = 0;
365 OutputWriter(
const OutputWriter &);
366 OutputWriter &
operator=(
const OutputWriter &);
370 class FileWriter :
public OutputWriter {
373 FileWriter(FILE * a_file) : m_file(a_file) { }
374 void Write(
const char * a_pBuf) {
375 fputs(a_pBuf, m_file);
378 FileWriter(
const FileWriter &);
379 FileWriter &
operator=(
const FileWriter &);
383 class StringWriter :
public OutputWriter {
384 std::string & m_string;
386 StringWriter(std::string & a_string) : m_string(a_string) { }
387 void Write(
const char * a_pBuf) {
388 m_string.append(a_pBuf);
391 StringWriter(
const StringWriter &);
392 StringWriter &
operator=(
const StringWriter &);
395 #ifdef SI_SUPPORT_IOSTREAMS
397 class StreamWriter :
public OutputWriter {
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
413 class Converter :
private SI_CONVERTER {
415 Converter(
bool a_bStoreIsUtf8) : SI_CONVERTER(a_bStoreIsUtf8) {
416 m_scratch.resize(1024);
418 Converter(
const Converter & rhs) {
operator=(rhs); }
419 Converter &
operator=(
const Converter & rhs) {
420 m_scratch = rhs.m_scratch;
423 bool ConvertToStore(
const SI_CHAR * a_pszString) {
424 size_t uLen = 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(); }
438 std::string m_scratch;
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
701 OutputWriter & a_oOutput,
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
743 StringWriter writer(a_sBuffer);
744 return Save(writer, a_bAddSignature);
787 const SI_CHAR * a_pSection,
808 const SI_CHAR * a_pSection,
809 const SI_CHAR * a_pKey,
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
1195 OutputWriter & a_oOutput,
1196 Converter & a_oConverter,
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
1256 , m_pFileComment(NULL)
1257 , m_bStoreIsUtf8(a_bIsUtf8)
1258 , m_bAllowMultiKey(a_bAllowMultiKey)
1259 , m_bAllowMultiLine(a_bAllowMultiLine)
1264 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1270 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1278 m_pFileComment = NULL;
1279 if (!m_data.empty()) {
1280 m_data.erase(m_data.begin(), m_data.end());
1284 if (!m_strings.empty()) {
1285 typename TNamesDepend::iterator i = m_strings.begin();
1286 for (; i != m_strings.end(); ++i) {
1287 delete[]
const_cast<SI_CHAR*
>(i->pItem);
1289 m_strings.erase(m_strings.begin(), m_strings.end());
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));
1334 return LoadFile(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) {
1369 SI_Error rc = LoadData(pData, uRead);
1374 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1377 const char * a_pData,
1381 SI_CONVERTER converter(m_bStoreIsUtf8);
1383 if (a_uDataLen == 0) {
1388 if (m_bStoreIsUtf8 && a_uDataLen >= 3) {
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;
1425 bool bCopyStrings = (m_pData != NULL);
1429 SI_Error rc = FindFileComment(pWork, bCopyStrings);
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;
1444 m_uDataLen = uLen+1;
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());
1464 return LoadData(strData);
1466 #endif // SI_SUPPORT_IOSTREAMS
1468 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
1476 if (m_pFileComment) {
1482 if (!LoadMultiLineText(a_pData, m_pFileComment, NULL,
false)) {
1487 if (a_bCopyStrings) {
1488 SI_Error rc = CopyString(m_pFileComment);
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)) {
1519 if (IsComment(*a_pData)) {
1520 LoadMultiLineText(a_pData, a_pComment, NULL,
true);
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)) {
1554 while (*a_pData && !IsNewLineChar(*a_pData)) {
1566 while (*a_pData && *a_pData !=
'=' && !IsNewLineChar(*a_pData)) {
1571 if (*a_pData !=
'=') {
1576 if (a_pKey == a_pData) {
1577 while (*a_pData && !IsNewLineChar(*a_pData)) {
1584 pTrail = a_pData - 1;
1585 while (pTrail >= a_pKey && IsSpace(*pTrail)) {
1593 while (*a_pData && !IsNewLineChar(*a_pData) && IsSpace(*a_pData)) {
1599 while (*a_pData && !IsNewLineChar(*a_pData)) {
1604 pTrail = a_pData - 1;
1606 SkipNewLine(a_pData);
1608 while (pTrail >= a_pVal && IsSpace(*pTrail)) {
1615 if (m_bAllowMultiLine && IsMultiLineTag(a_pVal)) {
1617 const SI_CHAR * pTagName = a_pVal + 3;
1618 return LoadMultiLineText(a_pData, a_pVal, pTagName);
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
1658 if (IsSpace(*a_pData)) {
1664 if (IsNewLineChar(*a_pData)) {
1671 if (IsSpace(*--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;
1728 while (IsSpace(*pCurr)) {
1729 if (IsNewLineChar(*pCurr)) {
1740 if (IsComment(*pCurr)) {
1741 for (; nNewLines > 0; --nNewLines) *pDataLine++ =
'\n';
1751 pCurrLine = a_pData;
1752 while (*a_pData && !IsNewLineChar(*a_pData)) ++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;
1784 SkipNewLine(a_pData);
1785 *pDataLine++ =
'\n';
1789 if (a_pVal == a_pData) {
1798 *--pDataLine =
'\0';
1802 if (a_pTagName && cEndOfLineChar) {
1803 SI_ASSERT(IsNewLineChar(cEndOfLineChar));
1804 *a_pData = cEndOfLineChar;
1805 SkipNewLine(a_pData);
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);
1833 m_strings.push_back(pCopy);
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;
1852 SI_ASSERT(!a_pComment || IsComment(*a_pComment));
1856 if (a_bCopyStrings && a_pComment) {
1857 rc = CopyString(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) {
1867 rc = CopyString(a_pSection);
1868 if (rc < 0)
return rc;
1872 Entry oSection(a_pSection, ++m_nOrder);
1873 if (a_pComment && (!a_pKey || !a_pValue)) {
1874 oSection.pComment = a_pComment;
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);
1894 int nLoadOrder = ++m_nOrder;
1895 if (iKey != keyval.end() && m_bAllowMultiKey && a_bForceReplace) {
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;
1905 DeleteString(a_pComment);
1906 a_pComment = pComment;
1907 CopyString(a_pComment);
1909 Delete(a_pSection, a_pKey);
1910 iKey = keyval.end();
1914 bool bForceCreateNewKey = m_bAllowMultiKey && !a_bForceReplace;
1915 if (a_bCopyStrings) {
1916 if (bForceCreateNewKey || iKey == keyval.end()) {
1920 rc = CopyString(a_pKey);
1921 if (rc < 0)
return rc;
1925 rc = CopyString(a_pValue);
1926 if (rc < 0)
return rc;
1930 if (iKey == keyval.end() || bForceCreateNewKey) {
1931 Entry oKey(a_pKey, nLoadOrder);
1933 oKey.pComment = a_pComment;
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()) {
1968 if (m_bAllowMultiKey && a_pHasMultiple) {
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 };
1995 SI_CONVERTER c(m_bStoreIsUtf8);
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];
2043 SI_CONVERTER c(m_bStoreIsUtf8);
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 };
2066 SI_CONVERTER c(m_bStoreIsUtf8);
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];
2105 SI_CONVERTER c(m_bStoreIsUtf8);
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];
2166 SI_CONVERTER c(m_bStoreIsUtf8);
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));
2198 if (m_bAllowMultiKey) {
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;
2227 if (!m_bAllowMultiKey || section.empty()) {
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);
2252 if (i != m_data.end()) {
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__
2317 SI_Error rc = SaveFile(fp, a_bAddSignature);
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__
2338 SI_Error rc = SaveFile(fp, a_bAddSignature);
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
2356 FileWriter writer(a_pFile);
2357 return Save(writer, a_bAddSignature);
2360 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2363 OutputWriter & a_oOutput,
2364 bool a_bAddSignature
2367 Converter convert(m_bStoreIsUtf8);
2370 if (m_bStoreIsUtf8 && a_bAddSignature) {
2376 GetAllSections(oSections);
2377 #if defined(_MSC_VER) && _MSC_VER <= 1200
2379 #elif defined(__BORLANDC__)
2380 oSections.sort(Entry::LoadOrder());
2382 oSections.sort(
typename Entry::LoadOrder());
2386 bool bNeedNewLine =
false;
2387 if (m_pFileComment) {
2388 if (!OutputMultiLineText(a_oOutput, convert, m_pFileComment)) {
2391 bNeedNewLine =
true;
2395 typename TNamesDepend::const_iterator iSection = oSections.begin();
2396 for ( ; iSection != oSections.end(); ++iSection ) {
2398 if (iSection->pComment) {
2403 if (!OutputMultiLineText(a_oOutput, convert, iSection->pComment)) {
2406 bNeedNewLine =
false;
2412 bNeedNewLine =
false;
2416 if (*iSection->pItem) {
2417 if (!convert.ConvertToStore(iSection->pItem)) {
2420 a_oOutput.Write(
"[");
2421 a_oOutput.Write(convert.Data());
2422 a_oOutput.Write(
"]");
2428 GetAllKeys(iSection->pItem, oKeys);
2429 #if defined(_MSC_VER) && _MSC_VER <= 1200
2431 #elif defined(__BORLANDC__)
2432 oKeys.sort(Entry::LoadOrder());
2434 oKeys.sort(
typename Entry::LoadOrder());
2438 typename TNamesDepend::const_iterator iKey = oKeys.begin();
2439 for ( ; iKey != oKeys.end(); ++iKey) {
2442 GetAllValues(iSection->pItem, iKey->pItem, oValues);
2444 typename TNamesDepend::const_iterator iValue = oValues.begin();
2445 for ( ; iValue != oValues.end(); ++iValue) {
2447 if (iValue->pComment) {
2449 if (!OutputMultiLineText(a_oOutput, convert, iValue->pComment)) {
2455 if (!convert.ConvertToStore(iKey->pItem)) {
2458 a_oOutput.Write(convert.Data());
2461 if (!convert.ConvertToStore(iValue->pItem)) {
2464 a_oOutput.Write(m_bSpaces ?
" = " :
"=");
2465 if (m_bAllowMultiLine && IsMultiLineData(iValue->pItem)) {
2469 if (!OutputMultiLineText(a_oOutput, convert, iValue->pItem)) {
2472 a_oOutput.Write(
"END_OF_TEXT");
2475 a_oOutput.Write(convert.Data());
2481 bNeedNewLine =
true;
2487 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2490 OutputWriter & a_oOutput,
2491 Converter & a_oConverter,
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;
2505 if (!a_oConverter.ConvertToStore(a_pText)) {
2508 *
const_cast<SI_CHAR*
>(pEndOfLine) = cEndOfLineChar;
2509 a_pText += (pEndOfLine - a_pText) + 1;
2510 a_oOutput.Write(a_oConverter.Data());
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++;
2545 DeleteString(iDelete->first.pItem);
2546 DeleteString(iDelete->second);
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) {
2564 DeleteString(iKeyVal->first.pItem);
2565 DeleteString(iKeyVal->second);
2570 DeleteString(iSection->first.pItem);
2571 m_data.erase(iSection);
2576 template<
class SI_CHAR,
class SI_STRLESS,
class SI_CONVERTER>
2579 const SI_CHAR * a_pString
2585 if (a_pString < m_pData || a_pString >= m_pData + m_uDataLen) {
2586 typename TNamesDepend::iterator i = m_strings.begin();
2587 for (;i != m_strings.end(); ++i) {
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>
2625 struct SI_GenericCase {
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>
2645 struct SI_GenericNoCase {
2646 inline SI_CHAR locase(SI_CHAR ch)
const {
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>
2666 bool m_bStoreIsUtf8;
2670 SI_ConvertA(
bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { }
2673 SI_ConvertA(
const SI_ConvertA & rhs) { operator=(rhs); }
2674 SI_ConvertA & operator=(
const SI_ConvertA & rhs) {
2675 m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8;
2692 size_t SizeFromStore(
2693 const char * a_pInputData,
2694 size_t a_uInputDataLen)
2697 SI_ASSERT(a_uInputDataLen != (
size_t) -1);
2700 return a_uInputDataLen;
2716 bool ConvertFromStore(
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;
2760 bool ConvertToStore(
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
2787 #include "ConvertUTF.h"
2793 template<
class SI_CHAR>
2795 bool m_bStoreIsUtf8;
2799 SI_ConvertW(
bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { }
2802 SI_ConvertW(
const SI_ConvertW & rhs) { operator=(rhs); }
2803 SI_ConvertW & operator=(
const SI_ConvertW & rhs) {
2804 m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8;
2821 size_t SizeFromStore(
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);
2851 bool ConvertFromStore(
2852 const char * a_pInputData,
2853 size_t a_uInputDataLen,
2854 SI_CHAR * a_pOutputData,
2855 size_t a_uOutputDataSize)
2857 if (m_bStoreIsUtf8) {
2863 ConversionResult retval;
2864 const UTF8 * pUtf8 = (
const UTF8 *) a_pInputData;
2865 if (
sizeof(
wchar_t) ==
sizeof(UTF32)) {
2866 UTF32 * pUtf32 = (UTF32 *) a_pOutputData;
2867 retval = ConvertUTF8toUTF32(
2868 &pUtf8, pUtf8 + a_uInputDataLen,
2869 &pUtf32, pUtf32 + a_uOutputDataSize,
2872 else if (
sizeof(
wchar_t) ==
sizeof(UTF16)) {
2873 UTF16 * pUtf16 = (UTF16 *) a_pOutputData;
2874 retval = ConvertUTF8toUTF16(
2875 &pUtf8, pUtf8 + a_uInputDataLen,
2876 &pUtf16, pUtf16 + a_uOutputDataSize,
2879 return retval == conversionOK;
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)) {
2931 bool ConvertToStore(
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]) {
2950 ConversionResult retval;
2951 UTF8 * pUtf8 = (UTF8 *) a_pOutputData;
2952 if (
sizeof(
wchar_t) ==
sizeof(UTF32)) {
2953 const UTF32 * pUtf32 = (
const UTF32 *) a_pInputData;
2954 retval = ConvertUTF32toUTF8(
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;
2961 retval = ConvertUTF16toUTF8(
2962 &pUtf16, pUtf16 + uInputLen,
2963 &pUtf8, pUtf8 + a_uOutputDataSize,
2966 return retval == conversionOK;
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;
2997 SI_ConvertW() : m_pEncoding(NULL), m_pConverter(NULL) { }
2999 SI_ConvertW(
bool a_bStoreIsUtf8) : m_pConverter(NULL) {
3000 m_pEncoding = a_bStoreIsUtf8 ?
"UTF-8" : NULL;
3004 SI_ConvertW(
const SI_ConvertW & rhs) { operator=(rhs); }
3005 SI_ConvertW & operator=(
const SI_ConvertW & rhs) {
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;
3205 return SI_GenericNoCase<SI_CHAR>()(pLeft, pRight);
3208 #endif // SI_NO_MBCS
3216 template<
class SI_CHAR>
3222 SI_ConvertW(
bool a_bStoreIsUtf8) {
3223 m_uCodePage = a_bStoreIsUtf8 ? CP_UTF8 : CP_ACP;
3227 SI_ConvertW(
const SI_ConvertW & rhs) { operator=(rhs); }
3228 SI_ConvertW & operator=(
const SI_ConvertW & rhs) {
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)
3345 SI_NoCase<UChar>,SI_ConvertW<UChar> >
CSimpleIniW;
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