Files
2026-05-20 03:08:08 +09:00

717 lines
16 KiB
C++

#include "inifile.h"
#include <stdio.h>
#include <fcntl.h>
#ifdef _WIN32
#include <sys/stat.h>
#include <io.h>
#else
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#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;
}