123
This commit is contained in:
284
ResourceCompiler/CfgFile.cpp
Normal file
284
ResourceCompiler/CfgFile.cpp
Normal file
@@ -0,0 +1,284 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: cfgfile.cpp
|
||||
// Version: v1.00
|
||||
// Created: 4/11/2002 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Configuration file class.
|
||||
// Use format similar to windows .ini files.
|
||||
//
|
||||
#include "StdAfx.h"
|
||||
#include "cfgfile.h"
|
||||
#include "Config.h"
|
||||
#include "DebugLog.h"
|
||||
|
||||
//#define Log DebugLog
|
||||
#define Log while (false)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class CfgFile implementation.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CfgFile::CfgFile()
|
||||
{
|
||||
// Create IsEmpty section.
|
||||
Section section;
|
||||
section.name = "";
|
||||
m_sections.push_back( section );
|
||||
|
||||
m_modified = false;
|
||||
}
|
||||
|
||||
|
||||
CfgFile::CfgFile( const CString &fileName )
|
||||
{
|
||||
// Create IsEmpty section.
|
||||
Section section;
|
||||
section.name = "";
|
||||
m_sections.push_back( section );
|
||||
m_modified = false;
|
||||
|
||||
Load( fileName );
|
||||
}
|
||||
|
||||
CfgFile::CfgFile( const char *buf,int bufSize ) {
|
||||
// Create IsEmpty section.
|
||||
Section section;
|
||||
section.name = "";
|
||||
m_sections.push_back( section );
|
||||
m_modified = false;
|
||||
|
||||
LoadBuf( buf,bufSize );
|
||||
}
|
||||
|
||||
CfgFile::~CfgFile()
|
||||
{
|
||||
}
|
||||
|
||||
//!
|
||||
void CfgFile::SetFileName( const CString &fileName )
|
||||
{
|
||||
m_fileName = fileName;
|
||||
}
|
||||
|
||||
// Load configuration file.
|
||||
bool CfgFile::Load( const CString &fileName )
|
||||
{
|
||||
m_fileName = fileName;
|
||||
m_modified = false;
|
||||
|
||||
FILE *file = fopen( fileName.GetString(),"rb" );
|
||||
if (!file)
|
||||
{
|
||||
char szCWD[0x400];
|
||||
getcwd(szCWD, sizeof(szCWD));
|
||||
Log ("Can't open \"%s\"", fileName.GetString());
|
||||
Log ("CWD=%s", szCWD);
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek( file,0,SEEK_END );
|
||||
int size = ftell(file);
|
||||
fseek( file,0,SEEK_SET );
|
||||
|
||||
// Read whole file to memory.
|
||||
char *s = (char*)malloc( size+1 );
|
||||
memset( s,0,size+1 );
|
||||
fread( s,1,size,file );
|
||||
LoadBuf( s,size );
|
||||
free(s);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Save configuration file, with the stored name in m_fileName
|
||||
bool CfgFile::Save( void )
|
||||
{
|
||||
FILE *file = fopen(m_fileName.GetBuffer(),"wb");
|
||||
|
||||
if(!file)
|
||||
return(false);
|
||||
|
||||
// Loop on sections.
|
||||
for (std::vector<Section>::iterator si = m_sections.begin(); si != m_sections.end(); si++)
|
||||
{
|
||||
Section &sec =*si;
|
||||
|
||||
if(sec.name!="")
|
||||
fprintf(file,"[%s]\r\n",sec.name); // section
|
||||
|
||||
for (std::list<Entry>::iterator it = sec.entries.begin(); it != sec.entries.end(); ++it)
|
||||
{
|
||||
if((*it).key=="")
|
||||
fprintf(file,"%s\r\n",(*it).value.GetBuffer()); // comment
|
||||
else
|
||||
fprintf(file,"%s=%s\r\n",(*it).key.GetBuffer(),(*it).value.GetBuffer()); // key=value
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
void CfgFile::UpdateOrCreateEntry( const char *inszSection, const char *inszKey, const char *inszValue )
|
||||
{
|
||||
Section *sec = FindSection( inszSection ); assert(sec);
|
||||
|
||||
for(std::list<Entry>::iterator it = sec->entries.begin(); it != sec->entries.end(); ++it)
|
||||
{
|
||||
if(stricmp(it->key.GetString(),inszKey) == 0) // Key found
|
||||
if(!it->IsComment()) // update key
|
||||
{
|
||||
if(it->value==inszValue)
|
||||
return;
|
||||
|
||||
it->value=inszValue;
|
||||
m_modified=true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new key
|
||||
Entry entry;
|
||||
entry.key = inszKey;
|
||||
entry.value = inszValue;
|
||||
|
||||
sec->entries.push_back(entry);
|
||||
m_modified=true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CfgFile::LoadBuf( const char *buf,size_t bufSize )
|
||||
{
|
||||
|
||||
// Read entries from config CString buffer.
|
||||
Section *curr_section = &m_sections.front(); // Empty section.
|
||||
|
||||
const char *s = buf;
|
||||
size_t size = bufSize;
|
||||
|
||||
CString ss = s;
|
||||
|
||||
char str[4096];
|
||||
size_t i = 0;
|
||||
|
||||
while (i < size)
|
||||
{
|
||||
// while (j < size && s[j] != '\n') j++;
|
||||
|
||||
sscanf( &s[i],"%[^\n]s",str );
|
||||
|
||||
Log ("Parsing line: \"%s\"", str);
|
||||
|
||||
i+=strlen(str);
|
||||
if(s[i]==10)i++;
|
||||
|
||||
bool bComment=false;
|
||||
|
||||
// Is comment?
|
||||
Entry entry;
|
||||
entry.key = "";
|
||||
entry.value = str;
|
||||
|
||||
bComment=entry.IsComment();
|
||||
|
||||
if (bComment)
|
||||
Log ("It's a comment");
|
||||
|
||||
// Analyze entry CString, split on key and value and store in lists.
|
||||
CString entrystr = str;
|
||||
|
||||
if(!bComment)
|
||||
entrystr.Trim();
|
||||
|
||||
if(bComment || entrystr.IsEmpty())
|
||||
{
|
||||
Log ("Empty!");
|
||||
// Add this comment to current section.
|
||||
curr_section->entries.push_back( entry );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int splitter = entrystr.Find( '=' );
|
||||
Log ("found splitter at %d", splitter);
|
||||
|
||||
if (splitter > 0)
|
||||
{
|
||||
// Key found.
|
||||
entry.key = entrystr.Mid( 0,splitter ); // Before spliter is key name.
|
||||
Log ("Key: %s", entry.key.GetString());
|
||||
entry.value = entrystr.Mid( splitter+1 ); // Everything after splittes is value CString.
|
||||
Log ("Value: %s", entry.value.GetString());
|
||||
entry.key.Trim();
|
||||
entry.value.Trim();
|
||||
Log ("Key: %s, Value: %s", entry.key.GetString(), entry.value.GetString());
|
||||
|
||||
// Add this entry to current section.
|
||||
curr_section->entries.push_back( entry );
|
||||
}
|
||||
else
|
||||
{
|
||||
// If not key then probably section CString.
|
||||
if (entrystr[0] == '[' && entrystr[entrystr.GetLength()-1] == ']')
|
||||
{
|
||||
// World in bracets is section name.
|
||||
Section section;
|
||||
section.name = entrystr.Mid( 1,entrystr.GetLength()-2 ); // Remove bracets.
|
||||
Log ("Section! name: %s", section.name.GetString());
|
||||
m_sections.push_back( section );
|
||||
// Set current section.
|
||||
curr_section = &m_sections.back();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just IsEmpty key value.
|
||||
entry.key = "";
|
||||
entry.value = entrystr;
|
||||
|
||||
curr_section->entries.push_back( entry );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CfgFile::Section* CfgFile::FindSection( const CString §ion )
|
||||
{
|
||||
return &m_sections[Find(section.GetString())];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CfgFile::SetConfig( const char *section, IConfig *config )
|
||||
{
|
||||
Section *sec = FindSection( section ); assert(sec);
|
||||
|
||||
for (std::list<Entry>::iterator it = sec->entries.begin(); it != sec->entries.end(); ++it)
|
||||
{
|
||||
if(!(*it).IsComment())
|
||||
config->Set( (*it).key.GetString(),(*it).value.GetString() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user