#include "inifile.h" #include #include #ifdef _WIN32 #include #include #else #include #include #include #include #endif #ifndef _WIN32 #ifndef BOOL typedef int BOOL; #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #endif #ifdef MULTI_THREAD_MODEL pthread_mutex_t g_mutex_for_ini_file; #define MDF_lock() pthread_mutex_lock(&g_mutex_for_ini_file); #define MDF_unlock() pthread_mutex_unlock(&g_mutex_for_ini_file); #else #define MDF_lock() ((void)0) #define MDF_unlock() ((void)0) #endif // MULTI_THREAD_MODEL #define MAX_INI_FILE_SIZE 1024 * 1024 * 8 // 8Mb #define MAX_INI_SECTION_NAME_BUFFER_SIZE 512 #ifdef _WIN32 #define MD_FA_WOPEN O_RDONLY | O_BINARY, S_IREAD | S_IWRITE | S_IRGRP | S_IROTH #define MD_FA_WCREATE O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IREAD | S_IWRITE | S_IRGRP | S_IROTH #else //#define MD_FA_WOPEN O_RDONLY, S_IREAD | S_IWRITE | S_IRGRP | S_IROTH //#define MD_FA_WCREATE O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE | S_IRGRP | S_IROTH #define MD_FA_WOPEN O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH #define MD_FA_WCREATE O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH #endif // _WIN32 #define GetPrivateProfileString_P GetPrivateProfileString #define GetPrivateProfileInt_P GetPrivateProfileInt #define WritePrivateProfileString_P WritePrivateProfileString char * __g_ini_file__search_section_ptr(const char * S1, const char * S2, int nFileSize, int * pnPos) { int j; char chBeforeCharacter = '\0'; if (S1 == NULL || S1[0] == '\0' || S2 == NULL || S2[0] == '\0') return NULL; for (*pnPos = 0; *pnPos < nFileSize; (*pnPos)++) { if (((*pnPos) == 0 && *S1 == '[') || (*S1 == '[' && (chBeforeCharacter == '\r' || chBeforeCharacter == '\n'))) { S1++; (*pnPos)++; BOOL bIsSectionFound = TRUE; for (j = 0; *pnPos < nFileSize; (*pnPos)++) { if (*S1 == ']' && S2[j] == '\0') break; if (*S1 != S2[j]) { bIsSectionFound = FALSE; break; } if (*S1 == ']' || *S1 == '\r' || *S1 == '\n') { bIsSectionFound = FALSE; break; } S1++; j++; } if (*pnPos >= nFileSize) return NULL; if (bIsSectionFound == TRUE) return (char *)S1; } chBeforeCharacter = *S1; S1++; } return NULL; } char * __g_ini_file__search_key_ptr(const char * S1, const char * S2, int nFileSize, int * pnPos) { int j; char chBeforeCharacter = '\0'; if (S1 == NULL || S1[0] == '\0' || S2 == NULL || S2[0] == '\0') return NULL; for (; *pnPos < nFileSize; (*pnPos)++) { if (*S1 == S2[0] && (chBeforeCharacter == '\r' || chBeforeCharacter == '\n')) { S1++; (*pnPos)++; BOOL bIsKeyFound = TRUE; for (j = 1; *pnPos < nFileSize; (*pnPos)++) { if (*S1 == '=' && S2[j] == '\0') break; if (*S1 != S2[j]) { bIsKeyFound = FALSE; break; } if (*S1 == '\r' || *S1 == '\n') { bIsKeyFound = FALSE; break; } S1++; j++; } if (*pnPos >= nFileSize) return NULL; if (bIsKeyFound == TRUE) return (char *)S1; else { for (; *pnPos < nFileSize; (*pnPos)++) { if (*S1 == '\r' || *S1 == '\n') break; S1++; } if (*pnPos >= nFileSize) return NULL; } } if (*S1 == '[' && (chBeforeCharacter == '\r' || chBeforeCharacter == '\n')) { for (S1--; *pnPos > 0; (*pnPos)--) { if (*S1 != '\r' && *S1 != '\n') break; S1--; } return NULL; } chBeforeCharacter = *S1; S1++; } return NULL; } size_t __g_ini_file__value_len_without_rear_space(const char * STR) { int i; if (STR == NULL || STR[0] == '\0') return 0; for (i = 0; STR[i] != '\0'; i++) { if (STR[i] == '\r' || STR[i] == '\n') break; } for (i--; i >= 0; i--) { if (STR[i] != ' ') return i + 1; } return 0; } int GetPrivateProfileString_P( const char * lpAppName, // section name const char * lpKeyName, // key name const char * lpDefault, // default string char * lpReturnedString, // destination buffer unsigned int nSize, // size of destination buffer const char * lpFileName // initialization file name ) { int fhINIFile; long nFileSize; char * pszBuffer; char * pszBufferPtr; char * pszSectionName; char * pszKeyName; size_t nCopySize; int nPos; if (lpReturnedString == NULL) return 0; if (lpAppName == NULL || lpAppName[0] == '\0' || lpKeyName == NULL || lpKeyName[0] == '\0' || lpDefault == NULL || lpFileName == NULL || lpFileName[0] == '\0' || nSize <= 0) { goto GetPrivateProfileString_P_Fail; } if (strlen(lpAppName) > MAX_INI_SECTION_NAME_BUFFER_SIZE - 3) { printf("inifile\t[ERROR] Too large section name. over %d byte.\n", MAX_INI_SECTION_NAME_BUFFER_SIZE - 3); goto GetPrivateProfileString_P_Fail; } lpReturnedString[0] = '\0'; MDF_lock(); fhINIFile = open(lpFileName, MD_FA_WOPEN); if (fhINIFile == -1) { MDF_unlock(); //printf("inifile\t[ERROR] Failed to open file. errno = %d\n", errno); nCopySize = __g_ini_file__value_len_without_rear_space(lpDefault); if (nSize <= nCopySize) nCopySize = nSize - 1; strncpy(lpReturnedString, lpDefault, nCopySize); lpReturnedString[nCopySize] = '\0'; return strlen(lpReturnedString); } nFileSize = lseek(fhINIFile, 0L, SEEK_END); if (nFileSize > MAX_INI_FILE_SIZE) { printf("inifile\t[ERROR] Too large file. over %d byte.\n", MAX_INI_FILE_SIZE); close(fhINIFile); MDF_unlock(); goto GetPrivateProfileString_P_Fail; } lseek(fhINIFile, 0L, SEEK_SET); pszBuffer = (char *)malloc(nFileSize + 1); if (read(fhINIFile, pszBuffer, nFileSize) == -1) { printf("inifile\t[ERROR] Failed to read file. errno = %d\n", errno); close(fhINIFile); MDF_unlock(); free(pszBuffer); goto GetPrivateProfileString_P_Fail; } pszBuffer[nFileSize] = '\0'; close(fhINIFile); nCopySize = __g_ini_file__value_len_without_rear_space(lpAppName); pszSectionName = (char *)malloc(nCopySize + 1); strncpy(pszSectionName, lpAppName, nCopySize); pszSectionName[nCopySize] = '\0'; nCopySize = __g_ini_file__value_len_without_rear_space(lpKeyName); pszKeyName = (char *)malloc(nCopySize + 1); strncpy(pszKeyName, lpKeyName, nCopySize); pszKeyName[nCopySize] = '\0'; pszBufferPtr = __g_ini_file__search_section_ptr(pszBuffer, pszSectionName, nFileSize, &nPos); if (pszBufferPtr != NULL) pszBufferPtr = __g_ini_file__search_key_ptr(pszBufferPtr, pszKeyName, nFileSize, &nPos); if (pszBufferPtr != NULL && nPos < nFileSize) { pszBufferPtr++; nCopySize = __g_ini_file__value_len_without_rear_space(pszBufferPtr); if (nSize <= nCopySize) nCopySize = nSize - 1; strncpy(lpReturnedString, pszBufferPtr, nCopySize); lpReturnedString[nCopySize] = '\0'; } else { nCopySize = __g_ini_file__value_len_without_rear_space(lpDefault); if (nSize <= nCopySize) nCopySize = nSize - 1; strncpy(lpReturnedString, lpDefault, nCopySize); lpReturnedString[nCopySize] = '\0'; } MDF_unlock(); free(pszSectionName); free(pszKeyName); free(pszBuffer); return strlen(lpReturnedString); GetPrivateProfileString_P_Fail: lpReturnedString[0] = '\0'; return 0; } int GetPrivateProfileInt_P( const char* lpAppName, // section name const char* lpKeyName, // key name int nDefault, // return value if key name not found const char* lpFileName // initialization file name ) { char szBuf[128]; GetPrivateProfileString_P(lpAppName, lpKeyName, "", szBuf, 128, lpFileName); if (strlen(szBuf) <= 0) return nDefault; return atoi(szBuf); } BOOL WritePrivateProfileString_P( const char* lpAppName, // section name const char* lpKeyName, // key name const char* lpString, // string to add const char* lpFileName // initialization file ) { #define FREE_BUFFERS() free(pszSectionName); free(pszKeyName); free(pszWriteString); free(pszBuffer) int fhINIFile; long nFileSize; char * pszBuffer; char * pszBufferPtr; char * pszSectionName; char * pszKeyName; char * pszWriteString; size_t nWriteSize; int nPos; if (lpAppName == NULL || lpAppName[0] == '\0' || lpKeyName == NULL || lpKeyName[0] == '\0' || lpFileName == NULL || lpFileName[0] == '\0') { return FALSE; } if (strlen(lpAppName) > MAX_INI_SECTION_NAME_BUFFER_SIZE - 3) { printf("inifile\t[ERROR] Too large section name. over %d byte.\n", MAX_INI_SECTION_NAME_BUFFER_SIZE - 3); return FALSE; } nWriteSize = __g_ini_file__value_len_without_rear_space(lpAppName); pszSectionName = (char *)malloc(nWriteSize + 1); strncpy(pszSectionName, lpAppName, nWriteSize); pszSectionName[nWriteSize] = '\0'; nWriteSize = __g_ini_file__value_len_without_rear_space(lpKeyName); pszKeyName = (char *)malloc(nWriteSize + 1); strncpy(pszKeyName, lpKeyName, nWriteSize); pszKeyName[nWriteSize] = '\0'; nWriteSize = __g_ini_file__value_len_without_rear_space(lpString); pszWriteString = (char *)malloc(nWriteSize + 1); strncpy(pszWriteString, lpString, nWriteSize); pszWriteString[nWriteSize] = '\0'; MDF_lock(); fhINIFile = open(lpFileName, MD_FA_WOPEN); if (fhINIFile == -1) { //printf("inifile\t[ERROR] Failed to open file. errno = %d\n", errno); goto WritePrivateProfileString_P_New; } nFileSize = lseek(fhINIFile, 0L, SEEK_END); if (nFileSize > MAX_INI_FILE_SIZE) { printf("inifile\t[ERROR] Too large file. over %d byte.\n", MAX_INI_FILE_SIZE); close(fhINIFile); MDF_unlock(); free(pszSectionName); free(pszKeyName); free(pszWriteString); return FALSE; } if (nFileSize == 0) { close(fhINIFile); goto WritePrivateProfileString_P_New; } lseek(fhINIFile, 0L, SEEK_SET); pszBuffer = (char *)malloc(nFileSize + strlen(lpAppName) + strlen(lpKeyName) + strlen(lpString) + 10); // 10 : \r \n [ ] \r \n = \r \n \0 if (read(fhINIFile, pszBuffer, nFileSize) == -1) { printf("inifile\t[ERROR] Failed to read file. errno = %d\n", errno); close(fhINIFile); MDF_unlock(); FREE_BUFFERS(); return FALSE; } pszBuffer[nFileSize] = '\0'; close(fhINIFile); pszBufferPtr = __g_ini_file__search_section_ptr(pszBuffer, pszSectionName, nFileSize, &nPos); if (pszBufferPtr == NULL) { pszBufferPtr = pszBuffer + nFileSize; #ifdef _WIN32 sprintf(pszBufferPtr, "\r\n[%s]\r\n%s=%s\r\n", pszSectionName, pszKeyName, pszWriteString); #else sprintf(pszBufferPtr, "\n[%s]\n%s=%s\n", pszSectionName, pszKeyName, pszWriteString); #endif fhINIFile = open(lpFileName, MD_FA_WCREATE); if (fhINIFile == -1) { printf("inifile\t[ERROR] Failed to open file. errno = %d\n", errno); MDF_unlock(); FREE_BUFFERS(); return FALSE; } if (write(fhINIFile, pszBuffer, strlen(pszBuffer)) == -1) { printf("inifile\t[ERROR] Failed to write file. errno = %d\n", errno); close(fhINIFile); MDF_unlock(); FREE_BUFFERS(); return FALSE; } close(fhINIFile); MDF_unlock(); FREE_BUFFERS(); return TRUE; } pszBufferPtr = __g_ini_file__search_key_ptr(pszBufferPtr, pszKeyName, nFileSize, &nPos); if (pszBufferPtr == NULL) { char * pszTempBuffer; fhINIFile = open(lpFileName, MD_FA_WCREATE); if (fhINIFile == -1) { printf("inifile\t[ERROR] Failed to open file. errno = %d\n", errno); MDF_unlock(); FREE_BUFFERS(); return FALSE; } pszBufferPtr = pszBuffer + nPos; pszTempBuffer = (char *)malloc(strlen(pszKeyName) + strlen(pszWriteString) + 6); // 6 : \r \n = \r \n \0 #ifdef _WIN32 if (*(pszBufferPtr - 1) != '\r' && *(pszBufferPtr - 1) != '\n') sprintf(pszTempBuffer, "\r\n%s=%s", pszKeyName, pszWriteString); else sprintf(pszTempBuffer, "%s=%s", pszKeyName, pszWriteString); #else if (*(pszBufferPtr - 1) != '\r' && *(pszBufferPtr - 1) != '\n') sprintf(pszTempBuffer, "\n%s=%s", pszKeyName, pszWriteString); else sprintf(pszTempBuffer, "%s=%s", pszKeyName, pszWriteString); #endif if (write(fhINIFile, pszBuffer, nPos) == -1 || write(fhINIFile, pszTempBuffer, strlen(pszTempBuffer)) == -1 || write(fhINIFile, pszBufferPtr, nFileSize - nPos) == -1) { printf("inifile\t[ERROR] Failed to write file. errno = %d\n", errno); close(fhINIFile); MDF_unlock(); free(pszTempBuffer); FREE_BUFFERS(); return FALSE; } close(fhINIFile); MDF_unlock(); free(pszTempBuffer); FREE_BUFFERS(); return TRUE; } pszBufferPtr++; nPos++; fhINIFile = open(lpFileName, MD_FA_WCREATE); if (fhINIFile == -1) { printf("inifile\t[ERROR] Failed to open file. errno = %d\n", errno); MDF_unlock(); FREE_BUFFERS(); return FALSE; } if (write(fhINIFile, pszBuffer, nPos) != -1 && write(fhINIFile, pszWriteString, strlen(pszWriteString)) != -1) { for (;;) { if (*pszBufferPtr == '\0' || *pszBufferPtr == '\r' || *pszBufferPtr == '\n') break; pszBufferPtr++; nPos++; } if (*pszBufferPtr == '\0' || write(fhINIFile, pszBufferPtr, nFileSize - nPos) != -1) { close(fhINIFile); MDF_unlock(); FREE_BUFFERS(); return TRUE; } } printf("inifile\t[ERROR] Failed to write file. errno = %d\n", errno); close(fhINIFile); MDF_unlock(); FREE_BUFFERS(); return FALSE; WritePrivateProfileString_P_New: fhINIFile = open(lpFileName, MD_FA_WCREATE); if (fhINIFile == -1) { printf("inifile\t[ERROR] Failed to open file. errno = %d\n", errno); MDF_unlock(); free(pszSectionName); free(pszKeyName); free(pszWriteString); return FALSE; } pszBuffer = (char *)malloc(strlen(pszSectionName) + strlen(pszKeyName) + strlen(pszWriteString) + 8); // 8 : [ ] \r \n = \r \n \0 #ifdef _WIN32 sprintf(pszBuffer, "[%s]\r\n%s=%s\r\n", pszSectionName, pszKeyName, pszWriteString); #else sprintf(pszBuffer, "[%s]\n%s=%s\n", pszSectionName, pszKeyName, pszWriteString); #endif if (write(fhINIFile, pszBuffer, strlen(pszBuffer)) == -1) { printf("inifile\t[ERROR] Failed to write file. errno = %d\n", errno); close(fhINIFile); MDF_unlock(); FREE_BUFFERS(); return FALSE; } close(fhINIFile); MDF_unlock(); FREE_BUFFERS(); return TRUE; } #endif // _WIN32 HIniFile::HIniFile() { m_szIniFileName[0] = '\0'; m_pszBuffer = NULL; } HIniFile::~HIniFile() { if (m_pszBuffer) free(m_pszBuffer); } bool HIniFile::SetIniFile(const char * pszFileName) { if (pszFileName && pszFileName[0] != '\0') { strncpy(m_szIniFileName, pszFileName, IF_MAX_PATH); m_pszBuffer = (char *)malloc(IF_DEFAULT_BUFFER_SIZE); m_dwBufferLength = IF_DEFAULT_BUFFER_SIZE; return true; } return false; } const char * HIniFile::ReadString(const char * pszSetionName, const char * pszKeyName, const char * pszDefault, unsigned long nMaxSize) { if (m_szIniFileName[0] == '\0') return ""; if (nMaxSize > IF_DEFAULT_BUFFER_SIZE) { free(m_pszBuffer); m_pszBuffer = (char *)malloc(nMaxSize); m_dwBufferLength = nMaxSize; } GetPrivateProfileString(pszSetionName, pszKeyName, pszDefault, m_pszBuffer, nMaxSize, m_szIniFileName); return m_pszBuffer; } bool HIniFile::WriteString(const char * pszSetionName, const char * pszKeyName, const char * pszString) { if (m_szIniFileName[0] == '\0') return false; return WritePrivateProfileString(pszSetionName, pszKeyName, pszString, m_szIniFileName) != FALSE; } int HIniFile::ReadNumber(const char * pszSetionName, const char * pszKeyName, int nDefault) { if (m_szIniFileName[0] == '\0') return 0; return GetPrivateProfileInt(pszSetionName, pszKeyName, nDefault, m_szIniFileName); } bool HIniFile::WriteNumber(const char * pszSetionName, const char * pszKeyName, int nNumber) { if (m_szIniFileName[0] == '\0') return false; snprintf(m_pszBuffer, m_dwBufferLength, "%d", nNumber); return WritePrivateProfileString(pszSetionName, pszKeyName, m_pszBuffer, m_szIniFileName) != FALSE; } bool HIniFile::ReadBoolean(const char * pszSetionName, const char * pszKeyName, bool bDefault) { if (m_szIniFileName[0] == '\0') return false; GetPrivateProfileString(pszSetionName, pszKeyName, "FALSE", m_pszBuffer, m_dwBufferLength, m_szIniFileName); if (strcasecmp(m_pszBuffer, "TRUE") == 0) return true; return false; } bool HIniFile::WriteBoolean(const char * pszSetionName, const char * pszKeyName, bool bValue) { if (m_szIniFileName[0] == '\0') return false; return WritePrivateProfileString(pszSetionName, pszKeyName, bValue ? "TRUE" : "FALSE", m_szIniFileName) != FALSE; }