- Added missing projects "VFS" & "export" to SVN

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4447 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2011-05-26 11:25:04 +00:00
parent 6e2bdd557c
commit be95a2a7b1
203 changed files with 44525 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
## Tools
set(INCLUDE_Tools
${MOD_INCLUDE}/vfs_allocator.h
${MOD_INCLUDE}/vfs_file_logger.h
${MOD_INCLUDE}/vfs_hp_timer.h
${MOD_INCLUDE}/vfs_log.h
${MOD_INCLUDE}/vfs_parser_tools.h
${MOD_INCLUDE}/vfs_profiler.h
${MOD_INCLUDE}/vfs_property_container.h
${MOD_INCLUDE}/vfs_tools.h
)
set(SOURCE_Tools
${MOD_SOURCE}/vfs_allocator.cpp
${MOD_SOURCE}/vfs_file_logger.cpp
${MOD_SOURCE}/vfs_hp_timer.cpp
${MOD_SOURCE}/vfs_log.cpp
${MOD_SOURCE}/vfs_parser_tools.cpp
${MOD_SOURCE}/vfs_profiler.cpp
${MOD_SOURCE}/vfs_property_container.cpp
${MOD_SOURCE}/vfs_tools.cpp
)
source_group(Tools FILES ${INCLUDE_Tools} ${SOURCE_Tools})
set(${mod}_files
${INCLUDE_Tools} ${SOURCE_Tools}
CACHE INTERNAL ""
)
+41
View File
@@ -0,0 +1,41 @@
/*
* bfVFS : vfs/Tools/vfs_allocator.cpp
* - allocator class to reserve memory blockwise for a larger amount of objects (that have constant size)
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/Tools/vfs_allocator.h>
std::vector<vfs::IAllocator*> vfs::ObjectAllocator::_valloc;
void vfs::ObjectAllocator::registerAllocator(vfs::IAllocator* allocator)
{
_valloc.push_back(allocator);
}
void vfs::ObjectAllocator::clear()
{
std::vector<IAllocator*>::iterator it = _valloc.begin();
for(; it != _valloc.end(); ++it)
{
delete *it;
*it = NULL;
}
_valloc.clear();
}
+59
View File
@@ -0,0 +1,59 @@
/*
* bfVFS : vfs/Tools/vfs_file_logger.cpp
* - implements Logging iterface in the Aspects module by using the vfs::Log class
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/Tools/vfs_file_logger.h>
vfs::FileLogger::FileLogger(vfs::Path const& log_file, bool append, vfs::Log::EFlushMode flush_mode)
: m_log( *vfs::Log::create(log_file, append, flush_mode) )
{
m_log.Reserve();
m_clock.startTimer();
}
vfs::FileLogger::FileLogger(vfs::tWritableFile* file, bool append, vfs::Log::EFlushMode flush_mode)
: m_log( *vfs::Log::create(file,append, flush_mode) )
{
m_log.Reserve();
m_clock.startTimer();
}
vfs::FileLogger::~FileLogger()
{
m_log.destroy();
}
void vfs::FileLogger::Msg(const wchar_t* msg)
{
m_log << "[" << m_clock.running() << "] : " << vfs::String::as_utf8(msg) << vfs::Log::endl;
}
void vfs::FileLogger::Msg(const char* msg)
{
m_log << "[" << m_clock.running() << "] : " << msg << vfs::Log::endl;
}
void vfs::FileLogger::Msg(vfs::String const& msg)
{
this->Msg(msg.c_str());
}
+93
View File
@@ -0,0 +1,93 @@
/*
* bfVFS : vfs/Tools/vfs_hp_timer.cpp
* - high performance/precision timer, used by profiler
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/Tools/vfs_hp_timer.h>
vfs::HPTimer::HPTimer() : is_running(false)
{
#ifdef WIN32
QueryPerformanceFrequency(&ticksPerSecond);
#endif
}
vfs::HPTimer::~HPTimer()
{
}
void vfs::HPTimer::startTimer()
{
#ifdef WIN32
QueryPerformanceCounter(&tick);
#elif __linux__
gettimeofday(&t1,0);
#endif
is_running = true;
}
long long vfs::HPTimer::ticks()
{
if(is_running)
{
#ifdef WIN32
QueryPerformanceCounter(&tick2);
return tick2.QuadPart - tick.QuadPart;
#elif __linux__
gettimeofday(&t2,0);
return t2.tv_usec - t1.tv_usec;
#endif
}
return 0;
}
double vfs::HPTimer::running()
{
if(is_running)
{
#ifdef WIN32
QueryPerformanceCounter(&tick2);
return (double)(tick2.QuadPart - tick.QuadPart)/(double)ticksPerSecond.QuadPart;
#elif __linux__
gettimeofday(&t2,0);
return (double)(t2.tv_usec - t1.tv_usec)/1000000.0;
#endif
}
return 0;
}
void vfs::HPTimer::stopTimer()
{
#ifdef WIN32
QueryPerformanceCounter(&tick2);
#elif __linux__
gettimeofday(&t2,0);
#endif
is_running = false;
}
double vfs::HPTimer::getElapsedTimeInSeconds()
{
#ifdef WIN32
return (double)(tick2.QuadPart - tick.QuadPart)/(double)ticksPerSecond.QuadPart;
#elif __linux__
return (double)(t2.tv_usec - t1.tv_usec)/1000000.0;
#endif
}
+412
View File
@@ -0,0 +1,412 @@
/*
* bfVFS : vfs/Tools/vfs_log.cpp
* - simple file logger
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/Tools/vfs_log.h>
#include <cstring>
#ifdef WIN32
static const char ENDL[] = "\r\n";
#else
static const char ENDL[] = "\n";
#endif
typedef std::list<vfs::Log*> LogList_t;
static LogList_t* __logs;
std::list<vfs::Log*>& vfs::Log::_logs()
{
if(!__logs)
{
__logs = new LogList_t;
}
return *__logs;
}
vfs::Log* vfs::Log::create(vfs::Path const& fileName, bool append, EFlushMode flushMode)
{
_logs().push_back(new vfs::Log(fileName, true, append, flushMode));
return _logs().back();
}
vfs::Log* vfs::Log::create(vfs::tWritableFile* file, bool append, EFlushMode flushMode)
{
_logs().push_back(new vfs::Log(file, append, flushMode));
return _logs().back();
}
void vfs::Log::flushDeleteAll()
{
LogList_t::iterator it = _logs().begin();
for(; it != _logs().end(); ++it)
{
(*it)->flush();
(*it)->Release();
}
_logs().clear();
}
void vfs::Log::flushReleaseAll()
{
LogList_t::iterator it = _logs().begin();
for(; it != _logs().end(); ++it)
{
(*it)->releaseFile();
}
}
vfs::String vfs::Log::_shared_id_str;
vfs::String const& vfs::Log::getSharedString()
{
return _shared_id_str;
}
void vfs::Log::setSharedString(vfs::String const& str)
{
_shared_id_str = str;
}
vfs::Log::Log(vfs::Path const& fileName, bool use_vfs_file, bool append, EFlushMode flushMode)
: IRefCountable(),
_filename(fileName), _file(NULL), _own_file(false),
_first_write(true), _flush_mode(flushMode), _append(append),
_buffer_size(0), _buffer_test_size(512)
{};
vfs::Log::Log(vfs::tWritableFile* file, bool append, EFlushMode flushMode)
: IRefCountable(),
_file(file), _own_file(false),
_first_write(true), _flush_mode(flushMode), _append(append),
_buffer_size(0), _buffer_test_size(512)
{
}
vfs::Log::~Log()
{
// the final flush
flush();
// also delete file pointer if we created it
if(_file && _own_file)
{
delete _file;
_file = NULL;
}
// one extra unlock wouldn't hurt
_mutex.unlock();
}
int vfs::Log::Reserve()
{
VFS_LOCK(_mutex);
return this->Register();
}
int vfs::Log::Release()
{
_mutex.lock();
int tmp_count = this->UnRegister();
if(tmp_count > 0)
{
_mutex.unlock();
}
// otherwise the mutex object is destroyed at that time
return tmp_count;
}
int vfs::Log::RefCount()
{
VFS_LOCK(_mutex);
return this->GetRefCount();
}
void vfs::Log::destroy()
{
// no need to lock here as 'flush' and 'Release' do it themselves
this->flush();
if(this->Release() <= 0)
{
// object is deleted, so remove it now from the static list
_logs().remove(this);
}
}
void vfs::Log::releaseFile()
{
VFS_LOCK(_mutex);
this->flush();
this->_file = NULL;
}
vfs::Log& vfs::Log::operator<<(vfs::UInt64 const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
vfs::Log& vfs::Log::operator<<(vfs::UInt32 const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
vfs::Log& vfs::Log::operator<<(vfs::UInt16 const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
vfs::Log& vfs::Log::operator<<(vfs::UInt8 const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
vfs::Log& vfs::Log::operator<<(vfs::Int64 const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
vfs::Log& vfs::Log::operator<<(vfs::Int32 const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
vfs::Log& vfs::Log::operator<<(vfs::Int16 const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
vfs::Log& vfs::Log::operator<<(vfs::Int8 const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
#ifdef _MSC_VER
vfs::Log& vfs::Log::operator<<(DWORD const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
#endif
vfs::Log& vfs::Log::operator<<(float const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
vfs::Log& vfs::Log::operator<<(double const& t)
{
VFS_LOCK(_mutex);
return pushNumber(t);
}
vfs::Log& vfs::Log::operator<<(const char* t)
{
VFS_LOCK(_mutex);
_buffer << t;
_buffer_size += strlen(t);
_test_flush();
return *this;
}
vfs::Log& vfs::Log::operator<<(const wchar_t* t)
{
VFS_LOCK(_mutex);
std::string s = vfs::String::as_utf8(t);
_buffer << s;
_buffer_size += s.length();
_test_flush();
return *this;
}
vfs::Log& vfs::Log::operator<<(std::string const& t)
{
VFS_LOCK(_mutex);
_buffer << t;
_buffer_size += t.length();
_test_flush();
return *this;
}
vfs::Log& vfs::Log::operator<<(std::wstring const& t)
{
VFS_LOCK(_mutex);
std::string s = vfs::String::as_utf8(t);
_buffer << s;
_buffer_size += s.length();
_test_flush();
return *this;
}
vfs::Log& vfs::Log::operator<<(vfs::String const& t)
{
VFS_LOCK(_mutex);
std::string s = t.utf8();
_buffer << s;
_buffer_size += s.length();
_test_flush();
return *this;
}
vfs::Log& vfs::Log::operator<<(void* const& t)
{
VFS_LOCK(_mutex);
_buffer << t;
return *this;
}
vfs::Log& vfs::Log::operator<<(vfs::Log::_endl const& endl)
{
VFS_LOCK(_mutex);
_buffer << ENDL;
_buffer_size += sizeof(ENDL)-1;
if(_flush_mode == vfs::Log::FLUSH_ON_ENDL) flush();
return *this;
}
/*
vfs::Log& vfs::Log::endl()
{
_buffer << ENDL;
_buffer_size += sizeof(ENDL)-1;
_test_flush();
return *this;
}
*/
void vfs::Log::setAppend(bool append)
{
VFS_LOCK(_mutex);
_append = append;
}
void vfs::Log::setBufferSize(vfs::UInt32 bufferSize)
{
VFS_LOCK(_mutex);
_buffer_test_size = bufferSize;
}
void vfs::Log::_test_flush(bool force)
{
if( (_flush_mode == FLUSH_IMMEDIATELY) ||
(_flush_mode == FLUSH_BUFFER && _buffer_size > _buffer_test_size) ||
(/*_flush_mode == FLUSH_ON_DELETE &&*/ force == true) )
{
flush();
}
}
vfs::Log::EFlushMode vfs::Log::flushMode()
{
return _flush_mode;
}
void vfs::Log::flushMode(vfs::Log::EFlushMode fmode)
{
_flush_mode = fmode;
}
#include <ctime>
#include <vfs/Core/vfs.h>
void vfs::Log::flush()
{
VFS_LOCK(_mutex);
::size_t buflen = _buffer.str().length();
if(buflen == 0)
{
return;
}
if(!_file)
{
VFS_THROW_IFF(!_filename.empty(), L"_file is NULL and _filename is empty");
//vfs::CVirtualProfile *prof = getVFS()->getProfileStack()->topProfile();
//if( prof && prof->cWritable )
if(vfs::canWrite())
{
try
{
vfs::COpenWriteFile file_raii(_filename,true,!_append);
_file = &file_raii.file();
file_raii.release();
_own_file = false;
}
catch(...)
{
}
}
else
{
try
{
_file = vfs::tWritableFile::cast(new vfs::CFile(_filename));
_file->openWrite(true,!_append);
_own_file = true;
}
catch(...)
{
}
}
}
vfs::COpenWriteFile wfile(_file);
if(_append)
{
wfile->setWritePosition(0,vfs::IBaseFile::SD_END);
}
if(_first_write)
{
time_t rawtime;
time ( &rawtime );
std::string datetime(ctime(&rawtime));
std::string s_out;
vfs::size_t wloc = wfile->getWritePosition();
if(wloc > 0)
{
s_out = ENDL;
}
s_out += " *** ";
s_out += datetime.substr(0,datetime.length()-1);
s_out += " *** ";
s_out += ENDL;
s_out += "[ ";
s_out += _shared_id_str.utf8();
s_out += " ]";
s_out += ENDL;
s_out += ENDL;
wfile->write(s_out.c_str(), s_out.length());
_first_write = false;
}
wfile->write(_buffer.str().c_str(), buflen);
_buffer.str("");
_buffer.clear();
_buffer_size = 0;
_append = true;
}
void vfs::Log::lock()
{
_mutex.lock();
}
void vfs::Log::unlock()
{
_mutex.unlock();
}
+249
View File
@@ -0,0 +1,249 @@
/*
* bfVFS : vfs/Tools/vfs_parser_tools.cpp
* - read file line-wise,
* - split string into tokens,
* - simple pattern matching
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/Core/vfs.h>
#include <vfs/Core/File/vfs_file.h>
#include <vfs/Core/vfs_file_raii.h>
#include <vfs/Tools/vfs_parser_tools.h>
#include <vfs/Tools/vfs_tools.h>
#include <cstring>
/*************************************************************************************/
/*************************************************************************************/
vfs::CReadLine::CReadLine(vfs::tReadableFile& rFile)
: _file(rFile), _buffer_pos(0), _eof(false)
{
memset(_buffer,0,sizeof(_buffer));
vfs::COpenReadFile rfile(&_file);
_bytes_left = rfile->getSize();
fillBuffer();
vfs::UByte utf8bom[3] = {0xef,0xbb,0xbf};
if(memcmp(utf8bom, &_buffer[0],3) == 0)
{
_buffer_pos += 3;
}
rfile.release();
};
vfs::CReadLine::~CReadLine()
{
if(_file.isOpenRead())
{
_file.close();
}
}
bool vfs::CReadLine::fillBuffer()
{
if(_eof)
{
return false;
}
vfs::size_t bytesRead = BUFFER_SIZE < _bytes_left ? BUFFER_SIZE : _bytes_left;
try
{
vfs::COpenReadFile rfile(&_file);
// fill the buffer from the start, BUFFER_SIZE charactes at max (_buffer has BUFFER_SIZE+1 elements)
VFS_THROW_IFF(bytesRead == _file.read(&_buffer[0], bytesRead), L"");
rfile.release();
}
catch(std::exception& ex)
{
VFS_RETHROW(L"", ex);
}
_bytes_left -= bytesRead;
_eof = (_bytes_left == 0);
// bite-wise read files usually terminate a line with \n (or \r\n on WIN32)
// line-wise read files just returns 0-terminated string
// always terminate the string with 0
_buffer[bytesRead] = 0;
_buffer_pos = 0;
_buffer_last = bytesRead;
return true;
}
bool vfs::CReadLine::fromBuffer(std::string& line)
{
bool done = false;
while(!done)
{
if(_buffer_pos < _buffer_last)
{
// start where we left last time
vfs::Byte *temp = &_buffer[_buffer_pos];
vfs::size_t start_pos = _buffer_pos;
// go until we hit 0. since our buffer is always 0 terminated, the second test should be redundant.
while(*temp && (_buffer_pos < _buffer_last))
{
// stop when we find a line terminator
if(*temp == '\n' || *temp == '\r' /* || *temp == '\0' */)
{
break;
}
temp++;
_buffer_pos++;
}
// need to append substring, as we might have refilles the buffer (because there was no \n or \r\n terminator)
line.append( (char*)&_buffer[start_pos], _buffer_pos - start_pos );
// if we reach the (real) end of the buffer (that always terminate with 0), this means
// that there was no line terminator and that we have to refill the buffer.
if( _buffer_pos < BUFFER_SIZE && (*temp == '\n' || *temp == '\r' || *temp == 0) )
{
// found the line terminator
if(*temp == '\r')
{
// the \r is most probably followed by \n. 'swallow' both characters
*temp++;
_buffer_pos++;
if( (_buffer_pos < BUFFER_SIZE) && (*temp == '\n' || *temp == 0) )
{
// increase buffer position, so that we can start with a valid character in the next run
_buffer_pos++;
return true;
}
else
{
done = !fillBuffer();
}
}
else if(*temp == '\n' || *temp == 0)
{
// increase buffer position, so that we can start with a valid character in the next run
_buffer_pos++;
return true;
}
}
else
{
done = !fillBuffer();
}
}
else
{
done = !fillBuffer();
}
}
return false;
}
bool vfs::CReadLine::getLine(std::string& line)
{
line.clear();
return fromBuffer(line);
}
/*************************************************************************************/
/*************************************************************************************/
vfs::CTokenizer::CTokenizer(vfs::String const& str)
: m_list(str), m_current(0), m_next(0)
{};
vfs::CTokenizer::~CTokenizer()
{};
bool vfs::CTokenizer::next(vfs::String& token, vfs::String::char_t delimeter)
{
if(m_next != vfs::String::str_t::npos)
{
m_next = m_list.c_wcs().find_first_of(delimeter, m_current);
if(m_next != vfs::String::str_t::npos)
{
token.r_wcs().assign(vfs::trimString(m_list,m_current,m_next > m_current ? m_next-1 : m_current).c_wcs());
m_current = m_next+1;
}
else
{
// last or only entry
token.r_wcs().assign(vfs::trimString(m_list,m_current,m_list.length()).c_wcs());
}
return true;
}
return false;
}
/*************************************************************************************/
/*************************************************************************************/
/**
* try to recursively match the pattern
*/
bool vfs::matchPattern(vfs::String const& sPattern, vfs::String const& sStr)
{
return matchPattern(sPattern,sStr.c_wcs());
}
bool vfs::matchPattern(vfs::String const& sPattern, vfs::String::str_t const& sStr)
{
vfs::String::str_t const& pat = sPattern.c_wcs();
vfs::String::size_t star = pat.find_first_of(vfs::Const::STAR());
if(star == vfs::String::str_t::npos)
{
return vfs::StrCmp::Equal( pat, sStr );
}
else if(star == 0)
{
if(pat.length() == 1)
{
// there is only the '*' -> matches all strings
return true;
}
vfs::String::char_t atpos1 = pat.at(1);
vfs::String::size_t match = vfs::String::size_t(-1);
do
{
match = sStr.find_first_of(atpos1,match+1);
if(match == vfs::String::str_t::npos)
{
return false;
}
} while(!matchPattern( pat.substr(1,pat.length()-1), sStr.substr(match,sStr.length()-match) ));
return true;
}
else // if(star > 0)
{
// check if characters before * match
if(!vfs::StrCmp::Equal(pat.substr(0,star), sStr.substr(0,star)) )
{
return false;
}
return matchPattern( pat.substr(star,pat.length()-star), sStr.substr(star,sStr.length()-star) );
}
}
/*************************************************************************************/
/*************************************************************************************/
+173
View File
@@ -0,0 +1,173 @@
/*
* bfVFS : vfs/Tools/vfs_profiler.cpp
* - basic profiler class and macros to measure execution time of code blocks
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define NOMINMAX
#include <vfs/Tools/vfs_profiler.h>
#include <vfs/Core/vfs_types.h>
#include <vfs/Core/File/vfs_file.h>
#include <sstream>
namespace vfs
{
class CProfileStarter
{
public:
CProfileStarter()
{
Profiler::getProfiler();
}
};
static CProfileStarter starter;
}
vfs::Profiler& vfs::Profiler::getProfiler()
{
static Profiler* _prof = new Profiler;
return *_prof;
}
vfs::Profiler::Profiler()
{
m_vMarker.resize(1024);
_nextMarker = 0;
}
void vfs::Profiler::clear()
{
for(unsigned int i = 0; i < _nextMarker; ++i)
{
m_vMarker[i].markername = "";
m_vMarker[i].time = 0;
m_vMarker[i].call_count = 0;
m_vMarker[i].success_count = 0;
m_vMarker[i].fail_count = 0;
}
_nextMarker = 0;
}
vfs::Profiler::tMarkerID vfs::Profiler::registerMarker(const char *marker)
{
m_vMarker[_nextMarker].markername = marker;
return _nextMarker++;
}
void vfs::Profiler::startMarker(tMarkerID id)
{
m_vMarker[id].timer.startTimer();
}
void vfs::Profiler::stopMarker(tMarkerID id, bool success)
{
m_vMarker[id].timer.stopTimer();
m_vMarker[id].time += m_vMarker[id].timer.getElapsedTimeInSeconds();
m_vMarker[id].call_count++;
if(success) m_vMarker[id].success_count++;
else m_vMarker[id].fail_count++;
}
inline std::string multChar(std::string::value_type c, unsigned int multiplicity)
{
std::string s;
s.resize(multiplicity);
for(unsigned int i=0; i<multiplicity; ++i)
{
s[i] = c;
}
return s;
}
inline long double perCent(unsigned long value, unsigned long ref)
{
return 100.0 * ((double)(value)/double(ref));
}
inline long double oneDigit(long double number)
{
unsigned long temp = (unsigned long)(number * 10);
return (temp / 10.0);
}
bool vfs::Profiler::printProfilerState(vfs::Path const& file)
{
vfs::CFile oFile(file);
if(!oFile.openWrite(true,true))
{
return false;
}
// get largest value
long double max_time = 0;
std::string::size_type max_prefix = 0;
for(unsigned int i=0; i<m_vMarker.size(); ++i)
{
if(m_vMarker[i].time > max_time)
{
max_time = m_vMarker[i].time;
}
std::string::size_type prefix_length = m_vMarker[i].markername.length();
if(prefix_length > max_prefix)
{
max_prefix = prefix_length;
}
}
const unsigned int WIDTH = 40;
std::stringstream line;
long double ld_success, ld_failure;
for(unsigned int i=0; i<m_vMarker.size(); ++i)
{
if(m_vMarker[i].markername.empty())
{
break;
}
if(m_vMarker[i].markername.length() < WIDTH)
{
unsigned int space = WIDTH - m_vMarker[i].markername.length();
line << m_vMarker[i].markername << multChar(' ',space) << " | ";
}
else
{
line << m_vMarker[i].markername.substr(0,WIDTH) << " | ";
}
if(max_time != 0)
{
unsigned int num_stars = (unsigned int)(WIDTH * (m_vMarker[i].time / max_time));
ld_success = perCent(m_vMarker[i].success_count,m_vMarker[i].call_count);
ld_failure = perCent(m_vMarker[i].fail_count,m_vMarker[i].call_count);
line << "[" << oneDigit(ld_success) << "|" << oneDigit(ld_failure) << "] "
<< multChar('*', num_stars) << multChar(' ', WIDTH - num_stars) << " | ";
}
line << "C: " << m_vMarker[i].call_count << ", T: " << m_vMarker[i].time << std::endl;
//line << std::endl;
}
std::string useless_copy = line.str();
oFile.write(useless_copy.c_str(), (vfs::size_t)(useless_copy.length()*sizeof(std::string::value_type)));
oFile.close();
return true;
}
void vfs::DumpProfileState(vfs::Path const& path)
{
vfs::Profiler::getProfiler().printProfilerState(path);
}
@@ -0,0 +1,798 @@
/*
* bfVFS : vfs/Tools/vfs_property_container.cpp
* - <string,string> key-value map with capability to convert values to other types
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/vfs_config.h>
#include <vfs/Core/vfs.h>
#include <vfs/Core/vfs_file_raii.h>
#include <vfs/Core/vfs_os_functions.h>
#include <vfs/Core/File/vfs_file.h>
#include <vfs/Core/File/vfs_buffer_file.h>
#include <vfs/Tools/vfs_tools.h>
#include <vfs/Tools/vfs_parser_tools.h>
#include <vfs/Tools/vfs_property_container.h>
#include <sstream>
#include <vector>
/*************************************************************************************/
/*************************************************************************************/
bool vfs::PropertyContainer::Section::has(vfs::String const& key)
{
return mapProps.find(key) != mapProps.end();
}
bool vfs::PropertyContainer::Section::add(vfs::String const& key, vfs::String const& value)
{
if(!mapProps[key].empty())
{
mapProps[key] += L", ";
}
mapProps[key] += value;
return true;
}
vfs::String& vfs::PropertyContainer::Section::value(vfs::String const& key)
{
return mapProps[key];
}
bool vfs::PropertyContainer::Section::value(vfs::String const& key, vfs::String& value)
{
tProps::iterator sit = mapProps.find(key);
if(sit != mapProps.end())
{
value.r_wcs().assign(sit->second.c_wcs());
return true;
}
return false;
}
void vfs::PropertyContainer::Section::print(std::ostream& out, vfs::String::str_t sPrefix)
{
tProps::iterator sit = mapProps.begin();
for(; sit != mapProps.end(); ++sit)
{
out << vfs::String::as_utf8(sPrefix) << sit->first.utf8() << " = " << sit->second.utf8() << "\r\n";
}
}
void vfs::PropertyContainer::Section::clear()
{
mapProps.clear();
}
/*************************************************************************************/
/*************************************************************************************/
void vfs::PropertyContainer::clearContainer()
{
tSections::iterator it = m_mapProps.begin();
for(;it != m_mapProps.end(); ++it)
{
it->second.clear();
}
m_mapProps.clear();
}
bool vfs::PropertyContainer::extractSection(vfs::String::str_t const& readStr, vfs::size_t startPos, vfs::String::str_t& sSection)
{
// extract section name
vfs::size_t close = readStr.find_first_of(L"]", startPos);
if( close != vfs::npos && close > startPos)
{
startPos += 1;
sSection = vfs::trimString(readStr,startPos,(vfs::size_t)(close-1));
return true;
}
return false;
}
vfs::PropertyContainer::EOperation vfs::PropertyContainer::extractKeyValue(vfs::String::str_t const &readStr, vfs::size_t startPos, vfs::String::str_t& sKey, vfs::String::str_t& sValue)
{
vfs::size_t iEqual = readStr.find_first_of(L"+=", startPos);
if(iEqual == vfs::npos)
{
VFS_LOG_WARNING(_BS("WARNING : could not extract key-value pair : ") << readStr << _BS::wget);
return vfs::PropertyContainer::Error;
}
// extract key
sKey = vfs::trimString(readStr,0,iEqual-1);
// extract value
EOperation op = vfs::PropertyContainer::Set;
if( readStr.at(iEqual) == L'+' )
{
if( (iEqual+1) < readStr.size() && (readStr.at(iEqual+1) == L'=') )
{
iEqual += 1;
op = vfs::PropertyContainer::Add;
}
}
sValue = vfs::trimString(readStr,iEqual+1,readStr.size());
return op;
}
bool vfs::PropertyContainer::initFromIniFile(vfs::Path const& sFileName)
{
// try to open via VirtualFileSystem
if(getVFS()->fileExists(sFileName))
{
return initFromIniFile(getVFS()->getReadFile(sFileName));
}
else
{
vfs::CFile file(sFileName);
if(file.openRead())
{
return initFromIniFile(vfs::tReadableFile::cast(&file));
}
return false;
}
}
bool vfs::PropertyContainer::initFromIniFile(vfs::tReadableFile *pFile)
{
if(!pFile)
{
return false;
}
std::string sBuffer;
vfs::String::str_t sCurrentSection;
int line_counter = 0;
CReadLine rl(*pFile);
while(rl.getLine(sBuffer))
{
line_counter++;
// very simple parsing : key = value
if(!sBuffer.empty())
{
// remove leading white spaces
::size_t iStart = sBuffer.find_first_not_of(" \t",0);
if(iStart == std::string::npos)
{
// only white space characters
continue;
}
char first = sBuffer.at(iStart);
switch(first)
{
case '!':
case ';':
case '#':
// comment -> do nothing
break;
case '[':
{
vfs::String u8s;
try
{
vfs::String::as_utf16(sBuffer.substr(iStart, sBuffer.length()-iStart), u8s.r_wcs());
}
catch(std::exception& ex)
{
VFS_RETHROW( _BS(L"Conversion error in file \"") << pFile->getPath()
<< L"\", line " << line_counter << _BS::wget, ex);
}
if(this->extractSection(u8s.c_wcs(), 0, sCurrentSection))
{
m_mapProps[sCurrentSection];
}
else
{
VFS_LOG_WARNING(_BS("WARNING : could not extract section name : ") << sBuffer << _BS::wget);
}
}
break;
default:
{
// probably key-value pair
vfs::String::str_t u8s;
try
{
vfs::String::as_utf16(sBuffer.substr(iStart, sBuffer.length()-iStart), u8s);
}
catch(std::exception& ex)
{
VFS_RETHROW( _BS(L"Conversion error in file \"") << pFile->getPath()
<< L"\", line " << line_counter << _BS::wget, ex);
}
vfs::String::str_t sKey, sValue;
EOperation op = this->extractKeyValue(u8s, 0, sKey, sValue);
if(op != Error)
{
// add key-value pair to map
if(m_mapProps.find(sCurrentSection) != m_mapProps.end())
{
if(op == Set)
{
this->section(sCurrentSection).value(sKey) = sValue;
}
else if(op == Add)
{
this->section(sCurrentSection).add(sKey, sValue);
}
}
else
{
VFS_LOG_WARNING(_BS(L"ERROR : could not find section [") << sCurrentSection
<< L"] in container" << _BS::wget);
}
}
}
break;
}; // end switch
} // end if (empty)
} // end while(!eof)
return true;
}
static vfs::UByte utf8bom[4] = {0xef,0xbb,0xbf,0x0};
bool vfs::PropertyContainer::writeToIniFile(vfs::Path const& sFilename, bool bCreateNew)
{
#ifdef WIN32
const char ENDL[] = "\r\n";
#else
const char ENDL[] = "\n";
#endif
if(bCreateNew)
{
vfs::tWritableFile* file;
bool delete_file = false;
try
{
vfs::COpenWriteFile wfile(sFilename,true,true);
file = &wfile.file();
wfile.release();
}
catch(std::exception& ex)
{
VFS_LOG_WARNING(ex.what());
// vfs not initialized?
vfs::CFile* cfile = new vfs::CFile(sFilename);
cfile->openWrite(true,true);
file = vfs::tWritableFile::cast(cfile);
delete_file = true;
}
tSections::iterator sit = m_mapProps.begin();
std::stringstream ss;
std::string str;
ss << (char*)utf8bom;
for(; sit != m_mapProps.end(); ++sit)
{
ss.str("");
ss << "[" << sit->first.utf8() << "]" << ENDL;
str = ss.str();
file->write(str.c_str(), str.length());
ss.clear();
ss.str("");
Section& section = sit->second;
section.print(ss);
ss << ENDL;
str = ss.str();
file->write(str.c_str(),str.length());
}
file->close();
if(delete_file)
{
delete file;
}
return true;
}
else
{
// try to open via VirtualFileSystem
vfs::CBufferFile rfile;
if(getVFS()->fileExists(sFilename))
{
vfs::COpenReadFile rf(sFilename);
rfile.copyToBuffer(rf.file());
}
else if(getVFS()->createNewFile(sFilename))
{
vfs::tReadableFile* pFile = getVFS()->getReadFile(sFilename);
if(pFile && pFile->openRead())
{
rfile.copyToBuffer(*pFile);
pFile->close();
}
}
else
{
// file doesn't exist or VFS not initialized yet
vfs::CFile file(sFilename);
rfile.copyToBuffer(*vfs::tReadableFile::cast(&file));
}
std::stringstream outbuffer;
std::string sBuffer;
vfs::String::str_t sCurrentSection;
std::set<vfs::String> setKeys;
std::set<vfs::String> setSections;
tSections::iterator sit = m_mapProps.begin();
for(; sit != m_mapProps.end(); ++sit)
{
setSections.insert(sit->first);
}
CReadLine rl(*vfs::tReadableFile::cast(&rfile));
outbuffer << (char*)(utf8bom);
vfs::UInt32 line_counter = 0;
while(rl.getLine(sBuffer))
{
line_counter++;
if(!sBuffer.empty())
{
// remove leading white spaces
::size_t iStart = sBuffer.find_first_not_of(" \t",0);
char first = sBuffer.at(iStart);
switch(first)
{
case '!':
case ';':
case '#':
outbuffer << sBuffer << ENDL;
break;
case '[':
{
vfs::String u8s;
try
{
vfs::String::as_utf16(sBuffer.substr(iStart, sBuffer.length()-iStart), u8s.r_wcs());
}
catch(std::exception& ex)
{
VFS_RETHROW(_BS(L"Conversion error in file \"") << sFilename
<< L"\", line " << line_counter << _BS::wget, ex);
}
vfs::String::str_t oldSection = sCurrentSection;
if(this->extractSection(u8s.c_wcs(), 0, sCurrentSection))
{
if(setSections.find(sCurrentSection) == setSections.end())
{
// section already handled ?!?!?!
// just print duplicate version
outbuffer << vfs::String::as_utf8(sBuffer) << ENDL;
break;
}
if(!setKeys.empty())
{
// there are new keys in the previous section
Section& oldsec = m_mapProps[oldSection];
std::set<vfs::String>::iterator kit = setKeys.begin();
for(; kit != setKeys.end(); ++kit)
{
outbuffer << vfs::String::as_utf8(*kit) << " = " << vfs::String::as_utf8(oldsec.value(*kit)) << ENDL;
}
// all remaining keys were written, clear set
setKeys.clear();
outbuffer << ENDL;
}
Section& sec = m_mapProps[sCurrentSection];
Section::tProps::iterator it = sec.mapProps.begin();
for(; it != sec.mapProps.end(); ++it)
{
setKeys.insert(it->first);
}
}
outbuffer << vfs::String::as_utf8(sBuffer) << ENDL;
}
break;
default:
{
// probably key-value pair
vfs::String u8s;
try
{
vfs::String::as_utf16(sBuffer.substr(iStart, sBuffer.length()-iStart), u8s.r_wcs());
}
catch(std::exception& ex)
{
VFS_RETHROW(_BS(L"Conversion error in file \"") << sFilename
<< L"\", line " << line_counter << _BS::wget, ex);
}
vfs::String::str_t sKey, sValue;
if(this->extractKeyValue(u8s.c_wcs(), 0, sKey, sValue))
{
if(setKeys.find(sKey) != setKeys.end())
{
outbuffer << vfs::String::as_utf8(sKey) << " = " << vfs::String::as_utf8(m_mapProps[sCurrentSection].value(sKey)) << "\r\n";
setKeys.erase(sKey);
}
else
{
outbuffer << vfs::String::as_utf8(sBuffer) << ENDL;
}
if(setKeys.empty())
{
setSections.erase(sCurrentSection);
}
}
}
break;
}; // end switch
}
else
{
outbuffer << ENDL;
}
}
if(!setKeys.empty())
{
Section& sec = m_mapProps[sCurrentSection];
std::set<vfs::String>::iterator kit = setKeys.begin();
for(; kit != setKeys.end(); ++kit)
{
outbuffer << vfs::String::as_utf8(*kit) << " = " << vfs::String::as_utf8(sec.value(*kit)) << ENDL;
}
setKeys.clear();
if(setKeys.empty())
{
setSections.erase(sCurrentSection);
}
}
std::set<vfs::String>::iterator it = setSections.begin();
for(; it != setSections.end(); ++it)
{
outbuffer << ENDL << "[" << vfs::String::as_utf8(*it) << "]" << ENDL;
std::stringstream ss;
m_mapProps[*it].print(outbuffer);
}
try
{
vfs::COpenWriteFile wfile(sFilename,true,true);
wfile->write(outbuffer.str().c_str(),(vfs::size_t)outbuffer.str().length());
}
catch(std::exception& ex)
{
VFS_LOG_WARNING(ex.what());
vfs::CFile file(sFilename);
if(file.openWrite(true,true))
{
file.write(outbuffer.str().c_str(),(vfs::size_t)outbuffer.str().length());
file.close();
}
}
return true;
}
}
void vfs::PropertyContainer::printProperties(std::ostream &out)
{
tSections::iterator pit = m_mapProps.begin();
for(;pit != m_mapProps.end(); ++pit)
{
out << "[" << pit->first.utf8() << "]\n";
pit->second.print(out, L" ");
out << std::endl;
}
}
vfs::PropertyContainer::Section& vfs::PropertyContainer::section(vfs::String const& sSection)
{
return m_mapProps[sSection];
}
bool vfs::PropertyContainer::getValueForKey(vfs::String const& sSection, vfs::String const& sKey, vfs::String &sValue)
{
tSections::iterator pit = m_mapProps.find(vfs::trimString(sSection,0,(vfs::size_t)sSection.length()));
if( pit != m_mapProps.end() )
{
return pit->second.value( vfs::trimString(sKey,0,(vfs::size_t)sKey.length()), sValue );
}
return false;
}
bool vfs::PropertyContainer::hasProperty(vfs::String const& sSection, vfs::String const& sKey)
{
tSections::iterator pit = m_mapProps.find(vfs::trimString(sSection,0,(vfs::size_t)sSection.length()));
if( pit != m_mapProps.end() )
{
return pit->second.has(vfs::trimString(sKey,0,sKey.length()));
}
return false;
}
vfs::String const& vfs::PropertyContainer::getStringProperty(vfs::String const& sSection, vfs::String const& sKey, vfs::String const& sDefaultValue)
{
vfs::PropertyContainer::tSections::iterator sit = m_mapProps.find(sSection);
if(sit != m_mapProps.end())
{
vfs::PropertyContainer::Section::tProps::iterator pit = sit->second.mapProps.find(sKey);
if(pit != sit->second.mapProps.end())
{
return pit->second;
}
}
return sDefaultValue;
}
bool vfs::PropertyContainer::getStringProperty(vfs::String const& sSection, vfs::String const& sKey, vfs::String& sValue, vfs::String const& sDefaultValue)
{
if(getValueForKey(sSection,sKey,sValue))
{
return true;
}
sValue = sDefaultValue;
return false;
}
bool vfs::PropertyContainer::getStringProperty(vfs::String const& sSection, vfs::String const& sKey, vfs::String::char_t* sValue, vfs::size_t len, vfs::String const& sDefaultValue)
{
vfs::String s;
if(getValueForKey(sSection,sKey,s))
{
vfs::size_t l = std::min<vfs::size_t>(s.length(), len-1);
wcsncpy(sValue,s.c_str(), l);
sValue[l] = 0;
return true;
}
vfs::size_t l = std::min<vfs::size_t>(sDefaultValue.length(), len-1);
wcsncpy(sValue,sDefaultValue.c_str(), l);
sValue[l] = 0;
return false;
}
vfs::Int64 vfs::PropertyContainer::getIntProperty(vfs::String const& sSection, vfs::String const& sKey, vfs::Int64 iDefaultValue, vfs::Int64 iMinValue, vfs::Int64 iMaxValue)
{
return std::min<vfs::Int64>(iMaxValue, std::max<vfs::Int64>(iMinValue, this->getIntProperty(sSection, sKey, iDefaultValue)));
}
vfs::Int64 vfs::PropertyContainer::getIntProperty(vfs::String const& sSection, vfs::String const& sKey, vfs::Int64 iDefaultValue)
{
vfs::String sValue;
if(getValueForKey(sSection,sKey,sValue))
{
vfs::Int64 iRetVal;
if(convertTo<vfs::Int64>(sValue,iRetVal))
{
return iRetVal;
}
}
return iDefaultValue;
}
vfs::UInt64 vfs::PropertyContainer::getUIntProperty(vfs::String const& sSection, vfs::String const& sKey, vfs::UInt64 iDefaultValue, vfs::UInt64 iMinValue, vfs::UInt64 iMaxValue)
{
return std::min<vfs::UInt64>(iMaxValue, std::max<vfs::UInt64>(iMinValue, this->getIntProperty(sSection, sKey, iDefaultValue)));
}
vfs::UInt64 vfs::PropertyContainer::getUIntProperty(vfs::String const& sSection, vfs::String const& sKey, vfs::UInt64 iDefaultValue)
{
vfs::String sValue;
if(getValueForKey(sSection,sKey,sValue))
{
vfs::UInt64 iRetVal;
if(convertTo<vfs::UInt64>(sValue,iRetVal))
{
return iRetVal;
}
}
return iDefaultValue;
}
double vfs::PropertyContainer::getFloatProperty(vfs::String const& sSection, vfs::String const& sKey, double fDefaultValue, double fMinValue, double fMaxValue)
{
return std::min<double>(fMaxValue, std::max<double>(fMinValue, this->getFloatProperty(sSection, sKey, fDefaultValue)));
}
double vfs::PropertyContainer::getFloatProperty(vfs::String const& sSection, vfs::String const& sKey, double fDefaultValue)
{
vfs::String sValue;
if(getValueForKey(sSection,sKey,sValue))
{
double fRetVal;
if(convertTo<double>(sValue,fRetVal))
{
return fRetVal;
}
}
return fDefaultValue;
}
bool vfs::PropertyContainer::getBoolProperty(vfs::String const& sSection, vfs::String const& sKey, bool bDefaultValue)
{
vfs::String sValue;
if(getValueForKey(sSection,sKey,sValue))
{
vfs::Int32 iRetVal;
if( StrCmp::Equal(sValue,L"true") || ( convertTo<>(sValue,iRetVal) && (iRetVal != 0) ) )
{
return true;
}
else if( StrCmp::Equal(sValue,"false") || ( convertTo<>(sValue,iRetVal) && (iRetVal == 0) ) )
{
return false;
}
// else return bDefaultValue
}
return bDefaultValue;
}
bool vfs::PropertyContainer::getStringListProperty(vfs::String const& sSection, vfs::String const& sKey, std::list<vfs::String> &lValueList, vfs::String sDefaultValue)
{
vfs::String sValue;
if(getValueForKey(sSection,sKey,sValue))
{
CTokenizer splitter(sValue);
vfs::String entry;
while( splitter.next(entry, L',') )
{
lValueList.push_back(vfs::trimString(entry,0,entry.length()));
}
return true;
}
return false;
}
bool vfs::PropertyContainer::getIntListProperty(vfs::String const& sSection, vfs::String const& sKey, std::list<vfs::Int64> &lValueList, vfs::Int64 iDefaultValue)
{
vfs::String sValue;
if(getValueForKey(sSection,sKey,sValue))
{
vfs::String entry;
CTokenizer splitter(sValue);
while( splitter.next(entry, L',') )
{
vfs::Int64 iRetVal;
if(convertTo<vfs::Int64>(entry,iRetVal))
{
lValueList.push_back(iRetVal);
}
else
{
lValueList.push_back(iDefaultValue);
}
}
return true;
}
return false;
}
bool vfs::PropertyContainer::getUIntListProperty(vfs::String const& sSection, vfs::String const& sKey, std::list<vfs::UInt64> &lValueList, vfs::UInt64 iDefaultValue)
{
vfs::String sValue;
if(getValueForKey(sSection,sKey,sValue))
{
vfs::String entry;
CTokenizer splitter(sValue);
while( splitter.next(entry, L',') )
{
vfs::UInt64 iRetVal;
if(convertTo<vfs::UInt64>(entry,iRetVal))
{
lValueList.push_back(iRetVal);
}
else
{
lValueList.push_back(iDefaultValue);
}
}
return true;
}
return false;
}
bool vfs::PropertyContainer::getFloatListProperty(vfs::String const& sSection, vfs::String const& sKey, std::list<double> &lValueList, double fDefaultValue)
{
vfs::String sValue;
if(getValueForKey(sSection,sKey,sValue))
{
vfs::String entry;
CTokenizer splitter(sValue);
while( splitter.next(entry, L',') )
{
double fRetVal;
if(convertTo<double>(entry,fRetVal))
{
lValueList.push_back(fRetVal);
}
else
{
lValueList.push_back(fDefaultValue);
}
}
return true;
}
return false;
}
bool vfs::PropertyContainer::getBoolListProperty(vfs::String const& sSection, vfs::String const& sKey, std::list<bool> &lValueList, bool bDefaultValue)
{
vfs::String sValue;
if(getValueForKey(sSection,sKey,sValue))
{
vfs::String entry;
CTokenizer splitter(sValue);
while( splitter.next(entry, L',') )
{
vfs::Int32 iRetVal;
if( StrCmp::Equal(entry,L"true") || ( convertTo<>(entry,iRetVal) && (iRetVal != 0) ) )
{
lValueList.push_back(true);
}
else if( StrCmp::Equal(entry,L"false") || ( convertTo<>(entry,iRetVal) && (iRetVal == 0) ) )
{
lValueList.push_back(false);
}
else
{
lValueList.push_back(bDefaultValue);
}
}
return true;
}
return false;
}
void vfs::PropertyContainer::setStringProperty(vfs::String const& sSection, vfs::String const& sKey, vfs::String const& sValue)
{
this->section(sSection).value(sKey) = sValue;
}
void vfs::PropertyContainer::setIntProperty(vfs::String const& sSection, vfs::String const& sKey, vfs::Int64 const& iValue)
{
this->section(sSection).value(sKey) = toString<wchar_t,vfs::Int64>(iValue);
}
void vfs::PropertyContainer::setUIntProperty(vfs::String const& sSection, vfs::String const& sKey, vfs::UInt64 const& iValue)
{
this->section(sSection).value(sKey) = toString<wchar_t,vfs::UInt64>(iValue);
}
void vfs::PropertyContainer::setFloatProperty(vfs::String const& sSection, vfs::String const& sKey, double const& fValue)
{
this->section(sSection).value(sKey) = toString<wchar_t,double>(fValue);
}
void vfs::PropertyContainer::setBoolProperty(vfs::String const& sSection, vfs::String const& sKey, bool const& bValue)
{
this->section(sSection).value(sKey) = toString<wchar_t,bool>(bValue);
}
void vfs::PropertyContainer::setStringListProperty(vfs::String const& sSection, vfs::String const& sKey, std::list<vfs::String> const& slValue)
{
this->section(sSection).value(sKey) = toStringList<vfs::String>(slValue);
}
void vfs::PropertyContainer::setIntListProperty(vfs::String const& sSection, vfs::String const& sKey, std::list<vfs::Int64> const& ilValue)
{
this->section(sSection).value(sKey) = toStringList<vfs::Int64>(ilValue);
}
void vfs::PropertyContainer::setFloatListProperty(vfs::String const& sSection, vfs::String const& sKey, std::list<double> const& flValue)
{
this->section(sSection).value(sKey) = toStringList<double>(flValue);
}
void vfs::PropertyContainer::setBoolListProperty(vfs::String const& sSection, vfs::String const& sKey, std::list<bool> const& blValue)
{
this->section(sSection).value(sKey) = toStringList<bool>(blValue);
}
/**************************************************************************************************/
/**************************************************************************************************/
+87
View File
@@ -0,0 +1,87 @@
/*
* bfVFS : vfs/Tools/vfs_tools.cpp
* - simple from/to string (list) conversion functions,
* - remove leading/trailing whitspace characters in a string
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/Tools/vfs_tools.h>
template<>
vfs::String vfs::toStringList<vfs::String>(std::list<vfs::String> const& rValList)
{
std::wstringstream ss;
std::list<vfs::String>::const_iterator cit = rValList.begin();
if(cit != rValList.end())
{
ss << (*cit);
cit++;
for(;cit != rValList.end(); ++cit)
{
ss << L" , " << (*cit);
}
}
if(!ss)
{
return L"";
}
return ss.str();
}
/*************************************************************************************/
/*************************************************************************************/
template<>
std::string vfs::trimString<std::string>(std::string const& sStr, vfs::size_t iMinPos, vfs::size_t iMaxPos)
{
if(iMinPos > iMaxPos || iMaxPos == vfs::npos)
{
return "";
}
::size_t iStart,iEnd;
iStart = sStr.find_first_not_of(" \t\r\n",(::size_t)iMinPos);
iEnd = sStr.find_last_not_of(" \t\r\n",(::size_t)iMaxPos);
if( (iStart != std::string::npos) && (iEnd != std::string::npos) )
{
return sStr.substr(iStart,iEnd-iStart+1);
}
return "";
}
template<>
std::wstring vfs::trimString<std::wstring>(std::wstring const& sStr, vfs::size_t iMinPos, vfs::size_t iMaxPos)
{
if(iMinPos > iMaxPos || iMaxPos == vfs::npos)
{
return L"";
}
::size_t iStart,iEnd;
iStart = sStr.find_first_not_of(L" \t\r\n",(::size_t)iMinPos);
iEnd = sStr.find_last_not_of(L" \t\r\n",(::size_t)iMaxPos);
if( (iStart != std::wstring::npos) && (iEnd != std::wstring::npos) )
{
return sStr.substr(iStart,iEnd-iStart+1);
}
return L"";
}
template<>
vfs::String vfs::trimString<vfs::String>(vfs::String const& sStr, vfs::size_t iMinPos, vfs::size_t iMaxPos)
{
return vfs::trimString(sStr.c_wcs(), iMinPos, iMaxPos);
}