// File: testsi.cpp // Library: SimpleIni // Author: Brodie Thiesfield // Source: http://code.jellycan.com/simpleini/ // // Demo of usage #ifdef _WIN32 # pragma warning(disable: 4786) #endif #include #include #include #define SI_SUPPORT_IOSTREAMS #if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE) # include #endif //#define SI_CONVERT_GENERIC //#define SI_CONVERT_ICU //#define SI_CONVERT_WIN32 #include "SimpleIni.h" #ifdef SI_CONVERT_ICU // if converting using ICU then we need the ICU library # pragma comment(lib, "icuuc.lib") #endif #ifdef _WIN32 # include #else // !_WIN32 # define TCHAR char # define _T(x) x # define _tprintf printf # define _tmain main #endif // _WIN32 static void Test( CSimpleIni & ini ) { const TCHAR *pszSection = 0; const TCHAR *pItem = 0; const TCHAR *pszVal = 0; // get the value of the key "foo" in section "standard" bool bHasMulti; pszVal = ini.GetValue(_T("standard"), _T("foo"), 0, &bHasMulti); _tprintf(_T("\n-- Value of standard::foo is '%s' (hasMulti = %d)\n"), pszVal ? pszVal : _T("(null)"), bHasMulti); // set the value of the key "foo" in section "standard" ini.SetValue(_T("standard"), _T("foo"), _T("wibble")); pszVal = ini.GetValue(_T("standard"), _T("foo"), 0, &bHasMulti); _tprintf(_T("\n-- Value of standard::foo is '%s' (hasMulti = %d)\n"), pszVal ? pszVal : _T("(null)"), bHasMulti); // get all values of the key "foo" in section "standard" CSimpleIni::TNamesDepend values; if (ini.GetAllValues(_T("standard"), _T("foo"), values)) { _tprintf(_T("\n-- Values of standard::foo are:\n")); CSimpleIni::TNamesDepend::const_iterator i = values.begin(); for (; i != values.end(); ++i) { pszVal = i->pItem; _tprintf(_T(" -> '%s'\n"), pszVal); } } // get the size of the section [standard] _tprintf(_T("\n-- Number of keys in section [standard] = %d\n"), ini.GetSectionSize(_T("standard"))); // delete the key "foo" in section "standard" ini.Delete(_T("standard"), _T("foo")); pszVal = ini.GetValue(_T("standard"), _T("foo"), 0); _tprintf(_T("\n-- Value of standard::foo is now '%s'\n"), pszVal ? pszVal : _T("(null)")); // get the size of the section [standard] _tprintf(_T("\n-- Number of keys in section [standard] = %d\n"), ini.GetSectionSize(_T("standard"))); // get the list of all key names for the section "standard" _tprintf(_T("\n-- Dumping keys of section: [standard]\n")); CSimpleIni::TNamesDepend keys; ini.GetAllKeys(_T("standard"), keys); // dump all of the key names CSimpleIni::TNamesDepend::const_iterator iKey = keys.begin(); for ( ; iKey != keys.end(); ++iKey ) { pItem = iKey->pItem; _tprintf(_T("Key: %s\n"), pItem); } // add a decimal value ini.SetLongValue(_T("integer"), _T("dec"), 42, NULL, false); ini.SetLongValue(_T("integer"), _T("hex"), 42, NULL, true); // add some bool values ini.SetBoolValue(_T("bool"), _T("t"), true); ini.SetBoolValue(_T("bool"), _T("f"), false); // get the values back assert(42 == ini.GetLongValue(_T("integer"), _T("dec"))); assert(42 == ini.GetLongValue(_T("integer"), _T("hex"))); assert(true == ini.GetBoolValue(_T("bool"), _T("t"))); assert(false == ini.GetBoolValue(_T("bool"), _T("f"))); // delete the section "standard" ini.Delete(_T("standard"), NULL); _tprintf(_T("\n-- Number of keys in section [standard] = %d\n"), ini.GetSectionSize(_T("standard"))); // iterate through every section in the file _tprintf(_T("\n-- Dumping all sections\n")); CSimpleIni::TNamesDepend sections; ini.GetAllSections(sections); CSimpleIni::TNamesDepend::const_iterator iSection = sections.begin(); for ( ; iSection != sections.end(); ++iSection ) { pszSection = iSection->pItem; // print the section name printf("\n"); if (*pszSection) { _tprintf(_T("[%s]\n"), pszSection); } // if there are keys and values... const CSimpleIni::TKeyVal * pSectionData = ini.GetSection(pszSection); if (pSectionData) { // iterate over all keys and dump the key name and value CSimpleIni::TKeyVal::const_iterator iKeyVal = pSectionData->begin(); for ( ;iKeyVal != pSectionData->end(); ++iKeyVal) { pItem = iKeyVal->first.pItem; pszVal = iKeyVal->second; _tprintf(_T("%s=%s\n"), pItem, pszVal); } } } } #if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE) static bool TestStreams( const TCHAR * a_pszFile, bool a_bIsUtf8, bool a_bUseMultiKey, bool a_bUseMultiLine ) { // load the file CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine); _tprintf(_T("Loading file: %s\n"), a_pszFile); std::ifstream instream; instream.open(a_pszFile, std::ifstream::in | std::ifstream::binary); SI_Error rc = ini.LoadData(instream); instream.close(); if (rc < 0) { printf("Failed to open file.\n"); return false; } Test(ini); // save the file (simple) _tprintf(_T("\n-- Saving file to: testsi-out-streams.ini\n")); std::ofstream outstream; outstream.open("testsi-out-streams.ini", std::ofstream::out | std::ofstream::binary); ini.Save(outstream); outstream.close(); return true; } #endif // SI_SUPPORT_IOSTREAMS static bool TestFile( const TCHAR * a_pszFile, bool a_bIsUtf8, bool a_bUseMultiKey, bool a_bUseMultiLine ) { // load the file CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine); _tprintf(_T("Loading file: %s\n"), a_pszFile); SI_Error rc = ini.LoadFile(a_pszFile); if (rc < 0) { printf("Failed to open file.\n"); return false; } // run the tests Test(ini); // save the file (simple) _tprintf(_T("\n-- Saving file to: testsi-out.ini\n")); ini.SaveFile("testsi-out.ini"); // save the file (with comments) // Note: to save the file and add a comment to the beginning, use // code such as the following. _tprintf(_T("\n-- Saving file to: testsi-out-comment.ini\n")); FILE * fp = NULL; #if __STDC_WANT_SECURE_LIB__ fopen_s(&fp, "testsi-out-comment.ini", "wb"); #else fp = fopen("testsi-out-comment.ini", "wb"); #endif if (fp) { CSimpleIni::FileWriter writer(fp); if (a_bIsUtf8) { writer.Write(SI_UTF8_SIGNATURE); } // add a string to the file in the correct text format CSimpleIni::Converter convert = ini.GetConverter(); convert.ConvertToStore(_T("; output from testsi.cpp test program") SI_NEWLINE SI_NEWLINE); writer.Write(convert.Data()); ini.Save(writer, false); fclose(fp); } return true; } static bool ParseCommandLine( int argc, TCHAR * argv[], const TCHAR * & a_pszFile, bool & a_bIsUtf8, bool & a_bUseMultiKey, bool & a_bUseMultiLine ) { a_pszFile = 0; a_bIsUtf8 = false; a_bUseMultiKey = false; a_bUseMultiLine = false; for (--argc; argc > 0; --argc) { if (argv[argc][0] == '-') { switch (argv[argc][1]) { case TCHAR('u'): a_bIsUtf8 = true; break; case TCHAR('m'): a_bUseMultiKey = true; break; case TCHAR('l'): a_bUseMultiLine = true; break; } } else { a_pszFile = argv[argc]; } } if (!a_pszFile) { _tprintf( _T("Usage: testsi [-u] [-m] [-l] iniFile\n") _T(" -u Load file as UTF-8 (Default is to use system locale)\n") _T(" -m Enable multiple keys\n") _T(" -l Enable multiple line values\n") ); return false; } return true; } extern bool TestStreams(); int _tmain( int argc, TCHAR * argv[] ) { setlocale(LC_ALL, ""); // start of automated testing... TestStreams(); // parse the command line const TCHAR * pszFile; bool bIsUtf8, bUseMultiKey, bUseMultiLine; if (!ParseCommandLine(argc, argv, pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) { return 1; } // run the test if (!TestFile(pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) { return 1; } #if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE) if (!TestStreams(pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) { return 1; } #endif return 0; }