Index: ext/libicpf/libicpf.vc71.sln =================================================================== diff -u -N -r6dae57f5e7aeeb965bc018024d8360069f6e15c1 -rb337c059691a6940b52a86388ff427c734be8eb6 --- ext/libicpf/libicpf.vc71.sln (.../libicpf.vc71.sln) (revision 6dae57f5e7aeeb965bc018024d8360069f6e15c1) +++ ext/libicpf/libicpf.vc71.sln (.../libicpf.vc71.sln) (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -1,5 +1,5 @@ Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libicpf", "libicpf.vc71.vcproj", "{5510B933-046F-4F75-8B46-5E8279C8CCDE}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libicpf", "src/libicpf/libicpf.vc71.vcproj", "{5510B933-046F-4F75-8B46-5E8279C8CCDE}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Index: ext/libicpf/src/Makefile.am =================================================================== diff -u -N -rfd1f0cf4d6ad9ff63fd9252a3f2f31c992431842 -rb337c059691a6940b52a86388ff427c734be8eb6 --- ext/libicpf/src/Makefile.am (.../Makefile.am) (revision fd1f0cf4d6ad9ff63fd9252a3f2f31c992431842) +++ ext/libicpf/src/Makefile.am (.../Makefile.am) (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -1,16 +1,5 @@ -lib_LTLIBRARIES = libicpf.la -libicpf_la_SOURCES = callback.cpp exception.cpp circ_buffer.cpp \ - log.cpp dumpctx.cpp cfg.cpp cfg_xml.cpp config_property.cpp str_help.cpp \ - crc32.cpp file.cpp module.cpp conv.cpp mutex.cpp - -# set the include path found by configure -INCLUDES = $(all_includes) - -# the library search path. -#libicpf_la_LDFLAGS = $(all_libraries) -libicpf_la_LIBADD = -ldl -lpthread -dist_include_HEADERS = callback.h exception.h dumpctx.h cfg.h circ_buffer.h module.h \ - file.h log.h cfg.h config_base.h config_property.h str_help.h crc32.h libicpf.h gen_types.h \ - conv.h err_codes.h gen_types.h macros.h mutex.h -AM_CFLAGS = -Wall -Wshadow -DLIBICPF_EXPORTS -AM_CXXFLAGS = -Wall -Wshadow -DLIBICPF_EXPORTS +# not a GNU package. You can remove this line, if +# have all needed files, that a GNU package needs +AUTOMAKE_OPTIONS = foreign 1.4 + +SUBDIRS = libicpf libicpf-tests Index: ext/libicpf/src/libicpf/Makefile.am =================================================================== diff -u -N --- ext/libicpf/src/libicpf/Makefile.am (revision 0) +++ ext/libicpf/src/libicpf/Makefile.am (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,16 @@ +lib_LTLIBRARIES = libicpf.la +libicpf_la_SOURCES = callback.cpp exception.cpp circ_buffer.cpp \ + log.cpp dumpctx.cpp cfg.cpp cfg_xml.cpp config_property.cpp str_help.cpp \ + crc32.cpp file.cpp module.cpp conv.cpp mutex.cpp + +# set the include path found by configure +INCLUDES = $(all_includes) + +# the library search path. +#libicpf_la_LDFLAGS = $(all_libraries) +libicpf_la_LIBADD = -ldl -lpthread +dist_include_HEADERS = callback.h exception.h dumpctx.h cfg.h circ_buffer.h module.h \ + file.h log.h cfg.h config_base.h config_property.h str_help.h crc32.h libicpf.h gen_types.h \ + conv.h err_codes.h gen_types.h macros.h mutex.h +AM_CFLAGS = -Wall -Wshadow -DLIBICPF_EXPORTS +AM_CXXFLAGS = -Wall -Wshadow -DLIBICPF_EXPORTS Index: ext/libicpf/src/libicpf/callback.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/callback.cpp (revision 0) +++ ext/libicpf/src/libicpf/callback.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,133 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + /** \file callback.cpp + * \brief File provides the implementation of callback classes. + */ +#include "callback.h" +#include +#include + +BEGIN_ICPF_NAMESPACE + +#define STORAGE ((std::vector*)m_pStorage) + +callback_list::callback_list() : + m_lock(), + m_pStorage((void*)new std::vector) +{ +} + +callback_list::callback_list(const callback_list& rSrc) : + m_lock(), + m_pStorage((void*)new std::vector) +{ + STORAGE->assign(((std::vector*)rSrc.m_pStorage)->begin(), ((std::vector*)rSrc.m_pStorage)->end()); + assert(false); // we should not use the copy constructor at all !!! +} + +callback_list::~callback_list() +{ + try + { + delete STORAGE; + } + catch(...) + { + + } +} + +const callback_list& callback_list::operator=(const callback_list& rSrc) +{ + assert(false); // we shouldn't use the assignment operator at all!!! + if (this != &rSrc) + { + delete STORAGE; + m_pStorage=(void*)new std::vector; + STORAGE->assign(((std::vector*)rSrc.m_pStorage)->begin(), ((std::vector*)rSrc.m_pStorage)->end()); + } + + return *this; +} + +void callback_list::add(PFNFUNC pfn, ptr_t param) +{ + m_lock.lock(); + CLBDATA clb = { pfn, param }; + STORAGE->push_back(clb); + m_lock.unlock(); +} + +bool callback_list::remove(PFNFUNC pfn) +{ + m_lock.lock(); + for (std::vector::iterator it=STORAGE->begin();it != STORAGE->end();it++) + { + if ((*it).pfn == pfn) + { + STORAGE->erase(it); + m_lock.unlock(); + return true; + } + } + + m_lock.unlock(); + return false; +} + +void callback_list::clear() +{ + m_lock.lock(); + STORAGE->clear(); + m_lock.unlock(); +} + +size_t callback_list::size() +{ + m_lock.lock(); + size_t tSize=STORAGE->size(); + m_lock.unlock(); + + return tSize; +} + +CLBDATA* callback_list::at(size_t tIndex) +{ + CLBDATA* pData=NULL; + m_lock.lock(); + if (tIndex < STORAGE->size()) + pData=&(STORAGE->at(tIndex)); + m_lock.unlock(); + + return pData; +} + +void callback_list::lock() +{ + m_lock.lock(); +} + +void callback_list::unlock() +{ + m_lock.unlock(); +} + + +END_ICPF_NAMESPACE Index: ext/libicpf/src/callback.cpp =================================================================== diff -u -N --- ext/libicpf/src/callback.cpp (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/callback.cpp (revision 0) @@ -1,133 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - /** \file callback.cpp - * \brief File provides the implementation of callback classes. - */ -#include "callback.h" -#include -#include - -BEGIN_ICPF_NAMESPACE - -#define STORAGE ((std::vector*)m_pStorage) - -callback_list::callback_list() : - m_lock(), - m_pStorage((void*)new std::vector) -{ -} - -callback_list::callback_list(const callback_list& rSrc) : - m_lock(), - m_pStorage((void*)new std::vector) -{ - STORAGE->assign(((std::vector*)rSrc.m_pStorage)->begin(), ((std::vector*)rSrc.m_pStorage)->end()); - assert(false); // we should not use the copy constructor at all !!! -} - -callback_list::~callback_list() -{ - try - { - delete STORAGE; - } - catch(...) - { - - } -} - -const callback_list& callback_list::operator=(const callback_list& rSrc) -{ - assert(false); // we shouldn't use the assignment operator at all!!! - if (this != &rSrc) - { - delete STORAGE; - m_pStorage=(void*)new std::vector; - STORAGE->assign(((std::vector*)rSrc.m_pStorage)->begin(), ((std::vector*)rSrc.m_pStorage)->end()); - } - - return *this; -} - -void callback_list::add(PFNFUNC pfn, ptr_t param) -{ - m_lock.lock(); - CLBDATA clb = { pfn, param }; - STORAGE->push_back(clb); - m_lock.unlock(); -} - -bool callback_list::remove(PFNFUNC pfn) -{ - m_lock.lock(); - for (std::vector::iterator it=STORAGE->begin();it != STORAGE->end();it++) - { - if ((*it).pfn == pfn) - { - STORAGE->erase(it); - m_lock.unlock(); - return true; - } - } - - m_lock.unlock(); - return false; -} - -void callback_list::clear() -{ - m_lock.lock(); - STORAGE->clear(); - m_lock.unlock(); -} - -size_t callback_list::size() -{ - m_lock.lock(); - size_t tSize=STORAGE->size(); - m_lock.unlock(); - - return tSize; -} - -CLBDATA* callback_list::at(size_t tIndex) -{ - CLBDATA* pData=NULL; - m_lock.lock(); - if (tIndex < STORAGE->size()) - pData=&(STORAGE->at(tIndex)); - m_lock.unlock(); - - return pData; -} - -void callback_list::lock() -{ - m_lock.lock(); -} - -void callback_list::unlock() -{ - m_lock.unlock(); -} - - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/callback.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/callback.h (revision 0) +++ ext/libicpf/src/libicpf/callback.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,264 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __CALLBACK_H__ +#define __CALLBACK_H__ + +/** \file callback.h + * \brief Provides callback classes + */ + +#include "libicpf.h" +#include "gen_types.h" +#include +#include "mutex.h" + +BEGIN_ICPF_NAMESPACE + +/// General function definition +#ifdef _WIN32 + typedef void(__stdcall *PFNFUNC)(void); +#else + typedef void(*PFNFUNC)(void); +#endif + +/// Helper structure for callback class +struct LIBICPF_API CLBDATA +{ + PFNFUNC pfn; ///< General function definition + ptr_t param; +}; + +class LIBICPF_API callback_list +{ +public: +/** \name Construction/destruction */ +/**@{*/ + callback_list(); + callback_list(const callback_list& rSrc); + virtual ~callback_list(); +/**@}*/ + + void add(PFNFUNC pfn, ptr_t param); + bool remove(PFNFUNC pfn); + void clear(); + size_t size(); + CLBDATA* at(size_t tIndex); + + void lock(); + void unlock(); + + const callback_list& operator=(const callback_list& rSrc); + +protected: + icpf::mutex m_lock; ///< A locking mechanism for the storage area + +private: + void* m_pStorage; ///< A pointer to a storage struct (a std::list probably), but must be inaccessible from outside +}; + +/** \brief Callback class with one parameter. + * + * Class provides a simple interface for user to call a specific callback + * function(s) registered by the user. Good for notifying user that something + * had happened. + */ +template +class /*LIBICPF_API*/ callback1 : public callback_list +{ +protected: + /// Callback1-type callback function +#ifdef _WIN32 + typedef R(__stdcall *PFNCALLBACKPROC1)(ptr_t, P1); +#else + typedef R(*PFNCALLBACKPROC1)(ptr_t, P1); +#endif + +public: +/** \name Construction/destruction */ +/**@{*/ + callback1() : callback_list() { }; ///< Standard constructor + virtual ~callback1() { }; ///< Standard destructor +/**@}*/ + +/** \name User interface */ +/**@{*/ + /** Executes a callback list associated with this object. + * \param[in] data - parameter that will be passed to a user callback function + */ + void exec(P1 data) + { + m_lock.lock(); + CLBDATA* pData; + for (size_t i=0;i != size();i++) + { + pData=at(i); + if (pData) + (*(PFNCALLBACKPROC1)(pData->pfn))(pData->param, data); + } + m_lock.unlock(); + } + + /** Connects a user callback function to this object. + * \param[in] pfn - user callback function address + * \param[in] appParam - user parameter to pass to the callback function when executing + */ + void connect(PFNCALLBACKPROC1 pfn, ptr_t appParam) + { + add((PFNFUNC)pfn, appParam); + } + + /** Disconnects the user callback function if connected earlier. + * \param[in] pfn - address of a function to remove + */ + void disconnect(PFNCALLBACKPROC1 pfn) + { + remove((PFNFUNC)pfn); + } +/**@}*/ +}; + +/** \brief Callback class with two parameters. + * + * Class provides a simple interface for user to call a specific callback + * function(s) registered by the user. Good for notifying user that something + * had happened. + */ +template +class /*LIBICPF_API*/ callback2 : public callback_list +{ +protected: + /// Callback2-type callback function +#ifdef _WIN32 + typedef R(__stdcall *PFNCALLBACKPROC2)(ptr_t, P1, P2); +#else + typedef R(*PFNCALLBACKPROC2)(ptr_t, P1, P2); +#endif + +public: +/** \name Construction/destruction */ +/**@{*/ + callback2() : callback_list() { }; ///< Standard constructor + virtual ~callback2() { }; ///< Standard destructor +/**@}*/ + +/** \name User interface */ +/**@{*/ + /** Executes a callback list associated with this object. + * \param[in] data1 - parameter that will be passed to a user callback function + * \param[in] data2 - parameter that will be passed to a user callback function + */ + void exec(P1 data1, P2 data2) + { + m_lock.lock(); + CLBDATA* pData; + for (size_t i=0;i != size();i++) + { + pData=at(i); + if (pData) + (*(PFNCALLBACKPROC2)(pData->pfn))(pData->param, data1, data2); + } + m_lock.unlock(); + } + + /** Connects a user callback function to this object. + * \param[in] pfn - user callback function address + * \param[in] appParam - user parameter to pass to the callback function when executing + */ + void connect(PFNCALLBACKPROC2 pfn, ptr_t appParam) + { + add((PFNFUNC)pfn, appParam); + } + + /** Disconnects the user callback function if connected earlier. + * \param[in] pfn - address of a function to remove + */ + void disconnect(PFNCALLBACKPROC2 pfn) + { + remove((PFNFUNC)pfn); + } +/**@}*/ +}; + +/** \brief Callback class with three parameters. + * + * Class provides a simple interface for user to call a specific callback + * function(s) registered by the user. Good for notifying user that something + * had happened. + */ +template +class /*LIBICPF_API*/ callback3 : public callback_list +{ +protected: + /// Callback2-type callback function +#ifdef _WIN32 + typedef R(__stdcall *PFNCALLBACKPROC3)(ptr_t, P1, P2, P3); +#else + typedef R(*PFNCALLBACKPROC3)(ptr_t, P1, P2, P3); +#endif + +public: +/** \name Construction/destruction */ +/**@{*/ + callback3() : callback_list() { }; ///< Standard constructor + virtual ~callback3() { }; ///< Standard destructor +/**@}*/ + +/** \name User interface */ +/**@{*/ + /** Executes a callback list associated with this object. + * \param[in] data1 - parameter that will be passed to a user callback function + * \param[in] data2 - parameter that will be passed to a user callback function + * \param[in] data3 - parameter that will be passed to a user callback function + */ + void exec(P1 data1, P2 data2, P3 data3) + { + m_lock.lock(); + CLBDATA* pData; + for (size_t i=0;i != size();i++) + { + pData=at(i); + if (pData) + (*(PFNCALLBACKPROC3)(pData->pfn))(pData->param, data1, data2, data3); + } + m_lock.unlock(); + } + + /** Connects a user callback function to this object. + * \param[in] pfn - user callback function address + * \param[in] appParam - user parameter to pass to the callback function when executing + */ + void connect(PFNCALLBACKPROC3 pfn, ptr_t appParam) + { + add((PFNFUNC)pfn, appParam); + } + + /** Disconnects the user callback function if connected earlier. + * \param[in] pfn - address of a function to remove + */ + void disconnect(PFNCALLBACKPROC3 pfn) + { + remove((PFNFUNC)pfn); + } +/**@}*/ +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/callback.h =================================================================== diff -u -N --- ext/libicpf/src/callback.h (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/callback.h (revision 0) @@ -1,264 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef __CALLBACK_H__ -#define __CALLBACK_H__ - -/** \file callback.h - * \brief Provides callback classes - */ - -#include "libicpf.h" -#include "gen_types.h" -#include -#include "mutex.h" - -BEGIN_ICPF_NAMESPACE - -/// General function definition -#ifdef _WIN32 - typedef void(__stdcall *PFNFUNC)(void); -#else - typedef void(*PFNFUNC)(void); -#endif - -/// Helper structure for callback class -struct LIBICPF_API CLBDATA -{ - PFNFUNC pfn; ///< General function definition - ptr_t param; -}; - -class LIBICPF_API callback_list -{ -public: -/** \name Construction/destruction */ -/**@{*/ - callback_list(); - callback_list(const callback_list& rSrc); - virtual ~callback_list(); -/**@}*/ - - void add(PFNFUNC pfn, ptr_t param); - bool remove(PFNFUNC pfn); - void clear(); - size_t size(); - CLBDATA* at(size_t tIndex); - - void lock(); - void unlock(); - - const callback_list& operator=(const callback_list& rSrc); - -protected: - icpf::mutex m_lock; ///< A locking mechanism for the storage area - -private: - void* m_pStorage; ///< A pointer to a storage struct (a std::list probably), but must be inaccessible from outside -}; - -/** \brief Callback class with one parameter. - * - * Class provides a simple interface for user to call a specific callback - * function(s) registered by the user. Good for notifying user that something - * had happened. - */ -template -class /*LIBICPF_API*/ callback1 : public callback_list -{ -protected: - /// Callback1-type callback function -#ifdef _WIN32 - typedef R(__stdcall *PFNCALLBACKPROC1)(ptr_t, P1); -#else - typedef R(*PFNCALLBACKPROC1)(ptr_t, P1); -#endif - -public: -/** \name Construction/destruction */ -/**@{*/ - callback1() : callback_list() { }; ///< Standard constructor - virtual ~callback1() { }; ///< Standard destructor -/**@}*/ - -/** \name User interface */ -/**@{*/ - /** Executes a callback list associated with this object. - * \param[in] data - parameter that will be passed to a user callback function - */ - void exec(P1 data) - { - m_lock.lock(); - CLBDATA* pData; - for (size_t i=0;i != size();i++) - { - pData=at(i); - if (pData) - (*(PFNCALLBACKPROC1)(pData->pfn))(pData->param, data); - } - m_lock.unlock(); - } - - /** Connects a user callback function to this object. - * \param[in] pfn - user callback function address - * \param[in] appParam - user parameter to pass to the callback function when executing - */ - void connect(PFNCALLBACKPROC1 pfn, ptr_t appParam) - { - add((PFNFUNC)pfn, appParam); - } - - /** Disconnects the user callback function if connected earlier. - * \param[in] pfn - address of a function to remove - */ - void disconnect(PFNCALLBACKPROC1 pfn) - { - remove((PFNFUNC)pfn); - } -/**@}*/ -}; - -/** \brief Callback class with two parameters. - * - * Class provides a simple interface for user to call a specific callback - * function(s) registered by the user. Good for notifying user that something - * had happened. - */ -template -class /*LIBICPF_API*/ callback2 : public callback_list -{ -protected: - /// Callback2-type callback function -#ifdef _WIN32 - typedef R(__stdcall *PFNCALLBACKPROC2)(ptr_t, P1, P2); -#else - typedef R(*PFNCALLBACKPROC2)(ptr_t, P1, P2); -#endif - -public: -/** \name Construction/destruction */ -/**@{*/ - callback2() : callback_list() { }; ///< Standard constructor - virtual ~callback2() { }; ///< Standard destructor -/**@}*/ - -/** \name User interface */ -/**@{*/ - /** Executes a callback list associated with this object. - * \param[in] data1 - parameter that will be passed to a user callback function - * \param[in] data2 - parameter that will be passed to a user callback function - */ - void exec(P1 data1, P2 data2) - { - m_lock.lock(); - CLBDATA* pData; - for (size_t i=0;i != size();i++) - { - pData=at(i); - if (pData) - (*(PFNCALLBACKPROC2)(pData->pfn))(pData->param, data1, data2); - } - m_lock.unlock(); - } - - /** Connects a user callback function to this object. - * \param[in] pfn - user callback function address - * \param[in] appParam - user parameter to pass to the callback function when executing - */ - void connect(PFNCALLBACKPROC2 pfn, ptr_t appParam) - { - add((PFNFUNC)pfn, appParam); - } - - /** Disconnects the user callback function if connected earlier. - * \param[in] pfn - address of a function to remove - */ - void disconnect(PFNCALLBACKPROC2 pfn) - { - remove((PFNFUNC)pfn); - } -/**@}*/ -}; - -/** \brief Callback class with three parameters. - * - * Class provides a simple interface for user to call a specific callback - * function(s) registered by the user. Good for notifying user that something - * had happened. - */ -template -class /*LIBICPF_API*/ callback3 : public callback_list -{ -protected: - /// Callback2-type callback function -#ifdef _WIN32 - typedef R(__stdcall *PFNCALLBACKPROC3)(ptr_t, P1, P2, P3); -#else - typedef R(*PFNCALLBACKPROC3)(ptr_t, P1, P2, P3); -#endif - -public: -/** \name Construction/destruction */ -/**@{*/ - callback3() : callback_list() { }; ///< Standard constructor - virtual ~callback3() { }; ///< Standard destructor -/**@}*/ - -/** \name User interface */ -/**@{*/ - /** Executes a callback list associated with this object. - * \param[in] data1 - parameter that will be passed to a user callback function - * \param[in] data2 - parameter that will be passed to a user callback function - * \param[in] data3 - parameter that will be passed to a user callback function - */ - void exec(P1 data1, P2 data2, P3 data3) - { - m_lock.lock(); - CLBDATA* pData; - for (size_t i=0;i != size();i++) - { - pData=at(i); - if (pData) - (*(PFNCALLBACKPROC3)(pData->pfn))(pData->param, data1, data2, data3); - } - m_lock.unlock(); - } - - /** Connects a user callback function to this object. - * \param[in] pfn - user callback function address - * \param[in] appParam - user parameter to pass to the callback function when executing - */ - void connect(PFNCALLBACKPROC3 pfn, ptr_t appParam) - { - add((PFNFUNC)pfn, appParam); - } - - /** Disconnects the user callback function if connected earlier. - * \param[in] pfn - address of a function to remove - */ - void disconnect(PFNCALLBACKPROC3 pfn) - { - remove((PFNFUNC)pfn); - } -/**@}*/ -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/cfg.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/cfg.cpp (revision 0) +++ ext/libicpf/src/libicpf/cfg.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,648 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file cfg.cpp + * \brief A placeholder for config class definitions. + * \todo Modify the class to use file class as a file access layer. + */ + +#include "cfg.h" +#include +#include "exception.h" +#include +#include + +BEGIN_ICPF_NAMESPACE + +////////////////////////////////////////////////////////////////////////////////// +// property_tracker class +#define m_psProperties ((std::set*)m_hProperties) + +/** Constructs the property_tracker object. + */ +property_tracker::property_tracker() : + m_hProperties((ptr_t)new std::set) +{ +} + +/** Constructs the property_tracker by copying data from source object. + * + * \param[in] rSrc - source property tracker + */ +property_tracker::property_tracker(const property_tracker& rSrc) : + m_hProperties((ptr_t)new std::set(*(std::set*)rSrc.m_hProperties)) +{ + +} + +/** Destructs the property tracker object. + */ +property_tracker::~property_tracker() +{ + delete m_psProperties; +} + +/** Function adds a new property id to the group. + * + * \param[in] uiProp - id of a property to add + */ +void property_tracker::add(uint_t uiProp) +{ + m_psProperties->insert(uiProp); +} + +/** Function searches for a specific property id inside the list. + * + * \param[in] uiProp - property id to check for + * \return True if the property has been found, false if not. + */ +bool property_tracker::is_set(uint_t uiProp) +{ + return m_psProperties->find(uiProp) != m_psProperties->end(); +} + +/** Function returns a count of properties contained in the list. + * + * \return A count of id's. + */ +size_t property_tracker::count() const +{ + return m_psProperties->size(); +} + +/** Function retrieves the id's contained in this tracker by copying + * them to the given array. + * + * \param[out] puiProps - pointer to the array of uint's to receive id's + * \param[in] stMaxCount - size of the array (max count of elements to retrieve) + */ +size_t property_tracker::get_ids(uint_t* puiProps, size_t stMaxCount) +{ + size_t tIndex=0; + for (std::set::iterator it=m_psProperties->begin();it != m_psProperties->end();it++) + { + puiProps[tIndex++]=(*it); + if (tIndex >= stMaxCount) + break; + } + + return tIndex; +} + +/** Function enumerates id's contained in this property_tracker using + * a callback function. + * + * \param[in] pfn - function to be called + * \param[in] pParam - parameter to pass to the callback + */ +void property_tracker::enum_ids(bool(*pfn)(uint_t uiProp, ptr_t pParam), ptr_t pParam) +{ + for (std::set::iterator it=m_psProperties->begin();it != m_psProperties->end();it++) + { + if (!(*pfn)((*it), pParam)) + break; + } +} + +///////////////////////////////////////////////////////////////////////////////////// +// config class + +#define m_pvProps ((std::vector*)m_hProps) + +/** Constructs a config object. + * \param[in] pCfgBase - pointer to a base handler of the configuration strings + * cound be pointer to xml handler, ini handler or any other + */ +config::config(config_base* pCfgBase) : + m_lock(), + m_hProps((ptr_t)new std::vector), + m_pCfgBase(pCfgBase) +{ +} + +/** Destructs the config class. + */ +config::~config() +{ + delete m_pvProps; +} + +/** Function opens the specified file using the underlying config base + * and converts the values read to a list of properties registered + * earlier. + * + * \param[in] pszPath - path to a file to be read + */ +void config::read(const tchar_t* pszPath) +{ + m_lock.lock(); + try + { + // read the data using underlying object + m_pCfgBase->read(pszPath); + + // and transform it to eatable form using registered properties + load_registered(); + } + catch(...) + { + m_lock.unlock(); + throw; + } + m_lock.unlock(); +} + +/** Writes all the registered properties into the given file using + * the underlying config base to do this. + * + * \param[in] pszPath - path to a file to write the properties to + */ +void config::write(const tchar_t* pszPath) +{ + m_lock.lock(); + + try + { + // store current properties to the underlying object + store_registered(); + + // and save + m_pCfgBase->save(pszPath); + } + catch(...) + { + m_lock.unlock(); + throw; + } + + m_lock.unlock(); +} + +/** Function returns a property type for a given property id. + * + * \param[in] uiProp - property id to get info about + * \return The property type along with its flags. + */ +uint_t config::get_type(uint_t uiProp) +{ + m_lock.lock(); + uint_t uiRet=m_pvProps->at(uiProp).get_type(); + m_lock.unlock(); + + return uiRet; +} + +/** Retrieves the count of values in the specified property. + * + * \param[in] uiProp - property id to retrieve information about + * \return Count of values. + */ +size_t config::get_value_count(uint_t uiProp) +{ + m_lock.lock(); + size_t stRet=m_pvProps->at(uiProp).get_count(); + m_lock.unlock(); + + return stRet; +} + +/** Removes an array value at a given index. + * + * \param[in] uiProp - property id to have the value removed + * \param[in] stIndex - index of the value to remove + */ +void config::remove_array_value(uint_t uiProp, size_t stIndex) +{ + m_lock.lock(); + m_pvProps->at(uiProp).remove(stIndex); + m_lock.unlock(); +} + +/** Clears the list of values in the given property. + * + * \param[in] uiProp - property id to have the values cleared + */ +void config::clear_array_values(uint_t uiProp) +{ + m_lock.lock(); + m_pvProps->at(uiProp).clear_array(); + m_lock.unlock(); +} + +/** Retrieves the count of registered properties contained in this config. + * + * \return Count of properties. + */ +size_t config::count() +{ + return m_pvProps->size(); +} + +/** Function registers the signed number property. If the underlying base object + * contains a string with a specified key - the value is being translated to + * the value of this property. + * + * \param[in] pszName - name of the property + * \param[in] llDef - default value for the property + * \param[in] llLo - the lower bound of the allowable value range + * \param[in] llHi - the higher bound of the allowable value range + * \param[in] uiFlags - additional flags that should be associated with property + * \return Property ID of the newly registered property. + */ +uint_t config::register_signed_num(const tchar_t* pszName, ll_t llDef, ll_t llLo, ll_t llHi, uint_t uiFlags) +{ + // prepare the property to insert + property prop(pszName, property::type_signed_num | (uiFlags & property::mask_flags)); + prop.set_signed_range(llLo, llHi); + + // and operate inside the internals + m_lock.lock(); + + // get the value for the property name + ptr_t hFind=NULL; + if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) + { + const tchar_t* psz=NULL; + while( (psz=m_pCfgBase->find_next(hFind)) != NULL) + { + prop.set_value(psz, property::action_add); + } + + m_pCfgBase->find_close(hFind); + } + else if (!(uiFlags & property::flag_array)) + prop.set_signed_num(llDef); + + // add to the vector + m_pvProps->push_back(prop); + uint_t uiProp=(uint_t)(m_pvProps->size()-1); + + m_lock.unlock(); + + return uiProp; +} + +/** Function registers the unsigned number property. If the underlying base object + * contains a string with a specified key - the value is being translated to + * the value of this property. + * + * \param[in] pszName - name of the property + * \param[in] ullDef - default value for the property + * \param[in] ullLo - the lower bound of the allowable value range + * \param[in] ullHi - the higher bound of the allowable value range + * \param[in] uiFlags - additional flags that should be associated with property + * \return Property ID of the newly registered property. + */ +uint_t config::register_unsigned_num(const tchar_t* pszName, ull_t ullDef, ull_t ullLo, ull_t ullHi, uint_t uiFlags) +{ + // prepare the property to insert + property prop(pszName, property::type_unsigned_num | (uiFlags & property::mask_flags)); + prop.set_unsigned_range(ullLo, ullHi); + + // and operate inside the internals + m_lock.lock(); + + // get the value for the property name + ptr_t hFind=NULL; + if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) + { + const tchar_t* psz=NULL; + while( (psz=m_pCfgBase->find_next(hFind)) != NULL) + { + prop.set_value(psz, property::action_add); + } + + m_pCfgBase->find_close(hFind); + } + else if (!(uiFlags & property::flag_array)) + prop.set_unsigned_num(ullDef); + + // add to the vector + m_pvProps->push_back(prop); + uint_t uiProp=(uint_t)(m_pvProps->size()-1); + + m_lock.unlock(); + + return uiProp; +} + +/** Function registers the boolean property. If the underlying base object + * contains a string with a specified key - the value is being translated to + * the value of this property. + * + * \param[in] pszName - name of the property + * \param[in] bDef - default value for the property + * \param[in] uiFlags - additional flags that should be associated with property + * \return Property ID of the newly registered property. + */ +uint_t config::register_bool(const tchar_t* pszName, bool bDef, uint_t uiFlags) +{ + // prepare the property to insert + property prop(pszName, property::type_bool | (uiFlags & property::mask_flags)); + + // and operate inside the internals + m_lock.lock(); + + // get the value for the property name + ptr_t hFind=NULL; + if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) + { + const tchar_t* psz=NULL; + while( (psz=m_pCfgBase->find_next(hFind)) != NULL) + { + prop.set_value(psz, property::action_add); + } + + m_pCfgBase->find_close(hFind); + } + else if (!(uiFlags & property::flag_array)) + prop.set_bool(bDef); + + // add to the vector + m_pvProps->push_back(prop); + uint_t uiProp=(uint_t)(m_pvProps->size()-1); + + m_lock.unlock(); + + return uiProp; +} + +/** Function registers the string property. If the underlying base object + * contains a string with a specified key - the value is being translated to + * the value of this property. + * + * \param[in] pszName - name of the property + * \param[in] pszDef - default value for the property + * \param[in] uiFlags - additional flags that should be associated with property + * \return Property ID of the newly registered property. + */ +uint_t config::register_string(const tchar_t* pszName, const tchar_t* pszDef, uint_t uiFlags) +{ + // prepare the property to insert + property prop(pszName, property::type_string | (uiFlags & property::mask_flags)); + + // and operate inside the internals + m_lock.lock(); + + // get the value for the property name + ptr_t hFind=NULL; + if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) + { + const tchar_t* psz=NULL; + while( (psz=m_pCfgBase->find_next(hFind)) != NULL) + { + prop.set_value(psz, property::action_add); + } + + m_pCfgBase->find_close(hFind); + } + else if (!(uiFlags & property::flag_array)) + prop.set_string(pszDef); + + // add to the vector + m_pvProps->push_back(prop); + uint_t uiProp=(uint_t)(m_pvProps->size()-1); + + m_lock.unlock(); + + return uiProp; +} + +/** Function retrieves the value as string. + * + * \param[in] uiProp - property to retrieve the value of + * \param[out] pszBuffer - pointer to a buffer to receive the string (unused + * if retrieving a string value) + * \param[in] stMaxSize - size of the buffer + * \param[in] stIndex - index of the value to retrieve (meaningful only for + * array-based properties) + * \return Pointer to the string. + * + * \note Always use the returned value instead of the buffer contents. Returned + * value may point to some other memory location instead of pszBuffer. + */ +const tchar_t* config::get_value(uint_t uiProp, tchar_t* pszBuffer, size_t stMaxSize, size_t stIndex) +{ + m_lock.lock(); + const tchar_t* psz=m_pvProps->at(uiProp).get_value(pszBuffer, stMaxSize, stIndex); + m_lock.unlock(); + + return psz; +} + +/** Function retrieves the signed number value. + * + * \param[in] uiProp - property to retrieve the value of + * \param[in] stIndex - index of the value to retrieve (meaningful only for + * array-based properties) + * \return Property value. + */ +ll_t config::get_signed_num(uint_t uiProp, size_t stIndex) +{ + m_lock.lock(); + ll_t ll=m_pvProps->at(uiProp).get_signed_num(stIndex); + m_lock.unlock(); + return ll; +} + +/** Function retrieves the unsigned number value. + * + * \param[in] uiProp - property to retrieve the value of + * \param[in] stIndex - index of the value to retrieve (meaningful only for + * array-based properties) + * \return Property value. + */ +ull_t config::get_unsigned_num(uint_t uiProp, size_t stIndex) +{ + m_lock.lock(); + ull_t ull=m_pvProps->at(uiProp).get_unsigned_num(stIndex); + m_lock.unlock(); + return ull; +} + +/** Function retrieves the bool value. + * + * \param[in] uiProp - property to retrieve the value of + * \param[in] stIndex - index of the value to retrieve (meaningful only for + * array-based properties) + * \return Property value. + */ +bool config::get_bool(uint_t uiProp, size_t stIndex) +{ + m_lock.lock(); + bool b=m_pvProps->at(uiProp).get_bool(stIndex); + m_lock.unlock(); + return b; +} + +/** Function retrieves the string value. + * + * \param[in] uiProp - property to retrieve the value of + * \param[in] stIndex - index of the value to retrieve (meaningful only for + * array-based properties) + * \return Property value. + */ +const tchar_t* config::get_string(uint_t uiProp, size_t stIndex) +{ + m_lock.lock(); + const tchar_t* psz=m_pvProps->at(uiProp).get_string(stIndex); + m_lock.unlock(); + return psz; +} + +/** Function sets the property value from string. + * + * \param[in] uiProp - property id to set the value for + * \param[in] pszVal - string with property value + * \param[in] a - action to take if the property is array based + * \param[in] tIndex - index of a value to set at (for action action_setat) + * \param[out] pTracker - property tracker that collects the property ID's + */ +void config::set_value(uint_t uiProp, const tchar_t* pszVal, property::actions a, size_t tIndex, property_tracker* pTracker) +{ + m_lock.lock(); + m_pvProps->at(uiProp).set_value(pszVal, a, tIndex); + if (pTracker) + pTracker->add(uiProp); + m_lock.unlock(); +} + +/** Function sets the signed number property value. + * + * \param[in] uiProp - property id to set the value for + * \param[in] llVal - property value to set + * \param[in] a - action to take if the property is array based + * \param[in] tIndex - index of a value to set at (for action action_setat) + * \param[out] pTracker - property tracker that collects the property ID's + */ +void config::set_signed_num(uint_t uiProp, ll_t llVal, property::actions a, size_t tIndex, property_tracker* pTracker) +{ + m_lock.lock(); + m_pvProps->at(uiProp).set_signed_num(llVal, a, tIndex); + if (pTracker) + pTracker->add(uiProp); + m_lock.unlock(); +} + +/** Function sets the unsigned number property value. + * + * \param[in] uiProp - property id to set the value for + * \param[in] llVal - property value to set + * \param[in] a - action to take if the property is array based + * \param[in] tIndex - index of a value to set at (for action action_setat) + * \param[out] pTracker - property tracker that collects the property ID's + */ +void config::set_unsigned_num(uint_t uiProp, ull_t ullVal, property::actions a, size_t tIndex, property_tracker* pTracker) +{ + m_lock.lock(); + m_pvProps->at(uiProp).set_unsigned_num(ullVal, a, tIndex); + if (pTracker) + pTracker->add(uiProp); + m_lock.unlock(); +} + +/** Function sets the bool property value. + * + * \param[in] uiProp - property id to set the value for + * \param[in] llVal - property value to set + * \param[in] a - action to take if the property is array based + * \param[in] tIndex - index of a value to set at (for action action_setat) + * \param[out] pTracker - property tracker that collects the property ID's + */ +void config::set_bool(uint_t uiProp, bool bVal, property::actions a, size_t tIndex, property_tracker* pTracker) +{ + m_lock.lock(); + m_pvProps->at(uiProp).set_bool(bVal, a, tIndex); + if (pTracker) + pTracker->add(uiProp); + m_lock.unlock(); +} + +/** Function sets the string property value. + * + * \param[in] uiProp - property id to set the value for + * \param[in] llVal - property value to set + * \param[in] a - action to take if the property is array based + * \param[in] tIndex - index of a value to set at (for action action_setat) + * \param[out] pTracker - property tracker that collects the property ID's + */ +void config::set_string(uint_t uiProp, const tchar_t* pszVal, property::actions a, size_t tIndex, property_tracker* pTracker) +{ + m_lock.lock(); + m_pvProps->at(uiProp).set_string(pszVal, a, tIndex); + if (pTracker) + pTracker->add(uiProp); + m_lock.unlock(); +} + +/** Function reads the values for the registered properties from the underlying + * base config object. + */ +void config::load_registered() +{ + m_lock.lock(); + + ptr_t hFind=NULL; + const tchar_t* psz=NULL; + for (std::vector::iterator it=m_pvProps->begin();it != m_pvProps->end();it++) + { + // is this an array property ? + if ((*it).is_array()) + (*it).clear_array(); + + // and fill with value(s) + if ( (hFind=m_pCfgBase->find((*it).get_name())) != NULL) + { + while( (psz=m_pCfgBase->find_next(hFind)) != NULL) + { + (*it).set_value(psz, property::action_add); + } + } + + m_pCfgBase->find_close(hFind); + } + + m_lock.unlock(); +} + +/** Function stores the values of a registered properties to the underlying + * base config object. + */ +void config::store_registered() +{ + m_lock.lock(); + + tchar_t szBuffer[128]; + for (std::vector::iterator it=m_pvProps->begin();it != m_pvProps->end();it++) + { + // clear the current attributes for the property + m_pCfgBase->clear((*it).get_name()); + + // and fill with value(s) + size_t tCount=(*it).get_count(); + for (size_t t=0;t != tCount;t++) + { + m_pCfgBase->set_value((*it).get_name(), (*it).get_value(szBuffer, 128, t));; + } + } + + m_lock.unlock(); +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/cfg.cpp =================================================================== diff -u -N --- ext/libicpf/src/cfg.cpp (revision 6dae57f5e7aeeb965bc018024d8360069f6e15c1) +++ ext/libicpf/src/cfg.cpp (revision 0) @@ -1,648 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file cfg.cpp - * \brief A placeholder for config class definitions. - * \todo Modify the class to use file class as a file access layer. - */ - -#include "cfg.h" -#include -#include "exception.h" -#include -#include - -BEGIN_ICPF_NAMESPACE - -////////////////////////////////////////////////////////////////////////////////// -// property_tracker class -#define m_psProperties ((std::set*)m_hProperties) - -/** Constructs the property_tracker object. - */ -property_tracker::property_tracker() : - m_hProperties((ptr_t)new std::set) -{ -} - -/** Constructs the property_tracker by copying data from source object. - * - * \param[in] rSrc - source property tracker - */ -property_tracker::property_tracker(const property_tracker& rSrc) : - m_hProperties((ptr_t)new std::set(*(std::set*)rSrc.m_hProperties)) -{ - -} - -/** Destructs the property tracker object. - */ -property_tracker::~property_tracker() -{ - delete m_psProperties; -} - -/** Function adds a new property id to the group. - * - * \param[in] uiProp - id of a property to add - */ -void property_tracker::add(uint_t uiProp) -{ - m_psProperties->insert(uiProp); -} - -/** Function searches for a specific property id inside the list. - * - * \param[in] uiProp - property id to check for - * \return True if the property has been found, false if not. - */ -bool property_tracker::is_set(uint_t uiProp) -{ - return m_psProperties->find(uiProp) != m_psProperties->end(); -} - -/** Function returns a count of properties contained in the list. - * - * \return A count of id's. - */ -size_t property_tracker::count() const -{ - return m_psProperties->size(); -} - -/** Function retrieves the id's contained in this tracker by copying - * them to the given array. - * - * \param[out] puiProps - pointer to the array of uint's to receive id's - * \param[in] stMaxCount - size of the array (max count of elements to retrieve) - */ -size_t property_tracker::get_ids(uint_t* puiProps, size_t stMaxCount) -{ - size_t tIndex=0; - for (std::set::iterator it=m_psProperties->begin();it != m_psProperties->end();it++) - { - puiProps[tIndex++]=(*it); - if (tIndex >= stMaxCount) - break; - } - - return tIndex; -} - -/** Function enumerates id's contained in this property_tracker using - * a callback function. - * - * \param[in] pfn - function to be called - * \param[in] pParam - parameter to pass to the callback - */ -void property_tracker::enum_ids(bool(*pfn)(uint_t uiProp, ptr_t pParam), ptr_t pParam) -{ - for (std::set::iterator it=m_psProperties->begin();it != m_psProperties->end();it++) - { - if (!(*pfn)((*it), pParam)) - break; - } -} - -///////////////////////////////////////////////////////////////////////////////////// -// config class - -#define m_pvProps ((std::vector*)m_hProps) - -/** Constructs a config object. - * \param[in] pCfgBase - pointer to a base handler of the configuration strings - * cound be pointer to xml handler, ini handler or any other - */ -config::config(config_base* pCfgBase) : - m_lock(), - m_hProps((ptr_t)new std::vector), - m_pCfgBase(pCfgBase) -{ -} - -/** Destructs the config class. - */ -config::~config() -{ - delete m_pvProps; -} - -/** Function opens the specified file using the underlying config base - * and converts the values read to a list of properties registered - * earlier. - * - * \param[in] pszPath - path to a file to be read - */ -void config::read(const tchar_t* pszPath) -{ - m_lock.lock(); - try - { - // read the data using underlying object - m_pCfgBase->read(pszPath); - - // and transform it to eatable form using registered properties - load_registered(); - } - catch(...) - { - m_lock.unlock(); - throw; - } - m_lock.unlock(); -} - -/** Writes all the registered properties into the given file using - * the underlying config base to do this. - * - * \param[in] pszPath - path to a file to write the properties to - */ -void config::write(const tchar_t* pszPath) -{ - m_lock.lock(); - - try - { - // store current properties to the underlying object - store_registered(); - - // and save - m_pCfgBase->save(pszPath); - } - catch(...) - { - m_lock.unlock(); - throw; - } - - m_lock.unlock(); -} - -/** Function returns a property type for a given property id. - * - * \param[in] uiProp - property id to get info about - * \return The property type along with its flags. - */ -uint_t config::get_type(uint_t uiProp) -{ - m_lock.lock(); - uint_t uiRet=m_pvProps->at(uiProp).get_type(); - m_lock.unlock(); - - return uiRet; -} - -/** Retrieves the count of values in the specified property. - * - * \param[in] uiProp - property id to retrieve information about - * \return Count of values. - */ -size_t config::get_value_count(uint_t uiProp) -{ - m_lock.lock(); - size_t stRet=m_pvProps->at(uiProp).get_count(); - m_lock.unlock(); - - return stRet; -} - -/** Removes an array value at a given index. - * - * \param[in] uiProp - property id to have the value removed - * \param[in] stIndex - index of the value to remove - */ -void config::remove_array_value(uint_t uiProp, size_t stIndex) -{ - m_lock.lock(); - m_pvProps->at(uiProp).remove(stIndex); - m_lock.unlock(); -} - -/** Clears the list of values in the given property. - * - * \param[in] uiProp - property id to have the values cleared - */ -void config::clear_array_values(uint_t uiProp) -{ - m_lock.lock(); - m_pvProps->at(uiProp).clear_array(); - m_lock.unlock(); -} - -/** Retrieves the count of registered properties contained in this config. - * - * \return Count of properties. - */ -size_t config::count() -{ - return m_pvProps->size(); -} - -/** Function registers the signed number property. If the underlying base object - * contains a string with a specified key - the value is being translated to - * the value of this property. - * - * \param[in] pszName - name of the property - * \param[in] llDef - default value for the property - * \param[in] llLo - the lower bound of the allowable value range - * \param[in] llHi - the higher bound of the allowable value range - * \param[in] uiFlags - additional flags that should be associated with property - * \return Property ID of the newly registered property. - */ -uint_t config::register_signed_num(const tchar_t* pszName, ll_t llDef, ll_t llLo, ll_t llHi, uint_t uiFlags) -{ - // prepare the property to insert - property prop(pszName, property::type_signed_num | (uiFlags & property::mask_flags)); - prop.set_signed_range(llLo, llHi); - - // and operate inside the internals - m_lock.lock(); - - // get the value for the property name - ptr_t hFind=NULL; - if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) - { - const tchar_t* psz=NULL; - while( (psz=m_pCfgBase->find_next(hFind)) != NULL) - { - prop.set_value(psz, property::action_add); - } - - m_pCfgBase->find_close(hFind); - } - else if (!(uiFlags & property::flag_array)) - prop.set_signed_num(llDef); - - // add to the vector - m_pvProps->push_back(prop); - uint_t uiProp=(uint_t)(m_pvProps->size()-1); - - m_lock.unlock(); - - return uiProp; -} - -/** Function registers the unsigned number property. If the underlying base object - * contains a string with a specified key - the value is being translated to - * the value of this property. - * - * \param[in] pszName - name of the property - * \param[in] ullDef - default value for the property - * \param[in] ullLo - the lower bound of the allowable value range - * \param[in] ullHi - the higher bound of the allowable value range - * \param[in] uiFlags - additional flags that should be associated with property - * \return Property ID of the newly registered property. - */ -uint_t config::register_unsigned_num(const tchar_t* pszName, ull_t ullDef, ull_t ullLo, ull_t ullHi, uint_t uiFlags) -{ - // prepare the property to insert - property prop(pszName, property::type_unsigned_num | (uiFlags & property::mask_flags)); - prop.set_unsigned_range(ullLo, ullHi); - - // and operate inside the internals - m_lock.lock(); - - // get the value for the property name - ptr_t hFind=NULL; - if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) - { - const tchar_t* psz=NULL; - while( (psz=m_pCfgBase->find_next(hFind)) != NULL) - { - prop.set_value(psz, property::action_add); - } - - m_pCfgBase->find_close(hFind); - } - else if (!(uiFlags & property::flag_array)) - prop.set_unsigned_num(ullDef); - - // add to the vector - m_pvProps->push_back(prop); - uint_t uiProp=(uint_t)(m_pvProps->size()-1); - - m_lock.unlock(); - - return uiProp; -} - -/** Function registers the boolean property. If the underlying base object - * contains a string with a specified key - the value is being translated to - * the value of this property. - * - * \param[in] pszName - name of the property - * \param[in] bDef - default value for the property - * \param[in] uiFlags - additional flags that should be associated with property - * \return Property ID of the newly registered property. - */ -uint_t config::register_bool(const tchar_t* pszName, bool bDef, uint_t uiFlags) -{ - // prepare the property to insert - property prop(pszName, property::type_bool | (uiFlags & property::mask_flags)); - - // and operate inside the internals - m_lock.lock(); - - // get the value for the property name - ptr_t hFind=NULL; - if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) - { - const tchar_t* psz=NULL; - while( (psz=m_pCfgBase->find_next(hFind)) != NULL) - { - prop.set_value(psz, property::action_add); - } - - m_pCfgBase->find_close(hFind); - } - else if (!(uiFlags & property::flag_array)) - prop.set_bool(bDef); - - // add to the vector - m_pvProps->push_back(prop); - uint_t uiProp=(uint_t)(m_pvProps->size()-1); - - m_lock.unlock(); - - return uiProp; -} - -/** Function registers the string property. If the underlying base object - * contains a string with a specified key - the value is being translated to - * the value of this property. - * - * \param[in] pszName - name of the property - * \param[in] pszDef - default value for the property - * \param[in] uiFlags - additional flags that should be associated with property - * \return Property ID of the newly registered property. - */ -uint_t config::register_string(const tchar_t* pszName, const tchar_t* pszDef, uint_t uiFlags) -{ - // prepare the property to insert - property prop(pszName, property::type_string | (uiFlags & property::mask_flags)); - - // and operate inside the internals - m_lock.lock(); - - // get the value for the property name - ptr_t hFind=NULL; - if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) - { - const tchar_t* psz=NULL; - while( (psz=m_pCfgBase->find_next(hFind)) != NULL) - { - prop.set_value(psz, property::action_add); - } - - m_pCfgBase->find_close(hFind); - } - else if (!(uiFlags & property::flag_array)) - prop.set_string(pszDef); - - // add to the vector - m_pvProps->push_back(prop); - uint_t uiProp=(uint_t)(m_pvProps->size()-1); - - m_lock.unlock(); - - return uiProp; -} - -/** Function retrieves the value as string. - * - * \param[in] uiProp - property to retrieve the value of - * \param[out] pszBuffer - pointer to a buffer to receive the string (unused - * if retrieving a string value) - * \param[in] stMaxSize - size of the buffer - * \param[in] stIndex - index of the value to retrieve (meaningful only for - * array-based properties) - * \return Pointer to the string. - * - * \note Always use the returned value instead of the buffer contents. Returned - * value may point to some other memory location instead of pszBuffer. - */ -const tchar_t* config::get_value(uint_t uiProp, tchar_t* pszBuffer, size_t stMaxSize, size_t stIndex) -{ - m_lock.lock(); - const tchar_t* psz=m_pvProps->at(uiProp).get_value(pszBuffer, stMaxSize, stIndex); - m_lock.unlock(); - - return psz; -} - -/** Function retrieves the signed number value. - * - * \param[in] uiProp - property to retrieve the value of - * \param[in] stIndex - index of the value to retrieve (meaningful only for - * array-based properties) - * \return Property value. - */ -ll_t config::get_signed_num(uint_t uiProp, size_t stIndex) -{ - m_lock.lock(); - ll_t ll=m_pvProps->at(uiProp).get_signed_num(stIndex); - m_lock.unlock(); - return ll; -} - -/** Function retrieves the unsigned number value. - * - * \param[in] uiProp - property to retrieve the value of - * \param[in] stIndex - index of the value to retrieve (meaningful only for - * array-based properties) - * \return Property value. - */ -ull_t config::get_unsigned_num(uint_t uiProp, size_t stIndex) -{ - m_lock.lock(); - ull_t ull=m_pvProps->at(uiProp).get_unsigned_num(stIndex); - m_lock.unlock(); - return ull; -} - -/** Function retrieves the bool value. - * - * \param[in] uiProp - property to retrieve the value of - * \param[in] stIndex - index of the value to retrieve (meaningful only for - * array-based properties) - * \return Property value. - */ -bool config::get_bool(uint_t uiProp, size_t stIndex) -{ - m_lock.lock(); - bool b=m_pvProps->at(uiProp).get_bool(stIndex); - m_lock.unlock(); - return b; -} - -/** Function retrieves the string value. - * - * \param[in] uiProp - property to retrieve the value of - * \param[in] stIndex - index of the value to retrieve (meaningful only for - * array-based properties) - * \return Property value. - */ -const tchar_t* config::get_string(uint_t uiProp, size_t stIndex) -{ - m_lock.lock(); - const tchar_t* psz=m_pvProps->at(uiProp).get_string(stIndex); - m_lock.unlock(); - return psz; -} - -/** Function sets the property value from string. - * - * \param[in] uiProp - property id to set the value for - * \param[in] pszVal - string with property value - * \param[in] a - action to take if the property is array based - * \param[in] tIndex - index of a value to set at (for action action_setat) - * \param[out] pTracker - property tracker that collects the property ID's - */ -void config::set_value(uint_t uiProp, const tchar_t* pszVal, property::actions a, size_t tIndex, property_tracker* pTracker) -{ - m_lock.lock(); - m_pvProps->at(uiProp).set_value(pszVal, a, tIndex); - if (pTracker) - pTracker->add(uiProp); - m_lock.unlock(); -} - -/** Function sets the signed number property value. - * - * \param[in] uiProp - property id to set the value for - * \param[in] llVal - property value to set - * \param[in] a - action to take if the property is array based - * \param[in] tIndex - index of a value to set at (for action action_setat) - * \param[out] pTracker - property tracker that collects the property ID's - */ -void config::set_signed_num(uint_t uiProp, ll_t llVal, property::actions a, size_t tIndex, property_tracker* pTracker) -{ - m_lock.lock(); - m_pvProps->at(uiProp).set_signed_num(llVal, a, tIndex); - if (pTracker) - pTracker->add(uiProp); - m_lock.unlock(); -} - -/** Function sets the unsigned number property value. - * - * \param[in] uiProp - property id to set the value for - * \param[in] llVal - property value to set - * \param[in] a - action to take if the property is array based - * \param[in] tIndex - index of a value to set at (for action action_setat) - * \param[out] pTracker - property tracker that collects the property ID's - */ -void config::set_unsigned_num(uint_t uiProp, ull_t ullVal, property::actions a, size_t tIndex, property_tracker* pTracker) -{ - m_lock.lock(); - m_pvProps->at(uiProp).set_unsigned_num(ullVal, a, tIndex); - if (pTracker) - pTracker->add(uiProp); - m_lock.unlock(); -} - -/** Function sets the bool property value. - * - * \param[in] uiProp - property id to set the value for - * \param[in] llVal - property value to set - * \param[in] a - action to take if the property is array based - * \param[in] tIndex - index of a value to set at (for action action_setat) - * \param[out] pTracker - property tracker that collects the property ID's - */ -void config::set_bool(uint_t uiProp, bool bVal, property::actions a, size_t tIndex, property_tracker* pTracker) -{ - m_lock.lock(); - m_pvProps->at(uiProp).set_bool(bVal, a, tIndex); - if (pTracker) - pTracker->add(uiProp); - m_lock.unlock(); -} - -/** Function sets the string property value. - * - * \param[in] uiProp - property id to set the value for - * \param[in] llVal - property value to set - * \param[in] a - action to take if the property is array based - * \param[in] tIndex - index of a value to set at (for action action_setat) - * \param[out] pTracker - property tracker that collects the property ID's - */ -void config::set_string(uint_t uiProp, const tchar_t* pszVal, property::actions a, size_t tIndex, property_tracker* pTracker) -{ - m_lock.lock(); - m_pvProps->at(uiProp).set_string(pszVal, a, tIndex); - if (pTracker) - pTracker->add(uiProp); - m_lock.unlock(); -} - -/** Function reads the values for the registered properties from the underlying - * base config object. - */ -void config::load_registered() -{ - m_lock.lock(); - - ptr_t hFind=NULL; - const tchar_t* psz=NULL; - for (std::vector::iterator it=m_pvProps->begin();it != m_pvProps->end();it++) - { - // is this an array property ? - if ((*it).is_array()) - (*it).clear_array(); - - // and fill with value(s) - if ( (hFind=m_pCfgBase->find((*it).get_name())) != NULL) - { - while( (psz=m_pCfgBase->find_next(hFind)) != NULL) - { - (*it).set_value(psz, property::action_add); - } - } - - m_pCfgBase->find_close(hFind); - } - - m_lock.unlock(); -} - -/** Function stores the values of a registered properties to the underlying - * base config object. - */ -void config::store_registered() -{ - m_lock.lock(); - - tchar_t szBuffer[128]; - for (std::vector::iterator it=m_pvProps->begin();it != m_pvProps->end();it++) - { - // clear the current attributes for the property - m_pCfgBase->clear((*it).get_name()); - - // and fill with value(s) - size_t tCount=(*it).get_count(); - for (size_t t=0;t != tCount;t++) - { - m_pCfgBase->set_value((*it).get_name(), (*it).get_value(szBuffer, 128, t));; - } - } - - m_lock.unlock(); -} - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/cfg.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/cfg.h (revision 0) +++ ext/libicpf/src/libicpf/cfg.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,159 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __CFG_H__ +#define __CFG_H__ + +/** \file cfg.h + * \brief A placeholder for config class. + */ +#include "mutex.h" +#include "libicpf.h" +#include "gen_types.h" +#include "config_base.h" +#include "config_property.h" + +BEGIN_ICPF_NAMESPACE + +/** \brief Property group handling class + * + * Class is being used to manipulate the property groups (in connection with config::begin_group() and + * config::end_group(). + */ +class LIBICPF_API property_tracker +{ +public: +/** \name Construction/destruction/operators */ +/**@{*/ + property_tracker(); ///< Standard constructor + property_tracker(const property_tracker& rSrc); ///< Copy constructor + ~property_tracker(); ///< Standard destructor + + property_tracker& operator=(const property_tracker& rSrc); ///< Assignment operator +/**@}*/ + +/** \name Operations */ +/**@{*/ + void add(uint_t uiProp); ///< Adds a new property id to the list + bool is_set(uint_t uiProp); ///< Checks if a property id is set inside this list + size_t count() const; ///< Returns a count of properties in a list + + /// Retrieves the list of ID's + size_t get_ids(uint_t* puiProps, size_t stMaxCount); + /// Retrieves the list of ID's using an enumeration function + void enum_ids(bool(*pfn)(uint_t uiProp, ptr_t pParam), ptr_t pParam); +/**@}*/ + +protected: + ptr_t m_hProperties; ///< Internal member. Pointer to a storage structure with an int_t. +}; + +/** \brief Configuration management class. + * + * Class allows user to read and write configuration file in standard unix + * format (comments, empty lines and key=value strings). Class is fully thread-safe. + * Access to the properties is done by registering one and then getting or setting + * a value using the property identifier. + */ +class LIBICPF_API config +{ +public: +/** \name Construction/destruction */ +/**@{*/ + config(config_base* pCfgBase); ///< Standard constructor + ~config(); ///< Standard destructor +/**@}*/ + +/** \name Reading and writing to the external medium */ +/**@{*/ + void read(const tchar_t *pszPath); ///< Reads the properties from the source file + void write(const tchar_t* pszPath); ///< Saves the properties to the file +/**@}*/ + +/** \name Class lock/unlock functions */ +/**@{*/ + /// Locks the config class for one thread + void lock() { m_lock.lock(); }; + /// Unlocks the class + void unlock() { m_lock.unlock(); }; +/**@}*/ + + // property type management +/** Property types */ +/**@{*/ + uint_t get_type(uint_t uiProp); ///< Retrieves the property type + size_t get_value_count(uint_t uiProp); ///< Retrieves the count of values for array-based property types + void remove_array_value(uint_t uiProp, size_t stIndex); ///< Removes a value at a specified index in array-based property type + void clear_array_values(uint_t uiProp); ///< Removes all values in array-based property + size_t count(); ///< Retrieves the count of properties contained in this config +/**@}*/ + + // registering the properties +/** \name Properties registration functions */ +/**@{*/ + /// Registers signed number-type property + uint_t register_signed_num(const tchar_t* pszName, ll_t llDef, ll_t llLo, ll_t llHi, uint_t uiFlags=property::flag_none); + /// Registers unsigned number-type property + uint_t register_unsigned_num(const tchar_t* pszName, ull_t ullDef, ull_t ullLo, ull_t ullHi, uint_t uiFlags=property::flag_none); + /// Registers bool-type property + uint_t register_bool(const tchar_t* pszName, bool bDef, uint_t uiFlags=property::flag_none); + /// Registers string-type property + uint_t register_string(const tchar_t* pszName, const tchar_t* pszDef, uint_t uiFlags=property::flag_none); +/**@}*/ + + // getting property data +/** \name Getting and setting values */ +/**@{*/ + /// Gets the value of string-type property + const tchar_t* get_value(uint_t uiProp, tchar_t* pszBuffer, size_t stMaxSize, size_t stIndex=0); + /// Gets the value of longlong_t-type property + ll_t get_signed_num(uint_t uiProp, size_t stIndex=0); + /// Gets the value of ulonglong_t-type property + ull_t get_unsigned_num(uint_t uiProp, size_t stIndex=0); + /// Gets the value of bool-type property + bool get_bool(uint_t uiProp, size_t stIndex=0); + /// Gets the value of string-type property + const tchar_t* get_string(uint_t uiProp, size_t stIndex=0); + + // setting property data + /// Sets the value from the string + void set_value(uint_t uiProp, const tchar_t* pszVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); + /// Sets the value of longlong_t-type property + void set_signed_num(uint_t uiProp, ll_t llVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); + /// Sets the value of ulonglong_t-type property + void set_unsigned_num(uint_t uiProp, ull_t ullVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); + /// Sets the value of bool-type property + void set_bool(uint_t uiProp, bool bVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); + /// Sets the value of string-type property + void set_string(uint_t uiProp, const tchar_t* pszVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); +/**@}*/ + +protected: + void load_registered(); ///< Loads the registered property values from the underlying config base + void store_registered(); ///< Stores the registered property values to the underlying config base + +protected: + mutex m_lock; ///< Lock for the multi-threaded access to the properties + ptr_t m_hProps; ///< Handle to the registered property storage + config_base* m_pCfgBase; ///< Underlying base for this class +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/cfg.h =================================================================== diff -u -N --- ext/libicpf/src/cfg.h (revision 0d9a4d94a98872815d5840d1bcc4d394d455307c) +++ ext/libicpf/src/cfg.h (revision 0) @@ -1,159 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef __CFG_H__ -#define __CFG_H__ - -/** \file cfg.h - * \brief A placeholder for config class. - */ -#include "mutex.h" -#include "libicpf.h" -#include "gen_types.h" -#include "config_base.h" -#include "config_property.h" - -BEGIN_ICPF_NAMESPACE - -/** \brief Property group handling class - * - * Class is being used to manipulate the property groups (in connection with config::begin_group() and - * config::end_group(). - */ -class LIBICPF_API property_tracker -{ -public: -/** \name Construction/destruction/operators */ -/**@{*/ - property_tracker(); ///< Standard constructor - property_tracker(const property_tracker& rSrc); ///< Copy constructor - ~property_tracker(); ///< Standard destructor - - property_tracker& operator=(const property_tracker& rSrc); ///< Assignment operator -/**@}*/ - -/** \name Operations */ -/**@{*/ - void add(uint_t uiProp); ///< Adds a new property id to the list - bool is_set(uint_t uiProp); ///< Checks if a property id is set inside this list - size_t count() const; ///< Returns a count of properties in a list - - /// Retrieves the list of ID's - size_t get_ids(uint_t* puiProps, size_t stMaxCount); - /// Retrieves the list of ID's using an enumeration function - void enum_ids(bool(*pfn)(uint_t uiProp, ptr_t pParam), ptr_t pParam); -/**@}*/ - -protected: - ptr_t m_hProperties; ///< Internal member. Pointer to a storage structure with an int_t. -}; - -/** \brief Configuration management class. - * - * Class allows user to read and write configuration file in standard unix - * format (comments, empty lines and key=value strings). Class is fully thread-safe. - * Access to the properties is done by registering one and then getting or setting - * a value using the property identifier. - */ -class LIBICPF_API config -{ -public: -/** \name Construction/destruction */ -/**@{*/ - config(config_base* pCfgBase); ///< Standard constructor - ~config(); ///< Standard destructor -/**@}*/ - -/** \name Reading and writing to the external medium */ -/**@{*/ - void read(const tchar_t *pszPath); ///< Reads the properties from the source file - void write(const tchar_t* pszPath); ///< Saves the properties to the file -/**@}*/ - -/** \name Class lock/unlock functions */ -/**@{*/ - /// Locks the config class for one thread - void lock() { m_lock.lock(); }; - /// Unlocks the class - void unlock() { m_lock.unlock(); }; -/**@}*/ - - // property type management -/** Property types */ -/**@{*/ - uint_t get_type(uint_t uiProp); ///< Retrieves the property type - size_t get_value_count(uint_t uiProp); ///< Retrieves the count of values for array-based property types - void remove_array_value(uint_t uiProp, size_t stIndex); ///< Removes a value at a specified index in array-based property type - void clear_array_values(uint_t uiProp); ///< Removes all values in array-based property - size_t count(); ///< Retrieves the count of properties contained in this config -/**@}*/ - - // registering the properties -/** \name Properties registration functions */ -/**@{*/ - /// Registers signed number-type property - uint_t register_signed_num(const tchar_t* pszName, ll_t llDef, ll_t llLo, ll_t llHi, uint_t uiFlags=property::flag_none); - /// Registers unsigned number-type property - uint_t register_unsigned_num(const tchar_t* pszName, ull_t ullDef, ull_t ullLo, ull_t ullHi, uint_t uiFlags=property::flag_none); - /// Registers bool-type property - uint_t register_bool(const tchar_t* pszName, bool bDef, uint_t uiFlags=property::flag_none); - /// Registers string-type property - uint_t register_string(const tchar_t* pszName, const tchar_t* pszDef, uint_t uiFlags=property::flag_none); -/**@}*/ - - // getting property data -/** \name Getting and setting values */ -/**@{*/ - /// Gets the value of string-type property - const tchar_t* get_value(uint_t uiProp, tchar_t* pszBuffer, size_t stMaxSize, size_t stIndex=0); - /// Gets the value of longlong_t-type property - ll_t get_signed_num(uint_t uiProp, size_t stIndex=0); - /// Gets the value of ulonglong_t-type property - ull_t get_unsigned_num(uint_t uiProp, size_t stIndex=0); - /// Gets the value of bool-type property - bool get_bool(uint_t uiProp, size_t stIndex=0); - /// Gets the value of string-type property - const tchar_t* get_string(uint_t uiProp, size_t stIndex=0); - - // setting property data - /// Sets the value from the string - void set_value(uint_t uiProp, const tchar_t* pszVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); - /// Sets the value of longlong_t-type property - void set_signed_num(uint_t uiProp, ll_t llVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); - /// Sets the value of ulonglong_t-type property - void set_unsigned_num(uint_t uiProp, ull_t ullVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); - /// Sets the value of bool-type property - void set_bool(uint_t uiProp, bool bVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); - /// Sets the value of string-type property - void set_string(uint_t uiProp, const tchar_t* pszVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); -/**@}*/ - -protected: - void load_registered(); ///< Loads the registered property values from the underlying config base - void store_registered(); ///< Stores the registered property values to the underlying config base - -protected: - mutex m_lock; ///< Lock for the multi-threaded access to the properties - ptr_t m_hProps; ///< Handle to the registered property storage - config_base* m_pCfgBase; ///< Underlying base for this class -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/cfg_xml.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/cfg_xml.cpp (revision 0) +++ ext/libicpf/src/libicpf/cfg_xml.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,362 @@ +#include "cfg_xml.h" +#include +#include "exception.h" +#include +#include +#include + +BEGIN_ICPF_NAMESPACE + +/// Buffer size for reading xml data from a file +#define XML_BUFFER 65536 + +// forward declaration +class xml_node; + +/// Xml node storage +typedef std::map xml_storage; +/// String storage (key(s)=>value(s)) +typedef std::multimap attr_storage; + +/** Class manages a single xml node. + */ +class xml_node +{ +public: +/** \name Construction/destruction */ +/**@{*/ + /// Standard constructor + xml_node() : m_mNodes(), m_mAttr(), m_pParentNode(NULL) { }; + /// Constructor defining the parent node + xml_node(xml_node* pParentNode) : m_mNodes(), m_mAttr(), m_pParentNode(pParentNode) { }; +/**@}*/ + +public: + xml_storage m_mNodes; ///< Additional nodes inside of this one + attr_storage m_mAttr; ///< String pairs belonging to this node + xml_node* m_pParentNode; ///< Parent node +}; + +/** State structure - used by expat notifications. + */ +struct XMLSTATE +{ + xml_cfg* pCfg; + xml_node* pNode; +}; + +/** Xml find handle structure - used for searching. + */ +struct XMLFINDHANDLE +{ + attr_storage::iterator it; ///< Iterator of currently retrieved string + attr_storage::iterator itEnd; ///< Iterator of a last string matching the criteria +}; + +/// Macro for faster access to the xml storage +#define m_pStorage ((xml_storage*)m_hStorage) + +/** Constructs the xml_cfg object. + */ +xml_cfg::xml_cfg() : + m_hStorage((ptr_t)new xml_storage) +{ + +} + +/** Destructs the xml config object. + */ +xml_cfg::~xml_cfg() +{ + delete m_pStorage; +} + +/** Expat start element handler. + * + * \param[in] userData - pointer to user defined parameters + * \param[in] name - name of the tag being processed + * \param[in] attrs - array of pointers to strings with attributes and their values + */ +void xml_cfg::element_start(void *userData, const tchar_t *name, const tchar_t **attrs) +{ + XMLSTATE* pState=(XMLSTATE*)userData; + + bool bContainer=true; + + for (size_t t=0;attrs[t] != NULL;t+=2) + { + if (_tcscmp(attrs[t], _t("value")) == 0) + { + // this is the value type tag + pState->pNode->m_mAttr.insert(attr_storage::value_type(tstring_t(name), tstring_t(attrs[t+1]))); + bContainer=false; + } + } + + if (bContainer) + { + std::pair pr; + if (pState->pNode) + pr=pState->pNode->m_mNodes.insert(xml_storage::value_type(tstring_t(name), xml_node(pState->pNode))); + else + pr=((xml_storage*)pState->pCfg->m_hStorage)->insert(xml_storage::value_type(tstring_t(name), xml_node(pState->pNode))); + pState->pNode=&((*pr.first).second); + } +} + +/** Expat handler for closing tag. + * + * \param[in] userData - user defined parameter + * \param[in] name - name of the tag being closed + */ +void xml_cfg::element_end(void *userData, const tchar_t* /*name*/) +{ + XMLSTATE* pState=(XMLSTATE*)userData; + + // go up one level + if (pState->pNode) + pState->pNode=pState->pNode->m_pParentNode; + else + THROW(_t("Trying to close non-existent tag."), 0, 0, 0); +} + +/*void XMLCALL element_content(void *userData, const XML_Char *s, int len) +{ + XMLSTATE* pState=(XMLSTATE*)userData; + +}*/ + +/** Function reads the contents of the xml file, parses it using expat parser + * and then creates xml nodes in memory that could be read using find functions. + * + * \param[in] pszPath - path to the file to be read + */ +void xml_cfg::read(const tchar_t* pszPath) +{ + // read the data from file in 64kB portions and feed it to the expat xml parser + FILE* pFile=_tfopen(pszPath, _t("r")); + if (pFile == NULL) + THROW(icpf::exception::format(_t("Cannot open the file ") STRFMT _t("."), pszPath), 0, errno, 0); + + // create the parser + XML_Parser parser=XML_ParserCreate(NULL); + XML_SetElementHandler(parser, element_start, element_end); +// XML_SetCharacterDataHandler(parser, element_content); + + XMLSTATE xs = { this, NULL }; + XML_SetUserData(parser, &xs); + + for (;;) + { + bool bLast=false; + + // get xml buffer + void* pBuffer=XML_GetBuffer(parser, XML_BUFFER); + + // read some data to it + size_t tSize=fread(pBuffer, 1, XML_BUFFER, pFile); + if (tSize < XML_BUFFER) + { + // check for errors + int iErr=0; + if ( (iErr=ferror(pFile)) != 0) + THROW(icpf::exception::format(_t("Error reading from the file ") STRFMT _t("."), pszPath), 0, iErr, 0); + else + bLast=true; + } + + // parse + if (!XML_ParseBuffer(parser, (int)tSize, bLast)) + { + // parser error + THROW(icpf::exception::format(_t("Error encountered while parsing the xml file ") STRFMT _t(" - ") STRFMT _t("."), pszPath, XML_ErrorString(XML_GetErrorCode(parser))), 0, 0, 0); + } + + // end of processing ? + if (bLast) + break; + } + + // free parser + XML_ParserFree(parser); + + // close the file + fclose(pFile); +} + +/** Saves the internal xml nodes to the specified xml file. + * + * \param[in] pszPath - path to the file the data should be written to + * + * \note Function overwrites the contents of a file + */ +void xml_cfg::save(const tchar_t* /*pszPath*/) +{ + +} + +/** Function starts a search operation. Given the name of the property + * to be searched for (ie. "ch/program/startup"), funtion searches for + * it and returns a handle that can be used by subsequent calls to the + * find_next(). Free the handle using find_close() after finish. + * + * \param[in] pszName - name of the property to search for (in the form of + * "ch/program/startup" for xml such as this: + * + * + * + * + * + * + * \return Handle to the search (NULL if not found). + */ +ptr_t xml_cfg::find(const tchar_t* pszName) +{ + return find(m_pStorage, pszName); +} + +/** A find() helper function - recursively searches a specific node + * for a given name. + * + * \param[in] pNodePtr - pointer to a node to search in + * \param[in] pszName - name of the property to search for + * \return Handle to the node or NULL if none. + */ +ptr_t xml_cfg::find(ptr_t pNodePtr, const tchar_t* pszName) +{ + xml_node* pNode=(xml_node*)pNodePtr; + + // parse the name + const tchar_t* pSign=_tcschr(pszName, _t('/')); + if (pSign) + { + // locate the xml_node associated with the name + xml_storage::iterator it=pNode->m_mNodes.find(tstring_t(pszName, pSign-pszName)); + if (it != pNode->m_mNodes.end()) + return find(&(*it).second, pSign+1); + else + return NULL; + } + else + { + XMLFINDHANDLE* pfh=new XMLFINDHANDLE; + std::pair pr=pNode->m_mAttr.equal_range(pszName); + pfh->it=pr.first; + pfh->itEnd=pr.second; + + return pfh; + } +} + +/** Finds the next string that belong to a specific key (as defined in + * a call to find() function. + * + * \param[in] pFindHandle - handle to the search (as returned from find()) + * \return Pointer to a next string found, NULL if none. + */ +const tchar_t* xml_cfg::find_next(ptr_t pFindHandle) +{ + XMLFINDHANDLE* pfh=(XMLFINDHANDLE*)pFindHandle; + if (pfh->it != pfh->itEnd) + return (*pfh->it++).second.c_str(); + else + return NULL; +} + +/** Closes the find handle. + * + * \param[in] pFindHandle - handle to the search (as returned from find()) + */ +void xml_cfg::find_close(ptr_t pFindHandle) +{ + delete ((XMLFINDHANDLE*)pFindHandle); +} + +/** Sets the specified value in the given key name. Value can be either added to + * the current ones (multi-string support) or replace them completely. + * + * \param[in] pszName - key name for which the string should be set at + * \param[in] pszValue - value to set + * \param[in] a - action to take while setting + */ +void xml_cfg::set_value(const tchar_t* pszName, const tchar_t* pszValue, actions a) +{ + // traverse the current tag tree + set_value(m_pStorage, pszName, pszValue, a); +} + +/** Sets the specified value in the given key name - recursive helper function. + * + * \param[in] pNodePtr - pointer to the xml node to process + * \param[in] pszName - key name for which the string should be set at + * \param[in] pszValue - value to set + * \param[in] a - action to take while setting + */ +void xml_cfg::set_value(ptr_t pNodePtr, const tchar_t* pszName, const tchar_t* pszValue, actions a) +{ + xml_node* pNode=(xml_node*)pNodePtr; + + const tchar_t* pszSign=_tcschr(pszName, _t('/')); + if (pszSign != NULL) + { + xml_storage::iterator it=pNode->m_mNodes.find(tstring_t(pszName, pszSign-pszName)); + if (it != pNode->m_mNodes.end()) + set_value(&(*it).second, pszSign+1, pszValue, a); + else + { + std::pair pr=pNode->m_mNodes.insert(xml_storage::value_type(tstring_t(pszName, pszSign-pszName), xml_node(pNode))); + set_value(&(*pr.first).second, pszSign+1, pszValue, a); + } + } + else + { + // clear if we're replacing + switch(a) + { + case config_base::action_replace: + pNode->m_mAttr.clear(); + case config_base::action_add: + pNode->m_mAttr.insert(attr_storage::value_type(tstring_t(pszName), tstring_t(pszValue))); + break; + default: + assert(false); + } + } +} + +/** Clear values for a given property name. + * + * \param[in] pszName - name of the property to clear the values for + */ +void xml_cfg::clear(const tchar_t* pszName) +{ + clear(m_pStorage, pszName); +} + +/** Recursive clear function - searches recursively for a proper node + * and finally clears the string map. + * + * \param[in] pNodePtr - pointer to a node to be processed + * \param[in] pszName - name of the property to search for in the given node + */ +void xml_cfg::clear(ptr_t pNodePtr, const tchar_t* pszName) +{ + xml_node* pNode=(xml_node*)pNodePtr; + + // parse the name + const tchar_t* pSign=_tcschr(pszName, _t('/')); + if (pSign) + { + // locate the xml_node associated with the name + xml_storage::iterator it=pNode->m_mNodes.find(tstring_t(pszName, pSign-pszName)); + if (it != pNode->m_mNodes.end()) + clear(&(*it).second, pSign+1); + } + else + { + std::pair pr=pNode->m_mAttr.equal_range(tstring_t(pszName)); + pNode->m_mAttr.erase(pr.first, pr.second); + } +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/cfg_xml.cpp =================================================================== diff -u -N --- ext/libicpf/src/cfg_xml.cpp (revision 9bdff2e0b309af11014634d8c38367e4f6b656e3) +++ ext/libicpf/src/cfg_xml.cpp (revision 0) @@ -1,362 +0,0 @@ -#include "cfg_xml.h" -#include -#include "exception.h" -#include -#include -#include - -BEGIN_ICPF_NAMESPACE - -/// Buffer size for reading xml data from a file -#define XML_BUFFER 65536 - -// forward declaration -class xml_node; - -/// Xml node storage -typedef std::map xml_storage; -/// String storage (key(s)=>value(s)) -typedef std::multimap attr_storage; - -/** Class manages a single xml node. - */ -class xml_node -{ -public: -/** \name Construction/destruction */ -/**@{*/ - /// Standard constructor - xml_node() : m_mNodes(), m_mAttr(), m_pParentNode(NULL) { }; - /// Constructor defining the parent node - xml_node(xml_node* pParentNode) : m_mNodes(), m_mAttr(), m_pParentNode(pParentNode) { }; -/**@}*/ - -public: - xml_storage m_mNodes; ///< Additional nodes inside of this one - attr_storage m_mAttr; ///< String pairs belonging to this node - xml_node* m_pParentNode; ///< Parent node -}; - -/** State structure - used by expat notifications. - */ -struct XMLSTATE -{ - xml_cfg* pCfg; - xml_node* pNode; -}; - -/** Xml find handle structure - used for searching. - */ -struct XMLFINDHANDLE -{ - attr_storage::iterator it; ///< Iterator of currently retrieved string - attr_storage::iterator itEnd; ///< Iterator of a last string matching the criteria -}; - -/// Macro for faster access to the xml storage -#define m_pStorage ((xml_storage*)m_hStorage) - -/** Constructs the xml_cfg object. - */ -xml_cfg::xml_cfg() : - m_hStorage((ptr_t)new xml_storage) -{ - -} - -/** Destructs the xml config object. - */ -xml_cfg::~xml_cfg() -{ - delete m_pStorage; -} - -/** Expat start element handler. - * - * \param[in] userData - pointer to user defined parameters - * \param[in] name - name of the tag being processed - * \param[in] attrs - array of pointers to strings with attributes and their values - */ -void xml_cfg::element_start(void *userData, const tchar_t *name, const tchar_t **attrs) -{ - XMLSTATE* pState=(XMLSTATE*)userData; - - bool bContainer=true; - - for (size_t t=0;attrs[t] != NULL;t+=2) - { - if (_tcscmp(attrs[t], _t("value")) == 0) - { - // this is the value type tag - pState->pNode->m_mAttr.insert(attr_storage::value_type(tstring_t(name), tstring_t(attrs[t+1]))); - bContainer=false; - } - } - - if (bContainer) - { - std::pair pr; - if (pState->pNode) - pr=pState->pNode->m_mNodes.insert(xml_storage::value_type(tstring_t(name), xml_node(pState->pNode))); - else - pr=((xml_storage*)pState->pCfg->m_hStorage)->insert(xml_storage::value_type(tstring_t(name), xml_node(pState->pNode))); - pState->pNode=&((*pr.first).second); - } -} - -/** Expat handler for closing tag. - * - * \param[in] userData - user defined parameter - * \param[in] name - name of the tag being closed - */ -void xml_cfg::element_end(void *userData, const tchar_t* /*name*/) -{ - XMLSTATE* pState=(XMLSTATE*)userData; - - // go up one level - if (pState->pNode) - pState->pNode=pState->pNode->m_pParentNode; - else - THROW(_t("Trying to close non-existent tag."), 0, 0, 0); -} - -/*void XMLCALL element_content(void *userData, const XML_Char *s, int len) -{ - XMLSTATE* pState=(XMLSTATE*)userData; - -}*/ - -/** Function reads the contents of the xml file, parses it using expat parser - * and then creates xml nodes in memory that could be read using find functions. - * - * \param[in] pszPath - path to the file to be read - */ -void xml_cfg::read(const tchar_t* pszPath) -{ - // read the data from file in 64kB portions and feed it to the expat xml parser - FILE* pFile=_tfopen(pszPath, _t("r")); - if (pFile == NULL) - THROW(icpf::exception::format(_t("Cannot open the file ") STRFMT _t("."), pszPath), 0, errno, 0); - - // create the parser - XML_Parser parser=XML_ParserCreate(NULL); - XML_SetElementHandler(parser, element_start, element_end); -// XML_SetCharacterDataHandler(parser, element_content); - - XMLSTATE xs = { this, NULL }; - XML_SetUserData(parser, &xs); - - for (;;) - { - bool bLast=false; - - // get xml buffer - void* pBuffer=XML_GetBuffer(parser, XML_BUFFER); - - // read some data to it - size_t tSize=fread(pBuffer, 1, XML_BUFFER, pFile); - if (tSize < XML_BUFFER) - { - // check for errors - int iErr=0; - if ( (iErr=ferror(pFile)) != 0) - THROW(icpf::exception::format(_t("Error reading from the file ") STRFMT _t("."), pszPath), 0, iErr, 0); - else - bLast=true; - } - - // parse - if (!XML_ParseBuffer(parser, (int)tSize, bLast)) - { - // parser error - THROW(icpf::exception::format(_t("Error encountered while parsing the xml file ") STRFMT _t(" - ") STRFMT _t("."), pszPath, XML_ErrorString(XML_GetErrorCode(parser))), 0, 0, 0); - } - - // end of processing ? - if (bLast) - break; - } - - // free parser - XML_ParserFree(parser); - - // close the file - fclose(pFile); -} - -/** Saves the internal xml nodes to the specified xml file. - * - * \param[in] pszPath - path to the file the data should be written to - * - * \note Function overwrites the contents of a file - */ -void xml_cfg::save(const tchar_t* /*pszPath*/) -{ - -} - -/** Function starts a search operation. Given the name of the property - * to be searched for (ie. "ch/program/startup"), funtion searches for - * it and returns a handle that can be used by subsequent calls to the - * find_next(). Free the handle using find_close() after finish. - * - * \param[in] pszName - name of the property to search for (in the form of - * "ch/program/startup" for xml such as this: - * - * - * - * - * - * - * \return Handle to the search (NULL if not found). - */ -ptr_t xml_cfg::find(const tchar_t* pszName) -{ - return find(m_pStorage, pszName); -} - -/** A find() helper function - recursively searches a specific node - * for a given name. - * - * \param[in] pNodePtr - pointer to a node to search in - * \param[in] pszName - name of the property to search for - * \return Handle to the node or NULL if none. - */ -ptr_t xml_cfg::find(ptr_t pNodePtr, const tchar_t* pszName) -{ - xml_node* pNode=(xml_node*)pNodePtr; - - // parse the name - const tchar_t* pSign=_tcschr(pszName, _t('/')); - if (pSign) - { - // locate the xml_node associated with the name - xml_storage::iterator it=pNode->m_mNodes.find(tstring_t(pszName, pSign-pszName)); - if (it != pNode->m_mNodes.end()) - return find(&(*it).second, pSign+1); - else - return NULL; - } - else - { - XMLFINDHANDLE* pfh=new XMLFINDHANDLE; - std::pair pr=pNode->m_mAttr.equal_range(pszName); - pfh->it=pr.first; - pfh->itEnd=pr.second; - - return pfh; - } -} - -/** Finds the next string that belong to a specific key (as defined in - * a call to find() function. - * - * \param[in] pFindHandle - handle to the search (as returned from find()) - * \return Pointer to a next string found, NULL if none. - */ -const tchar_t* xml_cfg::find_next(ptr_t pFindHandle) -{ - XMLFINDHANDLE* pfh=(XMLFINDHANDLE*)pFindHandle; - if (pfh->it != pfh->itEnd) - return (*pfh->it++).second.c_str(); - else - return NULL; -} - -/** Closes the find handle. - * - * \param[in] pFindHandle - handle to the search (as returned from find()) - */ -void xml_cfg::find_close(ptr_t pFindHandle) -{ - delete ((XMLFINDHANDLE*)pFindHandle); -} - -/** Sets the specified value in the given key name. Value can be either added to - * the current ones (multi-string support) or replace them completely. - * - * \param[in] pszName - key name for which the string should be set at - * \param[in] pszValue - value to set - * \param[in] a - action to take while setting - */ -void xml_cfg::set_value(const tchar_t* pszName, const tchar_t* pszValue, actions a) -{ - // traverse the current tag tree - set_value(m_pStorage, pszName, pszValue, a); -} - -/** Sets the specified value in the given key name - recursive helper function. - * - * \param[in] pNodePtr - pointer to the xml node to process - * \param[in] pszName - key name for which the string should be set at - * \param[in] pszValue - value to set - * \param[in] a - action to take while setting - */ -void xml_cfg::set_value(ptr_t pNodePtr, const tchar_t* pszName, const tchar_t* pszValue, actions a) -{ - xml_node* pNode=(xml_node*)pNodePtr; - - const tchar_t* pszSign=_tcschr(pszName, _t('/')); - if (pszSign != NULL) - { - xml_storage::iterator it=pNode->m_mNodes.find(tstring_t(pszName, pszSign-pszName)); - if (it != pNode->m_mNodes.end()) - set_value(&(*it).second, pszSign+1, pszValue, a); - else - { - std::pair pr=pNode->m_mNodes.insert(xml_storage::value_type(tstring_t(pszName, pszSign-pszName), xml_node(pNode))); - set_value(&(*pr.first).second, pszSign+1, pszValue, a); - } - } - else - { - // clear if we're replacing - switch(a) - { - case config_base::action_replace: - pNode->m_mAttr.clear(); - case config_base::action_add: - pNode->m_mAttr.insert(attr_storage::value_type(tstring_t(pszName), tstring_t(pszValue))); - break; - default: - assert(false); - } - } -} - -/** Clear values for a given property name. - * - * \param[in] pszName - name of the property to clear the values for - */ -void xml_cfg::clear(const tchar_t* pszName) -{ - clear(m_pStorage, pszName); -} - -/** Recursive clear function - searches recursively for a proper node - * and finally clears the string map. - * - * \param[in] pNodePtr - pointer to a node to be processed - * \param[in] pszName - name of the property to search for in the given node - */ -void xml_cfg::clear(ptr_t pNodePtr, const tchar_t* pszName) -{ - xml_node* pNode=(xml_node*)pNodePtr; - - // parse the name - const tchar_t* pSign=_tcschr(pszName, _t('/')); - if (pSign) - { - // locate the xml_node associated with the name - xml_storage::iterator it=pNode->m_mNodes.find(tstring_t(pszName, pSign-pszName)); - if (it != pNode->m_mNodes.end()) - clear(&(*it).second, pSign+1); - } - else - { - std::pair pr=pNode->m_mAttr.equal_range(tstring_t(pszName)); - pNode->m_mAttr.erase(pr.first, pr.second); - } -} - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/cfg_xml.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/cfg_xml.h (revision 0) +++ ext/libicpf/src/libicpf/cfg_xml.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,64 @@ +#ifndef __CFGXML_H__ +#define __CFGXML_H__ + +#include "gen_types.h" +#include "libicpf.h" +#include "config_base.h" + +BEGIN_ICPF_NAMESPACE + +/** Class provides the necessary base handlers for config class. + * It handles the xml data streams contained in the files, providing + * a way to set and retrieve data contained in the xml document. + */ +class LIBICPF_API xml_cfg : public config_base +{ +public: +/** \name Construction/destruction/operators */ +/**@{*/ + xml_cfg(); ///< Standard constructor + xml_cfg(const xml_cfg& rSrc); ///< Copy construtor + virtual ~xml_cfg(); ///< Standard destructor +/**@}*/ + +/** \name File operations */ +/**@{*/ + /// Reads the xml document from the specified file + virtual void read(const tchar_t* pszPath); + /// Saves the internal data to a specified file as the xml document + virtual void save(const tchar_t* pszPath); +/**@}*/ + +/** \name Key and value handling */ +/**@{*/ + /// Searches for a specified key (given all the path to a specific string) + virtual ptr_t find(const tchar_t* pszName); + /// Searches for the next string + virtual const tchar_t* find_next(ptr_t pFindHandle); + /// Closes the search operation + virtual void find_close(ptr_t pFindHandle); + + /// Sets a value for a given key + virtual void set_value(const tchar_t* pszName, const tchar_t* pszValue, actions a=action_add); + /// Clear values for a given property name + virtual void clear(const tchar_t* pszName); +/**@}*/ + +private: + /// Find helper - recursively searches for a specific key node + ptr_t find(ptr_t pNodePtr, const tchar_t* pszName); + /// Set value helper - searches for a specific node and sets the value + void set_value(ptr_t pNodePtr, const tchar_t* pszName, const tchar_t* pszValue, actions a=action_add); + /// Clear helper - clears the appropriate attribures + void clear(ptr_t pNodePtr, const tchar_t* pszName); + + static void element_start(void *userData, const tchar_t *name, const tchar_t **attrs); + static void element_end(void *userData, const tchar_t* /*name*/); + +protected: + ptr_t m_hStorage; ///< Handle to the internal xml storage +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/cfg_xml.h =================================================================== diff -u -N --- ext/libicpf/src/cfg_xml.h (revision 9bdff2e0b309af11014634d8c38367e4f6b656e3) +++ ext/libicpf/src/cfg_xml.h (revision 0) @@ -1,64 +0,0 @@ -#ifndef __CFGXML_H__ -#define __CFGXML_H__ - -#include "gen_types.h" -#include "libicpf.h" -#include "config_base.h" - -BEGIN_ICPF_NAMESPACE - -/** Class provides the necessary base handlers for config class. - * It handles the xml data streams contained in the files, providing - * a way to set and retrieve data contained in the xml document. - */ -class LIBICPF_API xml_cfg : public config_base -{ -public: -/** \name Construction/destruction/operators */ -/**@{*/ - xml_cfg(); ///< Standard constructor - xml_cfg(const xml_cfg& rSrc); ///< Copy construtor - virtual ~xml_cfg(); ///< Standard destructor -/**@}*/ - -/** \name File operations */ -/**@{*/ - /// Reads the xml document from the specified file - virtual void read(const tchar_t* pszPath); - /// Saves the internal data to a specified file as the xml document - virtual void save(const tchar_t* pszPath); -/**@}*/ - -/** \name Key and value handling */ -/**@{*/ - /// Searches for a specified key (given all the path to a specific string) - virtual ptr_t find(const tchar_t* pszName); - /// Searches for the next string - virtual const tchar_t* find_next(ptr_t pFindHandle); - /// Closes the search operation - virtual void find_close(ptr_t pFindHandle); - - /// Sets a value for a given key - virtual void set_value(const tchar_t* pszName, const tchar_t* pszValue, actions a=action_add); - /// Clear values for a given property name - virtual void clear(const tchar_t* pszName); -/**@}*/ - -private: - /// Find helper - recursively searches for a specific key node - ptr_t find(ptr_t pNodePtr, const tchar_t* pszName); - /// Set value helper - searches for a specific node and sets the value - void set_value(ptr_t pNodePtr, const tchar_t* pszName, const tchar_t* pszValue, actions a=action_add); - /// Clear helper - clears the appropriate attribures - void clear(ptr_t pNodePtr, const tchar_t* pszName); - - static void element_start(void *userData, const tchar_t *name, const tchar_t **attrs); - static void element_end(void *userData, const tchar_t* /*name*/); - -protected: - ptr_t m_hStorage; ///< Handle to the internal xml storage -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/circ_buffer.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/circ_buffer.cpp (revision 0) +++ ext/libicpf/src/libicpf/circ_buffer.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,548 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "circ_buffer.h" +#include +#include +#include + +BEGIN_ICPF_NAMESPACE + +// amount of bytes by which the buffer size will be incremented +// if there is one byte to be put in a full buffer +#define _BUFFER_INC (size_t)512ULL + +// if there is at least _BUFFER_DEC free space in the buffer then the buffer +// will be shrank (shrinked?) +#define _BUFFER_DEC (size_t)4096ULL + +// specifies if circular buffer should shrink the buffer size if there is too much free +// space in the buffer +#define _USE_SHRINKING 1 + +// if defined to 1 then function ForwardSeek will empty the whole +// internal buffer if it does not find the specified value inside of it +#define _FAILSEEK_TRUNCATES 1 + +circular_buffer::circular_buffer() : + m_pbyBuffer(NULL), + m_tSize(0), + m_tDataSize(0), + m_tBitsAtEndCount(0) +{ +} + +circular_buffer::circular_buffer(const circular_buffer& rSrc) : + m_pbyBuffer(NULL), + m_tSize(0), + m_tDataSize(0), + m_tBitsAtEndCount(0) +{ + copy_from(rSrc); +} + +circular_buffer::~circular_buffer() +{ + try + { + destroy(); + } + catch(...) + { + } +} + +circular_buffer& circular_buffer::operator=(const circular_buffer& rSrc) +{ + if (this == &rSrc) + { + // delete the old stuff + destroy(); + copy_from(rSrc); + } + + return *this; +} + +void circular_buffer::copy_from(const circular_buffer& rSrc) +{ + if (rSrc.m_pbyBuffer && rSrc.m_tSize > 0) + { + // copy the old stuff + m_pbyBuffer=new byte_t[rSrc.m_tSize]; + memcpy(m_pbyBuffer, rSrc.m_pbyBuffer, rSrc.m_tDataSize); + m_tSize=rSrc.m_tSize; + m_tDataSize=rSrc.m_tDataSize; + } + else + { + m_pbyBuffer=NULL; + m_tSize=0; + m_tDataSize=0; + } +} + +void circular_buffer::destroy() +{ + delete [] m_pbyBuffer; + m_pbyBuffer=NULL; + m_tSize=0; + m_tDataSize=0; +} + +void circular_buffer::push_data(const byte_t* pbyBuffer, size_t tCount) +{ + // check if there is enough space + if (m_tDataSize+tCount > m_tSize) + resize_buffer(m_tDataSize+tCount); + + // check for buffer + assert(m_pbyBuffer); + + // now there is enough space - fill it + memcpy(m_pbyBuffer+m_tDataSize, pbyBuffer, tCount); + + // increase the counters + m_tDataSize+=tCount; +} + +void circular_buffer::push_data(circular_buffer& rcb) +{ + if (rcb.m_pbyBuffer && rcb.m_tDataSize) + push_data(rcb.m_pbyBuffer, rcb.m_tDataSize); +} + +// pushes length and a string +void circular_buffer::push_string(const char_t* pszString) +{ + if (pszString) + { + ulong_t ulLen=(ulong_t)(strlen(pszString)+1); + push_ulong(ulLen); + push_data((const uchar_t*)pszString, ulLen); + } + else + { + push_ulong(0); + } +} + +void circular_buffer::push_ulonglong(ull_t ull) +{ + push_data((uchar_t*)&ull, sizeof(ull_t)); +} + +// pushes an unsigned long value +void circular_buffer::push_ulong(ulong_t ulData) +{ + push_data((uchar_t*)&ulData, sizeof(ulong_t)); +} + +void circular_buffer::push_ushort(ushort_t wData) +{ + push_data((uchar_t*)&wData, sizeof(ushort_t)); +} + +void circular_buffer::push_uchar(uchar_t byData) +{ + push_data(&byData, 1); +} + +size_t circular_buffer::pop_data(byte_t* pbyBuffer, size_t tCount) +{ + if (m_pbyBuffer == NULL || m_tDataSize == 0) + return 0; + + // how much data we are going to spare + size_t tRealCount=tCount; + if (m_tDataSize < tRealCount) + tRealCount=m_tDataSize; + + // copy the data + memcpy(pbyBuffer, m_pbyBuffer, tRealCount); + + // now move the data to beginning + skip_bytes(tRealCount); +#if _USE_SHRINKING == 1 + shrink_buffer(); +#endif + return tRealCount; +} + +bool circular_buffer::pop_ulonglong(ull_t* pull) +{ + return (pop_data((byte_t*)pull, sizeof(ull_t)) == sizeof(ull_t)); +} + +bool circular_buffer::pop_ulong(ulong_t* pul) +{ + return (pop_data((byte_t*)pul, sizeof(ulong_t)) == sizeof(ulong_t)); +} + +bool circular_buffer::pop_ushort(ushort_t* pw) +{ + return (pop_data((byte_t*)pw, sizeof(ushort_t)) == sizeof(ushort_t)); +} + +bool circular_buffer::pop_uchar(uchar_t* pby) +{ + return (pop_data((byte_t*)pby, 1) == 1); +} + +ulong_t circular_buffer::pop_string(char_t** pszString) +{ + ulong_t ul; + if (!pop_ulong(&ul)) + { + *pszString=NULL; + return (ulong_t)-1; + } + + if (ul == 0) + { + *pszString = NULL; + return 0; + } + else + { + // check if there is enough data + if (m_tDataSize < ul) + return (ulong_t)-1; + + // alloc buffer for a string + (*pszString)=new char_t[ul]; + if (pop_data((byte_t*)(*pszString), ul) != ul) + { + delete [] (*pszString); + *pszString=NULL; + return (ulong_t)-1; + } + else + { + (*pszString)[ul-1]='\0'; // just in case + return ul-1; // without the '\0' + } + } +} + +void circular_buffer::free_string(char_t* pszString) +{ + delete [] pszString; +} + +size_t circular_buffer::find(size_t tStartAt, ulong_t ulFnd) const +{ + assert(m_pbyBuffer); +// printf("searching for %lu from %lu\n", ulFnd, ulStartAt); +// printf("internal structures: buf: 0x%lx, data size: %lu, buf size: %lu\n", m_pbyBuffer, m_tDataSize, m_tSize); + for (size_t i=tStartAt;i m_tDataSize) + m_tDataSize=0; + else + { + memmove(m_pbyBuffer, m_pbyBuffer+tCount, m_tDataSize-tCount); + m_tDataSize-=tCount; + } +} + +void circular_buffer::resize_buffer(size_t tNewSize) +{ + // modify the new length & alloc the new buffer + tNewSize=(tNewSize & ~(_BUFFER_INC-1)) + _BUFFER_INC; + if (tNewSize < m_tSize) + return; + + byte_t *pszBuf=new byte_t[tNewSize]; + + if (m_pbyBuffer && m_tDataSize > 0) + { + // copy the old buffer to the new one + memcpy(pszBuf, m_pbyBuffer, m_tDataSize); + } + + // destroy the old buffer + delete [] m_pbyBuffer; + + // update data + m_pbyBuffer=pszBuf; + m_tSize=tNewSize; +} + +void circular_buffer::shrink_buffer() +{ +#if _USE_SHRINKING == 1 + assert(m_pbyBuffer); + + // check the current size of the data + size_t tNewSize=(m_tDataSize & ~(_BUFFER_INC-1)) + _BUFFER_INC; + if (m_tSize-tNewSize > _BUFFER_DEC) + { + // we must shrink the buffer + byte_t *pszBuf=new byte_t[tNewSize]; + memcpy(pszBuf, m_pbyBuffer, m_tDataSize); + delete [] m_pbyBuffer; + + m_pbyBuffer=pszBuf; + m_tSize=tNewSize; + } +#endif +} + +void circular_buffer::flush(size_t tToLeave) +{ + if (m_tDataSize > tToLeave) + skip_bytes(m_tDataSize-tToLeave); +} + +void circular_buffer::clear() +{ + m_tDataSize=0; +} + +size_t circular_buffer::get_datasize() const +{ + return m_tDataSize; +} + +bool circular_buffer::is_empty() const +{ + return m_tDataSize == 0; +} + +circular_buffer::operator const byte_t*() const +{ + return m_pbyBuffer; +} + +const byte_t* circular_buffer::get_buffer() const +{ + return m_pbyBuffer; +} + +void circular_buffer::push_bits(ulong_t ulBits, byte_t byCount) +{ +// assert(m_pbyBuffer); + assert(byCount <= 32 && byCount >= 1); // count of bits must be a sane value + assert(m_tBitsAtEndCount <= 7); // the internal bits count must be from the range [0..7]. For 8 bits in a buffer + // there is value of 0. + + do + { + // check if we have to add the bits to the last byte of a buffer + if (m_tBitsAtEndCount != 0) + { + // count of bits to copy into the last byte of the internal buffer + ulong_t ulCopy=(ulong_t)((byCount < 8-m_tBitsAtEndCount) ? byCount : 8-m_tBitsAtEndCount); + + // make some space for the incoming data + m_pbyBuffer[m_tDataSize-1] >>= ulCopy; + + // get the full byte from the in + byte_t uc=(byte_t)(ulBits & 0x000000ff); + + // we are getting from it only ulCopy lowest bits, so shift if a bit + uc <<= (8-ulCopy); + + // and apply + m_pbyBuffer[m_tDataSize-1] |= uc; + + // a bit of corrections + ulBits >>= ulCopy; + byCount-=(byte_t)ulCopy; + m_tBitsAtEndCount+=ulCopy; + if (m_tBitsAtEndCount == 8) + m_tBitsAtEndCount = 0; + } + else + { + // now there is something to add at the beginning of a next byte + // if there are some full bytes to add then simply add it through the + // PushData. + if (byCount >= 8) + { + // push the whole 8 bits as a byte into the buffer. Operation safe only + // on the little endian machines. + ulong_t ulCount=byCount/8; + push_data(((const byte_t*)&ulBits), ulCount); + + // corrections + ulBits >>= ulCount*8; + byCount-=(byte_t)(ulCount*8); + } + else + { + // we are about to add <8 bits of data into the last byte of a buffer which does not exist yet + // get the full byte from the input ulong + byte_t uc=(byte_t)(ulBits & 0x000000ff); + + // shift it a bit + uc <<= 8-byCount; + + // and add as a next byte + push_data(&uc, 1); + +// Dump(); + + // corrections + m_tBitsAtEndCount = byCount; + ulBits = 0; // since there are no data left + byCount = 0; // no data left + } + } + } + while(byCount > 0); +} + +// finished the operation of pushing bits, so we could use normal Push/PopData +/*void circular_buffer::PushBitsFinish() +{ + // check if there is unfinished byte at the end + if (m_tBitsAtEndCount != 0) + { + m_pbyBuffer[m_tDataSize-1] >>= 8-m_tBitsAtEndCount; + m_tBitsAtEndCount=0; + } +}*/ + +// enumerates all the bit-packs that exists in a buffer. If there were any bits operations performed +// on a buffer - they must be finished by the PushBitsFinish. +void circular_buffer::enum_bit_packets(ulong_t ulBitsCount, PFNBITSCALLBACK pfn, void* pParam) const +{ + assert(m_pbyBuffer); + assert(ulBitsCount >= 1 && ulBitsCount <=8); + assert(pfn); + + ushort_t w=0; // internal buffer for the next data from the class's buffer + ulong_t ulBits=0; // count of bits that was left in w + + size_t tIndex=0; // current index in the class's buffer + for (;;) + { + // make sure there is enough data in w so the next operation can succeed + // if there is less data in w than requested + if (ulBits < ulBitsCount) + { + // is there something left to read from the internal buffer + if (tIndex < m_tDataSize) + { + // append some bits into the buffer. + // NOTE: we are sure that there are at least 8 bits space in w + if (tIndex == m_tDataSize && m_tBitsAtEndCount != 0) + { + // there are less than 8 bits left. add only the part that exists + byte_t uc=(byte_t)(m_pbyBuffer[tIndex++] >> (8-m_tBitsAtEndCount)); + w |= (ushort_t)(uc) << ulBits; + } + else + { + w |= (ushort_t)(m_pbyBuffer[tIndex++]) << ulBits; + ulBits+=8; + } + } + else + { + // are there any bits left in the w ? + if (ulBits > 0) + { + // there are some bits left, so we should add a bit or two to make sure nothing is lost +// printf("$$$ Some (%lu) bits left. Current cache=%u\n", ulBits, w); + ulBits=ulBitsCount; + } + else + { + // there are no data left in the internal buffer, so finish the operation +// printf("&&& Leaving with %lu bits left\n", ulBits); + return; + } + } + } + else + { + // call the callback function with the ucData as a param + byte_t uc=(byte_t)((w & 0xff) << (8-ulBitsCount)); + uc >>= 8-ulBitsCount; + + (*pfn)(uc, pParam); + + // update variables + ulBits-=ulBitsCount; + w >>= ulBitsCount; + } + } +} + +/*void circular_buffer::dump() +{ + printf("circular_buffer::Dump()\n\tsize of data: %lu\n\tsizeof the buffer: %lu\n\tbits at end: %lu", m_tDataSize, m_tSize, m_tBitsAtEndCount); + for (unsigned long i=0;i -#include -#include - -BEGIN_ICPF_NAMESPACE - -// amount of bytes by which the buffer size will be incremented -// if there is one byte to be put in a full buffer -#define _BUFFER_INC (size_t)512ULL - -// if there is at least _BUFFER_DEC free space in the buffer then the buffer -// will be shrank (shrinked?) -#define _BUFFER_DEC (size_t)4096ULL - -// specifies if circular buffer should shrink the buffer size if there is too much free -// space in the buffer -#define _USE_SHRINKING 1 - -// if defined to 1 then function ForwardSeek will empty the whole -// internal buffer if it does not find the specified value inside of it -#define _FAILSEEK_TRUNCATES 1 - -circular_buffer::circular_buffer() : - m_pbyBuffer(NULL), - m_tSize(0), - m_tDataSize(0), - m_tBitsAtEndCount(0) -{ -} - -circular_buffer::circular_buffer(const circular_buffer& rSrc) : - m_pbyBuffer(NULL), - m_tSize(0), - m_tDataSize(0), - m_tBitsAtEndCount(0) -{ - copy_from(rSrc); -} - -circular_buffer::~circular_buffer() -{ - try - { - destroy(); - } - catch(...) - { - } -} - -circular_buffer& circular_buffer::operator=(const circular_buffer& rSrc) -{ - if (this == &rSrc) - { - // delete the old stuff - destroy(); - copy_from(rSrc); - } - - return *this; -} - -void circular_buffer::copy_from(const circular_buffer& rSrc) -{ - if (rSrc.m_pbyBuffer && rSrc.m_tSize > 0) - { - // copy the old stuff - m_pbyBuffer=new byte_t[rSrc.m_tSize]; - memcpy(m_pbyBuffer, rSrc.m_pbyBuffer, rSrc.m_tDataSize); - m_tSize=rSrc.m_tSize; - m_tDataSize=rSrc.m_tDataSize; - } - else - { - m_pbyBuffer=NULL; - m_tSize=0; - m_tDataSize=0; - } -} - -void circular_buffer::destroy() -{ - delete [] m_pbyBuffer; - m_pbyBuffer=NULL; - m_tSize=0; - m_tDataSize=0; -} - -void circular_buffer::push_data(const byte_t* pbyBuffer, size_t tCount) -{ - // check if there is enough space - if (m_tDataSize+tCount > m_tSize) - resize_buffer(m_tDataSize+tCount); - - // check for buffer - assert(m_pbyBuffer); - - // now there is enough space - fill it - memcpy(m_pbyBuffer+m_tDataSize, pbyBuffer, tCount); - - // increase the counters - m_tDataSize+=tCount; -} - -void circular_buffer::push_data(circular_buffer& rcb) -{ - if (rcb.m_pbyBuffer && rcb.m_tDataSize) - push_data(rcb.m_pbyBuffer, rcb.m_tDataSize); -} - -// pushes length and a string -void circular_buffer::push_string(const char_t* pszString) -{ - if (pszString) - { - ulong_t ulLen=(ulong_t)(strlen(pszString)+1); - push_ulong(ulLen); - push_data((const uchar_t*)pszString, ulLen); - } - else - { - push_ulong(0); - } -} - -void circular_buffer::push_ulonglong(ull_t ull) -{ - push_data((uchar_t*)&ull, sizeof(ull_t)); -} - -// pushes an unsigned long value -void circular_buffer::push_ulong(ulong_t ulData) -{ - push_data((uchar_t*)&ulData, sizeof(ulong_t)); -} - -void circular_buffer::push_ushort(ushort_t wData) -{ - push_data((uchar_t*)&wData, sizeof(ushort_t)); -} - -void circular_buffer::push_uchar(uchar_t byData) -{ - push_data(&byData, 1); -} - -size_t circular_buffer::pop_data(byte_t* pbyBuffer, size_t tCount) -{ - if (m_pbyBuffer == NULL || m_tDataSize == 0) - return 0; - - // how much data we are going to spare - size_t tRealCount=tCount; - if (m_tDataSize < tRealCount) - tRealCount=m_tDataSize; - - // copy the data - memcpy(pbyBuffer, m_pbyBuffer, tRealCount); - - // now move the data to beginning - skip_bytes(tRealCount); -#if _USE_SHRINKING == 1 - shrink_buffer(); -#endif - return tRealCount; -} - -bool circular_buffer::pop_ulonglong(ull_t* pull) -{ - return (pop_data((byte_t*)pull, sizeof(ull_t)) == sizeof(ull_t)); -} - -bool circular_buffer::pop_ulong(ulong_t* pul) -{ - return (pop_data((byte_t*)pul, sizeof(ulong_t)) == sizeof(ulong_t)); -} - -bool circular_buffer::pop_ushort(ushort_t* pw) -{ - return (pop_data((byte_t*)pw, sizeof(ushort_t)) == sizeof(ushort_t)); -} - -bool circular_buffer::pop_uchar(uchar_t* pby) -{ - return (pop_data((byte_t*)pby, 1) == 1); -} - -ulong_t circular_buffer::pop_string(char_t** pszString) -{ - ulong_t ul; - if (!pop_ulong(&ul)) - { - *pszString=NULL; - return (ulong_t)-1; - } - - if (ul == 0) - { - *pszString = NULL; - return 0; - } - else - { - // check if there is enough data - if (m_tDataSize < ul) - return (ulong_t)-1; - - // alloc buffer for a string - (*pszString)=new char_t[ul]; - if (pop_data((byte_t*)(*pszString), ul) != ul) - { - delete [] (*pszString); - *pszString=NULL; - return (ulong_t)-1; - } - else - { - (*pszString)[ul-1]='\0'; // just in case - return ul-1; // without the '\0' - } - } -} - -void circular_buffer::free_string(char_t* pszString) -{ - delete [] pszString; -} - -size_t circular_buffer::find(size_t tStartAt, ulong_t ulFnd) const -{ - assert(m_pbyBuffer); -// printf("searching for %lu from %lu\n", ulFnd, ulStartAt); -// printf("internal structures: buf: 0x%lx, data size: %lu, buf size: %lu\n", m_pbyBuffer, m_tDataSize, m_tSize); - for (size_t i=tStartAt;i m_tDataSize) - m_tDataSize=0; - else - { - memmove(m_pbyBuffer, m_pbyBuffer+tCount, m_tDataSize-tCount); - m_tDataSize-=tCount; - } -} - -void circular_buffer::resize_buffer(size_t tNewSize) -{ - // modify the new length & alloc the new buffer - tNewSize=(tNewSize & ~(_BUFFER_INC-1)) + _BUFFER_INC; - if (tNewSize < m_tSize) - return; - - byte_t *pszBuf=new byte_t[tNewSize]; - - if (m_pbyBuffer && m_tDataSize > 0) - { - // copy the old buffer to the new one - memcpy(pszBuf, m_pbyBuffer, m_tDataSize); - } - - // destroy the old buffer - delete [] m_pbyBuffer; - - // update data - m_pbyBuffer=pszBuf; - m_tSize=tNewSize; -} - -void circular_buffer::shrink_buffer() -{ -#if _USE_SHRINKING == 1 - assert(m_pbyBuffer); - - // check the current size of the data - size_t tNewSize=(m_tDataSize & ~(_BUFFER_INC-1)) + _BUFFER_INC; - if (m_tSize-tNewSize > _BUFFER_DEC) - { - // we must shrink the buffer - byte_t *pszBuf=new byte_t[tNewSize]; - memcpy(pszBuf, m_pbyBuffer, m_tDataSize); - delete [] m_pbyBuffer; - - m_pbyBuffer=pszBuf; - m_tSize=tNewSize; - } -#endif -} - -void circular_buffer::flush(size_t tToLeave) -{ - if (m_tDataSize > tToLeave) - skip_bytes(m_tDataSize-tToLeave); -} - -void circular_buffer::clear() -{ - m_tDataSize=0; -} - -size_t circular_buffer::get_datasize() const -{ - return m_tDataSize; -} - -bool circular_buffer::is_empty() const -{ - return m_tDataSize == 0; -} - -circular_buffer::operator const byte_t*() const -{ - return m_pbyBuffer; -} - -const byte_t* circular_buffer::get_buffer() const -{ - return m_pbyBuffer; -} - -void circular_buffer::push_bits(ulong_t ulBits, byte_t byCount) -{ -// assert(m_pbyBuffer); - assert(byCount <= 32 && byCount >= 1); // count of bits must be a sane value - assert(m_tBitsAtEndCount <= 7); // the internal bits count must be from the range [0..7]. For 8 bits in a buffer - // there is value of 0. - - do - { - // check if we have to add the bits to the last byte of a buffer - if (m_tBitsAtEndCount != 0) - { - // count of bits to copy into the last byte of the internal buffer - ulong_t ulCopy=(ulong_t)((byCount < 8-m_tBitsAtEndCount) ? byCount : 8-m_tBitsAtEndCount); - - // make some space for the incoming data - m_pbyBuffer[m_tDataSize-1] >>= ulCopy; - - // get the full byte from the in - byte_t uc=(byte_t)(ulBits & 0x000000ff); - - // we are getting from it only ulCopy lowest bits, so shift if a bit - uc <<= (8-ulCopy); - - // and apply - m_pbyBuffer[m_tDataSize-1] |= uc; - - // a bit of corrections - ulBits >>= ulCopy; - byCount-=(byte_t)ulCopy; - m_tBitsAtEndCount+=ulCopy; - if (m_tBitsAtEndCount == 8) - m_tBitsAtEndCount = 0; - } - else - { - // now there is something to add at the beginning of a next byte - // if there are some full bytes to add then simply add it through the - // PushData. - if (byCount >= 8) - { - // push the whole 8 bits as a byte into the buffer. Operation safe only - // on the little endian machines. - ulong_t ulCount=byCount/8; - push_data(((const byte_t*)&ulBits), ulCount); - - // corrections - ulBits >>= ulCount*8; - byCount-=(byte_t)(ulCount*8); - } - else - { - // we are about to add <8 bits of data into the last byte of a buffer which does not exist yet - // get the full byte from the input ulong - byte_t uc=(byte_t)(ulBits & 0x000000ff); - - // shift it a bit - uc <<= 8-byCount; - - // and add as a next byte - push_data(&uc, 1); - -// Dump(); - - // corrections - m_tBitsAtEndCount = byCount; - ulBits = 0; // since there are no data left - byCount = 0; // no data left - } - } - } - while(byCount > 0); -} - -// finished the operation of pushing bits, so we could use normal Push/PopData -/*void circular_buffer::PushBitsFinish() -{ - // check if there is unfinished byte at the end - if (m_tBitsAtEndCount != 0) - { - m_pbyBuffer[m_tDataSize-1] >>= 8-m_tBitsAtEndCount; - m_tBitsAtEndCount=0; - } -}*/ - -// enumerates all the bit-packs that exists in a buffer. If there were any bits operations performed -// on a buffer - they must be finished by the PushBitsFinish. -void circular_buffer::enum_bit_packets(ulong_t ulBitsCount, PFNBITSCALLBACK pfn, void* pParam) const -{ - assert(m_pbyBuffer); - assert(ulBitsCount >= 1 && ulBitsCount <=8); - assert(pfn); - - ushort_t w=0; // internal buffer for the next data from the class's buffer - ulong_t ulBits=0; // count of bits that was left in w - - size_t tIndex=0; // current index in the class's buffer - for (;;) - { - // make sure there is enough data in w so the next operation can succeed - // if there is less data in w than requested - if (ulBits < ulBitsCount) - { - // is there something left to read from the internal buffer - if (tIndex < m_tDataSize) - { - // append some bits into the buffer. - // NOTE: we are sure that there are at least 8 bits space in w - if (tIndex == m_tDataSize && m_tBitsAtEndCount != 0) - { - // there are less than 8 bits left. add only the part that exists - byte_t uc=(byte_t)(m_pbyBuffer[tIndex++] >> (8-m_tBitsAtEndCount)); - w |= (ushort_t)(uc) << ulBits; - } - else - { - w |= (ushort_t)(m_pbyBuffer[tIndex++]) << ulBits; - ulBits+=8; - } - } - else - { - // are there any bits left in the w ? - if (ulBits > 0) - { - // there are some bits left, so we should add a bit or two to make sure nothing is lost -// printf("$$$ Some (%lu) bits left. Current cache=%u\n", ulBits, w); - ulBits=ulBitsCount; - } - else - { - // there are no data left in the internal buffer, so finish the operation -// printf("&&& Leaving with %lu bits left\n", ulBits); - return; - } - } - } - else - { - // call the callback function with the ucData as a param - byte_t uc=(byte_t)((w & 0xff) << (8-ulBitsCount)); - uc >>= 8-ulBitsCount; - - (*pfn)(uc, pParam); - - // update variables - ulBits-=ulBitsCount; - w >>= ulBitsCount; - } - } -} - -/*void circular_buffer::dump() -{ - printf("circular_buffer::Dump()\n\tsize of data: %lu\n\tsizeof the buffer: %lu\n\tbits at end: %lu", m_tDataSize, m_tSize, m_tBitsAtEndCount); - for (unsigned long i=0;i +#endif + +BEGIN_ICPF_NAMESPACE + +// forward_seek() results +#define FS_NOTFOUND -1 +#define FS_PARTIAL 0 +#define FS_FOUND 1 + +typedef void(*PFNBITSCALLBACK)(unsigned char uc, void* pParam); + +class LIBICPF_API circular_buffer +{ +public: + // construction/destruction + circular_buffer(); + circular_buffer(const circular_buffer& rSrc); + ~circular_buffer(); + + circular_buffer& operator=(const circular_buffer& rSrc); + + void destroy(); // destroys the contents of this class + + // operations + void push_data(const byte_t* pbyBuffer, size_t tCount); + void push_data(circular_buffer& rcb); + + void push_string(const char_t* pszString); // pushes length and a string + void push_ulonglong(ull_t ull); + void push_ulong(ulong_t ulData); // pushes an unsigned long value + void push_ushort(ushort_t wData); + void push_uchar(uchar_t byData); + + size_t pop_data(byte_t* pbyBuffer, size_t tCount); + bool pop_ulonglong(ull_t* pull); + bool pop_ulong(ulong_t* pul); + bool pop_ushort(ushort_t* pw); + bool pop_uchar(uchar_t* pby); + ulong_t pop_string(char_t** pszString); // returns the length of alloc string (-1 for error) + static void free_string(char_t* pszString); // frees the string allocated with pop_string + + // operation on single bits + void push_bits(ulong_t ulBits, byte_t byCount); +// void PushBitsFinish(); // finishes the operation of pushing bits, so we could use normal Push/PopData + void enum_bit_packets(ulong_t ulBitsCount, PFNBITSCALLBACK pfn, void* pParam) const; + size_t get_bits_at_end() const { return m_tBitsAtEndCount; }; + + // searching + int forward_seek(ulong_t ulFnd); // seeks for the value and skips the bytes previous to it + size_t find(size_t tStartAt, ulong_t ulFnd) const; // searches for the specified value in the buffer, returns an index + // (size_t)-1 if not found + + void skip_bytes(size_t tCount); // skips some bytes from the beginning of a buffer + void flush(size_t ulToLeave); // removes (almost) all the data from a buffer + void clear(); + + size_t get_datasize() const; + bool is_empty() const; + + operator const byte_t*() const; + const byte_t* get_buffer() const; + +// void dump(); + +protected: + void copy_from(const circular_buffer& rSrc); + void resize_buffer(size_t tNewSize); // enlarges buffer + void shrink_buffer(); + +protected: + byte_t *m_pbyBuffer; // internal buffer + size_t m_tSize; // size of the buffer + size_t m_tDataSize; // data size inside the buffer (the last byte could be partially filled with data + // so when using PopData instead of PopBitsX make sure you understand it). + size_t m_tBitsAtEndCount; // count of bits in the last byte of the buffer. 0 if the last byte is full of data +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/circ_buffer.h =================================================================== diff -u -N --- ext/libicpf/src/circ_buffer.h (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/circ_buffer.h (revision 0) @@ -1,106 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef __CIRCULARBUFFER_H__ -#define __CIRCULARBUFFER_H__ - -#include "libicpf.h" -#include "gen_types.h" -#ifndef _WIN32 - #include -#endif - -BEGIN_ICPF_NAMESPACE - -// forward_seek() results -#define FS_NOTFOUND -1 -#define FS_PARTIAL 0 -#define FS_FOUND 1 - -typedef void(*PFNBITSCALLBACK)(unsigned char uc, void* pParam); - -class LIBICPF_API circular_buffer -{ -public: - // construction/destruction - circular_buffer(); - circular_buffer(const circular_buffer& rSrc); - ~circular_buffer(); - - circular_buffer& operator=(const circular_buffer& rSrc); - - void destroy(); // destroys the contents of this class - - // operations - void push_data(const byte_t* pbyBuffer, size_t tCount); - void push_data(circular_buffer& rcb); - - void push_string(const char_t* pszString); // pushes length and a string - void push_ulonglong(ull_t ull); - void push_ulong(ulong_t ulData); // pushes an unsigned long value - void push_ushort(ushort_t wData); - void push_uchar(uchar_t byData); - - size_t pop_data(byte_t* pbyBuffer, size_t tCount); - bool pop_ulonglong(ull_t* pull); - bool pop_ulong(ulong_t* pul); - bool pop_ushort(ushort_t* pw); - bool pop_uchar(uchar_t* pby); - ulong_t pop_string(char_t** pszString); // returns the length of alloc string (-1 for error) - static void free_string(char_t* pszString); // frees the string allocated with pop_string - - // operation on single bits - void push_bits(ulong_t ulBits, byte_t byCount); -// void PushBitsFinish(); // finishes the operation of pushing bits, so we could use normal Push/PopData - void enum_bit_packets(ulong_t ulBitsCount, PFNBITSCALLBACK pfn, void* pParam) const; - size_t get_bits_at_end() const { return m_tBitsAtEndCount; }; - - // searching - int forward_seek(ulong_t ulFnd); // seeks for the value and skips the bytes previous to it - size_t find(size_t tStartAt, ulong_t ulFnd) const; // searches for the specified value in the buffer, returns an index - // (size_t)-1 if not found - - void skip_bytes(size_t tCount); // skips some bytes from the beginning of a buffer - void flush(size_t ulToLeave); // removes (almost) all the data from a buffer - void clear(); - - size_t get_datasize() const; - bool is_empty() const; - - operator const byte_t*() const; - const byte_t* get_buffer() const; - -// void dump(); - -protected: - void copy_from(const circular_buffer& rSrc); - void resize_buffer(size_t tNewSize); // enlarges buffer - void shrink_buffer(); - -protected: - byte_t *m_pbyBuffer; // internal buffer - size_t m_tSize; // size of the buffer - size_t m_tDataSize; // data size inside the buffer (the last byte could be partially filled with data - // so when using PopData instead of PopBitsX make sure you understand it). - size_t m_tBitsAtEndCount; // count of bits in the last byte of the buffer. 0 if the last byte is full of data -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/config_base.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/config_base.h (revision 0) +++ ext/libicpf/src/libicpf/config_base.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,50 @@ +#ifndef __CONFIG_BASE_H__ +#define __CONFIG_BASE_H__ + +#include "gen_types.h" +#include "libicpf.h" + +BEGIN_ICPF_NAMESPACE + +/** Base config class. Manages the data that can be directly + * read or written to the storage medium (xml file, ini file, + * registry, ...). + */ +class config_base +{ +public: + /// Actions used when setting value + enum actions + { + action_add, + action_replace + }; + +public: +/** \name File operations */ +/**@{*/ + /// Reads the xml document from the specified file + virtual void read(const tchar_t* pszPath) = 0; + /// Saves the internal data to a specified file as the xml document + virtual void save(const tchar_t* pszPath) = 0; +/**@}*/ + +/** \name Key and value handling */ +/**@{*/ + /// Searches for a specified key (given all the path to a specific string) + virtual ptr_t find(const tchar_t* pszName) = 0; + /// Searches for the next string + virtual const tchar_t* find_next(ptr_t pFindHandle) = 0; + /// Closes the search operation + virtual void find_close(ptr_t pFindHandle) = 0; + + /// Sets a value for a given key + virtual void set_value(const tchar_t* pszName, const tchar_t* pszValue, actions a=action_add) = 0; + /// Clear values for a given property name + virtual void clear(const tchar_t* pszName) = 0; +/**@}*/ +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/config_base.h =================================================================== diff -u -N --- ext/libicpf/src/config_base.h (revision fd1f0cf4d6ad9ff63fd9252a3f2f31c992431842) +++ ext/libicpf/src/config_base.h (revision 0) @@ -1,50 +0,0 @@ -#ifndef __CONFIG_BASE_H__ -#define __CONFIG_BASE_H__ - -#include "gen_types.h" -#include "libicpf.h" - -BEGIN_ICPF_NAMESPACE - -/** Base config class. Manages the data that can be directly - * read or written to the storage medium (xml file, ini file, - * registry, ...). - */ -class config_base -{ -public: - /// Actions used when setting value - enum actions - { - action_add, - action_replace - }; - -public: -/** \name File operations */ -/**@{*/ - /// Reads the xml document from the specified file - virtual void read(const tchar_t* pszPath) = 0; - /// Saves the internal data to a specified file as the xml document - virtual void save(const tchar_t* pszPath) = 0; -/**@}*/ - -/** \name Key and value handling */ -/**@{*/ - /// Searches for a specified key (given all the path to a specific string) - virtual ptr_t find(const tchar_t* pszName) = 0; - /// Searches for the next string - virtual const tchar_t* find_next(ptr_t pFindHandle) = 0; - /// Closes the search operation - virtual void find_close(ptr_t pFindHandle) = 0; - - /// Sets a value for a given key - virtual void set_value(const tchar_t* pszName, const tchar_t* pszValue, actions a=action_add) = 0; - /// Clear values for a given property name - virtual void clear(const tchar_t* pszName) = 0; -/**@}*/ -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/config_property.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/config_property.cpp (revision 0) +++ ext/libicpf/src/libicpf/config_property.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,988 @@ +#include "config_property.h" +#include +#include + +BEGIN_ICPF_NAMESPACE + +////////////////////////////////////////////////////////////////////////////////// +// property class +// fast access to the array property types +#define m_paStrings ((std::vector*)m_val.hArray) +#define m_paSigneds ((std::vector*)m_val.hArray) +#define m_paUnsigneds ((std::vector*)m_val.hArray) +#define m_paBools ((std::vector*)m_val.hArray) + +/** Constructs a property object. + */ +property::property() : + m_uiPropType(type_unknown | flag_none), + m_pszName(NULL) +{ + memset(&m_val, 0, sizeof(_VALUE)); + memset(&m_range, 0, sizeof(_RANGE)); +} + +/** Constructs a property object with type initializer. + * + * \param[in] uiType - type and flags to set the property to + */ +property::property(const tchar_t* pszName, uint_t uiType) : + m_uiPropType(uiType), + m_pszName(NULL) +{ + memset(&m_val, 0, sizeof(_VALUE)); + memset(&m_range, 0, sizeof(_RANGE)); + + // init + init(pszName, uiType, false); +} + +/** Constructs a property object based on some other property object. + * + * \param[in] src - a source property object + */ +property::property(const property& src) +{ + copy_from(src, false); +} + +/** Destructs the property object. + */ +property::~property() +{ + clear(); +} + +/** Assigns one property to another. + * + * \param[in] rSrc - a source property to copy + * \return Reference to this object. + */ +property& property::operator=(const property& rSrc) +{ + if (this != &rSrc) + copy_from(rSrc, true); + + return *this; +} + +/** Clears all the internal members. + */ +void property::clear() +{ + // delete the property name + delete [] m_pszName; + m_pszName=NULL; + + clear_value(); + + // reset other members + m_uiPropType=type_unknown | flag_none; +} + +/** Initializes the property for storaging of the specific property + * type. Also sets the property name. + * The current property contents are being cleared before setting + * the new type. + * + * \param[in] uiType - the new property type + */ +void property::init(const tchar_t* pszName, uint_t uiType, bool bClear) +{ + // clear the current stuff + if (bClear) + clear(); + + // standard members + m_pszName=copy_string(pszName); + m_uiPropType=uiType; + + // and alloc memory for the array property types + if (uiType & flag_array) + { + switch(uiType & mask_type) + { + case type_string: + m_val.hArray=(ptr_t)new std::vector; + break; + case type_signed_num: + m_val.hArray=(ptr_t)new std::vector; + m_range.ll.llLo=_I64_MIN; + m_range.ll.llHi=_I64_MAX; + break; + case type_unsigned_num: + m_val.hArray=(ptr_t)new std::vector; + m_range.ull.ullLo=0; + m_range.ull.ullHi=_UI64_MAX; + break; + case type_bool: + m_val.hArray=(ptr_t)new std::vector; + break; + default: + assert(false); // unhandled property type + } + } + else + { + switch(uiType & mask_type) + { + case type_string: + case type_bool: + break; + case type_signed_num: + m_range.ll.llLo=_I64_MIN; + m_range.ll.llHi=_I64_MAX; + break; + case type_unsigned_num: + m_range.ull.ullLo=0; + m_range.ull.ullHi=_UI64_MAX; + break; + default: + assert(false); // unhandled property type + } + } +} + +/** Sets a property value from a given string. If this is the array property + * type, than the operation is defined by a given action - it either replaces + * all the previous values, or adds at the end or replaces value at a specific + * index. + * + * \param[in] pszValue - value to set (stored in a string) + * \param[in] a - action to take when the property is array-based + * \param[in] tIndex - an index at which to place the value (only meaningful + * for array property type). + */ +void property::set_value(const tchar_t* pszValue, actions a, size_t tIndex) +{ + if (m_uiPropType & flag_array) + { + switch(m_uiPropType & mask_type) + { + case type_string: + { + switch(a) + { + case action_replace: + { + m_paStrings->clear(); + m_paStrings->push_back(tstring(pszValue)); + break; + } + case action_add: + { + m_paStrings->push_back(tstring(pszValue)); + break; + } + case action_setat: + { + assert(tIndex < m_paStrings->size()); + + tstring& str=m_paStrings->at(tIndex); + str=pszValue; + break; + } + default: + assert(false); // unhandled action type + } + break; + } + case type_bool: + { + switch(a) + { + case action_replace: + { + m_paBools->clear(); + m_paBools->push_back(bool_from_string(pszValue)); + break; + } + case action_add: + { + m_paBools->push_back(bool_from_string(pszValue)); + break; + } + case action_setat: + { + assert(tIndex < m_paBools->size()); + + std::vector::iterator it=m_paBools->begin()+tIndex; + (*it)=bool_from_string(pszValue); + break; + } + default: + assert(false); // unhandled action type + } + break; + } + case type_signed_num: + { + switch(a) + { + case action_replace: + { + m_paSigneds->clear(); + m_paSigneds->push_back(signed_from_string(pszValue)); + break; + } + case action_add: + { + m_paSigneds->push_back(signed_from_string(pszValue)); + break; + } + case action_setat: + { + assert(tIndex < m_paSigneds->size()); + + ll_t& ll=m_paSigneds->at(tIndex); + ll=signed_from_string(pszValue); + break; + } + default: + assert(false); // unhandled action type + } + break; + } + case type_unsigned_num: + { + switch(a) + { + case action_replace: + { + m_paUnsigneds->clear(); + m_paUnsigneds->push_back(unsigned_from_string(pszValue)); + break; + } + case action_add: + { + m_paUnsigneds->push_back(unsigned_from_string(pszValue)); + break; + } + case action_setat: + { + assert(tIndex < m_paUnsigneds->size()); + + ull_t& ull=m_paUnsigneds->at(tIndex); + ull=unsigned_from_string(pszValue); + break; + } + default: + assert(false); // unhandled action type + } + break; + } + } + } + else + { + switch(m_uiPropType & mask_type) + { + case type_string: + { + delete [] m_val.pszVal; + m_val.pszVal=copy_string(pszValue); + break; + } + case type_signed_num: + { + m_val.llVal=signed_from_string(pszValue); + break; + } + case type_unsigned_num: + { + m_val.ullVal=unsigned_from_string(pszValue); + break; + } + case type_bool: + { + m_val.bVal=bool_from_string(pszValue); + break; + } + default: + assert(false); // not implemented? + } + } +} + +/** Retrieves the value as a string. + * + * \param[out] pszString - pointer to a string that will receive the value (could + * be NULL when retrieving string value type) + * \param[in] stMaxSize - size of the buffer (could be 0 for string value retrieval) + * \param[in] stIndex - an index at which to get the value (only meaningful + * for array property type). + * \return Pointer to the string with value. + * \note Always use the returned value as a string pointer - it could be different + * than the one provided as a buffer (in case of retrieving string value). + */ +const tchar_t* property::get_value(tchar_t* pszString, size_t stMaxSize, size_t stIndex) +{ + assert(pszString); + + if (m_uiPropType & flag_array) + { + switch(m_uiPropType & mask_type) + { + case type_string: + assert(stIndex < m_paStrings->size()); + return m_paStrings->at(stIndex).c_str(); + break; + case type_signed_num: + assert(stIndex < m_paSigneds->size()); + _sntprintf(pszString, stMaxSize, LLFMT, m_paSigneds->at(stIndex)); + break; + case type_unsigned_num: + assert(stIndex < m_paUnsigneds->size()); + _sntprintf(pszString, stMaxSize, ULLFMT, m_paUnsigneds->at(stIndex)); + break; + case type_bool: + assert(stIndex < m_paBools->size()); + _sntprintf(pszString, stMaxSize, USFMT, (ushort_t)m_paBools->at(stIndex)); + break; + default: + assert(false); + } + } + else + { + switch(m_uiPropType & mask_type) + { + case type_string: + return m_val.pszVal; + break; + case type_signed_num: + _sntprintf(pszString, stMaxSize, LLFMT, m_val.llVal); + break; + case type_unsigned_num: + _sntprintf(pszString, stMaxSize, ULLFMT, m_val.ullVal); + break; + case type_bool: + _sntprintf(pszString, stMaxSize, USFMT, (ushort_t)m_val.bVal); + break; + default: + assert(false); + } + } + + return pszString; +} + +/** Sets the string value for this property. + * + * \param[in] pszValue - string to set + * \param[in] a - action to take when property is array-based + * \param[in] tIndex - index at which to replace value in case of item + * replace action (for array-based property types) + */ +void property::set_string(const tchar_t* pszValue, actions a, size_t tIndex) +{ + assert((m_uiPropType & mask_type) == type_string); + + if (m_uiPropType & flag_array) + { + switch(a) + { + case action_replace: + { + m_paStrings->clear(); + m_paStrings->push_back(tstring(pszValue)); + break; + } + case action_add: + { + m_paStrings->push_back(tstring(pszValue)); + break; + } + case action_setat: + { + assert(tIndex < m_paStrings->size()); + tstring& str=m_paStrings->at(tIndex); + str=pszValue; + break; + } + default: + assert(false); // unhandled action type + } + } + else + { + delete [] m_val.pszVal; + m_val.pszVal=copy_string(pszValue); + } +} + +/** Retrieves the string value type. + * + * \param[in] stIndex - index at which to retrieve value (meaningful only + * for array property type) + * \return Pointer to the string. + */ +const tchar_t* property::get_string(size_t stIndex) const +{ + assert((m_uiPropType & mask_type) == type_string); + + if (m_uiPropType & flag_array) + { + assert(stIndex < m_paStrings->size()); + return m_paStrings->at(stIndex).c_str(); + } + else + return m_val.pszVal; +} + +/** Sets a signed number property value. + * + * \param[in] llValue - signed number value to set + * \param[in] a - action to take when property is array-based + * \param[in] tIndex - index at which to replace value in case of item + * replace action (for array-based property types) + */ +void property::set_signed_num(ll_t llValue, actions a, size_t tIndex) +{ + assert((m_uiPropType & mask_type) == type_signed_num); + + if (m_uiPropType & flag_array) + { + switch(a) + { + case action_replace: + { + m_paSigneds->clear(); + m_paSigneds->push_back(llValue); + break; + } + case action_add: + { + m_paSigneds->push_back(llValue); + break; + } + case action_setat: + { + assert(tIndex < m_paSigneds->size()); + ll_t& ll=m_paSigneds->at(tIndex); + ll=llValue; + break; + } + default: + assert(false); // unhandled action type + } + } + else + m_val.llVal=llValue; + + check_range(); +} + +/** Sets the range of the signed number property value. + * + * \param[in] llMin - minimum acceptable value of the property + * \param[in] llMax - maximum acceptable value of the property + */ +void property::set_signed_range(ll_t llMin, ll_t llMax) +{ + assert((m_uiPropType & mask_type) == type_signed_num); + + // set new range + m_range.ll.llLo=llMin; + m_range.ll.llHi=llMax; + + // check range + check_range(); +} + +/** Retrieves the signed number value. + * + * \param[in] stIndex - index at which to retrieve value (array-based + * property types) + * \return Signed number value. + */ +ll_t property::get_signed_num(size_t stIndex) const +{ + assert((m_uiPropType & mask_type) == type_signed_num); + + if (m_uiPropType & flag_array) + { + assert(stIndex < m_paSigneds->size()); + return m_paSigneds->at(stIndex); + } + else + return m_val.llVal; +} + +/** Sets an unsigned number property value. + * + * \param[in] ullValue - unsigned number value to set + * \param[in] a - action to take when property is array-based + * \param[in] tIndex - index at which to replace value in case of item + * replace action (for array-based property types) + */ +void property::set_unsigned_num(ull_t ullValue, actions a, size_t tIndex) +{ + assert((m_uiPropType & mask_type) == type_unsigned_num); + + if (m_uiPropType & flag_array) + { + switch(a) + { + case action_replace: + { + m_paUnsigneds->clear(); + m_paUnsigneds->push_back(ullValue); + break; + } + case action_add: + { + m_paUnsigneds->push_back(ullValue); + break; + } + case action_setat: + { + assert(tIndex < m_paUnsigneds->size()); + ull_t& ull=m_paUnsigneds->at(tIndex); + ull=ullValue; + break; + } + default: + assert(false); // unhandled action type + } + } + else + m_val.ullVal=ullValue; + + check_range(); +} + +/** Sets the range of the unsigned number property value. + * + * \param[in] ullMin - minimum acceptable value of the property + * \param[in] ullMax - maximum acceptable value of the property + */ +void property::set_unsigned_range(ull_t ullMin, ull_t ullMax) +{ + assert((m_uiPropType & mask_type) == type_unsigned_num); + + // set new range + m_range.ull.ullLo=ullMin; + m_range.ull.ullHi=ullMax; + + // check range + check_range(); +} + +/** Retrieves the unsigned number value. + * + * \param[in] stIndex - index at which to retrieve value (array-based + * property types) + * \return Unsigned number value. + */ +ull_t property::get_unsigned_num(size_t stIndex) const +{ + assert((m_uiPropType & mask_type) == type_unsigned_num); + + if (m_uiPropType & flag_array) + { + assert(stIndex < m_paUnsigneds->size()); + return m_paUnsigneds->at(stIndex); + } + else + return m_val.ullVal; +} + +/** Sets a bool property value. + * + * \param[in] bValue - bool value to set + * \param[in] a - action to take when property is array-based + * \param[in] tIndex - index at which to replace value in case of item + * replace action (for array-based property types) + */ +void property::set_bool(bool bValue, actions a, size_t tIndex) +{ + assert((m_uiPropType & mask_type) == type_bool); + + if (m_uiPropType & flag_array) + { + switch(a) + { + case action_replace: + { + m_paBools->clear(); + m_paBools->push_back(bValue); + break; + } + case action_add: + { + m_paBools->push_back(bValue); + break; + } + case action_setat: + { + assert(tIndex < m_paBools->size()); + std::vector::iterator it=m_paBools->begin()+tIndex; + (*it)=bValue; + break; + } + default: + assert(false); // unhandled action type + } + } + else + m_val.bVal=bValue; +} + +/** Retrieves the bool value. + * + * \param[in] stIndex - index at which to retrieve value (array-based + * property types) + * \return Bool value. + */ +bool property::get_bool(size_t stIndex) const +{ + assert((m_uiPropType & mask_type) == type_bool); + + if (m_uiPropType & flag_array) + { + assert(stIndex < m_paBools->size()); + return m_paBools->at(stIndex); + } + else + return m_val.bVal; +} + +/** Retrieves the property count for this property. + * + * \return Property count. + */ +size_t property::get_count() const +{ + if (m_uiPropType & flag_array) + { + switch(m_uiPropType & mask_type) + { + case type_string: + return m_paStrings->size(); + case type_signed_num: + return m_paSigneds->size(); + case type_unsigned_num: + return m_paUnsigneds->size(); + case type_bool: + return m_paBools->size(); + default: + assert(false); // unhandled property type + return 0; + } + } + else + return 1; +} + +/** Removes a property value at a given index. + * + * \param[in] stIndex - index of value to remove + */ +void property::remove(size_t stIndex) +{ + if (m_uiPropType & flag_array) + { + switch(m_uiPropType & mask_type) + { + case type_string: + { + assert(stIndex < m_paStrings->size()); + m_paStrings->erase(m_paStrings->begin()+stIndex); + break; + } + case type_signed_num: + { + assert(stIndex < m_paSigneds->size()); + m_paSigneds->erase(m_paSigneds->begin()+stIndex); + break; + } + case type_unsigned_num: + { + assert(stIndex < m_paUnsigneds->size()); + m_paUnsigneds->erase(m_paUnsigneds->begin()+stIndex); + break; + } + case type_bool: + { + assert(stIndex < m_paBools->size()); + m_paBools->erase(m_paBools->begin()+stIndex); + break; + } + default: + assert(false); // unhandled property type + } + } + else + assert(false); +} + +/** Clears the array property value. + */ +void property::clear_array() +{ + if (m_uiPropType & flag_array) + { + switch(m_uiPropType & mask_type) + { + case type_string: + m_paStrings->clear(); + break; + case type_signed_num: + m_paSigneds->clear(); + break; + case type_unsigned_num: + m_paUnsigneds->clear(); + break; + case type_bool: + m_paBools->clear(); + break; + default: + assert(false); // unhandled property type + } + } +} + +/** Completely clears the value part internal members. + * Unallocates all the memory associated with values and sets + * those members to NULL. + */ +void property::clear_value() +{ + if (m_uiPropType & flag_array) + { + switch(m_uiPropType & mask_type) + { + case type_string: + delete m_paStrings; + break; + case type_signed_num: + delete m_paSigneds; + break; + case type_unsigned_num: + delete m_paUnsigneds; + break; + case type_bool: + delete m_paBools; + break; + default: + assert(false); // unhandled property type + } + + m_val.hArray=NULL; + } + else + { + switch(m_uiPropType & mask_type) + { + case type_string: + delete [] m_val.pszVal; + m_val.pszVal=NULL; + break; + case type_signed_num: + m_val.llVal=0LL; + break; + case type_unsigned_num: + m_val.ullVal=0ULL; + break; + case type_bool: + m_val.bVal=false; + break; + default: + assert(false); // not implemented? + } + } +} + +/** Function corrects the property value(s) based on the provided + * property value range. + */ +void property::check_range() +{ + if (m_uiPropType & flag_array) + { + switch(m_uiPropType & mask_type) + { + case type_signed_num: + { + for (std::vector::iterator it=m_paSigneds->begin();it != m_paSigneds->end();it++) + { + if ((*it) < m_range.ll.llLo) + (*it)=m_range.ll.llLo; + else if ((*it) > m_range.ll.llHi) + (*it)=m_range.ll.llHi; + } + break; + } + case type_unsigned_num: + { + for (std::vector::iterator it=m_paUnsigneds->begin();it != m_paUnsigneds->end();it++) + { + if ((*it) < m_range.ull.ullLo) + (*it)=m_range.ull.ullLo; + else if ((*it) > m_range.ull.ullHi) + (*it)=m_range.ull.ullHi; + } + break; + } + } + } + else + { + switch(m_uiPropType & mask_type) + { + case type_signed_num: + { + // check range + if (m_val.llVal < m_range.ll.llLo) + m_val.llVal=m_range.ll.llLo; + else if (m_val.llVal > m_range.ll.llHi) + m_val.llVal=m_range.ll.llHi; + break; + } + case type_unsigned_num: + { + // check range + if (m_val.ullVal < m_range.ull.ullLo) + m_val.ullVal=m_range.ull.ullLo; + else if (m_val.ullVal > m_range.ull.ullHi) + m_val.ullVal=m_range.ull.ullHi; + break; + } + default: + assert(false); // need to be implemented + } + } +} + +/** Makes a copy of a given string with allocating the necessary memory. + * + * \param[in] pszSrc - a source string + * \return Pointer to a newly allocated memory with new string + */ +tchar_t* property::copy_string(const tchar_t* pszSrc) +{ + if (pszSrc) + { + tchar_t *psz=new tchar_t[_tcslen(pszSrc)+1]; + _tcscpy(psz, pszSrc); + return psz; + } + else + return NULL; +} + +/** Converts a string to a boolean value. + * + * \param[in] pszSrc - string to convert + * \return Converted value. + */ +bool property::bool_from_string(const tchar_t* pszSrc) +{ + assert(pszSrc); + return pszSrc[0] != _t('0'); +} + +/** Converts a string to a signed number value. + * + * \param[in] pszSrc - string to convert + * \return Converted value. + */ +ll_t property::signed_from_string(const tchar_t* pszSrc) +{ +#if defined(_WIN32) || defined(_WIN64) + return _ttoi64(pszSrc); +#else + return atoll(pszSrc); +#endif +} + +/** Converts a string to an unsigned number value. + * + * \param[in] pszSrc - string to convert + * \return Converted value. + */ +ull_t property::unsigned_from_string(const tchar_t* pszSrc) +{ + // currently does not support full range of unsigned long long + // since there are no (?) function to convert string to ull_t +#if defined(_WIN32) || defined(_WIN64) + return _ttoi64(pszSrc); +#else + return atoll(pszSrc); +#endif +} + +/** Function makes a copy of a given property storing it in this one. + * + * \param[in] rSrc - property to copy from + * \param[in] bClear - should we cleat current contents first + */ +void property::copy_from(const property& rSrc, bool bClear) +{ + // clear values in this class + if (bClear) + clear_value(); + + // copy the value(s) + if (rSrc.m_uiPropType & flag_array) + { + // source property is an array + switch(rSrc.m_uiPropType & mask_type) + { + case type_string: + m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); + break; + case type_signed_num: + m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); + break; + case type_unsigned_num: + m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); + break; + case type_bool: + m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); + break; + default: + assert(false); // unknown property type + } + } + else + { + // source property is normal value + switch(rSrc.m_uiPropType & mask_type) + { + case type_string: + { + m_val.pszVal=copy_string(rSrc.m_val.pszVal); + break; + } + case type_signed_num: + { + m_val.llVal=rSrc.m_val.llVal; + m_range.ll.llHi=rSrc.m_range.ll.llHi; + m_range.ll.llLo=rSrc.m_range.ll.llLo; + break; + } + case type_unsigned_num: + { + m_val.ullVal=rSrc.m_val.ullVal; + m_range.ull.ullHi=rSrc.m_range.ull.ullHi; + m_range.ull.ullLo=rSrc.m_range.ull.ullLo; + break; + } + case type_bool: + { + m_val.bVal=rSrc.m_val.bVal; + break; + } + default: + assert(false); // property type not implemented? + } + } + + // copy values + m_uiPropType=rSrc.m_uiPropType; + m_pszName=copy_string(rSrc.m_pszName); +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/config_property.cpp =================================================================== diff -u -N --- ext/libicpf/src/config_property.cpp (revision 9bdff2e0b309af11014634d8c38367e4f6b656e3) +++ ext/libicpf/src/config_property.cpp (revision 0) @@ -1,988 +0,0 @@ -#include "config_property.h" -#include -#include - -BEGIN_ICPF_NAMESPACE - -////////////////////////////////////////////////////////////////////////////////// -// property class -// fast access to the array property types -#define m_paStrings ((std::vector*)m_val.hArray) -#define m_paSigneds ((std::vector*)m_val.hArray) -#define m_paUnsigneds ((std::vector*)m_val.hArray) -#define m_paBools ((std::vector*)m_val.hArray) - -/** Constructs a property object. - */ -property::property() : - m_uiPropType(type_unknown | flag_none), - m_pszName(NULL) -{ - memset(&m_val, 0, sizeof(_VALUE)); - memset(&m_range, 0, sizeof(_RANGE)); -} - -/** Constructs a property object with type initializer. - * - * \param[in] uiType - type and flags to set the property to - */ -property::property(const tchar_t* pszName, uint_t uiType) : - m_uiPropType(uiType), - m_pszName(NULL) -{ - memset(&m_val, 0, sizeof(_VALUE)); - memset(&m_range, 0, sizeof(_RANGE)); - - // init - init(pszName, uiType, false); -} - -/** Constructs a property object based on some other property object. - * - * \param[in] src - a source property object - */ -property::property(const property& src) -{ - copy_from(src, false); -} - -/** Destructs the property object. - */ -property::~property() -{ - clear(); -} - -/** Assigns one property to another. - * - * \param[in] rSrc - a source property to copy - * \return Reference to this object. - */ -property& property::operator=(const property& rSrc) -{ - if (this != &rSrc) - copy_from(rSrc, true); - - return *this; -} - -/** Clears all the internal members. - */ -void property::clear() -{ - // delete the property name - delete [] m_pszName; - m_pszName=NULL; - - clear_value(); - - // reset other members - m_uiPropType=type_unknown | flag_none; -} - -/** Initializes the property for storaging of the specific property - * type. Also sets the property name. - * The current property contents are being cleared before setting - * the new type. - * - * \param[in] uiType - the new property type - */ -void property::init(const tchar_t* pszName, uint_t uiType, bool bClear) -{ - // clear the current stuff - if (bClear) - clear(); - - // standard members - m_pszName=copy_string(pszName); - m_uiPropType=uiType; - - // and alloc memory for the array property types - if (uiType & flag_array) - { - switch(uiType & mask_type) - { - case type_string: - m_val.hArray=(ptr_t)new std::vector; - break; - case type_signed_num: - m_val.hArray=(ptr_t)new std::vector; - m_range.ll.llLo=_I64_MIN; - m_range.ll.llHi=_I64_MAX; - break; - case type_unsigned_num: - m_val.hArray=(ptr_t)new std::vector; - m_range.ull.ullLo=0; - m_range.ull.ullHi=_UI64_MAX; - break; - case type_bool: - m_val.hArray=(ptr_t)new std::vector; - break; - default: - assert(false); // unhandled property type - } - } - else - { - switch(uiType & mask_type) - { - case type_string: - case type_bool: - break; - case type_signed_num: - m_range.ll.llLo=_I64_MIN; - m_range.ll.llHi=_I64_MAX; - break; - case type_unsigned_num: - m_range.ull.ullLo=0; - m_range.ull.ullHi=_UI64_MAX; - break; - default: - assert(false); // unhandled property type - } - } -} - -/** Sets a property value from a given string. If this is the array property - * type, than the operation is defined by a given action - it either replaces - * all the previous values, or adds at the end or replaces value at a specific - * index. - * - * \param[in] pszValue - value to set (stored in a string) - * \param[in] a - action to take when the property is array-based - * \param[in] tIndex - an index at which to place the value (only meaningful - * for array property type). - */ -void property::set_value(const tchar_t* pszValue, actions a, size_t tIndex) -{ - if (m_uiPropType & flag_array) - { - switch(m_uiPropType & mask_type) - { - case type_string: - { - switch(a) - { - case action_replace: - { - m_paStrings->clear(); - m_paStrings->push_back(tstring(pszValue)); - break; - } - case action_add: - { - m_paStrings->push_back(tstring(pszValue)); - break; - } - case action_setat: - { - assert(tIndex < m_paStrings->size()); - - tstring& str=m_paStrings->at(tIndex); - str=pszValue; - break; - } - default: - assert(false); // unhandled action type - } - break; - } - case type_bool: - { - switch(a) - { - case action_replace: - { - m_paBools->clear(); - m_paBools->push_back(bool_from_string(pszValue)); - break; - } - case action_add: - { - m_paBools->push_back(bool_from_string(pszValue)); - break; - } - case action_setat: - { - assert(tIndex < m_paBools->size()); - - std::vector::iterator it=m_paBools->begin()+tIndex; - (*it)=bool_from_string(pszValue); - break; - } - default: - assert(false); // unhandled action type - } - break; - } - case type_signed_num: - { - switch(a) - { - case action_replace: - { - m_paSigneds->clear(); - m_paSigneds->push_back(signed_from_string(pszValue)); - break; - } - case action_add: - { - m_paSigneds->push_back(signed_from_string(pszValue)); - break; - } - case action_setat: - { - assert(tIndex < m_paSigneds->size()); - - ll_t& ll=m_paSigneds->at(tIndex); - ll=signed_from_string(pszValue); - break; - } - default: - assert(false); // unhandled action type - } - break; - } - case type_unsigned_num: - { - switch(a) - { - case action_replace: - { - m_paUnsigneds->clear(); - m_paUnsigneds->push_back(unsigned_from_string(pszValue)); - break; - } - case action_add: - { - m_paUnsigneds->push_back(unsigned_from_string(pszValue)); - break; - } - case action_setat: - { - assert(tIndex < m_paUnsigneds->size()); - - ull_t& ull=m_paUnsigneds->at(tIndex); - ull=unsigned_from_string(pszValue); - break; - } - default: - assert(false); // unhandled action type - } - break; - } - } - } - else - { - switch(m_uiPropType & mask_type) - { - case type_string: - { - delete [] m_val.pszVal; - m_val.pszVal=copy_string(pszValue); - break; - } - case type_signed_num: - { - m_val.llVal=signed_from_string(pszValue); - break; - } - case type_unsigned_num: - { - m_val.ullVal=unsigned_from_string(pszValue); - break; - } - case type_bool: - { - m_val.bVal=bool_from_string(pszValue); - break; - } - default: - assert(false); // not implemented? - } - } -} - -/** Retrieves the value as a string. - * - * \param[out] pszString - pointer to a string that will receive the value (could - * be NULL when retrieving string value type) - * \param[in] stMaxSize - size of the buffer (could be 0 for string value retrieval) - * \param[in] stIndex - an index at which to get the value (only meaningful - * for array property type). - * \return Pointer to the string with value. - * \note Always use the returned value as a string pointer - it could be different - * than the one provided as a buffer (in case of retrieving string value). - */ -const tchar_t* property::get_value(tchar_t* pszString, size_t stMaxSize, size_t stIndex) -{ - assert(pszString); - - if (m_uiPropType & flag_array) - { - switch(m_uiPropType & mask_type) - { - case type_string: - assert(stIndex < m_paStrings->size()); - return m_paStrings->at(stIndex).c_str(); - break; - case type_signed_num: - assert(stIndex < m_paSigneds->size()); - _sntprintf(pszString, stMaxSize, LLFMT, m_paSigneds->at(stIndex)); - break; - case type_unsigned_num: - assert(stIndex < m_paUnsigneds->size()); - _sntprintf(pszString, stMaxSize, ULLFMT, m_paUnsigneds->at(stIndex)); - break; - case type_bool: - assert(stIndex < m_paBools->size()); - _sntprintf(pszString, stMaxSize, USFMT, (ushort_t)m_paBools->at(stIndex)); - break; - default: - assert(false); - } - } - else - { - switch(m_uiPropType & mask_type) - { - case type_string: - return m_val.pszVal; - break; - case type_signed_num: - _sntprintf(pszString, stMaxSize, LLFMT, m_val.llVal); - break; - case type_unsigned_num: - _sntprintf(pszString, stMaxSize, ULLFMT, m_val.ullVal); - break; - case type_bool: - _sntprintf(pszString, stMaxSize, USFMT, (ushort_t)m_val.bVal); - break; - default: - assert(false); - } - } - - return pszString; -} - -/** Sets the string value for this property. - * - * \param[in] pszValue - string to set - * \param[in] a - action to take when property is array-based - * \param[in] tIndex - index at which to replace value in case of item - * replace action (for array-based property types) - */ -void property::set_string(const tchar_t* pszValue, actions a, size_t tIndex) -{ - assert((m_uiPropType & mask_type) == type_string); - - if (m_uiPropType & flag_array) - { - switch(a) - { - case action_replace: - { - m_paStrings->clear(); - m_paStrings->push_back(tstring(pszValue)); - break; - } - case action_add: - { - m_paStrings->push_back(tstring(pszValue)); - break; - } - case action_setat: - { - assert(tIndex < m_paStrings->size()); - tstring& str=m_paStrings->at(tIndex); - str=pszValue; - break; - } - default: - assert(false); // unhandled action type - } - } - else - { - delete [] m_val.pszVal; - m_val.pszVal=copy_string(pszValue); - } -} - -/** Retrieves the string value type. - * - * \param[in] stIndex - index at which to retrieve value (meaningful only - * for array property type) - * \return Pointer to the string. - */ -const tchar_t* property::get_string(size_t stIndex) const -{ - assert((m_uiPropType & mask_type) == type_string); - - if (m_uiPropType & flag_array) - { - assert(stIndex < m_paStrings->size()); - return m_paStrings->at(stIndex).c_str(); - } - else - return m_val.pszVal; -} - -/** Sets a signed number property value. - * - * \param[in] llValue - signed number value to set - * \param[in] a - action to take when property is array-based - * \param[in] tIndex - index at which to replace value in case of item - * replace action (for array-based property types) - */ -void property::set_signed_num(ll_t llValue, actions a, size_t tIndex) -{ - assert((m_uiPropType & mask_type) == type_signed_num); - - if (m_uiPropType & flag_array) - { - switch(a) - { - case action_replace: - { - m_paSigneds->clear(); - m_paSigneds->push_back(llValue); - break; - } - case action_add: - { - m_paSigneds->push_back(llValue); - break; - } - case action_setat: - { - assert(tIndex < m_paSigneds->size()); - ll_t& ll=m_paSigneds->at(tIndex); - ll=llValue; - break; - } - default: - assert(false); // unhandled action type - } - } - else - m_val.llVal=llValue; - - check_range(); -} - -/** Sets the range of the signed number property value. - * - * \param[in] llMin - minimum acceptable value of the property - * \param[in] llMax - maximum acceptable value of the property - */ -void property::set_signed_range(ll_t llMin, ll_t llMax) -{ - assert((m_uiPropType & mask_type) == type_signed_num); - - // set new range - m_range.ll.llLo=llMin; - m_range.ll.llHi=llMax; - - // check range - check_range(); -} - -/** Retrieves the signed number value. - * - * \param[in] stIndex - index at which to retrieve value (array-based - * property types) - * \return Signed number value. - */ -ll_t property::get_signed_num(size_t stIndex) const -{ - assert((m_uiPropType & mask_type) == type_signed_num); - - if (m_uiPropType & flag_array) - { - assert(stIndex < m_paSigneds->size()); - return m_paSigneds->at(stIndex); - } - else - return m_val.llVal; -} - -/** Sets an unsigned number property value. - * - * \param[in] ullValue - unsigned number value to set - * \param[in] a - action to take when property is array-based - * \param[in] tIndex - index at which to replace value in case of item - * replace action (for array-based property types) - */ -void property::set_unsigned_num(ull_t ullValue, actions a, size_t tIndex) -{ - assert((m_uiPropType & mask_type) == type_unsigned_num); - - if (m_uiPropType & flag_array) - { - switch(a) - { - case action_replace: - { - m_paUnsigneds->clear(); - m_paUnsigneds->push_back(ullValue); - break; - } - case action_add: - { - m_paUnsigneds->push_back(ullValue); - break; - } - case action_setat: - { - assert(tIndex < m_paUnsigneds->size()); - ull_t& ull=m_paUnsigneds->at(tIndex); - ull=ullValue; - break; - } - default: - assert(false); // unhandled action type - } - } - else - m_val.ullVal=ullValue; - - check_range(); -} - -/** Sets the range of the unsigned number property value. - * - * \param[in] ullMin - minimum acceptable value of the property - * \param[in] ullMax - maximum acceptable value of the property - */ -void property::set_unsigned_range(ull_t ullMin, ull_t ullMax) -{ - assert((m_uiPropType & mask_type) == type_unsigned_num); - - // set new range - m_range.ull.ullLo=ullMin; - m_range.ull.ullHi=ullMax; - - // check range - check_range(); -} - -/** Retrieves the unsigned number value. - * - * \param[in] stIndex - index at which to retrieve value (array-based - * property types) - * \return Unsigned number value. - */ -ull_t property::get_unsigned_num(size_t stIndex) const -{ - assert((m_uiPropType & mask_type) == type_unsigned_num); - - if (m_uiPropType & flag_array) - { - assert(stIndex < m_paUnsigneds->size()); - return m_paUnsigneds->at(stIndex); - } - else - return m_val.ullVal; -} - -/** Sets a bool property value. - * - * \param[in] bValue - bool value to set - * \param[in] a - action to take when property is array-based - * \param[in] tIndex - index at which to replace value in case of item - * replace action (for array-based property types) - */ -void property::set_bool(bool bValue, actions a, size_t tIndex) -{ - assert((m_uiPropType & mask_type) == type_bool); - - if (m_uiPropType & flag_array) - { - switch(a) - { - case action_replace: - { - m_paBools->clear(); - m_paBools->push_back(bValue); - break; - } - case action_add: - { - m_paBools->push_back(bValue); - break; - } - case action_setat: - { - assert(tIndex < m_paBools->size()); - std::vector::iterator it=m_paBools->begin()+tIndex; - (*it)=bValue; - break; - } - default: - assert(false); // unhandled action type - } - } - else - m_val.bVal=bValue; -} - -/** Retrieves the bool value. - * - * \param[in] stIndex - index at which to retrieve value (array-based - * property types) - * \return Bool value. - */ -bool property::get_bool(size_t stIndex) const -{ - assert((m_uiPropType & mask_type) == type_bool); - - if (m_uiPropType & flag_array) - { - assert(stIndex < m_paBools->size()); - return m_paBools->at(stIndex); - } - else - return m_val.bVal; -} - -/** Retrieves the property count for this property. - * - * \return Property count. - */ -size_t property::get_count() const -{ - if (m_uiPropType & flag_array) - { - switch(m_uiPropType & mask_type) - { - case type_string: - return m_paStrings->size(); - case type_signed_num: - return m_paSigneds->size(); - case type_unsigned_num: - return m_paUnsigneds->size(); - case type_bool: - return m_paBools->size(); - default: - assert(false); // unhandled property type - return 0; - } - } - else - return 1; -} - -/** Removes a property value at a given index. - * - * \param[in] stIndex - index of value to remove - */ -void property::remove(size_t stIndex) -{ - if (m_uiPropType & flag_array) - { - switch(m_uiPropType & mask_type) - { - case type_string: - { - assert(stIndex < m_paStrings->size()); - m_paStrings->erase(m_paStrings->begin()+stIndex); - break; - } - case type_signed_num: - { - assert(stIndex < m_paSigneds->size()); - m_paSigneds->erase(m_paSigneds->begin()+stIndex); - break; - } - case type_unsigned_num: - { - assert(stIndex < m_paUnsigneds->size()); - m_paUnsigneds->erase(m_paUnsigneds->begin()+stIndex); - break; - } - case type_bool: - { - assert(stIndex < m_paBools->size()); - m_paBools->erase(m_paBools->begin()+stIndex); - break; - } - default: - assert(false); // unhandled property type - } - } - else - assert(false); -} - -/** Clears the array property value. - */ -void property::clear_array() -{ - if (m_uiPropType & flag_array) - { - switch(m_uiPropType & mask_type) - { - case type_string: - m_paStrings->clear(); - break; - case type_signed_num: - m_paSigneds->clear(); - break; - case type_unsigned_num: - m_paUnsigneds->clear(); - break; - case type_bool: - m_paBools->clear(); - break; - default: - assert(false); // unhandled property type - } - } -} - -/** Completely clears the value part internal members. - * Unallocates all the memory associated with values and sets - * those members to NULL. - */ -void property::clear_value() -{ - if (m_uiPropType & flag_array) - { - switch(m_uiPropType & mask_type) - { - case type_string: - delete m_paStrings; - break; - case type_signed_num: - delete m_paSigneds; - break; - case type_unsigned_num: - delete m_paUnsigneds; - break; - case type_bool: - delete m_paBools; - break; - default: - assert(false); // unhandled property type - } - - m_val.hArray=NULL; - } - else - { - switch(m_uiPropType & mask_type) - { - case type_string: - delete [] m_val.pszVal; - m_val.pszVal=NULL; - break; - case type_signed_num: - m_val.llVal=0LL; - break; - case type_unsigned_num: - m_val.ullVal=0ULL; - break; - case type_bool: - m_val.bVal=false; - break; - default: - assert(false); // not implemented? - } - } -} - -/** Function corrects the property value(s) based on the provided - * property value range. - */ -void property::check_range() -{ - if (m_uiPropType & flag_array) - { - switch(m_uiPropType & mask_type) - { - case type_signed_num: - { - for (std::vector::iterator it=m_paSigneds->begin();it != m_paSigneds->end();it++) - { - if ((*it) < m_range.ll.llLo) - (*it)=m_range.ll.llLo; - else if ((*it) > m_range.ll.llHi) - (*it)=m_range.ll.llHi; - } - break; - } - case type_unsigned_num: - { - for (std::vector::iterator it=m_paUnsigneds->begin();it != m_paUnsigneds->end();it++) - { - if ((*it) < m_range.ull.ullLo) - (*it)=m_range.ull.ullLo; - else if ((*it) > m_range.ull.ullHi) - (*it)=m_range.ull.ullHi; - } - break; - } - } - } - else - { - switch(m_uiPropType & mask_type) - { - case type_signed_num: - { - // check range - if (m_val.llVal < m_range.ll.llLo) - m_val.llVal=m_range.ll.llLo; - else if (m_val.llVal > m_range.ll.llHi) - m_val.llVal=m_range.ll.llHi; - break; - } - case type_unsigned_num: - { - // check range - if (m_val.ullVal < m_range.ull.ullLo) - m_val.ullVal=m_range.ull.ullLo; - else if (m_val.ullVal > m_range.ull.ullHi) - m_val.ullVal=m_range.ull.ullHi; - break; - } - default: - assert(false); // need to be implemented - } - } -} - -/** Makes a copy of a given string with allocating the necessary memory. - * - * \param[in] pszSrc - a source string - * \return Pointer to a newly allocated memory with new string - */ -tchar_t* property::copy_string(const tchar_t* pszSrc) -{ - if (pszSrc) - { - tchar_t *psz=new tchar_t[_tcslen(pszSrc)+1]; - _tcscpy(psz, pszSrc); - return psz; - } - else - return NULL; -} - -/** Converts a string to a boolean value. - * - * \param[in] pszSrc - string to convert - * \return Converted value. - */ -bool property::bool_from_string(const tchar_t* pszSrc) -{ - assert(pszSrc); - return pszSrc[0] != _t('0'); -} - -/** Converts a string to a signed number value. - * - * \param[in] pszSrc - string to convert - * \return Converted value. - */ -ll_t property::signed_from_string(const tchar_t* pszSrc) -{ -#if defined(_WIN32) || defined(_WIN64) - return _ttoi64(pszSrc); -#else - return atoll(pszSrc); -#endif -} - -/** Converts a string to an unsigned number value. - * - * \param[in] pszSrc - string to convert - * \return Converted value. - */ -ull_t property::unsigned_from_string(const tchar_t* pszSrc) -{ - // currently does not support full range of unsigned long long - // since there are no (?) function to convert string to ull_t -#if defined(_WIN32) || defined(_WIN64) - return _ttoi64(pszSrc); -#else - return atoll(pszSrc); -#endif -} - -/** Function makes a copy of a given property storing it in this one. - * - * \param[in] rSrc - property to copy from - * \param[in] bClear - should we cleat current contents first - */ -void property::copy_from(const property& rSrc, bool bClear) -{ - // clear values in this class - if (bClear) - clear_value(); - - // copy the value(s) - if (rSrc.m_uiPropType & flag_array) - { - // source property is an array - switch(rSrc.m_uiPropType & mask_type) - { - case type_string: - m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); - break; - case type_signed_num: - m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); - break; - case type_unsigned_num: - m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); - break; - case type_bool: - m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); - break; - default: - assert(false); // unknown property type - } - } - else - { - // source property is normal value - switch(rSrc.m_uiPropType & mask_type) - { - case type_string: - { - m_val.pszVal=copy_string(rSrc.m_val.pszVal); - break; - } - case type_signed_num: - { - m_val.llVal=rSrc.m_val.llVal; - m_range.ll.llHi=rSrc.m_range.ll.llHi; - m_range.ll.llLo=rSrc.m_range.ll.llLo; - break; - } - case type_unsigned_num: - { - m_val.ullVal=rSrc.m_val.ullVal; - m_range.ull.ullHi=rSrc.m_range.ull.ullHi; - m_range.ull.ullLo=rSrc.m_range.ull.ullLo; - break; - } - case type_bool: - { - m_val.bVal=rSrc.m_val.bVal; - break; - } - default: - assert(false); // property type not implemented? - } - } - - // copy values - m_uiPropType=rSrc.m_uiPropType; - m_pszName=copy_string(rSrc.m_pszName); -} - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/config_property.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/config_property.h (revision 0) +++ ext/libicpf/src/libicpf/config_property.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,165 @@ +#ifndef __CONFIGPROPERTY_H__ +#define __CONFIGPROPERTY_H__ + +#include "gen_types.h" +#include "libicpf.h" + +BEGIN_ICPF_NAMESPACE + +/** \brief Basic property description class. + */ +class LIBICPF_API property +{ +public: + /// Masks identifiers for property type + enum prop_mask + { + mask_type=0x0000ffff, ///< Property type mask + mask_flags=0xffff0000 ///< Property flags mask + }; + + /// Property type definitions + enum prop_type + { + type_unknown=0x00000001, /// Unknown type (partial synonym of PT_STRING) + type_signed_num=0x00000002, /// Signed 64-bit type property + type_unsigned_num=0x00000003, /// Unsigned 64-bit type property + type_bool=0x00000004, /// Bool type property + type_string=0x00000005 /// String type property + }; + + /// Property flags definitions + enum prop_flags + { + flag_none=0x00000000, /// Standard property flag + flag_path=0x00010000, /// The string specifies a pathname flag + flag_encrypt=0x00040000, /// This flag indicates that the property has been encrypted with a password (only string values) + flag_decoded=0x00080000, /// The property is currently in decrypted state (but should be encrypted when saving) + flag_array=0x00100000, /// Array property type + flag_modified=0x00200000 /// Modification flag + }; + + // actions used by set_xxx() + enum actions + { + action_add, ///< Value should be added + action_replace, ///< Value should replace all previous values + action_setat ///< Value should replace only a specific value + }; +public: +/** \brief Construction/destruction/operators */ +/**@{*/ + property(); ///< Standard constructor + property(const tchar_t* pszName, uint_t uiType); ///< Constructor with initializer + property(const property& src); ///< Copy constructor + ~property(); ///< Standard destructor + + property& operator=(const property& rSrc); ///< Assignment operator +/**@}*/ + +/** \brief Property settings/operations */ +/**@{*/ + /// Resets the internal members + void clear(); + + /// Sets a property type + void init(const tchar_t* pszName, uint_t uiType, bool bClear=true); + /// Retrieves a property type (with flags) + uint_t get_type() const { return m_uiPropType; }; + /// Checks if the property is array-based + bool is_array() const { return (m_uiPropType & flag_array) != false; }; + + /// Sets a property name + void set_name(const tchar_t* pszName) { m_pszName=copy_string(pszName); }; + /// Gets a property name + const tchar_t* get_name() const { return m_pszName; }; + + /// Sets the modified flag + void set_modified(bool bModified) { if (bModified) m_uiPropType |= flag_modified; else m_uiPropType &= ~flag_modified; }; + /// Gets the modified flag + bool is_modified() const { return (m_uiPropType & flag_modified) != false; }; +/**@}*/ + +/** \brief Property values */ +/**@{*/ + /// Sets a value from string + void set_value(const tchar_t* pszValue, actions a=action_replace, size_t tIndex=0); + /// Gets the value as string + const tchar_t* get_value(tchar_t* pszString, size_t stMaxSize, size_t stIndex=0); + + /// Sets the string value + void set_string(const tchar_t* pszValue, actions a=action_replace, size_t tIndex=0); + /// Gets the string value + const tchar_t* get_string(size_t stIndex=0) const; + + /// Sets the signed number value + void set_signed_num(ll_t llValue, actions a=action_replace, size_t tIndex=0); + /// Sets the signed number range + void set_signed_range(ll_t llMin, ll_t llMax); + /// Gets the signed number value + ll_t get_signed_num(size_t stIndex=0) const; + + /// Sets the unsigned number value + void set_unsigned_num(ull_t ullValue, actions a=action_replace, size_t tIndex=0); + /// Sets the unsigned number range + void set_unsigned_range(ull_t ullMin, ull_t ullMax); + /// Gets the unsigned number value + ull_t get_unsigned_num(size_t stIndex=0) const; + + /// Sets the bool value + void set_bool(bool bValue, actions a=action_replace, size_t tIndex=0); + /// Gets the bool value + bool get_bool(size_t stIndex=0) const; + + /// Gets the property count for an array property type + size_t get_count() const; + /// Removes a property at a given index + void remove(size_t stIndex); + /// Clears the array + void clear_array(); +/**@}*/ + +protected: + void clear_value(); ///< Clears the current value (frees any allocated memory) + void check_range(); ///< Performs a range check on the property value + + tchar_t* copy_string(const tchar_t* pszSrc); ///< Makes a copy of a given string + bool bool_from_string(const tchar_t* pszSrc); ///< Retrieves a bool value from a string + ll_t signed_from_string(const tchar_t* pszSrc); ///< Retrieves a signed number from a string + ull_t unsigned_from_string(const tchar_t* pszSrc); ///< Retrieves an unsigned number from a string + + void copy_from(const property& rSrc, bool bClear); ///< Makes a copy of a given property + +protected: + // basic, common property description + uint_t m_uiPropType; ///< Property type and flags + tchar_t* m_pszName; ///< Name of the property + + // values + union _VALUE /// Union with different types of properties + { + ll_t llVal; ///< Signed number value + ull_t ullVal; ///< Unsigned number value + bool bVal; ///< A bool-type value + tchar_t* pszVal; ///< A string-type value + ptr_t hArray; ///< An array-type value + } m_val; + + union _RANGE /// Union with numeric properties ranges + { + struct LLRANGE + { + ll_t llLo; ///< Minimum allowed value for the longlong_t property + ll_t llHi; ///< Maximum allowed value for the longlong_t property + } ll; + struct ULLRANGE + { + ull_t ullLo; ///< Minimum allowed value for the ull_t property + ull_t ullHi; ///< Maximum allowed value for the ull_t property + } ull; + } m_range; +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/config_property.h =================================================================== diff -u -N --- ext/libicpf/src/config_property.h (revision 9bdff2e0b309af11014634d8c38367e4f6b656e3) +++ ext/libicpf/src/config_property.h (revision 0) @@ -1,165 +0,0 @@ -#ifndef __CONFIGPROPERTY_H__ -#define __CONFIGPROPERTY_H__ - -#include "gen_types.h" -#include "libicpf.h" - -BEGIN_ICPF_NAMESPACE - -/** \brief Basic property description class. - */ -class LIBICPF_API property -{ -public: - /// Masks identifiers for property type - enum prop_mask - { - mask_type=0x0000ffff, ///< Property type mask - mask_flags=0xffff0000 ///< Property flags mask - }; - - /// Property type definitions - enum prop_type - { - type_unknown=0x00000001, /// Unknown type (partial synonym of PT_STRING) - type_signed_num=0x00000002, /// Signed 64-bit type property - type_unsigned_num=0x00000003, /// Unsigned 64-bit type property - type_bool=0x00000004, /// Bool type property - type_string=0x00000005 /// String type property - }; - - /// Property flags definitions - enum prop_flags - { - flag_none=0x00000000, /// Standard property flag - flag_path=0x00010000, /// The string specifies a pathname flag - flag_encrypt=0x00040000, /// This flag indicates that the property has been encrypted with a password (only string values) - flag_decoded=0x00080000, /// The property is currently in decrypted state (but should be encrypted when saving) - flag_array=0x00100000, /// Array property type - flag_modified=0x00200000 /// Modification flag - }; - - // actions used by set_xxx() - enum actions - { - action_add, ///< Value should be added - action_replace, ///< Value should replace all previous values - action_setat ///< Value should replace only a specific value - }; -public: -/** \brief Construction/destruction/operators */ -/**@{*/ - property(); ///< Standard constructor - property(const tchar_t* pszName, uint_t uiType); ///< Constructor with initializer - property(const property& src); ///< Copy constructor - ~property(); ///< Standard destructor - - property& operator=(const property& rSrc); ///< Assignment operator -/**@}*/ - -/** \brief Property settings/operations */ -/**@{*/ - /// Resets the internal members - void clear(); - - /// Sets a property type - void init(const tchar_t* pszName, uint_t uiType, bool bClear=true); - /// Retrieves a property type (with flags) - uint_t get_type() const { return m_uiPropType; }; - /// Checks if the property is array-based - bool is_array() const { return (m_uiPropType & flag_array) != false; }; - - /// Sets a property name - void set_name(const tchar_t* pszName) { m_pszName=copy_string(pszName); }; - /// Gets a property name - const tchar_t* get_name() const { return m_pszName; }; - - /// Sets the modified flag - void set_modified(bool bModified) { if (bModified) m_uiPropType |= flag_modified; else m_uiPropType &= ~flag_modified; }; - /// Gets the modified flag - bool is_modified() const { return (m_uiPropType & flag_modified) != false; }; -/**@}*/ - -/** \brief Property values */ -/**@{*/ - /// Sets a value from string - void set_value(const tchar_t* pszValue, actions a=action_replace, size_t tIndex=0); - /// Gets the value as string - const tchar_t* get_value(tchar_t* pszString, size_t stMaxSize, size_t stIndex=0); - - /// Sets the string value - void set_string(const tchar_t* pszValue, actions a=action_replace, size_t tIndex=0); - /// Gets the string value - const tchar_t* get_string(size_t stIndex=0) const; - - /// Sets the signed number value - void set_signed_num(ll_t llValue, actions a=action_replace, size_t tIndex=0); - /// Sets the signed number range - void set_signed_range(ll_t llMin, ll_t llMax); - /// Gets the signed number value - ll_t get_signed_num(size_t stIndex=0) const; - - /// Sets the unsigned number value - void set_unsigned_num(ull_t ullValue, actions a=action_replace, size_t tIndex=0); - /// Sets the unsigned number range - void set_unsigned_range(ull_t ullMin, ull_t ullMax); - /// Gets the unsigned number value - ull_t get_unsigned_num(size_t stIndex=0) const; - - /// Sets the bool value - void set_bool(bool bValue, actions a=action_replace, size_t tIndex=0); - /// Gets the bool value - bool get_bool(size_t stIndex=0) const; - - /// Gets the property count for an array property type - size_t get_count() const; - /// Removes a property at a given index - void remove(size_t stIndex); - /// Clears the array - void clear_array(); -/**@}*/ - -protected: - void clear_value(); ///< Clears the current value (frees any allocated memory) - void check_range(); ///< Performs a range check on the property value - - tchar_t* copy_string(const tchar_t* pszSrc); ///< Makes a copy of a given string - bool bool_from_string(const tchar_t* pszSrc); ///< Retrieves a bool value from a string - ll_t signed_from_string(const tchar_t* pszSrc); ///< Retrieves a signed number from a string - ull_t unsigned_from_string(const tchar_t* pszSrc); ///< Retrieves an unsigned number from a string - - void copy_from(const property& rSrc, bool bClear); ///< Makes a copy of a given property - -protected: - // basic, common property description - uint_t m_uiPropType; ///< Property type and flags - tchar_t* m_pszName; ///< Name of the property - - // values - union _VALUE /// Union with different types of properties - { - ll_t llVal; ///< Signed number value - ull_t ullVal; ///< Unsigned number value - bool bVal; ///< A bool-type value - tchar_t* pszVal; ///< A string-type value - ptr_t hArray; ///< An array-type value - } m_val; - - union _RANGE /// Union with numeric properties ranges - { - struct LLRANGE - { - ll_t llLo; ///< Minimum allowed value for the longlong_t property - ll_t llHi; ///< Maximum allowed value for the longlong_t property - } ll; - struct ULLRANGE - { - ull_t ullLo; ///< Minimum allowed value for the ull_t property - ull_t ullHi; ///< Maximum allowed value for the ull_t property - } ull; - } m_range; -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/conv.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/conv.cpp (revision 0) +++ ext/libicpf/src/libicpf/conv.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "conv.h" +#include + +BEGIN_ICPF_NAMESPACE + +char_t __hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + +LIBICPF_API void bin2hex(const uchar_t* pbyIn, uint_t tInCount, char_t *pszOut) +{ + for (uint_t i=0;i> 4) & 0x0f]; + *pszOut++=__hex[pbyIn[i] & 0x0f]; + } +} + +LIBICPF_API bool hex2bin(const char_t* pszIn, uint_t tInCount, uchar_t *pbyOut) +{ + // we can pass -1 as in size - count it then + if (tInCount == (uint_t)-1) + tInCount=(uint_t)strlen(pszIn); + + // make sure the tInCount is even + tInCount &= ~((size_t)1); + byte_t by; + for (size_t i=0;i= '0' && *pszIn <= '9') + by=(byte_t)(*pszIn - '0') << 4; + else if (*pszIn >= 'a' && *pszIn <= 'f') + by=(byte_t)(*pszIn - 'a' + 10) << 4; + else if (*pszIn >= 'A' && *pszIn <= 'F') + by=(byte_t)(*pszIn - 'A' + 10) << 4; + else + return false; + + // lsb 4bits + pszIn++; + if (*pszIn >= '0' && *pszIn <= '9') + by|=(*pszIn - '0'); + else if (*pszIn >= 'a' && *pszIn <= 'f') + by|=(*pszIn - 'a' + 10); + else if (*pszIn >= 'A' && *pszIn <= 'F') + by|=(*pszIn - 'A' + 10); + else + return false; + + pszIn++; + *pbyOut++=by; + } + + return true; +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/conv.cpp =================================================================== diff -u -N --- ext/libicpf/src/conv.cpp (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/conv.cpp (revision 0) @@ -1,75 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "conv.h" -#include - -BEGIN_ICPF_NAMESPACE - -char_t __hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - -LIBICPF_API void bin2hex(const uchar_t* pbyIn, uint_t tInCount, char_t *pszOut) -{ - for (uint_t i=0;i> 4) & 0x0f]; - *pszOut++=__hex[pbyIn[i] & 0x0f]; - } -} - -LIBICPF_API bool hex2bin(const char_t* pszIn, uint_t tInCount, uchar_t *pbyOut) -{ - // we can pass -1 as in size - count it then - if (tInCount == (uint_t)-1) - tInCount=(uint_t)strlen(pszIn); - - // make sure the tInCount is even - tInCount &= ~((size_t)1); - byte_t by; - for (size_t i=0;i= '0' && *pszIn <= '9') - by=(byte_t)(*pszIn - '0') << 4; - else if (*pszIn >= 'a' && *pszIn <= 'f') - by=(byte_t)(*pszIn - 'a' + 10) << 4; - else if (*pszIn >= 'A' && *pszIn <= 'F') - by=(byte_t)(*pszIn - 'A' + 10) << 4; - else - return false; - - // lsb 4bits - pszIn++; - if (*pszIn >= '0' && *pszIn <= '9') - by|=(*pszIn - '0'); - else if (*pszIn >= 'a' && *pszIn <= 'f') - by|=(*pszIn - 'a' + 10); - else if (*pszIn >= 'A' && *pszIn <= 'F') - by|=(*pszIn - 'A' + 10); - else - return false; - - pszIn++; - *pbyOut++=by; - } - - return true; -} - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/conv.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/conv.h (revision 0) +++ ext/libicpf/src/libicpf/conv.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __CONV_H__ +#define __CONV_H__ + +#include "libicpf.h" +#include "gen_types.h" + +BEGIN_ICPF_NAMESPACE + +LIBICPF_API void bin2hex(const uchar_t *pbyIn, uint_t tInCount, char_t *pszOut); +LIBICPF_API bool hex2bin(const char_t* pszIn, uint_t tInCount, uchar_t* pbyOut); + +END_ICPF_NAMESPACE + +#endif + Index: ext/libicpf/src/conv.h =================================================================== diff -u -N --- ext/libicpf/src/conv.h (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/conv.h (revision 0) @@ -1,34 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef __CONV_H__ -#define __CONV_H__ - -#include "libicpf.h" -#include "gen_types.h" - -BEGIN_ICPF_NAMESPACE - -LIBICPF_API void bin2hex(const uchar_t *pbyIn, uint_t tInCount, char_t *pszOut); -LIBICPF_API bool hex2bin(const char_t* pszIn, uint_t tInCount, uchar_t* pbyOut); - -END_ICPF_NAMESPACE - -#endif - Index: ext/libicpf/src/libicpf/crc32.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/crc32.cpp (revision 0) +++ ext/libicpf/src/libicpf/crc32.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,160 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file crc32.cpp + * \brief Contain implementation of a function counting crc32 checksum + */ + +#include "crc32.h" +#include +#ifndef _WIN32 + #include +#endif + +BEGIN_ICPF_NAMESPACE + +/// Helper data for calculating crc32 values +uint_t __crc32data__[256] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, +}; + +/** \brief Updates the partial crc32 checksum with an additional byte. + * \param[in] byte - next byte of a buffer to process + * \param[in,out] pdwCrc32 - ptr to a current crc32 checksum + */ +inline void __crc32partial(byte_t byte, uint_t *pdwCrc32) +{ +// assert(pdwCrc32 != NULL); + *pdwCrc32 = ((*pdwCrc32) >> 8) ^ __crc32data__[byte ^ ((*pdwCrc32) & 0x000000FF)]; +} + +/** Function calculates the crc32 checksum for the given data buffer. + * \param[in] pbyData - pointer to a buffer with data which checksum is to be calculated + * \param[in] tLen - length of the data in a buffer + * \return Calculated crc32 checksum. + */ +uint_t crc32(const byte_t* pbyData, size_t tLen) +{ + uint_t dwCRC=0xffffffff; + for (size_t i=0;i -#ifndef _WIN32 - #include -#endif - -BEGIN_ICPF_NAMESPACE - -/// Helper data for calculating crc32 values -uint_t __crc32data__[256] = -{ - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, -}; - -/** \brief Updates the partial crc32 checksum with an additional byte. - * \param[in] byte - next byte of a buffer to process - * \param[in,out] pdwCrc32 - ptr to a current crc32 checksum - */ -inline void __crc32partial(byte_t byte, uint_t *pdwCrc32) -{ -// assert(pdwCrc32 != NULL); - *pdwCrc32 = ((*pdwCrc32) >> 8) ^ __crc32data__[byte ^ ((*pdwCrc32) & 0x000000FF)]; -} - -/** Function calculates the crc32 checksum for the given data buffer. - * \param[in] pbyData - pointer to a buffer with data which checksum is to be calculated - * \param[in] tLen - length of the data in a buffer - * \return Calculated crc32 checksum. - */ -uint_t crc32(const byte_t* pbyData, size_t tLen) -{ - uint_t dwCRC=0xffffffff; - for (size_t i=0;i + +BEGIN_ICPF_NAMESPACE + +/// Calculates crc32 checksum for a given data +LIBICPF_API uint_t crc32(const byte_t* pbyData, size_t tLen); + +LIBICPF_API void crc32_begin(uint_t *puiValue); +LIBICPF_API void crc32_partial(uint_t *puiPrev, const byte_t *pbyData, size_t tLen); +LIBICPF_API void crc32_finish(const uint_t* puiValue); + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/crc32.h =================================================================== diff -u -N --- ext/libicpf/src/crc32.h (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/crc32.h (revision 0) @@ -1,43 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -/** \file crc32.h - * \brief Contain function counting crc32 checksum - */ - -#ifndef __CRC32_H__ -#define __CRC32_H__ - -#include "libicpf.h" -#include "gen_types.h" -#include - -BEGIN_ICPF_NAMESPACE - -/// Calculates crc32 checksum for a given data -LIBICPF_API uint_t crc32(const byte_t* pbyData, size_t tLen); - -LIBICPF_API void crc32_begin(uint_t *puiValue); -LIBICPF_API void crc32_partial(uint_t *puiPrev, const byte_t *pbyData, size_t tLen); -LIBICPF_API void crc32_finish(const uint_t* puiValue); - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/dmutex.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/dmutex.cpp (revision 0) +++ ext/libicpf/src/libicpf/dmutex.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file dmutex.cpp + * \brief Contains mutex class for thread safe access with debugging capabilities (implementation). + * \see The mutex class. + */ +#include "dmutex.h" + +#ifdef ENABLE_MUTEX_DEBUGGING + +#include +#include + +#ifdef _WIN32 + #include +#endif + +BEGIN_ICPF_NAMESPACE + +/////////////////////////////////////////////////////////////// +// debuggable mutex + +/** \brief Static dump context. + * + * Must be initialized before using this class. + */ +dumpctx* d_mutex::m_pContext=NULL; + +/** Constructs an unnamed mutex with a given dump context which will receive + * notifications about locking and unlocking of this mutex. + */ +d_mutex::d_mutex() : + mutex(), + m_ulLockCount(0) +{ + const char_t* psz="Unnamed"; + m_pszName=new char_t[strlen(psz)+1]; + strcpy(m_pszName, psz); + + m_ulLockCount=0; +} + +/** Constructs a named mutex with a given dump context which will receive + * notifications about locking and unlocking of this mutex. + * + * \param[in] pszStr - name of this mutex (will be used for logging purposes) + */ +d_mutex::d_mutex(const char_t* pszStr) : + mutex(pszStr), + m_ulLockCount(0) +{ + m_pszName=new char_t[strlen(pszStr)+1]; + strcpy(m_pszName, pszStr); +} + +/** Destructs the object + */ +d_mutex::~d_mutex() +{ + delete [] m_pszName; +} + +/** Locks this mutex. Takes some parameters that should identify the place in code which + * at which the locking occurs. + * + * \param[in] pszFile - name of the source file in which the locking was requested + * \param[in] ulLine - line of code in the file at which the locking was requested + * \param[in] pszFunction - name of the function in which the locking was requested + */ +void d_mutex::lock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction) +{ + assert(m_pContext); + char_t sz[512]; + + // pre-lock notification + if (m_pContext) + { +#ifdef _WIN32 + uint_t uiThread=GetCurrentThreadId(); + uint_t uiTime=GetTickCount(); +#else + // TODO: linux version of thread id must be put here sometime in the future + assert(false); + uint_t uiThread=0; + uint_t uiTime=time(NULL); +#endif + _snprintf(sz, 512, "[%lu][%lu][%s] Lock attempt (current lock count: %lu) in (%s - %lu: %s)", uiTime, uiThread, m_pszName, m_ulLockCount, pszFile, ulLine, pszFunction); + m_pContext->open(sz); + m_pContext->close(); + } + + // this is the real locking + ((mutex*)this)->lock(); + m_ulLockCount++; + + // post-lock information + if (m_pContext) + { +#ifdef _WIN32 + uint_t uiThread=GetCurrentThreadId(); + uint_t uiTime=GetTickCount(); +#else + // TODO: linux version of thread id must be put here sometime in the future + assert(false); + uint_t uiThread=0; + uint_t uiTime=time(NULL); +#endif + _snprintf(sz, 512, "[%lu][%lu][%s] LOCKED (current lock count: %lu) in (%s - %lu: %s)", uiTime, uiThread, m_pszName, m_ulLockCount, pszFile, ulLine, pszFunction); + m_pContext->open(sz); + m_pContext->close(); + } +} + +/** Unlocks this mutex. Takes some parameters that should identify the place in code which + * at which the unlocking occurs. + * + * \param[in] pszFile - name of the source file in which the unlocking was requested + * \param[in] ulLine - line of code in the file at which the unlocking was requested + * \param[in] pszFunction - name of the function in which the unlocking was requested + */ +void d_mutex::unlock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction) +{ + assert(m_pContext); + char_t sz[512]; + + // pre-lock notification + if (m_pContext) + { +#ifdef _WIN32 + uint_t uiThread=GetCurrentThreadId(); + uint_t uiTime=GetTickCount(); +#else + // TODO: linux version of thread id must be put here sometime in the future + assert(false); + uint_t uiThread=0; + uint_t uiTime=time(NULL); +#endif + _snprintf(sz, 512, "[%lu][%lu][%s] Unlock attempt (current lock count: %lu) in (%s - %lu: %s)", uiTime, uiThread, m_pszName, m_ulLockCount, pszFile, ulLine, pszFunction); + m_pContext->open(sz); + m_pContext->close(); + } + + // log the attempt and lock it + m_ulLockCount--; + ((mutex*)this)->unlock(); + + // post-unlock notification + // NOTE: code here is quite dangerous - and could CRASH the application; + // we have just unlocked the real mutex, so anyone has access to the object protected + // by this d_mutex. If the object being protected is removed - the internal members + // would be invalid. It especially have some meaning for the sprintf function + // probably because of the m_pszName member + if (m_pContext) + { +#ifdef _WIN32 + uint_t uiThread=GetCurrentThreadId(); + uint_t uiTime=GetTickCount(); +#else + // TODO: linux version of thread id must be put here sometime in the future + assert(false); + uint_t uiThread=0; + uint_t uiTime=time(NULL); +#endif + _snprintf(sz, 512, "[%lu][%lu][%s] UNLOCKED (current lock count: %lu) in (%s - %lu: %s)", uiTime, uiThread, m_pszName, m_ulLockCount, pszFile, ulLine, pszFunction); + m_pContext->open(sz); + m_pContext->close(); + } +} + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/dmutex.cpp =================================================================== diff -u -N --- ext/libicpf/src/dmutex.cpp (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/dmutex.cpp (revision 0) @@ -1,189 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file dmutex.cpp - * \brief Contains mutex class for thread safe access with debugging capabilities (implementation). - * \see The mutex class. - */ -#include "dmutex.h" - -#ifdef ENABLE_MUTEX_DEBUGGING - -#include -#include - -#ifdef _WIN32 - #include -#endif - -BEGIN_ICPF_NAMESPACE - -/////////////////////////////////////////////////////////////// -// debuggable mutex - -/** \brief Static dump context. - * - * Must be initialized before using this class. - */ -dumpctx* d_mutex::m_pContext=NULL; - -/** Constructs an unnamed mutex with a given dump context which will receive - * notifications about locking and unlocking of this mutex. - */ -d_mutex::d_mutex() : - mutex(), - m_ulLockCount(0) -{ - const char_t* psz="Unnamed"; - m_pszName=new char_t[strlen(psz)+1]; - strcpy(m_pszName, psz); - - m_ulLockCount=0; -} - -/** Constructs a named mutex with a given dump context which will receive - * notifications about locking and unlocking of this mutex. - * - * \param[in] pszStr - name of this mutex (will be used for logging purposes) - */ -d_mutex::d_mutex(const char_t* pszStr) : - mutex(pszStr), - m_ulLockCount(0) -{ - m_pszName=new char_t[strlen(pszStr)+1]; - strcpy(m_pszName, pszStr); -} - -/** Destructs the object - */ -d_mutex::~d_mutex() -{ - delete [] m_pszName; -} - -/** Locks this mutex. Takes some parameters that should identify the place in code which - * at which the locking occurs. - * - * \param[in] pszFile - name of the source file in which the locking was requested - * \param[in] ulLine - line of code in the file at which the locking was requested - * \param[in] pszFunction - name of the function in which the locking was requested - */ -void d_mutex::lock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction) -{ - assert(m_pContext); - char_t sz[512]; - - // pre-lock notification - if (m_pContext) - { -#ifdef _WIN32 - uint_t uiThread=GetCurrentThreadId(); - uint_t uiTime=GetTickCount(); -#else - // TODO: linux version of thread id must be put here sometime in the future - assert(false); - uint_t uiThread=0; - uint_t uiTime=time(NULL); -#endif - _snprintf(sz, 512, "[%lu][%lu][%s] Lock attempt (current lock count: %lu) in (%s - %lu: %s)", uiTime, uiThread, m_pszName, m_ulLockCount, pszFile, ulLine, pszFunction); - m_pContext->open(sz); - m_pContext->close(); - } - - // this is the real locking - ((mutex*)this)->lock(); - m_ulLockCount++; - - // post-lock information - if (m_pContext) - { -#ifdef _WIN32 - uint_t uiThread=GetCurrentThreadId(); - uint_t uiTime=GetTickCount(); -#else - // TODO: linux version of thread id must be put here sometime in the future - assert(false); - uint_t uiThread=0; - uint_t uiTime=time(NULL); -#endif - _snprintf(sz, 512, "[%lu][%lu][%s] LOCKED (current lock count: %lu) in (%s - %lu: %s)", uiTime, uiThread, m_pszName, m_ulLockCount, pszFile, ulLine, pszFunction); - m_pContext->open(sz); - m_pContext->close(); - } -} - -/** Unlocks this mutex. Takes some parameters that should identify the place in code which - * at which the unlocking occurs. - * - * \param[in] pszFile - name of the source file in which the unlocking was requested - * \param[in] ulLine - line of code in the file at which the unlocking was requested - * \param[in] pszFunction - name of the function in which the unlocking was requested - */ -void d_mutex::unlock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction) -{ - assert(m_pContext); - char_t sz[512]; - - // pre-lock notification - if (m_pContext) - { -#ifdef _WIN32 - uint_t uiThread=GetCurrentThreadId(); - uint_t uiTime=GetTickCount(); -#else - // TODO: linux version of thread id must be put here sometime in the future - assert(false); - uint_t uiThread=0; - uint_t uiTime=time(NULL); -#endif - _snprintf(sz, 512, "[%lu][%lu][%s] Unlock attempt (current lock count: %lu) in (%s - %lu: %s)", uiTime, uiThread, m_pszName, m_ulLockCount, pszFile, ulLine, pszFunction); - m_pContext->open(sz); - m_pContext->close(); - } - - // log the attempt and lock it - m_ulLockCount--; - ((mutex*)this)->unlock(); - - // post-unlock notification - // NOTE: code here is quite dangerous - and could CRASH the application; - // we have just unlocked the real mutex, so anyone has access to the object protected - // by this d_mutex. If the object being protected is removed - the internal members - // would be invalid. It especially have some meaning for the sprintf function - // probably because of the m_pszName member - if (m_pContext) - { -#ifdef _WIN32 - uint_t uiThread=GetCurrentThreadId(); - uint_t uiTime=GetTickCount(); -#else - // TODO: linux version of thread id must be put here sometime in the future - assert(false); - uint_t uiThread=0; - uint_t uiTime=time(NULL); -#endif - _snprintf(sz, 512, "[%lu][%lu][%s] UNLOCKED (current lock count: %lu) in (%s - %lu: %s)", uiTime, uiThread, m_pszName, m_ulLockCount, pszFile, ulLine, pszFunction); - m_pContext->open(sz); - m_pContext->close(); - } -} - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/dmutex.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/dmutex.h (revision 0) +++ ext/libicpf/src/libicpf/dmutex.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file dmutex.h + * \brief Contains mutex class for thread safe access with debugging capabilities. + * \see The mutex class. + */ +#ifndef __DMUTEX_H__ +#define __DMUTEX_H__ + +#include "libicpf.h" +#include "gen_types.h" +#include "dumpctx.h" +#include "mutex.h" + +#ifdef ENABLE_MUTEX_DEBUGGING + +BEGIN_ICPF_NAMESPACE + +/** \brief Class provides the locking and unlocking capabilities for use with threads. + * + * Class is a simple wrapper over the system related thread locking functions. In linux + * those functions are pthread_mutex_* and in windoze the functions related to CRITICAL_SECTION + * structure. + * This class is very similar to the mutex class, with the difference that it allows logging + * of the locking/unlocking allowing easier debugging of the mutexes. Interface is almost + * out-of-the-box replaceable with standard mutex class. + * To use this class properly - the icpf::d_mutex::m_pContext static member has to be initialized + * to a pointer to a dumpctx class that will receive notifications. + */ +class LIBICPF_API d_mutex : public mutex +{ +public: +/** \name Construction/destruction */ +/**@{*/ + d_mutex(); ///< Constructs an unnamed mutex + d_mutex(const char_t* pszStr); ///< Constructs a named mutex + virtual ~d_mutex(); ///< Standard destructor +/**@}*/ + + // standard locking +/** \name Locking/unlocking */ +/**@{*/ + void lock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction); ///< Locking with logging + void unlock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction); ///< Unlocking with logging +/**@}*/ + +public: + static dumpctx* m_pContext; ///< Dump context that will receive informations about locking/unlocking + +private: + char* m_pszName; ///< Name of the mutex + ulong_t m_ulLockCount; ///< Current lock count +}; + +END_ICPF_NAMESPACE + +#endif + +#endif Index: ext/libicpf/src/dmutex.h =================================================================== diff -u -N --- ext/libicpf/src/dmutex.h (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/dmutex.h (revision 0) @@ -1,76 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file dmutex.h - * \brief Contains mutex class for thread safe access with debugging capabilities. - * \see The mutex class. - */ -#ifndef __DMUTEX_H__ -#define __DMUTEX_H__ - -#include "libicpf.h" -#include "gen_types.h" -#include "dumpctx.h" -#include "mutex.h" - -#ifdef ENABLE_MUTEX_DEBUGGING - -BEGIN_ICPF_NAMESPACE - -/** \brief Class provides the locking and unlocking capabilities for use with threads. - * - * Class is a simple wrapper over the system related thread locking functions. In linux - * those functions are pthread_mutex_* and in windoze the functions related to CRITICAL_SECTION - * structure. - * This class is very similar to the mutex class, with the difference that it allows logging - * of the locking/unlocking allowing easier debugging of the mutexes. Interface is almost - * out-of-the-box replaceable with standard mutex class. - * To use this class properly - the icpf::d_mutex::m_pContext static member has to be initialized - * to a pointer to a dumpctx class that will receive notifications. - */ -class LIBICPF_API d_mutex : public mutex -{ -public: -/** \name Construction/destruction */ -/**@{*/ - d_mutex(); ///< Constructs an unnamed mutex - d_mutex(const char_t* pszStr); ///< Constructs a named mutex - virtual ~d_mutex(); ///< Standard destructor -/**@}*/ - - // standard locking -/** \name Locking/unlocking */ -/**@{*/ - void lock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction); ///< Locking with logging - void unlock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction); ///< Unlocking with logging -/**@}*/ - -public: - static dumpctx* m_pContext; ///< Dump context that will receive informations about locking/unlocking - -private: - char* m_pszName; ///< Name of the mutex - ulong_t m_ulLockCount; ///< Current lock count -}; - -END_ICPF_NAMESPACE - -#endif - -#endif Index: ext/libicpf/src/libicpf/dumpctx.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/dumpctx.cpp (revision 0) +++ ext/libicpf/src/libicpf/dumpctx.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,265 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file dumpctx.cpp + * \brief Contain implementation of class dumpctx - a debug helper class. + */ +#include "dumpctx.h" +#include +#include "log.h" + +BEGIN_ICPF_NAMESPACE + +/// Helper definition for faster access +#define m_pBuffer ((tstring_t*)m_hBuffer) + +/** Constructor stores the passed data in the internal members. + * \param[in] uiType - type of dump (one of the DCX_*) + * \param[in] pParam - additional param - the type of theis param depends on the ulType + */ +dumpctx::dumpctx(uint_t uiType, ptr_t pParam) : + m_lock(), + m_hBuffer((ptr_t)new tstring_t), + m_uiType(uiType), + m_pParam(pParam) +{ + m_uiType=uiType; + if (uiType == type_file) + { + size_t tLen=_tcslen((const tchar_t*)pParam); + m_pParam=(ptr_t)new tchar_t[tLen+1]; + _tcscpy((tchar_t*)m_pParam, (const tchar_t*)pParam); + } + else + m_pParam=pParam; + m_szBuffer[0]=_t('\0'); +} + +/** Destructor frees the internal data if needed + */ +dumpctx::~dumpctx() +{ + if (m_uiType == type_file) + delete [] (tchar_t*)m_pParam; + else + m_pParam=NULL; // we won't have a leak here, since we don't alloc memory for case m_uiType != type_file +} + +/** Function opens the dump. It means initializing the internal string + * that will contain the dump result and locking the class (using mutex). + * \note Always call the close() member if you have opened the dump. + */ +void dumpctx::open(const tchar_t* pszObject) +{ + MLOCK(m_lock); + *m_pBuffer=pszObject; + *m_pBuffer+=_t("\n"); +} + +/** Closes the dump. Depending on the type specified in the constructor the + * function outputs the dump to the specified location. Also the internal + * buffer is cleared. + */ +void dumpctx::close() +{ + // perform a dump - depending on the type of a dest object + switch(m_uiType) + { + case type_std: + { + _tprintf(TSTRFMT, m_pBuffer->c_str()); + break; + } + case type_file: + { + FILE* pFile=_tfopen((const tchar_t*)m_pParam, _t("a")); + if (pFile != NULL) + { + _ftprintf(pFile, TSTRFMT, m_pBuffer->c_str()); + fclose(pFile); + } + + break; + } + case type_filehandle: + { + _ftprintf((FILE*)m_pParam, TSTRFMT, m_pBuffer->c_str()); + break; + } + case type_log: + { + ((log_file*)m_pParam)->logd(TSTRFMT, m_pBuffer->c_str()); + break; + } + default: + break; + } + + // clean the internal buffer + m_pBuffer->clear(); + + MUNLOCK(m_lock); +} + +/** Function dumps (stores in the internal string object) the given ansi string. + * Strings longer than max_dump characters will be truncated. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] pszValue - an ansi string - the value of a given member + */ +void dumpctx::dump(const tchar_t* pszName, const tchar_t* pszValue) +{ + _sntprintf(m_szBuffer, max_dump, TSTRFMT _t(" (tstring):\n\t") PTRFMT _t(" (\"") TSTRFMT _t("\")\n"), pszName, pszValue, pszValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +} + +/** Function dumps (stores in the internal string object) the given unicode string. + * Strings longer than max_dump characters will be truncated. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] pszValue - an unicode string - the value of a given member + */ +/*void dumpctx::dump(const tchar_t* pszName, const wchar_t* pszValue) +{ + _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (wide string):\n\t") PTRFMT _t(" (\"") WSTRFMT _t("\")\n"), pszName, pszValue, pszValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +}*/ + +/** Function dumps (stores in the internal string object) the given character. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] cValue - a character (signed tchar_t) value + */ +void dumpctx::dump(const tchar_t* pszName, const tchar_t cValue) +{ + _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (tchar_t):\n\t'") CHARFMT _t("' (hex: ") CXFMT _t(" / dec: ") CFMT _t(")\n"), pszName, cValue, (short_t)cValue, (short_t)cValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +} + +/** Function dumps (stores in the internal string object) the given short_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] sValue - a short_t value to dump + */ +void dumpctx::dump(const tchar_t* pszName, const short_t sValue) +{ + _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (short_t):\n\t") SFMT _t(" (hex: ") SXFMT _t(")\n"), pszName, sValue, sValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +} + +/** Function dumps (stores in the internal string object) the given int_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] iValue - a int_t value to dump + */ +void dumpctx::dump(const tchar_t* pszName, const int_t iValue) +{ + _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (int_t):\n\t") LFMT _t(" (hex: ") LXFMT _t(")\n"), pszName, iValue, iValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +} + +/** Function dumps (stores in the internal string object) the given uchar_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] ucValue - an uchar_t value to dump + */ +void dumpctx::dump(const tchar_t* pszName, const uchar_t ucValue) +{ + _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (uchar_t):\n\t'") UCHARFMT _t("' (hex: ") UCXFMT _t(" / dec: ") UCFMT _t(")\n"), pszName, ucValue, (ushort_t)ucValue, (ushort_t)ucValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +} + +/** Function dumps (stores in the internal string object) the given ushort_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] usValue - an ushort_t value to dump + */ +void dumpctx::dump(const tchar_t* pszName, const ushort_t usValue) +{ + _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (ushort_t):\n\t") USFMT _t(" (hex: ") USXFMT _t(")\n"), pszName, usValue, usValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +} + +/** Function dumps (stores in the internal string object) the given uint_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] uiValue - an uint_t value to dump + */ +void dumpctx::dump(const tchar_t* pszName, const uint_t uiValue) +{ + _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (uint_t):\n\t") ULFMT _t(" (hex: ") ULXFMT _t(")\n"), pszName, uiValue, uiValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +} + +/** Function dumps (stores in the internal string object) the longlong_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] llValue - a longlong_t value to dump + */ +void dumpctx::dump(const tchar_t* pszName, const longlong_t llValue) +{ + _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (longlong_t):\n\t") LLFMT _t(" (hex: ") LLXFMT _t(")\n"), pszName, llValue, llValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +} + +/** Function dumps (stores in the internal string object) the ulonglong_t. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] ullValue - an ulonglong_t value to dump + */ +void dumpctx::dump(const tchar_t* pszName, const ulonglong_t ullValue) +{ + _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (ulonglong_t):\n\t") ULLFMT _t(" (hex: ") ULLXFMT _t(")\n"), pszName, ullValue, ullValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +} + +/** Function dumps (stores in the internal string object) the untyped pointer. + * \param[in] pszName - name of the member variable of the dumped object + * \param[in] pValue - an untyped pointer value to dump + */ +void dumpctx::dump(const tchar_t* pszName, const ptr_t pValue) +{ + _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (ptr_t):\n\t") PTRFMT _t("\n"), pszName, pValue); + m_szBuffer[max_dump-1]=_t('\0'); + MLOCK(m_lock); + *m_pBuffer+=m_szBuffer; + MUNLOCK(m_lock); +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/dumpctx.cpp =================================================================== diff -u -N --- ext/libicpf/src/dumpctx.cpp (revision ea1d52b4f82729e45b3b6683df8341edcd9f7348) +++ ext/libicpf/src/dumpctx.cpp (revision 0) @@ -1,265 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file dumpctx.cpp - * \brief Contain implementation of class dumpctx - a debug helper class. - */ -#include "dumpctx.h" -#include -#include "log.h" - -BEGIN_ICPF_NAMESPACE - -/// Helper definition for faster access -#define m_pBuffer ((tstring_t*)m_hBuffer) - -/** Constructor stores the passed data in the internal members. - * \param[in] uiType - type of dump (one of the DCX_*) - * \param[in] pParam - additional param - the type of theis param depends on the ulType - */ -dumpctx::dumpctx(uint_t uiType, ptr_t pParam) : - m_lock(), - m_hBuffer((ptr_t)new tstring_t), - m_uiType(uiType), - m_pParam(pParam) -{ - m_uiType=uiType; - if (uiType == type_file) - { - size_t tLen=_tcslen((const tchar_t*)pParam); - m_pParam=(ptr_t)new tchar_t[tLen+1]; - _tcscpy((tchar_t*)m_pParam, (const tchar_t*)pParam); - } - else - m_pParam=pParam; - m_szBuffer[0]=_t('\0'); -} - -/** Destructor frees the internal data if needed - */ -dumpctx::~dumpctx() -{ - if (m_uiType == type_file) - delete [] (tchar_t*)m_pParam; - else - m_pParam=NULL; // we won't have a leak here, since we don't alloc memory for case m_uiType != type_file -} - -/** Function opens the dump. It means initializing the internal string - * that will contain the dump result and locking the class (using mutex). - * \note Always call the close() member if you have opened the dump. - */ -void dumpctx::open(const tchar_t* pszObject) -{ - MLOCK(m_lock); - *m_pBuffer=pszObject; - *m_pBuffer+=_t("\n"); -} - -/** Closes the dump. Depending on the type specified in the constructor the - * function outputs the dump to the specified location. Also the internal - * buffer is cleared. - */ -void dumpctx::close() -{ - // perform a dump - depending on the type of a dest object - switch(m_uiType) - { - case type_std: - { - _tprintf(TSTRFMT, m_pBuffer->c_str()); - break; - } - case type_file: - { - FILE* pFile=_tfopen((const tchar_t*)m_pParam, _t("a")); - if (pFile != NULL) - { - _ftprintf(pFile, TSTRFMT, m_pBuffer->c_str()); - fclose(pFile); - } - - break; - } - case type_filehandle: - { - _ftprintf((FILE*)m_pParam, TSTRFMT, m_pBuffer->c_str()); - break; - } - case type_log: - { - ((log_file*)m_pParam)->logd(TSTRFMT, m_pBuffer->c_str()); - break; - } - default: - break; - } - - // clean the internal buffer - m_pBuffer->clear(); - - MUNLOCK(m_lock); -} - -/** Function dumps (stores in the internal string object) the given ansi string. - * Strings longer than max_dump characters will be truncated. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] pszValue - an ansi string - the value of a given member - */ -void dumpctx::dump(const tchar_t* pszName, const tchar_t* pszValue) -{ - _sntprintf(m_szBuffer, max_dump, TSTRFMT _t(" (tstring):\n\t") PTRFMT _t(" (\"") TSTRFMT _t("\")\n"), pszName, pszValue, pszValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -} - -/** Function dumps (stores in the internal string object) the given unicode string. - * Strings longer than max_dump characters will be truncated. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] pszValue - an unicode string - the value of a given member - */ -/*void dumpctx::dump(const tchar_t* pszName, const wchar_t* pszValue) -{ - _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (wide string):\n\t") PTRFMT _t(" (\"") WSTRFMT _t("\")\n"), pszName, pszValue, pszValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -}*/ - -/** Function dumps (stores in the internal string object) the given character. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] cValue - a character (signed tchar_t) value - */ -void dumpctx::dump(const tchar_t* pszName, const tchar_t cValue) -{ - _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (tchar_t):\n\t'") CHARFMT _t("' (hex: ") CXFMT _t(" / dec: ") CFMT _t(")\n"), pszName, cValue, (short_t)cValue, (short_t)cValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -} - -/** Function dumps (stores in the internal string object) the given short_t. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] sValue - a short_t value to dump - */ -void dumpctx::dump(const tchar_t* pszName, const short_t sValue) -{ - _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (short_t):\n\t") SFMT _t(" (hex: ") SXFMT _t(")\n"), pszName, sValue, sValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -} - -/** Function dumps (stores in the internal string object) the given int_t. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] iValue - a int_t value to dump - */ -void dumpctx::dump(const tchar_t* pszName, const int_t iValue) -{ - _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (int_t):\n\t") LFMT _t(" (hex: ") LXFMT _t(")\n"), pszName, iValue, iValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -} - -/** Function dumps (stores in the internal string object) the given uchar_t. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] ucValue - an uchar_t value to dump - */ -void dumpctx::dump(const tchar_t* pszName, const uchar_t ucValue) -{ - _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (uchar_t):\n\t'") UCHARFMT _t("' (hex: ") UCXFMT _t(" / dec: ") UCFMT _t(")\n"), pszName, ucValue, (ushort_t)ucValue, (ushort_t)ucValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -} - -/** Function dumps (stores in the internal string object) the given ushort_t. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] usValue - an ushort_t value to dump - */ -void dumpctx::dump(const tchar_t* pszName, const ushort_t usValue) -{ - _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (ushort_t):\n\t") USFMT _t(" (hex: ") USXFMT _t(")\n"), pszName, usValue, usValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -} - -/** Function dumps (stores in the internal string object) the given uint_t. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] uiValue - an uint_t value to dump - */ -void dumpctx::dump(const tchar_t* pszName, const uint_t uiValue) -{ - _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (uint_t):\n\t") ULFMT _t(" (hex: ") ULXFMT _t(")\n"), pszName, uiValue, uiValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -} - -/** Function dumps (stores in the internal string object) the longlong_t. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] llValue - a longlong_t value to dump - */ -void dumpctx::dump(const tchar_t* pszName, const longlong_t llValue) -{ - _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (longlong_t):\n\t") LLFMT _t(" (hex: ") LLXFMT _t(")\n"), pszName, llValue, llValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -} - -/** Function dumps (stores in the internal string object) the ulonglong_t. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] ullValue - an ulonglong_t value to dump - */ -void dumpctx::dump(const tchar_t* pszName, const ulonglong_t ullValue) -{ - _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (ulonglong_t):\n\t") ULLFMT _t(" (hex: ") ULLXFMT _t(")\n"), pszName, ullValue, ullValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -} - -/** Function dumps (stores in the internal string object) the untyped pointer. - * \param[in] pszName - name of the member variable of the dumped object - * \param[in] pValue - an untyped pointer value to dump - */ -void dumpctx::dump(const tchar_t* pszName, const ptr_t pValue) -{ - _sntprintf(m_szBuffer, max_dump, STRFMT _t(" (ptr_t):\n\t") PTRFMT _t("\n"), pszName, pValue); - m_szBuffer[max_dump-1]=_t('\0'); - MLOCK(m_lock); - *m_pBuffer+=m_szBuffer; - MUNLOCK(m_lock); -} - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/dumpctx.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/dumpctx.h (revision 0) +++ ext/libicpf/src/libicpf/dumpctx.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file dumpctx.h + * \brief Contain class dumpctx - a debug helper class. + */ + +#ifndef __DUMPCONTEXT_H__ +#define __DUMPCONTEXT_H__ + +#include "mutex.h" +#include "gen_types.h" +//#include "str.h" + +BEGIN_ICPF_NAMESPACE + +/// Maximum size of a single variable dump (ie. string) +//#define MAX_DUMP 4096 + +// dump type flags +/// Std out; pParam is NULL +/*#define DCX_STD 0x00000000 +/// File object; pParam is const tchar_t* with file path +#define DCX_FILE 0x00000001 +/// File object; pParam is FILE* - handle to a file opened in write mode +#define DCX_FILEHANDLE 0x00000002 +/// Log file; pParam is log_file* with the given log (dump's will be logged as LT_DEBUG) +#define DCX_LOG 0x00000003 +*/ + +/** \brief Class used as dump context (debugging purposes). + * + * Class should be used to perform dump's of any object's internal state. + * Any class could (should?) use this class as a param to the dump member. + * Usage is quite simple - construct an object with needed flags and when + * need to dump an object - call open with an object name, dump what's needed + * and then close. + * Class is thread safe. + */ +class LIBICPF_API dumpctx +{ + /// Dump types available + enum dump_types + { + type_std, /// Reporting to the console + type_file, /// Reporting to the file + type_filehandle, /// Reporting to the file handle + type_log /// Reporting to a log file + }; + + /// Internal buffer size to use + enum buf_sizes { max_dump=4096 }; +public: +/** \name Construction/destruction */ +/**@{*/ + explicit dumpctx(uint_t uiType, ptr_t pParam=NULL); ///< Standard constructor + ~dumpctx(); ///< Standard destructor +/**@}*/ + +/** \name Opening/closing dump process */ +/**@{*/ + void open(const tchar_t* pszObject); ///< Begins the specified object dump + void close(); ///< Ends the object dump +/**@}*/ + +/** \name Dumping functions + * Operations to be executed between calls to open() and close() + */ +/**@{*/ + void dump(const tchar_t* pszName, const tchar_t* pszValue); ///< Ansi string dump +// void dump(const tchar_t* pszName, const wchar_t* pszValue); ///< Unicode string dump + void dump(const tchar_t* pszName, const tchar_t cValue); ///< tchar_t dump + void dump(const tchar_t* pszName, const short_t sValue); ///< short_t dump + void dump(const tchar_t* pszName, const int_t iValue); ///< int_t dump + void dump(const tchar_t* pszName, const uchar_t ucValue); ///< uchar_t dump + void dump(const tchar_t* pszName, const ushort_t usValue); ///< ushort_t dump + void dump(const tchar_t* pszName, const uint_t uiValue); ///< uint_t dump + void dump(const tchar_t* pszName, const longlong_t llValue); ///< longlong_t dump + void dump(const tchar_t* pszName, const ulonglong_t ullValue); ///< ulonglong_t dump + void dump(const tchar_t* pszName, const ptr_t pValue); ///< pointer dump +/**@}*/ +protected: + mutex m_lock; ///< A mutex or d_mutex class cast to void* because of the circular dependencies problem +// string m_strBuffer; ///< String object that will gather information about dump + ptr_t m_hBuffer; ///< Internal buffer handle + tchar_t m_szBuffer[max_dump]; ///< Buffer used in formatting output data + uint_t m_uiType; ///< Type of dump (as passed to constructor) + ptr_t m_pParam; ///< Parameter - the real type depends on the m_ulType field +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/dumpctx.h =================================================================== diff -u -N --- ext/libicpf/src/dumpctx.h (revision 6dae57f5e7aeeb965bc018024d8360069f6e15c1) +++ ext/libicpf/src/dumpctx.h (revision 0) @@ -1,109 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file dumpctx.h - * \brief Contain class dumpctx - a debug helper class. - */ - -#ifndef __DUMPCONTEXT_H__ -#define __DUMPCONTEXT_H__ - -#include "mutex.h" -#include "gen_types.h" -//#include "str.h" - -BEGIN_ICPF_NAMESPACE - -/// Maximum size of a single variable dump (ie. string) -//#define MAX_DUMP 4096 - -// dump type flags -/// Std out; pParam is NULL -/*#define DCX_STD 0x00000000 -/// File object; pParam is const tchar_t* with file path -#define DCX_FILE 0x00000001 -/// File object; pParam is FILE* - handle to a file opened in write mode -#define DCX_FILEHANDLE 0x00000002 -/// Log file; pParam is log_file* with the given log (dump's will be logged as LT_DEBUG) -#define DCX_LOG 0x00000003 -*/ - -/** \brief Class used as dump context (debugging purposes). - * - * Class should be used to perform dump's of any object's internal state. - * Any class could (should?) use this class as a param to the dump member. - * Usage is quite simple - construct an object with needed flags and when - * need to dump an object - call open with an object name, dump what's needed - * and then close. - * Class is thread safe. - */ -class LIBICPF_API dumpctx -{ - /// Dump types available - enum dump_types - { - type_std, /// Reporting to the console - type_file, /// Reporting to the file - type_filehandle, /// Reporting to the file handle - type_log /// Reporting to a log file - }; - - /// Internal buffer size to use - enum buf_sizes { max_dump=4096 }; -public: -/** \name Construction/destruction */ -/**@{*/ - explicit dumpctx(uint_t uiType, ptr_t pParam=NULL); ///< Standard constructor - ~dumpctx(); ///< Standard destructor -/**@}*/ - -/** \name Opening/closing dump process */ -/**@{*/ - void open(const tchar_t* pszObject); ///< Begins the specified object dump - void close(); ///< Ends the object dump -/**@}*/ - -/** \name Dumping functions - * Operations to be executed between calls to open() and close() - */ -/**@{*/ - void dump(const tchar_t* pszName, const tchar_t* pszValue); ///< Ansi string dump -// void dump(const tchar_t* pszName, const wchar_t* pszValue); ///< Unicode string dump - void dump(const tchar_t* pszName, const tchar_t cValue); ///< tchar_t dump - void dump(const tchar_t* pszName, const short_t sValue); ///< short_t dump - void dump(const tchar_t* pszName, const int_t iValue); ///< int_t dump - void dump(const tchar_t* pszName, const uchar_t ucValue); ///< uchar_t dump - void dump(const tchar_t* pszName, const ushort_t usValue); ///< ushort_t dump - void dump(const tchar_t* pszName, const uint_t uiValue); ///< uint_t dump - void dump(const tchar_t* pszName, const longlong_t llValue); ///< longlong_t dump - void dump(const tchar_t* pszName, const ulonglong_t ullValue); ///< ulonglong_t dump - void dump(const tchar_t* pszName, const ptr_t pValue); ///< pointer dump -/**@}*/ -protected: - mutex m_lock; ///< A mutex or d_mutex class cast to void* because of the circular dependencies problem -// string m_strBuffer; ///< String object that will gather information about dump - ptr_t m_hBuffer; ///< Internal buffer handle - tchar_t m_szBuffer[max_dump]; ///< Buffer used in formatting output data - uint_t m_uiType; ///< Type of dump (as passed to constructor) - ptr_t m_pParam; ///< Parameter - the real type depends on the m_ulType field -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/err_codes.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/err_codes.h (revision 0) +++ ext/libicpf/src/libicpf/err_codes.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __ERR_CODES_H__ +#define __ERR_CODES_H__ + +//////////////////////////////////////////////////////////////// +// file related +/// Base define for file related errors +#define FE_BASE 0x00010000 + +/// Unknown error +#define FERR_UNKNOWN (FE_BASE+0x0000) +/// Error while opening file +#define FERR_OPEN (FE_BASE+0x0001) +/// Error while closing file +#define FERR_CLOSE (FE_BASE+0x0002) +/// Error reading data from file +#define FERR_READ (FE_BASE+0x0003) +/// Error writing data to a file +#define FERR_WRITE (FE_BASE+0x0004) +/// Error setting file pointer position +#define FERR_SEEK (FE_BASE+0x0005) +/// eof encountered - currently unused +#define FERR_EOF (FE_BASE+0x0006) +/// error while setting an eof in file +#define FERR_SETEOF (FE_BASE+0x0007) +/// error getting file size +#define FERR_GETSIZE (FE_BASE+0x0008) +/// serialization error +#define FERR_SERIALIZE (FE_BASE+0x0009) +/// trying to read the data beyond the index +#define FERR_MEMORY (FE_BASE+0x000a) +/// encryption/decryption error +#define FERR_CRYPT (FE_BASE+0x000b) +/// search error +#define FERR_SEARCH (FE_BASE+0x000c) +/// set/get attrib error +#define FERR_FINFO (FE_BASE+0x000d) +/// fast-move/rename error +#define FERR_MOVE (FE_BASE+0x000e) +/// Unicode strings not supported in this build of library +#define FERR_UNICODE (FE_BASE+0x000f) + +//////////////////////////////////////////////////////////////////// +// module-related +/// Base define for module related errors +#define PE_BASE 0x00000000 + +/// plugin found with the id equal to one of the loaded plugins +#define PE_DUPLICATEPLUG (PE_BASE+0x0000) +/// the module does not implement a mandatory function (or other words - cannot load an export from a module) +#define PE_CALLNOTIMPLEMENTED (PE_BASE+0x0001) +/// the search error +#define PE_SEARCHERROR (PE_BASE+0x0002) +/// Cannot load an external module +#define PE_CANNOTLOAD (PE_BASE+0x0003) +/// Cannot unload the external module +#define PE_CANNOTUNLOAD (PE_BASE+0x0004) +/// Module not found +#define PE_NOTFOUND (PE_BASE+0x0005) + +///////////////////////////////////////////////////////////////////// +// encryption related + +/// Base define for encryption related error codes +#define EE_BASE 0x00020000 + +/// Initialization of the cipher failed +#define EE_INIT (EE_BASE+0x0000) +/// Encryption failed +#define EE_CRYPT (EE_BASE+0x0001) +/// Decryption failed +#define EE_DECRYPT (EE_BASE+0x0002) + +///////////////////////////////////////////////////////////////////// +// conversion related +/// Base define for conversion errors +#define CE_BASE 0x00030000 +/// Error in converting a hex string to the binary data +#define CE_HEX2BIN (CE_BASE+0x0000) + +#endif Index: ext/libicpf/src/err_codes.h =================================================================== diff -u -N --- ext/libicpf/src/err_codes.h (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/err_codes.h (revision 0) @@ -1,99 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef __ERR_CODES_H__ -#define __ERR_CODES_H__ - -//////////////////////////////////////////////////////////////// -// file related -/// Base define for file related errors -#define FE_BASE 0x00010000 - -/// Unknown error -#define FERR_UNKNOWN (FE_BASE+0x0000) -/// Error while opening file -#define FERR_OPEN (FE_BASE+0x0001) -/// Error while closing file -#define FERR_CLOSE (FE_BASE+0x0002) -/// Error reading data from file -#define FERR_READ (FE_BASE+0x0003) -/// Error writing data to a file -#define FERR_WRITE (FE_BASE+0x0004) -/// Error setting file pointer position -#define FERR_SEEK (FE_BASE+0x0005) -/// eof encountered - currently unused -#define FERR_EOF (FE_BASE+0x0006) -/// error while setting an eof in file -#define FERR_SETEOF (FE_BASE+0x0007) -/// error getting file size -#define FERR_GETSIZE (FE_BASE+0x0008) -/// serialization error -#define FERR_SERIALIZE (FE_BASE+0x0009) -/// trying to read the data beyond the index -#define FERR_MEMORY (FE_BASE+0x000a) -/// encryption/decryption error -#define FERR_CRYPT (FE_BASE+0x000b) -/// search error -#define FERR_SEARCH (FE_BASE+0x000c) -/// set/get attrib error -#define FERR_FINFO (FE_BASE+0x000d) -/// fast-move/rename error -#define FERR_MOVE (FE_BASE+0x000e) -/// Unicode strings not supported in this build of library -#define FERR_UNICODE (FE_BASE+0x000f) - -//////////////////////////////////////////////////////////////////// -// module-related -/// Base define for module related errors -#define PE_BASE 0x00000000 - -/// plugin found with the id equal to one of the loaded plugins -#define PE_DUPLICATEPLUG (PE_BASE+0x0000) -/// the module does not implement a mandatory function (or other words - cannot load an export from a module) -#define PE_CALLNOTIMPLEMENTED (PE_BASE+0x0001) -/// the search error -#define PE_SEARCHERROR (PE_BASE+0x0002) -/// Cannot load an external module -#define PE_CANNOTLOAD (PE_BASE+0x0003) -/// Cannot unload the external module -#define PE_CANNOTUNLOAD (PE_BASE+0x0004) -/// Module not found -#define PE_NOTFOUND (PE_BASE+0x0005) - -///////////////////////////////////////////////////////////////////// -// encryption related - -/// Base define for encryption related error codes -#define EE_BASE 0x00020000 - -/// Initialization of the cipher failed -#define EE_INIT (EE_BASE+0x0000) -/// Encryption failed -#define EE_CRYPT (EE_BASE+0x0001) -/// Decryption failed -#define EE_DECRYPT (EE_BASE+0x0002) - -///////////////////////////////////////////////////////////////////// -// conversion related -/// Base define for conversion errors -#define CE_BASE 0x00030000 -/// Error in converting a hex string to the binary data -#define CE_HEX2BIN (CE_BASE+0x0000) - -#endif Index: ext/libicpf/src/libicpf/exception.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/exception.cpp (revision 0) +++ ext/libicpf/src/libicpf/exception.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,211 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file exception.cpp + * \brief Contain an implementation of an exception handling class. + */ +#include "exception.h" +#include +#include + +BEGIN_ICPF_NAMESPACE + +/// Defines max length of the exception description +#define MAX_EXCEPTION 4096 + +/** Constructor that takes the const description. The description (along with other tchar_t* parameters) + * are copied to the internal members (so there is some memory allocation). + * + * \param[in] pszDesc - exception description (currently should be in english) + * \param[in] pszFilename - source file name from which the exception is thrown + * \param[in] pszFunction - function name from which the exception is thrown + * \param[in] uiLine - line in the source file from which the exception is thrown + * \param[in] uiAppCode - application defined error code + * \param[in] uiSystemCode - system error code (platform dependent) + * \param[in] uiReserved - currently unused; must be 0 + */ +exception::exception(const tchar_t* pszDesc, const tchar_t* pszFilename, const tchar_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved) : + m_pszDesc(NULL), + m_pszFilename(NULL), + m_pszFunction(NULL), + m_uiLine(uiLine), + m_uiAppCode(uiAppCode), + m_uiSystemCode(uiSystemCode), + m_uiReserved(uiReserved) +{ + set_string(&m_pszDesc, pszDesc); + set_string(&m_pszFilename, pszFilename); + set_string(&m_pszFunction, pszFunction); +#if defined(_DEBUG) && (defined(_WIN32) || defined(_WIN64)) + tchar_t szInfo[MAX_EXCEPTION]; + OutputDebugString(get_info(szInfo, MAX_EXCEPTION)); +#endif +} + +/** Constructor that takes the ptr to a buffer as a description. The pointer to a buffer is + * stored in the internal member and will be deleted in the destructor. Other tchar_t* parameters + * are copied to the internal members (so there is some memory allocated). + * + * \param[in] pszDesc - ptr to exception description (currently should be in english) allocated with new operator + * \param[in] pszFilename - source file name from which the exception is thrown + * \param[in] pszFunction - function name from which the exception is thrown + * \param[in] uiLine - line in the source file from which the exception is thrown + * \param[in] uiAppCode - application defined error code + * \param[in] uiSystemCode - system error code (platform dependent) + * \param[in] uiReserved - currently unused; must be 0 + */ +exception::exception(tchar_t* pszDesc, const tchar_t* pszFilename, const tchar_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved) : + m_pszDesc(pszDesc), + m_pszFilename(NULL), + m_pszFunction(NULL), + m_uiLine(uiLine), + m_uiAppCode(uiAppCode), + m_uiSystemCode(uiSystemCode), + m_uiReserved(uiReserved) +{ + set_string(&m_pszFilename, pszFilename); + set_string(&m_pszFunction, pszFunction); +#if defined(_DEBUG) && (defined(_WIN32) || defined(_WIN64)) + tchar_t szInfo[MAX_EXCEPTION]; + OutputDebugString(get_info(szInfo, MAX_EXCEPTION)); +#endif +} + +/** Copy constructor for the exception class. + * + * \param[in] rSrc - source exception to copy data from + */ +exception::exception(const exception& rSrc) : + m_pszDesc(NULL), + m_pszFilename(NULL), + m_pszFunction(NULL), + m_uiLine(rSrc.m_uiLine), + m_uiAppCode(rSrc.m_uiAppCode), + m_uiSystemCode(rSrc.m_uiSystemCode), + m_uiReserved(rSrc.m_uiReserved) +{ + set_string(&m_pszDesc, rSrc.m_pszDesc); + set_string(&m_pszFilename, rSrc.m_pszFilename); + set_string(&m_pszFunction, rSrc.m_pszFunction); +} + +/** Destructor deletes all the allocated memory for the exception object + */ +exception::~exception() +{ + delete [] m_pszDesc; + delete [] m_pszFilename; + delete [] m_pszFunction; +} + +/** Assigns another exception data to this object. + * + * \param[in] e - source exception to copy from. + * \return Reference to this object. + */ +exception& exception::operator=(const exception& eSrc) +{ + if (this != &eSrc) + { + delete [] m_pszDesc; + delete [] m_pszFilename; + delete [] m_pszFunction; + + set_string(&m_pszDesc, eSrc.m_pszDesc); + set_string(&m_pszFilename, eSrc.m_pszFilename); + set_string(&m_pszFunction, eSrc.m_pszFunction); + m_uiLine=eSrc.m_uiLine; + m_uiAppCode=eSrc.m_uiAppCode; + m_uiSystemCode=eSrc.m_uiSystemCode; + m_uiReserved=eSrc.m_uiReserved; + } + + return *this; +} + +/** Function retrieves the full information about the exception into + * the string buffer specified by user. + * \param[out] pszInfo - buffer fot the full exception description + * \param[in] tMaxLen - size of the specified buffer + * \return Pointer to the exception description (to the pszInfo to be specific) + */ +const tchar_t* exception::get_info(tchar_t* pszInfo, size_t stMaxLen) +{ + _sntprintf(pszInfo, stMaxLen, _t("description: ") TSTRFMT _t("\nfile: ") TSTRFMT _t("\nfunction: ") TSTRFMT _t("\nline: ") ULFMT _t("\napp code: ") ULFMT _t("\nsys code: ") ULFMT _t("\nreserved: ") ULFMT _t("\n"), + m_pszDesc, m_pszFilename, m_pszFunction, m_uiLine, m_uiAppCode, m_uiSystemCode, m_uiReserved); + pszInfo[stMaxLen-1]=_t('\0'); + + return pszInfo; +} + +/** Function logs the full information about an exception to the specified log file. + * \param[in] pszDesc - additional description of the exception object + * \param[in] plog - pointer to a log file to log the exception to + */ +void exception::log(const tchar_t* pszDesc, log_file* plog) +{ + plog->loge(TSTRFMT _t("\n\tdesc: ") TSTRFMT _t("\n\tfile: ") TSTRFMT _t("\n\tfunc: ") TSTRFMT _t("\n\tline: ") ULFMT _t("\n\tapp code: ") ULFMT _t("\n\tsys code: ") ULFMT _t("\n\treserved: ") ULFMT _t("\n"), + pszDesc, m_pszDesc, m_pszFilename, m_pszFunction, m_uiLine, m_uiAppCode, m_uiSystemCode, m_uiReserved); +} + +/** Function logs the full information about an exception to the specified log file. + * Function takes two additional descriptions - will be logged as separated by space one description. + * \param[in] pszDesc - additional description of the exception object + * \param[in] pszDesc2 - the second part of an additional description + * \param[in] plog - pointer to a log file to log the exception to + */ +void exception::log(const tchar_t* pszDesc, const tchar_t* pszDesc2, log_file* plog) +{ + plog->loge(TSTRFMT _t(" ") TSTRFMT _t("\n\tdesc: ") TSTRFMT _t("\n\tfile: ") TSTRFMT _t("\n\tfunc: ") TSTRFMT _t("\n\tline: ") ULFMT _t("\n\tapp code: ") ULFMT _t("\n\tsys code: ") ULFMT _t("\n\treserved: ") ULFMT _t("\n"), + pszDesc, pszDesc2, m_pszDesc, m_pszFilename, m_pszFunction, m_uiLine, m_uiAppCode, m_uiSystemCode, m_uiReserved); +} + +/** Exception's description formatting routine. Acts just as normal sprintf + * function, but allocates a buffer for the output result and returns a pointer + * to it. Used for formatting the exception description - usage: + * THROW(exception::format(_t("test ") TSTRFMT , _t("abc")), ...). + * It will enforce compiler to use the second constructor (non-const description). + * And the allocated buffer (result of this func) will be freed. + * \param[in] pszFormat - format string followed by some additional data (as in printf) + * \return Pointer to the newly allocated buffer with formatted output. + */ +tchar_t* exception::format(const tchar_t* pszFormat, ...) +{ + va_list vl; + va_start(vl, pszFormat); + + // alloc some space - no more than MAX_EXCEPTION chracters + tchar_t* psz=new tchar_t[(size_t)MAX_EXCEPTION]; + _vsntprintf(psz, (size_t)MAX_EXCEPTION, pszFormat, vl); + psz[MAX_EXCEPTION-1]=_t('\0'); + return psz; +} + +/** Allocates a string buffer and makes a copy of an input data. Used to + * make a copy of the constructor string parameteres. + * \param[out] pszOut - pointer to tchar_t* which will receive the new buffer address + * \param[in] pszIn - string to make a copy of + */ +void exception::set_string(tchar_t** pszOut, const tchar_t* pszIn) const +{ + *pszOut=new tchar_t[_tcslen(pszIn)+(uint_t)1]; + _tcscpy(*pszOut, pszIn); +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/exception.cpp =================================================================== diff -u -N --- ext/libicpf/src/exception.cpp (revision 9bdff2e0b309af11014634d8c38367e4f6b656e3) +++ ext/libicpf/src/exception.cpp (revision 0) @@ -1,211 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file exception.cpp - * \brief Contain an implementation of an exception handling class. - */ -#include "exception.h" -#include -#include - -BEGIN_ICPF_NAMESPACE - -/// Defines max length of the exception description -#define MAX_EXCEPTION 4096 - -/** Constructor that takes the const description. The description (along with other tchar_t* parameters) - * are copied to the internal members (so there is some memory allocation). - * - * \param[in] pszDesc - exception description (currently should be in english) - * \param[in] pszFilename - source file name from which the exception is thrown - * \param[in] pszFunction - function name from which the exception is thrown - * \param[in] uiLine - line in the source file from which the exception is thrown - * \param[in] uiAppCode - application defined error code - * \param[in] uiSystemCode - system error code (platform dependent) - * \param[in] uiReserved - currently unused; must be 0 - */ -exception::exception(const tchar_t* pszDesc, const tchar_t* pszFilename, const tchar_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved) : - m_pszDesc(NULL), - m_pszFilename(NULL), - m_pszFunction(NULL), - m_uiLine(uiLine), - m_uiAppCode(uiAppCode), - m_uiSystemCode(uiSystemCode), - m_uiReserved(uiReserved) -{ - set_string(&m_pszDesc, pszDesc); - set_string(&m_pszFilename, pszFilename); - set_string(&m_pszFunction, pszFunction); -#if defined(_DEBUG) && (defined(_WIN32) || defined(_WIN64)) - tchar_t szInfo[MAX_EXCEPTION]; - OutputDebugString(get_info(szInfo, MAX_EXCEPTION)); -#endif -} - -/** Constructor that takes the ptr to a buffer as a description. The pointer to a buffer is - * stored in the internal member and will be deleted in the destructor. Other tchar_t* parameters - * are copied to the internal members (so there is some memory allocated). - * - * \param[in] pszDesc - ptr to exception description (currently should be in english) allocated with new operator - * \param[in] pszFilename - source file name from which the exception is thrown - * \param[in] pszFunction - function name from which the exception is thrown - * \param[in] uiLine - line in the source file from which the exception is thrown - * \param[in] uiAppCode - application defined error code - * \param[in] uiSystemCode - system error code (platform dependent) - * \param[in] uiReserved - currently unused; must be 0 - */ -exception::exception(tchar_t* pszDesc, const tchar_t* pszFilename, const tchar_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved) : - m_pszDesc(pszDesc), - m_pszFilename(NULL), - m_pszFunction(NULL), - m_uiLine(uiLine), - m_uiAppCode(uiAppCode), - m_uiSystemCode(uiSystemCode), - m_uiReserved(uiReserved) -{ - set_string(&m_pszFilename, pszFilename); - set_string(&m_pszFunction, pszFunction); -#if defined(_DEBUG) && (defined(_WIN32) || defined(_WIN64)) - tchar_t szInfo[MAX_EXCEPTION]; - OutputDebugString(get_info(szInfo, MAX_EXCEPTION)); -#endif -} - -/** Copy constructor for the exception class. - * - * \param[in] rSrc - source exception to copy data from - */ -exception::exception(const exception& rSrc) : - m_pszDesc(NULL), - m_pszFilename(NULL), - m_pszFunction(NULL), - m_uiLine(rSrc.m_uiLine), - m_uiAppCode(rSrc.m_uiAppCode), - m_uiSystemCode(rSrc.m_uiSystemCode), - m_uiReserved(rSrc.m_uiReserved) -{ - set_string(&m_pszDesc, rSrc.m_pszDesc); - set_string(&m_pszFilename, rSrc.m_pszFilename); - set_string(&m_pszFunction, rSrc.m_pszFunction); -} - -/** Destructor deletes all the allocated memory for the exception object - */ -exception::~exception() -{ - delete [] m_pszDesc; - delete [] m_pszFilename; - delete [] m_pszFunction; -} - -/** Assigns another exception data to this object. - * - * \param[in] e - source exception to copy from. - * \return Reference to this object. - */ -exception& exception::operator=(const exception& eSrc) -{ - if (this != &eSrc) - { - delete [] m_pszDesc; - delete [] m_pszFilename; - delete [] m_pszFunction; - - set_string(&m_pszDesc, eSrc.m_pszDesc); - set_string(&m_pszFilename, eSrc.m_pszFilename); - set_string(&m_pszFunction, eSrc.m_pszFunction); - m_uiLine=eSrc.m_uiLine; - m_uiAppCode=eSrc.m_uiAppCode; - m_uiSystemCode=eSrc.m_uiSystemCode; - m_uiReserved=eSrc.m_uiReserved; - } - - return *this; -} - -/** Function retrieves the full information about the exception into - * the string buffer specified by user. - * \param[out] pszInfo - buffer fot the full exception description - * \param[in] tMaxLen - size of the specified buffer - * \return Pointer to the exception description (to the pszInfo to be specific) - */ -const tchar_t* exception::get_info(tchar_t* pszInfo, size_t stMaxLen) -{ - _sntprintf(pszInfo, stMaxLen, _t("description: ") TSTRFMT _t("\nfile: ") TSTRFMT _t("\nfunction: ") TSTRFMT _t("\nline: ") ULFMT _t("\napp code: ") ULFMT _t("\nsys code: ") ULFMT _t("\nreserved: ") ULFMT _t("\n"), - m_pszDesc, m_pszFilename, m_pszFunction, m_uiLine, m_uiAppCode, m_uiSystemCode, m_uiReserved); - pszInfo[stMaxLen-1]=_t('\0'); - - return pszInfo; -} - -/** Function logs the full information about an exception to the specified log file. - * \param[in] pszDesc - additional description of the exception object - * \param[in] plog - pointer to a log file to log the exception to - */ -void exception::log(const tchar_t* pszDesc, log_file* plog) -{ - plog->loge(TSTRFMT _t("\n\tdesc: ") TSTRFMT _t("\n\tfile: ") TSTRFMT _t("\n\tfunc: ") TSTRFMT _t("\n\tline: ") ULFMT _t("\n\tapp code: ") ULFMT _t("\n\tsys code: ") ULFMT _t("\n\treserved: ") ULFMT _t("\n"), - pszDesc, m_pszDesc, m_pszFilename, m_pszFunction, m_uiLine, m_uiAppCode, m_uiSystemCode, m_uiReserved); -} - -/** Function logs the full information about an exception to the specified log file. - * Function takes two additional descriptions - will be logged as separated by space one description. - * \param[in] pszDesc - additional description of the exception object - * \param[in] pszDesc2 - the second part of an additional description - * \param[in] plog - pointer to a log file to log the exception to - */ -void exception::log(const tchar_t* pszDesc, const tchar_t* pszDesc2, log_file* plog) -{ - plog->loge(TSTRFMT _t(" ") TSTRFMT _t("\n\tdesc: ") TSTRFMT _t("\n\tfile: ") TSTRFMT _t("\n\tfunc: ") TSTRFMT _t("\n\tline: ") ULFMT _t("\n\tapp code: ") ULFMT _t("\n\tsys code: ") ULFMT _t("\n\treserved: ") ULFMT _t("\n"), - pszDesc, pszDesc2, m_pszDesc, m_pszFilename, m_pszFunction, m_uiLine, m_uiAppCode, m_uiSystemCode, m_uiReserved); -} - -/** Exception's description formatting routine. Acts just as normal sprintf - * function, but allocates a buffer for the output result and returns a pointer - * to it. Used for formatting the exception description - usage: - * THROW(exception::format(_t("test ") TSTRFMT , _t("abc")), ...). - * It will enforce compiler to use the second constructor (non-const description). - * And the allocated buffer (result of this func) will be freed. - * \param[in] pszFormat - format string followed by some additional data (as in printf) - * \return Pointer to the newly allocated buffer with formatted output. - */ -tchar_t* exception::format(const tchar_t* pszFormat, ...) -{ - va_list vl; - va_start(vl, pszFormat); - - // alloc some space - no more than MAX_EXCEPTION chracters - tchar_t* psz=new tchar_t[(size_t)MAX_EXCEPTION]; - _vsntprintf(psz, (size_t)MAX_EXCEPTION, pszFormat, vl); - psz[MAX_EXCEPTION-1]=_t('\0'); - return psz; -} - -/** Allocates a string buffer and makes a copy of an input data. Used to - * make a copy of the constructor string parameteres. - * \param[out] pszOut - pointer to tchar_t* which will receive the new buffer address - * \param[in] pszIn - string to make a copy of - */ -void exception::set_string(tchar_t** pszOut, const tchar_t* pszIn) const -{ - *pszOut=new tchar_t[_tcslen(pszIn)+(uint_t)1]; - _tcscpy(*pszOut, pszIn); -} - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/exception.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/exception.h (revision 0) +++ ext/libicpf/src/libicpf/exception.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,107 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file exception.h + * \brief Contain an exception handling class. + */ + +#ifndef __EXCEPTION_H__ +#define __EXCEPTION_H__ + +#include "log.h" +#include "libicpf.h" +#include "gen_types.h" + +#undef THROW +/** \brief Macro used for throwing an exception the easy way. + * + * Macro throws an exception specified by the parameters. Other params needed by + * the exception class are taken indirectly from the position of a macro in the + * source file. + * \param[in] desc - error description; if any formatting should be used use exception::format() function + * \param[in] app_code - application error code (definitions are in engine_defs.h) + * \param[in] sys_code - system error code (platform specific) + * \param[in] reserved_code - currently unused; must be 0 + */ +#define THROW(desc,app_code,sys_code,reserved_code) throw icpf::exception(desc, _t(__FILE__), _t(__FUNCTION__), __LINE__, app_code, sys_code, reserved_code) +/// Logs an exception in a log file +#define LOG_EXCEPTION(except, ptr_log) (except)->log("Caught an exception in ", _t(__FUNCTION__), ptr_log) +/// Logs an unknown exception in a log file +#define LOG_UEXCEPTION(ptr_log) (ptr_log)->loge("Caught an unknown exception in " TSTRFMT, _t(__FUNCTION__)) + +BEGIN_ICPF_NAMESPACE + +/** \brief Exception class used by most of the engine. + * + * Exception class thrown by most of the engine functions. Provides user + * with an additional formatting and outputting capabilities. + */ +class LIBICPF_API exception +{ +public: +/** \name Construction/destruction */ +/**@{*/ + /// Standard constructor that takes the const description + exception(const tchar_t* pszDesc, const tchar_t* pszFilename, const tchar_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved); + /// Standard constructor that takes non-const ptr to a buffer as the description + exception(tchar_t* pszDesc, const tchar_t* pszFilename, const tchar_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved); + /// Copy constructor + exception(const exception& rSrc); + /// Standard destructor + ~exception(); + + /// Assignment operator + exception& operator=(const exception& eSrc); +/**@}*/ + +/** \name Outputting */ +/**@{*/ + const tchar_t* get_info(tchar_t* pszInfo, size_t stMaxLen); ///< Retrieves the exception information to a specified string buffer + const tchar_t* get_desc() const { return m_pszDesc; }; + const tchar_t* get_filename() const { return m_pszFilename; }; + const tchar_t* get_function() const { return m_pszFunction; }; + uint_t get_line() const { return m_uiLine; }; + uint_t get_appcode() const { return m_uiAppCode; }; + uint_t get_syscode() const { return m_uiSystemCode; }; + + void log(const tchar_t* pszDesc, log_file* plog); ///< Logs the exception information to the log file + void log(const tchar_t* pszDesc, const tchar_t* pszDesc2, log_file* plog); ///< Logs the exception to the log file with an additional description +/**@}*/ + +/** \name Formatting */ +/**@{*/ + static tchar_t* format(const tchar_t* pszFormat, ...); ///< Description formatting function +/**@}*/ + +protected: + void set_string(tchar_t** pszOut, const tchar_t* pszIn) const; ///< Makes a copy of an input string + +protected: + tchar_t* m_pszDesc; ///< Exception description + tchar_t* m_pszFilename; ///< Source file in which the exception has been thrown + tchar_t* m_pszFunction; ///< Function name in the source file in which the exception has been thrown + uint_t m_uiLine; ///< Line in the source file in which the exception has been thrown + uint_t m_uiAppCode; ///< Application error code + uint_t m_uiSystemCode; ///< System error code (platform dependent) + uint_t m_uiReserved; ///< Reserved code - currently unused and should be 0 +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/exception.h =================================================================== diff -u -N --- ext/libicpf/src/exception.h (revision 9bdff2e0b309af11014634d8c38367e4f6b656e3) +++ ext/libicpf/src/exception.h (revision 0) @@ -1,107 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file exception.h - * \brief Contain an exception handling class. - */ - -#ifndef __EXCEPTION_H__ -#define __EXCEPTION_H__ - -#include "log.h" -#include "libicpf.h" -#include "gen_types.h" - -#undef THROW -/** \brief Macro used for throwing an exception the easy way. - * - * Macro throws an exception specified by the parameters. Other params needed by - * the exception class are taken indirectly from the position of a macro in the - * source file. - * \param[in] desc - error description; if any formatting should be used use exception::format() function - * \param[in] app_code - application error code (definitions are in engine_defs.h) - * \param[in] sys_code - system error code (platform specific) - * \param[in] reserved_code - currently unused; must be 0 - */ -#define THROW(desc,app_code,sys_code,reserved_code) throw icpf::exception(desc, _t(__FILE__), _t(__FUNCTION__), __LINE__, app_code, sys_code, reserved_code) -/// Logs an exception in a log file -#define LOG_EXCEPTION(except, ptr_log) (except)->log("Caught an exception in ", _t(__FUNCTION__), ptr_log) -/// Logs an unknown exception in a log file -#define LOG_UEXCEPTION(ptr_log) (ptr_log)->loge("Caught an unknown exception in " TSTRFMT, _t(__FUNCTION__)) - -BEGIN_ICPF_NAMESPACE - -/** \brief Exception class used by most of the engine. - * - * Exception class thrown by most of the engine functions. Provides user - * with an additional formatting and outputting capabilities. - */ -class LIBICPF_API exception -{ -public: -/** \name Construction/destruction */ -/**@{*/ - /// Standard constructor that takes the const description - exception(const tchar_t* pszDesc, const tchar_t* pszFilename, const tchar_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved); - /// Standard constructor that takes non-const ptr to a buffer as the description - exception(tchar_t* pszDesc, const tchar_t* pszFilename, const tchar_t* pszFunction, uint_t uiLine, uint_t uiAppCode, uint_t uiSystemCode, uint_t uiReserved); - /// Copy constructor - exception(const exception& rSrc); - /// Standard destructor - ~exception(); - - /// Assignment operator - exception& operator=(const exception& eSrc); -/**@}*/ - -/** \name Outputting */ -/**@{*/ - const tchar_t* get_info(tchar_t* pszInfo, size_t stMaxLen); ///< Retrieves the exception information to a specified string buffer - const tchar_t* get_desc() const { return m_pszDesc; }; - const tchar_t* get_filename() const { return m_pszFilename; }; - const tchar_t* get_function() const { return m_pszFunction; }; - uint_t get_line() const { return m_uiLine; }; - uint_t get_appcode() const { return m_uiAppCode; }; - uint_t get_syscode() const { return m_uiSystemCode; }; - - void log(const tchar_t* pszDesc, log_file* plog); ///< Logs the exception information to the log file - void log(const tchar_t* pszDesc, const tchar_t* pszDesc2, log_file* plog); ///< Logs the exception to the log file with an additional description -/**@}*/ - -/** \name Formatting */ -/**@{*/ - static tchar_t* format(const tchar_t* pszFormat, ...); ///< Description formatting function -/**@}*/ - -protected: - void set_string(tchar_t** pszOut, const tchar_t* pszIn) const; ///< Makes a copy of an input string - -protected: - tchar_t* m_pszDesc; ///< Exception description - tchar_t* m_pszFilename; ///< Source file in which the exception has been thrown - tchar_t* m_pszFunction; ///< Function name in the source file in which the exception has been thrown - uint_t m_uiLine; ///< Line in the source file in which the exception has been thrown - uint_t m_uiAppCode; ///< Application error code - uint_t m_uiSystemCode; ///< System error code (platform dependent) - uint_t m_uiReserved; ///< Reserved code - currently unused and should be 0 -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/file.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/file.cpp (revision 0) +++ ext/libicpf/src/libicpf/file.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,1170 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file file.cpp + * \brief Contains file/serializer class */ + +#include "file.h" +#include "crc32.h" +#include +#include "macros.h" +#include "err_codes.h" + +#ifndef _WIN32 + #include + #include + #include + #include +#endif + +BEGIN_ICPF_NAMESPACE + +#include + +/// Serialization buffer increment value +#define SERIALBUFFER_DELTA 4096UL + +// for making life easier +#ifdef _WIN32 + /// Macro representing the current value of last encountered error + #define CURRENT_LAST_ERROR GetLastError() + /// Null value for a file handle - platform compatibility helper + #define FNULL NULL +#else + /// Windoze compatibility macro - value returned from erroneous call to ::open() system call + #define INVALID_HANDLE_VALUE -1 + /// Macro representing the current value of last encountered error + #define CURRENT_LAST_ERROR errno + /// Null value for a file handle - platform compatibility helper + #define FNULL 0 +#endif + + +/** Standard constructor - nullifies all member variables. + */ +file::file() : + m_hFile(FNULL), + m_pszPath(NULL), + m_uiFlags(0), + m_bLastOperation(false), + m_bBuffered(false), + m_uiBufferSize(0), + m_pbyBuffer(NULL), + m_uiCurrentPos(0), + m_uiDataCount(0), + m_bRememberedState(false), + m_bSerializing(0), + m_pbySerialBuffer(NULL), + m_uiSerialBufferSize(0), + m_uiSerialBufferPos(0), + m_uiDataBlockFlags(BF_NONE) +{ +} + +/** Standard destructor - tries to close a file, but catches any exception thrown + * and does not throw it again. + */ +file::~file() +{ + // close all the stuff, but make sure no exception is thrown + try + { + close(); + } + catch(exception&) + { + } +} + +/** Opens a filesystem object (a file) with a given flags and (if needed) with + * some buffer size used in internal buffering. In case of error throws an icpf::exception + * with the error description. + * \param[in] pszPath - path to a file to open + * \param[in] uiFlags - flags that determine the type of access to a file (FA_*) + * \param[in] uiBufSize - buffer size that will be used for internal buffering (if enabled) + */ +void file::open(const tchar_t* pszPath, uint_t uiFlags, uint_t uiBufSize) +{ + // check if this object is ready to open a file + if (m_hFile) + close(); + + // check for the flags completion +#ifdef _WIN32 + uint_t mode=0, flags=OPEN_EXISTING; +#else + int_t mode=0; +#endif + + // read flag + if (uiFlags & FA_READ) +#ifdef _WIN32 + mode |= GENERIC_READ; +#else + mode |= O_RDONLY; +#endif + + // write flag + if (uiFlags & FA_WRITE) +#ifdef _WIN32 + mode |= GENERIC_WRITE; +#else + mode |= O_WRONLY; +#endif + + // creation flag + if (uiFlags & FA_CREATE) +#ifdef _WIN32 + { + if (uiFlags & FA_TRUNCATE) + flags = CREATE_ALWAYS; + else + flags = OPEN_ALWAYS; + } +#else + mode |= O_CREAT; +#endif + + // truncation + if (uiFlags & FA_TRUNCATE) +#ifdef _WIN32 + { + if (!(uiFlags & FA_CREATE)) + flags = TRUNCATE_EXISTING; + } +#else + mode |= O_TRUNC; +#endif + + // make a system call +#ifdef _WIN32 + m_hFile=::CreateFile(pszPath, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, flags, FILE_ATTRIBUTE_NORMAL, NULL); +#else + m_hFile=::open(pszPath, mode); +#endif + + if (m_hFile == INVALID_HANDLE_VALUE) + { + m_hFile=FNULL; + THROW(exception::format(_t("[file] Cannot open the file ") STRFMT _t(" with flags ") ULXFMT, pszPath, uiFlags), FERR_OPEN, CURRENT_LAST_ERROR, 0); + } + else + { + // remember the path of this file + m_pszPath=new tchar_t[_tcslen(pszPath)+1]; + _tcscpy(m_pszPath, pszPath); + + // remember the mode + m_uiFlags=uiFlags; + + // is this buffered ? + set_buffering((uiFlags & FA_BUFFERED) != 0, uiBufSize); + } +} + +/** Tries to save the data contained in internal buffer (if any) and frees all the + * resources used by this class. Can be used on closed files. In case of error the + * ch::exception is thrown. + */ +void file::close() +{ + // only if the file has been opened + if (m_hFile != FNULL) + { + // flush all data + flush(); + + // free strings and other data (at first, because of the destruction call) + delete [] m_pszPath; + m_pszPath=NULL; + delete [] m_pbyBuffer; + m_pbyBuffer=NULL; + + delete [] m_pbySerialBuffer; + m_pbySerialBuffer=NULL; + + m_uiFlags=0; + m_bLastOperation=false; + + m_bBuffered=false; + m_uiBufferSize=0; + m_uiCurrentPos=0; + m_uiDataCount=0; + + m_bSerializing=false; + m_uiSerialBufferSize=0; + m_uiSerialBufferPos=0; + m_uiDataBlockFlags=0; + + m_bRememberedState=false; + + // close the file +#ifdef _WIN32 + if (!::CloseHandle(m_hFile)) +#else + if (::close(m_hFile) == -1) +#endif + THROW(exception::format(_t("[file] Cannot close the handle associated with a file ") STRFMT, m_pszPath), FERR_CLOSE, CURRENT_LAST_ERROR, 0); + else + m_hFile=FNULL; + } +} + +/** Does anything only if the file is opened, the operation is being buffered and the data + * count contained in the internal buffer is >0. If the last operation performed was + * storing data then the function tries to store a packet of data to the file. If the data + * has been read lately then only the file pointer will be repositioned. Also the internal buffer + * will be made empty. Function can throw an ch::exception in case of error. + */ +void file::flush() +{ + if (m_hFile && m_bBuffered && m_uiDataCount > 0) + { + if (m_bLastOperation) + { + // last operation - storing data + _write_packet(); + } + else + { + // last - reading data + // set file pointer to position current-(m_uiDataCount-m_uiCurrentPos) + _seek(-(longlong_t)(m_uiDataCount-m_uiCurrentPos), FS_CURRENT); + m_uiCurrentPos=0; + m_uiDataCount=0; + } + } +} + +/** Tries to read a specified count of bytes from a file to the specified buffer. + * If the is currently in buffered state the reading is being done with internal + * buffering. It could be helpful when reading small amounts of data. + * \param[out] pBuffer - ptr to a buffer that is about to receive data + * \param[in] iSize - count of bytes to read + * \return Count of bytes that has been read (could be less than iSize) + */ +ulong_t file::read(ptr_t pBuffer, ulong_t ulSize) +{ + assert(m_hFile); // forgot to open the file ? + + // flush if needed + if (m_bLastOperation) + { + flush(); + m_bLastOperation=false; + } + + if (!m_bBuffered) + { + // unbuffered operation (read what is needed) +#ifdef _WIN32 + DWORD rd=0; + if (!ReadFile(m_hFile, pBuffer, ulSize, &rd, NULL)) +#else + int_t rd=0; + if ((rd=::read(m_hFile, pBuffer, ulSize)) < 0) +#endif + THROW(exception::format(_t("Cannot read data from file ") STRFMT, m_pszPath), FERR_READ, CURRENT_LAST_ERROR, 0); + + return rd; // if 0 - eof (not treated as exception) + } + else + { + // reads must be done by packets + uint_t uiCurrPos=0; // position in external buffer + while (uiCurrPos < ulSize) + { + // are there any data left ? + if (m_uiDataCount == 0 || m_uiCurrentPos == m_uiDataCount) + { + if (_read_packet() == 0) + return uiCurrPos; // return what was read 'til now + } + + // copy data into external buffer + uint_t uiCount=minval(m_uiDataCount-m_uiCurrentPos, ulSize-uiCurrPos); + memcpy(((byte_t*)pBuffer)+uiCurrPos, m_pbyBuffer+m_uiCurrentPos, uiCount); + + // update positions + uiCurrPos+=uiCount; + m_uiCurrentPos+=uiCount; + } + + return uiCurrPos; + } +} + +/** Tries to write a specified amount of data from a buffer to a file. If the buffered + * operations are enabled then this operation could store data in the internal buffer + * instead of a file. + * \param[in] pBuffer - ptr to a buffer with data to store + * \param[in] iSize - count of data to store + * \return Count of data that has been stored + */ +ulong_t file::write(ptr_t pBuffer, ulong_t ulSize) +{ + assert(m_hFile); + + if (!m_bLastOperation) + { + flush(); + m_bLastOperation=true; + } + + if (!m_bBuffered) + { + // standard write +#ifdef _WIN32 + DWORD wr=0; + if (!WriteFile(m_hFile, pBuffer, ulSize, &wr, NULL)) +#else + int_t wr; + if ((wr=::write(m_hFile, pBuffer, ulSize) == -1)) +#endif + THROW(exception::format(_t("[file] Cannot write data to a file"), m_pszPath), FERR_WRITE, CURRENT_LAST_ERROR, 0); + + return (ulong_t)wr; + } + else + { + uint_t uiPos=0; + + while (uiPos < ulSize) + { + // check if buffer need storing + if (m_uiCurrentPos == m_uiBufferSize) + _write_packet(); + + // now add to internal buffer some data + uint_t uiCount=minval(m_uiBufferSize-m_uiCurrentPos, ulSize-uiPos); + + memcpy(m_pbyBuffer+m_uiCurrentPos, ((byte_t*)pBuffer)+uiPos, uiCount); + + // update + m_uiCurrentPos+=uiCount; + m_uiDataCount+=uiCount; + uiPos+=uiCount; + } + + return uiPos; + } +} + +/** Tries to read a string from a file. Uses a buffering to achieve it. If the + * current file mode is unbuffered then this function enables buffering, makes + * requested operation and disables buffering. If the buffer is too small to + * contain all the line read then the rest of line is lost. + * \param[out] pszStr - ptr to a buffer to receive a string + * \param[in] uiMaxLen - size of the string buffer + * \return If the line has been succesfully read. + */ +bool file::read_line(tchar_t* pszStr, uint_t uiMaxLen) +{ + // for unbuffered operations enable buffering for this op + if (m_bBuffered) + return _read_string(pszStr, uiMaxLen); + else + { + uint_t uiSize=m_uiBufferSize; + set_buffering(true, 4096); + + bool bRet=_read_string(pszStr, uiMaxLen); + + set_buffering(false, uiSize); + return bRet; + } +} + +/** Tries to write some text into a file. Function allocates a buffer for the string + * copy and appends a \\r\\n to this text. + * \param[in] pszString - string to store + */ +void file::write_line(tchar_t* pszString) +{ + assert(m_hFile); + + if (!m_bLastOperation) + { + flush(); + m_bLastOperation=true; + } + + // make new string with \r\n at the end - cannot use old buffer - unknown size + // NOTE: \r\n added for windoze compat; when reading file function properly handles unix style line endings + uint_t uiLen=(uint_t)_tcslen(pszString); + + tchar_t *pszData=new tchar_t[uiLen+3]; + _tcscpy(pszData, pszString); + pszData[uiLen]=_t('\r'); + pszData[uiLen+1]=_t('\n'); + pszData[uiLen+2]=_t('\0'); + + try + { + if (m_bBuffered) + { + uint_t uiStrPos=0; // current index in pszString + uint_t uiMin=0; // helper + uint_t uiSize=uiLen+2; + + // processing whole string + while (uiStrPos < uiSize) + { + if (m_uiCurrentPos == m_uiBufferSize) + _write_packet(); + + // count of chars to be copied + uiMin=minval(uiSize-uiStrPos, m_uiBufferSize-m_uiCurrentPos); + + // copy data from pszString into internal buffer (maybe part of it) + memcpy(m_pbyBuffer+m_uiCurrentPos, pszData+uiStrPos, uiMin); + + // move offsets + m_uiCurrentPos+=uiMin; + m_uiDataCount+=uiMin; + uiStrPos+=uiMin; + } + } + else + { + // standard write +#ifdef _WIN32 + DWORD wr=0; + if (!WriteFile(m_hFile, pszData, uiLen+2, &wr, NULL)) +#else + int_t wr; + if ((wr=::write(m_hFile, pszData, uiLen+2)) == -1) +#endif + THROW(exception::format(_t("Cannot write data to a file ") STRFMT, m_pszPath), FERR_WRITE, CURRENT_LAST_ERROR, 0); + } + } + catch(...) + { + delete [] pszData; + throw; + } + + delete [] pszData; +} + +/** Moves the file pointer to some place in the file. If the file is in buffered + * state, then the data is flushed and then the real seek takes place. + * \param[in] llOffset - offset of the new file pointer position + * \param[in] uiFrom - specifies the relative point (FS_*) from which the llOffset will be counted + */ +void file::seek(longlong_t llOffset, uint_t uiFrom) +{ + // flush buffer + flush(); + + // seek + _seek(llOffset, uiFrom); +} + +/** Retrieves the current file pointer position (corrected by the content of + * internal buffer if buffered mode enabled). + * \return Current file position. + */ +longlong_t file::getpos() +{ + // return corrected by internal members current file position + return _seek(0, FS_CURRENT)-m_uiDataCount+m_uiCurrentPos; +} + +/** Tries to set end-of-file marker on the current file pointer position. The internal buffer + * is flushed before truncating (or extending). + */ +void file::seteof() +{ + assert(m_hFile); + + // flush da buffers + flush(); + + // now set the end of file +#ifdef _WIN32 + if (!::SetEndOfFile(m_hFile)) +#else + if (::ftruncate(m_hFile, getpos()) == -1) +#endif + THROW(exception::format(_t("[file] Cannot truncate the file ") STRFMT, m_pszPath), FERR_SETEOF, CURRENT_LAST_ERROR, 0); +} + +/** Returns a size of the file. + * \return Size of the file. + */ +longlong_t file::get_size() +{ + flush(); + +#ifdef _WIN32 + ULARGE_INTEGER li; + li.LowPart=GetFileSize(m_hFile, &li.HighPart); + if (li.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) +#else + // NOTE: a strange way to check the file size... + struct stat st; + if (fstat(m_hFile, &st) == -1) +#endif + THROW(exception::format(_t("[file] Cannot get the size of the file ") STRFMT, m_pszPath), FERR_GETSIZE, CURRENT_LAST_ERROR, 0); + +#ifdef _WIN32 + return li.QuadPart; +#else + return st.st_size; +#endif +} + +/** Changes the buffering state (or internal buffer length). The internal buffer + * is always flushed before making any changes. + * \param[in] bEnable - specifies if the buffering is about to be enabled + * \param[in] uiSize - the new size of the internal buffer + */ +void file::set_buffering(bool bEnable, uint_t uiSize) +{ + assert(uiSize > 0); // couldn't use 0-sized internal buffer + + // flush + flush(); + + // delete old buffer + if (m_bBuffered && (!bEnable || uiSize != m_uiBufferSize)) + { + delete [] m_pbyBuffer; + m_pbyBuffer=NULL; + } + + // alloc new buffer if needed + if (bEnable && (!m_bBuffered || uiSize != m_uiBufferSize)) + m_pbyBuffer=new byte_t[uiSize]; + + m_bBuffered=bEnable; + m_uiBufferSize=uiSize; +} + +/** Switches access mode to unbuffered one and remembers the last state. If already + * in unbuffered mode the function does nothing. + */ +void file::switch_unbuffered() +{ + if (!m_bBuffered) + return; // it's already unbuffered - leave it as is + else + { + m_bRememberedState=true; // mark that we change state to a different one + set_buffering(false, m_uiBufferSize); // do no change internal buffer size + } +} + +/** Switches access mode to buffered one and remembers the last state. If already + * in buffered mode the function does nothing. + */ +void file::switch_buffered() +{ + if (m_bBuffered) + return; // already buffered + else + { + m_bRememberedState=true; + set_buffering(true, m_uiBufferSize); + } +} + +/** Restores the buffered/unbuffered access mode if stored with switch_* functions. + */ +void file::restore_state() +{ + // restore state only if changed + if (m_bRememberedState) + { + set_buffering(!m_bBuffered, m_uiBufferSize); + m_bRememberedState=false; + } +} + +/** Begins the serialization data block. Each block can have it's + * own flags. Each block have to be ended with datablock_end before + * beginning another one. If the access is read then function tries to read + * the data block from a file and checks the crc checksums. If writing - only + * the buffer is allocated and initialized. + * Blocks cannot be nested. + * \param[in] uiFlags - block flags - look at BF_* macros + */ +void file::datablock_begin(uint_t uiFlags) +{ + // do not call begin data block within another data block + assert(!m_bSerializing && m_pbySerialBuffer == NULL); + + // alloc the new buffer and insert there a header (a few unsigned chars) + m_pbySerialBuffer=new byte_t[SERIALBUFFER_DELTA]; + m_uiSerialBufferSize=SERIALBUFFER_DELTA; + + // check flags + if ((m_uiFlags & FA_READ) && (m_uiFlags & FA_WRITE)) + THROW(exception::format(_t("[file] Tried to begin a data block with file ") STRFMT _t(" opened for both read and write."), m_pszPath), FERR_SERIALIZE, 0, 0); + + // action + if (m_uiFlags & FA_WRITE) + { + // reserve some space for a header + m_uiSerialBufferPos=sizeof(SERIALIZEINFOHEADER); + } + else + { + // we need to read the block from a file + if (read(m_pbySerialBuffer, sizeof(SERIALIZEINFOHEADER)) != sizeof(SERIALIZEINFOHEADER)) + { + _clear_serialization(); + THROW(exception::format(_t("[file] Cannot read the specified amount of data from a file (reading serialization header)."), m_pszPath), FERR_SERIALIZE, CURRENT_LAST_ERROR, 0); + } + + // move forward + m_uiSerialBufferPos=sizeof(SERIALIZEINFOHEADER); + + // determine the size of the remaining data in file + SERIALIZEINFOHEADER* psih=(SERIALIZEINFOHEADER*)m_pbySerialBuffer; + uint_t uiSize=(uint_t)(psih->iRealSize-sizeof(SERIALIZEINFOHEADER)); + + // check the header crc + uint_t uihc=crc32(m_pbySerialBuffer, sizeof(SERIALIZEINFOHEADER)-sizeof(uint_t)); + if (uihc != psih->uiHeaderCRC32) + { + _clear_serialization(); + THROW(exception::format(_t("[file] Block contained in file ") STRFMT _t(" is corrupted. Header CRC check failed."), m_pszPath), FERR_SERIALIZE, 0, 0); + } + + // resize the buffer + _sbuf_resize((uint_t)psih->iRealSize); + + // refresh the psih + psih=(SERIALIZEINFOHEADER*)m_pbySerialBuffer; + + // read the remaining data + if (read(m_pbySerialBuffer+m_uiSerialBufferPos, uiSize) != (int_t)uiSize) + { + _clear_serialization(); + THROW(exception::format(_t("Cannot read specified amount of data from a file ") STRFMT _t(" (reading the after-header data)."), m_pszPath), FERR_SERIALIZE, CURRENT_LAST_ERROR, 0); + } + + // NOTE: do not update the position - we need ptr at the beginning of data + // now we are almost ready to retrieve data - only the crc check for the data + uint_t uiCRC=crc32(m_pbySerialBuffer+sizeof(SERIALIZEINFOHEADER), psih->iDataSize-sizeof(SERIALIZEINFOHEADER)); + if (psih->uiCRC32 != uiCRC) + { + _clear_serialization(); + THROW(exception::format(_t("CRC check of the data read from file ") STRFMT _t(" failed."), m_pszPath), FERR_SERIALIZE, 0, 0); + } + } + + // make a mark + m_uiDataBlockFlags=uiFlags; + m_bSerializing=true; +} + +/** Ends the data block opened previously with datablock_begin. If the access is writing + * then the function updates the crc checksums in the buffer and tries to write the block + * of data to the file. If reading - only the serialization is cancelled. + */ +void file::datablock_end() +{ + // make sure everything is ok + assert(m_bSerializing && m_pbySerialBuffer != NULL); + + // check the operation type + if ((m_uiFlags & FA_READ) && (m_uiFlags & FA_WRITE)) + THROW(exception::format(_t("[file] Tried to end a data block with file ") STRFMT _t(" opened for both read and write."), m_pszPath), FERR_SERIALIZE, 0, 0); + + // when writing - make a header, ...; when reading - do nothing important + if (m_uiFlags & FA_WRITE) + { + // check if there is any data + if (m_uiSerialBufferPos == sizeof(SERIALIZEINFOHEADER)) + return; // no data has been serialized + + // fill the header (real data information) + SERIALIZEINFOHEADER *psih=(SERIALIZEINFOHEADER*)m_pbySerialBuffer; + psih->iDataSize=m_uiSerialBufferPos; + psih->uiCRC32=crc32(m_pbySerialBuffer+sizeof(SERIALIZEINFOHEADER), m_uiSerialBufferPos-sizeof(SERIALIZEINFOHEADER)); + + // the rest of header + psih->iRealSize=m_uiSerialBufferPos; + + // calc the header crc + psih->uiHeaderCRC32=crc32(m_pbySerialBuffer, sizeof(SERIALIZEINFOHEADER)-sizeof(uint_t)); + + // write the buffer + write(m_pbySerialBuffer, psih->iRealSize); + } + + // remove all the traces of serializing + _clear_serialization(); +} + +/** Writes some bytes of data to a serialization buffer opened + * with the datablock_begin. Causes the class to reallocate an internal + * buffer(if needed) to make all the data fit into the buffer. + * NOTE: do not use too large data blocks because of the buffer reallocation. + * \param[in] pData - buffer address with some data + * \param[in] uiSize - count of bytes to write + */ +void file::swrite(ptr_t pData, uint_t uiSize) +{ + _sbuf_append(pData, uiSize); +} + +/** Reads some bytes of data from a serialization buffer opened by + * datablock_end call. + * \param[out] pData - buffer for the received data + * \param[in] uiSize - count of data to read; if user requests more data than available then an exception will be thrown + */ +void file::sread(ptr_t pData, uint_t uiSize) +{ + _sbuf_read(pData, uiSize); +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(bool val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(bool& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(tchar_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(tchar_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(uchar_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(uchar_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(short_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(short_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(ushort_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(ushort_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(int_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(int_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(uint_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(uint_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(ll_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(ll_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Writes a value of a given type to the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - value to be stored in a file + * \return Reference to this file object. + */ +file& file::operator<<(ull_t val) +{ + swrite(&val, sizeof(val)); + return *this; +} + +/** Reads a value of a given type from the file. This is a serialization related function, so + * the datablock has to be opened prior to using this operator. + * \param[in] val - reference to a variable to receive data + * \return Reference to this file object. + */ +file& file::operator>>(ull_t& val) +{ + sread(&val, sizeof(val)); + return *this; +} + +/** Cancels the serialization process and removes all the traces of data being serialized + * (it includes deleting the serialization buffer). + */ +void file::_clear_serialization() +{ + // remove all the traces of serializing + delete [] m_pbySerialBuffer; + m_pbySerialBuffer=NULL; + m_uiSerialBufferSize=0; + m_uiSerialBufferPos=0; + m_bSerializing=false; +} + +/** Used to read the next packet of data into the internal buffer (used for + * buffering). + * \return Count of bytes that has been read from a file. + */ +uint_t file::_read_packet() +{ + assert(m_hFile); + + // read data +#ifdef _WIN32 + DWORD rd=0; + if (!ReadFile(m_hFile, m_pbyBuffer, m_uiBufferSize, &rd, NULL)) +#else + int_t rd; + if ((rd=::read(m_hFile, m_pbyBuffer, m_uiBufferSize)) == -1) +#endif + THROW(exception::format(_t("[file] Cannot read data from a file ") STRFMT _t("."), m_pszPath), FERR_READ, CURRENT_LAST_ERROR, 0); + + // reset internal members + m_uiDataCount=rd; + m_uiCurrentPos=0; + + return rd; +} + +/** Used to write the next packet of data from an internal buffer (buffering + * related) to a file. + * \return Count of bytes written. + */ +uint_t file::_write_packet() +{ + assert(m_hFile); + +#ifdef _WIN32 + DWORD wr=0; + if (!WriteFile(m_hFile, m_pbyBuffer, m_uiDataCount, &wr, NULL)) +#else + int_t wr; + if ((wr=::write(m_hFile, m_pbyBuffer, m_uiDataCount)) == -1) +#endif + { + THROW(exception::format(_t("Cannot write data to a file ") STRFMT _t("."), m_pszPath), FERR_WRITE, CURRENT_LAST_ERROR, 0); + } + + // reset internal members + m_uiDataCount=0; + m_uiCurrentPos=0; + + return wr; +} + +/** Reads some data from the internal serialization buffer. + * \param[out] pData - ptr to a buffer that is about to receive data + * \param[in] uiLen - count of data to be read + */ +void file::_sbuf_read(ptr_t pData, uint_t uiLen) +{ + // check if we are reading + assert(m_uiFlags & FA_READ); + + // check the ranges + if (m_uiSerialBufferPos+uiLen > m_uiSerialBufferSize) + { + // throw an exception - read beyond the data range in a given object + THROW(exception::format(_t("[file] Trying to read the serialization data beyond the range (file ") STRFMT _t(")."), m_pszPath), FERR_MEMORY, CURRENT_LAST_ERROR, 0); + } + + // read the data + memcpy(pData, m_pbySerialBuffer+m_uiSerialBufferPos, uiLen); + m_uiSerialBufferPos+=uiLen; +} + +/** Appends some bytes to the internal serialization buffer (data block). + * \param[in] pData - ptr to a data buffer + * \param[in] uiCount - count of data to store + */ +void file::_sbuf_append(ptr_t pData, uint_t uiCount) +{ + // check if we are writing + assert(m_pbySerialBuffer); + assert(m_uiFlags & FA_WRITE); + + // check serial buffer size (if there is enough room for the data) + if (m_uiSerialBufferPos+uiCount > m_uiSerialBufferSize) + { + // we need a buffer reallocation + uint_t uiDelta=((uiCount/SERIALBUFFER_DELTA)+1)*SERIALBUFFER_DELTA; + + // alloc the new buffer + _sbuf_resize(m_uiSerialBufferSize+uiDelta); + } + + // real storage of the data + if (uiCount > 0) + { + memcpy(m_pbySerialBuffer+m_uiSerialBufferPos, pData, uiCount); + m_uiSerialBufferPos+=uiCount; + } +} + +/** Resizes the internal serialization buffer to the new length. + * Also does copy the old data to the new buffer. + * \param[in] uiNewLen - new buffer length + */ +void file::_sbuf_resize(uint_t uiNewLen) +{ + assert(m_pbySerialBuffer); + + // alloc the new buffer + byte_t* pbyNewBuffer=new byte_t[uiNewLen]; + + // copy the old data into the new one + uint_t uiCount=minval(m_uiSerialBufferPos, uiNewLen); + if (m_uiSerialBufferPos > 0) + memcpy(pbyNewBuffer, m_pbySerialBuffer, uiCount); + + // delete the old buffer + delete [] m_pbySerialBuffer; + + // set the new buffer inplace and update the internal size + m_pbySerialBuffer=pbyNewBuffer; + m_uiSerialBufferSize=uiNewLen; +} + + +/** Reads a line of text from text file - only for buffered operations. + * Properly interpretes the windoze and unix line endings. + * \param[out] pszStr - buffer for the string that is about to be read + * \param[in] uiMaxLen - size of the string buffer + * \return Bool value that states if the string has been read. + */ +bool file::_read_string(tchar_t* pszStr, uint_t uiMaxLen) +{ + assert(m_hFile); // file wasn_t('t opened - error opening or you')ve forgotten to do so ? + assert(m_pbyBuffer != NULL); + + // last time was writing - free buffer + if (m_bLastOperation) + { + flush(); + m_bLastOperation=false; + } + + // zero all the string + memset(pszStr, 0, uiMaxLen*sizeof(tchar_t)); + + // additional vars + uint_t uiStrPos=0; // current pos in external buffer + bool bSecondPass=false; // if there is need to check data for 0x0a tchar_t + + // copy each tchar_t into pszString + for (;;) + { + // if buffer is empty - fill it + if (m_uiDataCount == 0 || m_uiCurrentPos == m_uiDataCount) + { + if (_read_packet() == 0) + return _tcslen(pszStr) != 0; + } + + // skipping 0x0a in second pass + if (bSecondPass) + { + if (m_pbyBuffer[m_uiCurrentPos] == 0x0a) + m_uiCurrentPos++; + return true; + } + + // now process chars + while (m_uiCurrentPos < m_uiDataCount) + { + if (m_pbyBuffer[m_uiCurrentPos] == 0x0d) + { + bSecondPass=true; + m_uiCurrentPos++; + break; + } + else if (m_pbyBuffer[m_uiCurrentPos] == 0x0a) + { + m_uiCurrentPos++; + return true; + } + else + { + if (uiStrPos < uiMaxLen-1) + pszStr[uiStrPos++]=m_pbyBuffer[m_uiCurrentPos]; + m_uiCurrentPos++; + } + } + } +} + +/** Sets file pointer in a file. + * \param[in] llOffset - position to move the file pointer to + * \param[in] uiFrom - the relative position of a base position (FS_*) + * \return The new file pointer position. + */ +longlong_t file::_seek(longlong_t llOffset, uint_t uiFrom) +{ +#ifdef _WIN32 + LARGE_INTEGER li; + li.QuadPart = llOffset; + li.LowPart = SetFilePointer (m_hFile, li.LowPart, &li.HighPart, uiFrom); + + if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) +#else + int_t lRes; + if ((lRes=lseek(m_hFile, llOffset, uiFrom)) == -1) +#endif + THROW(exception::format(_t("Seek error in file ") STRFMT _t("."), m_pszPath), FERR_SEEK, CURRENT_LAST_ERROR, 0); + +#ifdef _WIN32 + return li.QuadPart; +#else + return lRes; +#endif +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/file.cpp =================================================================== diff -u -N --- ext/libicpf/src/file.cpp (revision 6dae57f5e7aeeb965bc018024d8360069f6e15c1) +++ ext/libicpf/src/file.cpp (revision 0) @@ -1,1170 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file file.cpp - * \brief Contains file/serializer class */ - -#include "file.h" -#include "crc32.h" -#include -#include "macros.h" -#include "err_codes.h" - -#ifndef _WIN32 - #include - #include - #include - #include -#endif - -BEGIN_ICPF_NAMESPACE - -#include - -/// Serialization buffer increment value -#define SERIALBUFFER_DELTA 4096UL - -// for making life easier -#ifdef _WIN32 - /// Macro representing the current value of last encountered error - #define CURRENT_LAST_ERROR GetLastError() - /// Null value for a file handle - platform compatibility helper - #define FNULL NULL -#else - /// Windoze compatibility macro - value returned from erroneous call to ::open() system call - #define INVALID_HANDLE_VALUE -1 - /// Macro representing the current value of last encountered error - #define CURRENT_LAST_ERROR errno - /// Null value for a file handle - platform compatibility helper - #define FNULL 0 -#endif - - -/** Standard constructor - nullifies all member variables. - */ -file::file() : - m_hFile(FNULL), - m_pszPath(NULL), - m_uiFlags(0), - m_bLastOperation(false), - m_bBuffered(false), - m_uiBufferSize(0), - m_pbyBuffer(NULL), - m_uiCurrentPos(0), - m_uiDataCount(0), - m_bRememberedState(false), - m_bSerializing(0), - m_pbySerialBuffer(NULL), - m_uiSerialBufferSize(0), - m_uiSerialBufferPos(0), - m_uiDataBlockFlags(BF_NONE) -{ -} - -/** Standard destructor - tries to close a file, but catches any exception thrown - * and does not throw it again. - */ -file::~file() -{ - // close all the stuff, but make sure no exception is thrown - try - { - close(); - } - catch(exception&) - { - } -} - -/** Opens a filesystem object (a file) with a given flags and (if needed) with - * some buffer size used in internal buffering. In case of error throws an icpf::exception - * with the error description. - * \param[in] pszPath - path to a file to open - * \param[in] uiFlags - flags that determine the type of access to a file (FA_*) - * \param[in] uiBufSize - buffer size that will be used for internal buffering (if enabled) - */ -void file::open(const tchar_t* pszPath, uint_t uiFlags, uint_t uiBufSize) -{ - // check if this object is ready to open a file - if (m_hFile) - close(); - - // check for the flags completion -#ifdef _WIN32 - uint_t mode=0, flags=OPEN_EXISTING; -#else - int_t mode=0; -#endif - - // read flag - if (uiFlags & FA_READ) -#ifdef _WIN32 - mode |= GENERIC_READ; -#else - mode |= O_RDONLY; -#endif - - // write flag - if (uiFlags & FA_WRITE) -#ifdef _WIN32 - mode |= GENERIC_WRITE; -#else - mode |= O_WRONLY; -#endif - - // creation flag - if (uiFlags & FA_CREATE) -#ifdef _WIN32 - { - if (uiFlags & FA_TRUNCATE) - flags = CREATE_ALWAYS; - else - flags = OPEN_ALWAYS; - } -#else - mode |= O_CREAT; -#endif - - // truncation - if (uiFlags & FA_TRUNCATE) -#ifdef _WIN32 - { - if (!(uiFlags & FA_CREATE)) - flags = TRUNCATE_EXISTING; - } -#else - mode |= O_TRUNC; -#endif - - // make a system call -#ifdef _WIN32 - m_hFile=::CreateFile(pszPath, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, flags, FILE_ATTRIBUTE_NORMAL, NULL); -#else - m_hFile=::open(pszPath, mode); -#endif - - if (m_hFile == INVALID_HANDLE_VALUE) - { - m_hFile=FNULL; - THROW(exception::format(_t("[file] Cannot open the file ") STRFMT _t(" with flags ") ULXFMT, pszPath, uiFlags), FERR_OPEN, CURRENT_LAST_ERROR, 0); - } - else - { - // remember the path of this file - m_pszPath=new tchar_t[_tcslen(pszPath)+1]; - _tcscpy(m_pszPath, pszPath); - - // remember the mode - m_uiFlags=uiFlags; - - // is this buffered ? - set_buffering((uiFlags & FA_BUFFERED) != 0, uiBufSize); - } -} - -/** Tries to save the data contained in internal buffer (if any) and frees all the - * resources used by this class. Can be used on closed files. In case of error the - * ch::exception is thrown. - */ -void file::close() -{ - // only if the file has been opened - if (m_hFile != FNULL) - { - // flush all data - flush(); - - // free strings and other data (at first, because of the destruction call) - delete [] m_pszPath; - m_pszPath=NULL; - delete [] m_pbyBuffer; - m_pbyBuffer=NULL; - - delete [] m_pbySerialBuffer; - m_pbySerialBuffer=NULL; - - m_uiFlags=0; - m_bLastOperation=false; - - m_bBuffered=false; - m_uiBufferSize=0; - m_uiCurrentPos=0; - m_uiDataCount=0; - - m_bSerializing=false; - m_uiSerialBufferSize=0; - m_uiSerialBufferPos=0; - m_uiDataBlockFlags=0; - - m_bRememberedState=false; - - // close the file -#ifdef _WIN32 - if (!::CloseHandle(m_hFile)) -#else - if (::close(m_hFile) == -1) -#endif - THROW(exception::format(_t("[file] Cannot close the handle associated with a file ") STRFMT, m_pszPath), FERR_CLOSE, CURRENT_LAST_ERROR, 0); - else - m_hFile=FNULL; - } -} - -/** Does anything only if the file is opened, the operation is being buffered and the data - * count contained in the internal buffer is >0. If the last operation performed was - * storing data then the function tries to store a packet of data to the file. If the data - * has been read lately then only the file pointer will be repositioned. Also the internal buffer - * will be made empty. Function can throw an ch::exception in case of error. - */ -void file::flush() -{ - if (m_hFile && m_bBuffered && m_uiDataCount > 0) - { - if (m_bLastOperation) - { - // last operation - storing data - _write_packet(); - } - else - { - // last - reading data - // set file pointer to position current-(m_uiDataCount-m_uiCurrentPos) - _seek(-(longlong_t)(m_uiDataCount-m_uiCurrentPos), FS_CURRENT); - m_uiCurrentPos=0; - m_uiDataCount=0; - } - } -} - -/** Tries to read a specified count of bytes from a file to the specified buffer. - * If the is currently in buffered state the reading is being done with internal - * buffering. It could be helpful when reading small amounts of data. - * \param[out] pBuffer - ptr to a buffer that is about to receive data - * \param[in] iSize - count of bytes to read - * \return Count of bytes that has been read (could be less than iSize) - */ -ulong_t file::read(ptr_t pBuffer, ulong_t ulSize) -{ - assert(m_hFile); // forgot to open the file ? - - // flush if needed - if (m_bLastOperation) - { - flush(); - m_bLastOperation=false; - } - - if (!m_bBuffered) - { - // unbuffered operation (read what is needed) -#ifdef _WIN32 - DWORD rd=0; - if (!ReadFile(m_hFile, pBuffer, ulSize, &rd, NULL)) -#else - int_t rd=0; - if ((rd=::read(m_hFile, pBuffer, ulSize)) < 0) -#endif - THROW(exception::format(_t("Cannot read data from file ") STRFMT, m_pszPath), FERR_READ, CURRENT_LAST_ERROR, 0); - - return rd; // if 0 - eof (not treated as exception) - } - else - { - // reads must be done by packets - uint_t uiCurrPos=0; // position in external buffer - while (uiCurrPos < ulSize) - { - // are there any data left ? - if (m_uiDataCount == 0 || m_uiCurrentPos == m_uiDataCount) - { - if (_read_packet() == 0) - return uiCurrPos; // return what was read 'til now - } - - // copy data into external buffer - uint_t uiCount=minval(m_uiDataCount-m_uiCurrentPos, ulSize-uiCurrPos); - memcpy(((byte_t*)pBuffer)+uiCurrPos, m_pbyBuffer+m_uiCurrentPos, uiCount); - - // update positions - uiCurrPos+=uiCount; - m_uiCurrentPos+=uiCount; - } - - return uiCurrPos; - } -} - -/** Tries to write a specified amount of data from a buffer to a file. If the buffered - * operations are enabled then this operation could store data in the internal buffer - * instead of a file. - * \param[in] pBuffer - ptr to a buffer with data to store - * \param[in] iSize - count of data to store - * \return Count of data that has been stored - */ -ulong_t file::write(ptr_t pBuffer, ulong_t ulSize) -{ - assert(m_hFile); - - if (!m_bLastOperation) - { - flush(); - m_bLastOperation=true; - } - - if (!m_bBuffered) - { - // standard write -#ifdef _WIN32 - DWORD wr=0; - if (!WriteFile(m_hFile, pBuffer, ulSize, &wr, NULL)) -#else - int_t wr; - if ((wr=::write(m_hFile, pBuffer, ulSize) == -1)) -#endif - THROW(exception::format(_t("[file] Cannot write data to a file"), m_pszPath), FERR_WRITE, CURRENT_LAST_ERROR, 0); - - return (ulong_t)wr; - } - else - { - uint_t uiPos=0; - - while (uiPos < ulSize) - { - // check if buffer need storing - if (m_uiCurrentPos == m_uiBufferSize) - _write_packet(); - - // now add to internal buffer some data - uint_t uiCount=minval(m_uiBufferSize-m_uiCurrentPos, ulSize-uiPos); - - memcpy(m_pbyBuffer+m_uiCurrentPos, ((byte_t*)pBuffer)+uiPos, uiCount); - - // update - m_uiCurrentPos+=uiCount; - m_uiDataCount+=uiCount; - uiPos+=uiCount; - } - - return uiPos; - } -} - -/** Tries to read a string from a file. Uses a buffering to achieve it. If the - * current file mode is unbuffered then this function enables buffering, makes - * requested operation and disables buffering. If the buffer is too small to - * contain all the line read then the rest of line is lost. - * \param[out] pszStr - ptr to a buffer to receive a string - * \param[in] uiMaxLen - size of the string buffer - * \return If the line has been succesfully read. - */ -bool file::read_line(tchar_t* pszStr, uint_t uiMaxLen) -{ - // for unbuffered operations enable buffering for this op - if (m_bBuffered) - return _read_string(pszStr, uiMaxLen); - else - { - uint_t uiSize=m_uiBufferSize; - set_buffering(true, 4096); - - bool bRet=_read_string(pszStr, uiMaxLen); - - set_buffering(false, uiSize); - return bRet; - } -} - -/** Tries to write some text into a file. Function allocates a buffer for the string - * copy and appends a \\r\\n to this text. - * \param[in] pszString - string to store - */ -void file::write_line(tchar_t* pszString) -{ - assert(m_hFile); - - if (!m_bLastOperation) - { - flush(); - m_bLastOperation=true; - } - - // make new string with \r\n at the end - cannot use old buffer - unknown size - // NOTE: \r\n added for windoze compat; when reading file function properly handles unix style line endings - uint_t uiLen=(uint_t)_tcslen(pszString); - - tchar_t *pszData=new tchar_t[uiLen+3]; - _tcscpy(pszData, pszString); - pszData[uiLen]=_t('\r'); - pszData[uiLen+1]=_t('\n'); - pszData[uiLen+2]=_t('\0'); - - try - { - if (m_bBuffered) - { - uint_t uiStrPos=0; // current index in pszString - uint_t uiMin=0; // helper - uint_t uiSize=uiLen+2; - - // processing whole string - while (uiStrPos < uiSize) - { - if (m_uiCurrentPos == m_uiBufferSize) - _write_packet(); - - // count of chars to be copied - uiMin=minval(uiSize-uiStrPos, m_uiBufferSize-m_uiCurrentPos); - - // copy data from pszString into internal buffer (maybe part of it) - memcpy(m_pbyBuffer+m_uiCurrentPos, pszData+uiStrPos, uiMin); - - // move offsets - m_uiCurrentPos+=uiMin; - m_uiDataCount+=uiMin; - uiStrPos+=uiMin; - } - } - else - { - // standard write -#ifdef _WIN32 - DWORD wr=0; - if (!WriteFile(m_hFile, pszData, uiLen+2, &wr, NULL)) -#else - int_t wr; - if ((wr=::write(m_hFile, pszData, uiLen+2)) == -1) -#endif - THROW(exception::format(_t("Cannot write data to a file ") STRFMT, m_pszPath), FERR_WRITE, CURRENT_LAST_ERROR, 0); - } - } - catch(...) - { - delete [] pszData; - throw; - } - - delete [] pszData; -} - -/** Moves the file pointer to some place in the file. If the file is in buffered - * state, then the data is flushed and then the real seek takes place. - * \param[in] llOffset - offset of the new file pointer position - * \param[in] uiFrom - specifies the relative point (FS_*) from which the llOffset will be counted - */ -void file::seek(longlong_t llOffset, uint_t uiFrom) -{ - // flush buffer - flush(); - - // seek - _seek(llOffset, uiFrom); -} - -/** Retrieves the current file pointer position (corrected by the content of - * internal buffer if buffered mode enabled). - * \return Current file position. - */ -longlong_t file::getpos() -{ - // return corrected by internal members current file position - return _seek(0, FS_CURRENT)-m_uiDataCount+m_uiCurrentPos; -} - -/** Tries to set end-of-file marker on the current file pointer position. The internal buffer - * is flushed before truncating (or extending). - */ -void file::seteof() -{ - assert(m_hFile); - - // flush da buffers - flush(); - - // now set the end of file -#ifdef _WIN32 - if (!::SetEndOfFile(m_hFile)) -#else - if (::ftruncate(m_hFile, getpos()) == -1) -#endif - THROW(exception::format(_t("[file] Cannot truncate the file ") STRFMT, m_pszPath), FERR_SETEOF, CURRENT_LAST_ERROR, 0); -} - -/** Returns a size of the file. - * \return Size of the file. - */ -longlong_t file::get_size() -{ - flush(); - -#ifdef _WIN32 - ULARGE_INTEGER li; - li.LowPart=GetFileSize(m_hFile, &li.HighPart); - if (li.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) -#else - // NOTE: a strange way to check the file size... - struct stat st; - if (fstat(m_hFile, &st) == -1) -#endif - THROW(exception::format(_t("[file] Cannot get the size of the file ") STRFMT, m_pszPath), FERR_GETSIZE, CURRENT_LAST_ERROR, 0); - -#ifdef _WIN32 - return li.QuadPart; -#else - return st.st_size; -#endif -} - -/** Changes the buffering state (or internal buffer length). The internal buffer - * is always flushed before making any changes. - * \param[in] bEnable - specifies if the buffering is about to be enabled - * \param[in] uiSize - the new size of the internal buffer - */ -void file::set_buffering(bool bEnable, uint_t uiSize) -{ - assert(uiSize > 0); // couldn't use 0-sized internal buffer - - // flush - flush(); - - // delete old buffer - if (m_bBuffered && (!bEnable || uiSize != m_uiBufferSize)) - { - delete [] m_pbyBuffer; - m_pbyBuffer=NULL; - } - - // alloc new buffer if needed - if (bEnable && (!m_bBuffered || uiSize != m_uiBufferSize)) - m_pbyBuffer=new byte_t[uiSize]; - - m_bBuffered=bEnable; - m_uiBufferSize=uiSize; -} - -/** Switches access mode to unbuffered one and remembers the last state. If already - * in unbuffered mode the function does nothing. - */ -void file::switch_unbuffered() -{ - if (!m_bBuffered) - return; // it's already unbuffered - leave it as is - else - { - m_bRememberedState=true; // mark that we change state to a different one - set_buffering(false, m_uiBufferSize); // do no change internal buffer size - } -} - -/** Switches access mode to buffered one and remembers the last state. If already - * in buffered mode the function does nothing. - */ -void file::switch_buffered() -{ - if (m_bBuffered) - return; // already buffered - else - { - m_bRememberedState=true; - set_buffering(true, m_uiBufferSize); - } -} - -/** Restores the buffered/unbuffered access mode if stored with switch_* functions. - */ -void file::restore_state() -{ - // restore state only if changed - if (m_bRememberedState) - { - set_buffering(!m_bBuffered, m_uiBufferSize); - m_bRememberedState=false; - } -} - -/** Begins the serialization data block. Each block can have it's - * own flags. Each block have to be ended with datablock_end before - * beginning another one. If the access is read then function tries to read - * the data block from a file and checks the crc checksums. If writing - only - * the buffer is allocated and initialized. - * Blocks cannot be nested. - * \param[in] uiFlags - block flags - look at BF_* macros - */ -void file::datablock_begin(uint_t uiFlags) -{ - // do not call begin data block within another data block - assert(!m_bSerializing && m_pbySerialBuffer == NULL); - - // alloc the new buffer and insert there a header (a few unsigned chars) - m_pbySerialBuffer=new byte_t[SERIALBUFFER_DELTA]; - m_uiSerialBufferSize=SERIALBUFFER_DELTA; - - // check flags - if ((m_uiFlags & FA_READ) && (m_uiFlags & FA_WRITE)) - THROW(exception::format(_t("[file] Tried to begin a data block with file ") STRFMT _t(" opened for both read and write."), m_pszPath), FERR_SERIALIZE, 0, 0); - - // action - if (m_uiFlags & FA_WRITE) - { - // reserve some space for a header - m_uiSerialBufferPos=sizeof(SERIALIZEINFOHEADER); - } - else - { - // we need to read the block from a file - if (read(m_pbySerialBuffer, sizeof(SERIALIZEINFOHEADER)) != sizeof(SERIALIZEINFOHEADER)) - { - _clear_serialization(); - THROW(exception::format(_t("[file] Cannot read the specified amount of data from a file (reading serialization header)."), m_pszPath), FERR_SERIALIZE, CURRENT_LAST_ERROR, 0); - } - - // move forward - m_uiSerialBufferPos=sizeof(SERIALIZEINFOHEADER); - - // determine the size of the remaining data in file - SERIALIZEINFOHEADER* psih=(SERIALIZEINFOHEADER*)m_pbySerialBuffer; - uint_t uiSize=(uint_t)(psih->iRealSize-sizeof(SERIALIZEINFOHEADER)); - - // check the header crc - uint_t uihc=crc32(m_pbySerialBuffer, sizeof(SERIALIZEINFOHEADER)-sizeof(uint_t)); - if (uihc != psih->uiHeaderCRC32) - { - _clear_serialization(); - THROW(exception::format(_t("[file] Block contained in file ") STRFMT _t(" is corrupted. Header CRC check failed."), m_pszPath), FERR_SERIALIZE, 0, 0); - } - - // resize the buffer - _sbuf_resize((uint_t)psih->iRealSize); - - // refresh the psih - psih=(SERIALIZEINFOHEADER*)m_pbySerialBuffer; - - // read the remaining data - if (read(m_pbySerialBuffer+m_uiSerialBufferPos, uiSize) != (int_t)uiSize) - { - _clear_serialization(); - THROW(exception::format(_t("Cannot read specified amount of data from a file ") STRFMT _t(" (reading the after-header data)."), m_pszPath), FERR_SERIALIZE, CURRENT_LAST_ERROR, 0); - } - - // NOTE: do not update the position - we need ptr at the beginning of data - // now we are almost ready to retrieve data - only the crc check for the data - uint_t uiCRC=crc32(m_pbySerialBuffer+sizeof(SERIALIZEINFOHEADER), psih->iDataSize-sizeof(SERIALIZEINFOHEADER)); - if (psih->uiCRC32 != uiCRC) - { - _clear_serialization(); - THROW(exception::format(_t("CRC check of the data read from file ") STRFMT _t(" failed."), m_pszPath), FERR_SERIALIZE, 0, 0); - } - } - - // make a mark - m_uiDataBlockFlags=uiFlags; - m_bSerializing=true; -} - -/** Ends the data block opened previously with datablock_begin. If the access is writing - * then the function updates the crc checksums in the buffer and tries to write the block - * of data to the file. If reading - only the serialization is cancelled. - */ -void file::datablock_end() -{ - // make sure everything is ok - assert(m_bSerializing && m_pbySerialBuffer != NULL); - - // check the operation type - if ((m_uiFlags & FA_READ) && (m_uiFlags & FA_WRITE)) - THROW(exception::format(_t("[file] Tried to end a data block with file ") STRFMT _t(" opened for both read and write."), m_pszPath), FERR_SERIALIZE, 0, 0); - - // when writing - make a header, ...; when reading - do nothing important - if (m_uiFlags & FA_WRITE) - { - // check if there is any data - if (m_uiSerialBufferPos == sizeof(SERIALIZEINFOHEADER)) - return; // no data has been serialized - - // fill the header (real data information) - SERIALIZEINFOHEADER *psih=(SERIALIZEINFOHEADER*)m_pbySerialBuffer; - psih->iDataSize=m_uiSerialBufferPos; - psih->uiCRC32=crc32(m_pbySerialBuffer+sizeof(SERIALIZEINFOHEADER), m_uiSerialBufferPos-sizeof(SERIALIZEINFOHEADER)); - - // the rest of header - psih->iRealSize=m_uiSerialBufferPos; - - // calc the header crc - psih->uiHeaderCRC32=crc32(m_pbySerialBuffer, sizeof(SERIALIZEINFOHEADER)-sizeof(uint_t)); - - // write the buffer - write(m_pbySerialBuffer, psih->iRealSize); - } - - // remove all the traces of serializing - _clear_serialization(); -} - -/** Writes some bytes of data to a serialization buffer opened - * with the datablock_begin. Causes the class to reallocate an internal - * buffer(if needed) to make all the data fit into the buffer. - * NOTE: do not use too large data blocks because of the buffer reallocation. - * \param[in] pData - buffer address with some data - * \param[in] uiSize - count of bytes to write - */ -void file::swrite(ptr_t pData, uint_t uiSize) -{ - _sbuf_append(pData, uiSize); -} - -/** Reads some bytes of data from a serialization buffer opened by - * datablock_end call. - * \param[out] pData - buffer for the received data - * \param[in] uiSize - count of data to read; if user requests more data than available then an exception will be thrown - */ -void file::sread(ptr_t pData, uint_t uiSize) -{ - _sbuf_read(pData, uiSize); -} - -/** Writes a value of a given type to the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - value to be stored in a file - * \return Reference to this file object. - */ -file& file::operator<<(bool val) -{ - swrite(&val, sizeof(val)); - return *this; -} - -/** Reads a value of a given type from the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - reference to a variable to receive data - * \return Reference to this file object. - */ -file& file::operator>>(bool& val) -{ - sread(&val, sizeof(val)); - return *this; -} - -/** Writes a value of a given type to the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - value to be stored in a file - * \return Reference to this file object. - */ -file& file::operator<<(tchar_t val) -{ - swrite(&val, sizeof(val)); - return *this; -} - -/** Reads a value of a given type from the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - reference to a variable to receive data - * \return Reference to this file object. - */ -file& file::operator>>(tchar_t& val) -{ - sread(&val, sizeof(val)); - return *this; -} - -/** Writes a value of a given type to the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - value to be stored in a file - * \return Reference to this file object. - */ -file& file::operator<<(uchar_t val) -{ - swrite(&val, sizeof(val)); - return *this; -} - -/** Reads a value of a given type from the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - reference to a variable to receive data - * \return Reference to this file object. - */ -file& file::operator>>(uchar_t& val) -{ - sread(&val, sizeof(val)); - return *this; -} - -/** Writes a value of a given type to the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - value to be stored in a file - * \return Reference to this file object. - */ -file& file::operator<<(short_t val) -{ - swrite(&val, sizeof(val)); - return *this; -} - -/** Reads a value of a given type from the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - reference to a variable to receive data - * \return Reference to this file object. - */ -file& file::operator>>(short_t& val) -{ - sread(&val, sizeof(val)); - return *this; -} - -/** Writes a value of a given type to the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - value to be stored in a file - * \return Reference to this file object. - */ -file& file::operator<<(ushort_t val) -{ - swrite(&val, sizeof(val)); - return *this; -} - -/** Reads a value of a given type from the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - reference to a variable to receive data - * \return Reference to this file object. - */ -file& file::operator>>(ushort_t& val) -{ - sread(&val, sizeof(val)); - return *this; -} - -/** Writes a value of a given type to the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - value to be stored in a file - * \return Reference to this file object. - */ -file& file::operator<<(int_t val) -{ - swrite(&val, sizeof(val)); - return *this; -} - -/** Reads a value of a given type from the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - reference to a variable to receive data - * \return Reference to this file object. - */ -file& file::operator>>(int_t& val) -{ - sread(&val, sizeof(val)); - return *this; -} - -/** Writes a value of a given type to the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - value to be stored in a file - * \return Reference to this file object. - */ -file& file::operator<<(uint_t val) -{ - swrite(&val, sizeof(val)); - return *this; -} - -/** Reads a value of a given type from the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - reference to a variable to receive data - * \return Reference to this file object. - */ -file& file::operator>>(uint_t& val) -{ - sread(&val, sizeof(val)); - return *this; -} - -/** Writes a value of a given type to the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - value to be stored in a file - * \return Reference to this file object. - */ -file& file::operator<<(ll_t val) -{ - swrite(&val, sizeof(val)); - return *this; -} - -/** Reads a value of a given type from the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - reference to a variable to receive data - * \return Reference to this file object. - */ -file& file::operator>>(ll_t& val) -{ - sread(&val, sizeof(val)); - return *this; -} - -/** Writes a value of a given type to the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - value to be stored in a file - * \return Reference to this file object. - */ -file& file::operator<<(ull_t val) -{ - swrite(&val, sizeof(val)); - return *this; -} - -/** Reads a value of a given type from the file. This is a serialization related function, so - * the datablock has to be opened prior to using this operator. - * \param[in] val - reference to a variable to receive data - * \return Reference to this file object. - */ -file& file::operator>>(ull_t& val) -{ - sread(&val, sizeof(val)); - return *this; -} - -/** Cancels the serialization process and removes all the traces of data being serialized - * (it includes deleting the serialization buffer). - */ -void file::_clear_serialization() -{ - // remove all the traces of serializing - delete [] m_pbySerialBuffer; - m_pbySerialBuffer=NULL; - m_uiSerialBufferSize=0; - m_uiSerialBufferPos=0; - m_bSerializing=false; -} - -/** Used to read the next packet of data into the internal buffer (used for - * buffering). - * \return Count of bytes that has been read from a file. - */ -uint_t file::_read_packet() -{ - assert(m_hFile); - - // read data -#ifdef _WIN32 - DWORD rd=0; - if (!ReadFile(m_hFile, m_pbyBuffer, m_uiBufferSize, &rd, NULL)) -#else - int_t rd; - if ((rd=::read(m_hFile, m_pbyBuffer, m_uiBufferSize)) == -1) -#endif - THROW(exception::format(_t("[file] Cannot read data from a file ") STRFMT _t("."), m_pszPath), FERR_READ, CURRENT_LAST_ERROR, 0); - - // reset internal members - m_uiDataCount=rd; - m_uiCurrentPos=0; - - return rd; -} - -/** Used to write the next packet of data from an internal buffer (buffering - * related) to a file. - * \return Count of bytes written. - */ -uint_t file::_write_packet() -{ - assert(m_hFile); - -#ifdef _WIN32 - DWORD wr=0; - if (!WriteFile(m_hFile, m_pbyBuffer, m_uiDataCount, &wr, NULL)) -#else - int_t wr; - if ((wr=::write(m_hFile, m_pbyBuffer, m_uiDataCount)) == -1) -#endif - { - THROW(exception::format(_t("Cannot write data to a file ") STRFMT _t("."), m_pszPath), FERR_WRITE, CURRENT_LAST_ERROR, 0); - } - - // reset internal members - m_uiDataCount=0; - m_uiCurrentPos=0; - - return wr; -} - -/** Reads some data from the internal serialization buffer. - * \param[out] pData - ptr to a buffer that is about to receive data - * \param[in] uiLen - count of data to be read - */ -void file::_sbuf_read(ptr_t pData, uint_t uiLen) -{ - // check if we are reading - assert(m_uiFlags & FA_READ); - - // check the ranges - if (m_uiSerialBufferPos+uiLen > m_uiSerialBufferSize) - { - // throw an exception - read beyond the data range in a given object - THROW(exception::format(_t("[file] Trying to read the serialization data beyond the range (file ") STRFMT _t(")."), m_pszPath), FERR_MEMORY, CURRENT_LAST_ERROR, 0); - } - - // read the data - memcpy(pData, m_pbySerialBuffer+m_uiSerialBufferPos, uiLen); - m_uiSerialBufferPos+=uiLen; -} - -/** Appends some bytes to the internal serialization buffer (data block). - * \param[in] pData - ptr to a data buffer - * \param[in] uiCount - count of data to store - */ -void file::_sbuf_append(ptr_t pData, uint_t uiCount) -{ - // check if we are writing - assert(m_pbySerialBuffer); - assert(m_uiFlags & FA_WRITE); - - // check serial buffer size (if there is enough room for the data) - if (m_uiSerialBufferPos+uiCount > m_uiSerialBufferSize) - { - // we need a buffer reallocation - uint_t uiDelta=((uiCount/SERIALBUFFER_DELTA)+1)*SERIALBUFFER_DELTA; - - // alloc the new buffer - _sbuf_resize(m_uiSerialBufferSize+uiDelta); - } - - // real storage of the data - if (uiCount > 0) - { - memcpy(m_pbySerialBuffer+m_uiSerialBufferPos, pData, uiCount); - m_uiSerialBufferPos+=uiCount; - } -} - -/** Resizes the internal serialization buffer to the new length. - * Also does copy the old data to the new buffer. - * \param[in] uiNewLen - new buffer length - */ -void file::_sbuf_resize(uint_t uiNewLen) -{ - assert(m_pbySerialBuffer); - - // alloc the new buffer - byte_t* pbyNewBuffer=new byte_t[uiNewLen]; - - // copy the old data into the new one - uint_t uiCount=minval(m_uiSerialBufferPos, uiNewLen); - if (m_uiSerialBufferPos > 0) - memcpy(pbyNewBuffer, m_pbySerialBuffer, uiCount); - - // delete the old buffer - delete [] m_pbySerialBuffer; - - // set the new buffer inplace and update the internal size - m_pbySerialBuffer=pbyNewBuffer; - m_uiSerialBufferSize=uiNewLen; -} - - -/** Reads a line of text from text file - only for buffered operations. - * Properly interpretes the windoze and unix line endings. - * \param[out] pszStr - buffer for the string that is about to be read - * \param[in] uiMaxLen - size of the string buffer - * \return Bool value that states if the string has been read. - */ -bool file::_read_string(tchar_t* pszStr, uint_t uiMaxLen) -{ - assert(m_hFile); // file wasn_t('t opened - error opening or you')ve forgotten to do so ? - assert(m_pbyBuffer != NULL); - - // last time was writing - free buffer - if (m_bLastOperation) - { - flush(); - m_bLastOperation=false; - } - - // zero all the string - memset(pszStr, 0, uiMaxLen*sizeof(tchar_t)); - - // additional vars - uint_t uiStrPos=0; // current pos in external buffer - bool bSecondPass=false; // if there is need to check data for 0x0a tchar_t - - // copy each tchar_t into pszString - for (;;) - { - // if buffer is empty - fill it - if (m_uiDataCount == 0 || m_uiCurrentPos == m_uiDataCount) - { - if (_read_packet() == 0) - return _tcslen(pszStr) != 0; - } - - // skipping 0x0a in second pass - if (bSecondPass) - { - if (m_pbyBuffer[m_uiCurrentPos] == 0x0a) - m_uiCurrentPos++; - return true; - } - - // now process chars - while (m_uiCurrentPos < m_uiDataCount) - { - if (m_pbyBuffer[m_uiCurrentPos] == 0x0d) - { - bSecondPass=true; - m_uiCurrentPos++; - break; - } - else if (m_pbyBuffer[m_uiCurrentPos] == 0x0a) - { - m_uiCurrentPos++; - return true; - } - else - { - if (uiStrPos < uiMaxLen-1) - pszStr[uiStrPos++]=m_pbyBuffer[m_uiCurrentPos]; - m_uiCurrentPos++; - } - } - } -} - -/** Sets file pointer in a file. - * \param[in] llOffset - position to move the file pointer to - * \param[in] uiFrom - the relative position of a base position (FS_*) - * \return The new file pointer position. - */ -longlong_t file::_seek(longlong_t llOffset, uint_t uiFrom) -{ -#ifdef _WIN32 - LARGE_INTEGER li; - li.QuadPart = llOffset; - li.LowPart = SetFilePointer (m_hFile, li.LowPart, &li.HighPart, uiFrom); - - if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) -#else - int_t lRes; - if ((lRes=lseek(m_hFile, llOffset, uiFrom)) == -1) -#endif - THROW(exception::format(_t("Seek error in file ") STRFMT _t("."), m_pszPath), FERR_SEEK, CURRENT_LAST_ERROR, 0); - -#ifdef _WIN32 - return li.QuadPart; -#else - return lRes; -#endif -} - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/file.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/file.h (revision 0) +++ ext/libicpf/src/libicpf/file.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,246 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file file.h + * \brief Contains system independent file/serializer class + * \todo Apply properly handling of the encryption/decryption stuff. + * \todo Modify the class so it could handle full 64bit files. + * \todo Correct the file creation flags under linux (wrong umask value?). + */ + +#ifndef __FILE_H__ +#define __FILE_H__ + +#include "exception.h" +#include "libicpf.h" +//#include "str.h" +#ifdef _WIN32 + #include "windows.h" +#endif + +/// A synonym for the file class +#define serializer file; + +// file access modes +/// Read access to the file +#define FA_READ 0x0001 +/// Write access to the file +#define FA_WRITE 0x0002 +/// Create file if does not exist +#define FA_CREATE 0x0004 +/// Truncate file if not empty +#define FA_TRUNCATE 0x0008 + +// additional mode mods +/// Enable buffered access +#define FA_BUFFERED 0x8000 + +// begin data block flags +/// Standard flag - cannot be combined with others +#define BF_NONE 0x00 + +// seek constants +#ifdef _WIN32 + /// Seeks from the current file pointer position + #define FS_CURRENT FILE_CURRENT + /// Seeks from the beginning of the file + #define FS_SET FILE_BEGIN + /// Seeks from the end of file + #define FS_END FILE_END +#else + /// Seeks from the current file pointer position + #define FS_CURRENT SEEK_CUR + /// Seeks from the beginning of the file + #define FS_SET SEEK_SET + /// Seeks from the end of file + #define FS_END SEEK_END +#endif + +BEGIN_ICPF_NAMESPACE + +/** \brief Structure describes the data inside a data block + * + * Structure contain crc fields to make sure data block is consistent. + * Also the real data size and stored data size are included */ +struct SERIALIZEINFOHEADER +{ + // main header + int_t iDataSize; ///< Size of the meaningful data (including this header) + int_t iRealSize; ///< Size of the data stored in file (may differ from ulDataSize ie. when encrypting) + uint_t uiCRC32; ///< Crc32 of the data (only the data part) + + // helper + uint_t uiHeaderCRC32; ///< Header's crc32 (without this field) +}; + +/** \brief Platform independent file and serialization class + * + * Class allows to access file objects using system dependent functions. Allow + * to use internal buffering for faster reading small amounts of data. + * Also allows to serialize data in blocks (with crc checksums). + */ +class LIBICPF_API file +{ +public: + // construction/destruction +/** \name Construction/destruction +@{*/ + file(); ///< Constructs a file object + ~file(); ///< Destructs a file object +/**@}*/ + +/** \name Standard operations + * Standard file operations that works both in buffered and unbuffered mode. + */ +/**@{*/ + // open/close the file + void open(const tchar_t* pszPath, uint_t uiFlags, uint_t uiBufSize=4096); ///< Opens a file with a given path + void close(); ///< Closes the currently opened file + + // reads or writes the data from/to a file (uses buffering for these operations if enabled) + ulong_t read(ptr_t pBuffer, ulong_t ulSize); ///< Reads some data from a file + ulong_t write(ptr_t pBuffer, ulong_t ulSize); ///< Writes some data to a file + + // handling the lines of text in a file (autodetecting the windows/unix style of line ending) + bool read_line(tchar_t* pszStr, uint_t uiMaxLen); ///< Reads a line of text from a file + void write_line(tchar_t* pszString); ///< Writes a line of text to a file + + // position related functions + void seek(longlong_t llOffset, uint_t uiFrom); ///< Moves a file pointer in a file + longlong_t getpos(); ///< Gets the current position of a file pointer + + // size related functions + void seteof(); ///< Sets the end of file in the current file pointer place + longlong_t get_size(); ///< Retrieves the size of a file + + void flush(); ///< Flushes the internal buffers +/**@}*/ + + +/** \name Buffering state functions + * Operations that allow manipulating the file buffering state. + */ +/**@{*/ + // buffered/unbuffered state management + /// Enables or disables the buffering + void set_buffering(bool bEnable=true, uint_t dwSize=4096); + /// Returns the buffering state + bool is_buffered() const { return m_bBuffered; }; + /// Returns the current buffer size (for buffered operations) + uint_t get_buffersize() const { return m_uiBufferSize; }; + + void switch_unbuffered(); ///< Stores current buffered/unbuffered state and switches to unbuffered + void switch_buffered(); ///< Stores current buffered/unbuffered state and switches to buffered + void restore_state(); ///< Restores (un)buffered last state +/**@}*/ + +/** \name Serialization functions + * Operations that allow manipulating the file buffering state. + */ +/**@{*/ + // serialization (block operation) + void datablock_begin(uint_t dwFlags=BF_NONE); ///< Begins the serialization data block + void datablock_end(); ///< Ends the serialization data block + + // serialization stuff + void swrite(ptr_t pData, uint_t dwSize); ///< Appends some data to the serialialization buffer + void sread(ptr_t pData, uint_t dwSize); ///< Reads some data from serialization buffer + + // state checking + /// Checks if the class is performing write-type serialization + bool is_storing() const { return (m_uiFlags & FA_WRITE) != 0; }; + /// Checks if the class is performing read-type serialization + bool is_loading() const { return (m_uiFlags & FA_READ) != 0; }; + + // storing&reading data + file& operator<<(bool val); ///< Stores a given 'val' parameter in the file + file& operator>>(bool& val); ///< Reads a value of a given type from the file + file& operator<<(tchar_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(tchar_t& val); ///< Reads a value of a given type from the file + file& operator<<(uchar_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(uchar_t& val); ///< Reads a value of a given type from the file + file& operator<<(short_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(short_t& val); ///< Reads a value of a given type from the file + file& operator<<(ushort_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(ushort_t& val); ///< Reads a value of a given type from the file + file& operator<<(int_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(int_t& val); ///< Reads a value of a given type from the file + file& operator<<(uint_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(uint_t& val); ///< Reads a value of a given type from the file + file& operator<<(ll_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(ll_t& val); ///< Reads a value of a given type from the file + file& operator<<(ull_t val); ///< Stores a given 'val' parameter in the file + file& operator>>(ull_t& val); ///< Reads a value of a given type from the file + +/* /// Stores some integral type as a part of serialization data block + template file& operator<<(T tData) { swrite(&tData, sizeof(T)); return *this; }; + /// Reads some integral type from a serialization data block + template file& operator>>(T& tData) { sread(&tData, sizeof(T)); return *this; };*/ + + // specialized serialization stuff +// file& operator<<(icpf::string& str); ///< Stores a CString object in this file (only usable when used in an MFC program) +// file& operator>>(icpf::string& str); ///< Reads a CString object from this file (only usable when used in an mfc program) +/**@}*/ + +protected: + // serialization related internal functions + void _sbuf_append(ptr_t pData, uint_t dwCount); ///< Adds some data to the end of serialization buffer + void _sbuf_resize(uint_t dwNewLen); ///< Resizes the serialization buffer to make some more additional space + void _sbuf_read(ptr_t pData, uint_t dwLen); ///< Gets some data from the serialization buffer + void _clear_serialization(); ///< Cancels the serialization + + // file-buffering related operations + uint_t _read_packet(); ///< Reads next packet of data into the internal buffer + uint_t _write_packet(); ///< Writes next packet of data into a file + + bool _read_string(tchar_t* pszStr, uint_t dwMaxLen); ///< Reads a string from an internal buffer + longlong_t _seek(longlong_t llOffset, uint_t uiFrom); ///< A standard seek command done wo any flushing + +protected: +#ifdef _WIN32 + HANDLE m_hFile; ///< Handle to a real file +#else + intptr_t m_hFile; ///< Handle to a real file +#endif + tchar_t* m_pszPath; ///< Path to the opened file as passed to file::open() + uint_t m_uiFlags; ///< File flags as passed to file::open() + + bool m_bLastOperation; ///< States the last operation performed - false=>READ, true=>WRITE + + // read/write buffering + bool m_bBuffered; ///< States if the file is currently in buffered state + uint_t m_uiBufferSize; ///< Internal buffer size for buffering + byte_t* m_pbyBuffer; ///< Ptr to the internal buffer + uint_t m_uiCurrentPos; ///< Current position in the internal buffer + uint_t m_uiDataCount; ///< Count of data in the internal buffer (counting from beginning) + + // state + bool m_bRememberedState; ///< Specifies if the buffering state was saved + + // serialization stuff + bool m_bSerializing; ///< States if the serialization is in progress + byte_t* m_pbySerialBuffer; ///< Serialization buffer + uint_t m_uiSerialBufferSize; ///< Current size of the serialization buffer + uint_t m_uiSerialBufferPos; ///< Current position in the serialization buffer + uint_t m_uiDataBlockFlags; ///< Flags of the current serialization block +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/file.h =================================================================== diff -u -N --- ext/libicpf/src/file.h (revision 6dae57f5e7aeeb965bc018024d8360069f6e15c1) +++ ext/libicpf/src/file.h (revision 0) @@ -1,246 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file file.h - * \brief Contains system independent file/serializer class - * \todo Apply properly handling of the encryption/decryption stuff. - * \todo Modify the class so it could handle full 64bit files. - * \todo Correct the file creation flags under linux (wrong umask value?). - */ - -#ifndef __FILE_H__ -#define __FILE_H__ - -#include "exception.h" -#include "libicpf.h" -//#include "str.h" -#ifdef _WIN32 - #include "windows.h" -#endif - -/// A synonym for the file class -#define serializer file; - -// file access modes -/// Read access to the file -#define FA_READ 0x0001 -/// Write access to the file -#define FA_WRITE 0x0002 -/// Create file if does not exist -#define FA_CREATE 0x0004 -/// Truncate file if not empty -#define FA_TRUNCATE 0x0008 - -// additional mode mods -/// Enable buffered access -#define FA_BUFFERED 0x8000 - -// begin data block flags -/// Standard flag - cannot be combined with others -#define BF_NONE 0x00 - -// seek constants -#ifdef _WIN32 - /// Seeks from the current file pointer position - #define FS_CURRENT FILE_CURRENT - /// Seeks from the beginning of the file - #define FS_SET FILE_BEGIN - /// Seeks from the end of file - #define FS_END FILE_END -#else - /// Seeks from the current file pointer position - #define FS_CURRENT SEEK_CUR - /// Seeks from the beginning of the file - #define FS_SET SEEK_SET - /// Seeks from the end of file - #define FS_END SEEK_END -#endif - -BEGIN_ICPF_NAMESPACE - -/** \brief Structure describes the data inside a data block - * - * Structure contain crc fields to make sure data block is consistent. - * Also the real data size and stored data size are included */ -struct SERIALIZEINFOHEADER -{ - // main header - int_t iDataSize; ///< Size of the meaningful data (including this header) - int_t iRealSize; ///< Size of the data stored in file (may differ from ulDataSize ie. when encrypting) - uint_t uiCRC32; ///< Crc32 of the data (only the data part) - - // helper - uint_t uiHeaderCRC32; ///< Header's crc32 (without this field) -}; - -/** \brief Platform independent file and serialization class - * - * Class allows to access file objects using system dependent functions. Allow - * to use internal buffering for faster reading small amounts of data. - * Also allows to serialize data in blocks (with crc checksums). - */ -class LIBICPF_API file -{ -public: - // construction/destruction -/** \name Construction/destruction -@{*/ - file(); ///< Constructs a file object - ~file(); ///< Destructs a file object -/**@}*/ - -/** \name Standard operations - * Standard file operations that works both in buffered and unbuffered mode. - */ -/**@{*/ - // open/close the file - void open(const tchar_t* pszPath, uint_t uiFlags, uint_t uiBufSize=4096); ///< Opens a file with a given path - void close(); ///< Closes the currently opened file - - // reads or writes the data from/to a file (uses buffering for these operations if enabled) - ulong_t read(ptr_t pBuffer, ulong_t ulSize); ///< Reads some data from a file - ulong_t write(ptr_t pBuffer, ulong_t ulSize); ///< Writes some data to a file - - // handling the lines of text in a file (autodetecting the windows/unix style of line ending) - bool read_line(tchar_t* pszStr, uint_t uiMaxLen); ///< Reads a line of text from a file - void write_line(tchar_t* pszString); ///< Writes a line of text to a file - - // position related functions - void seek(longlong_t llOffset, uint_t uiFrom); ///< Moves a file pointer in a file - longlong_t getpos(); ///< Gets the current position of a file pointer - - // size related functions - void seteof(); ///< Sets the end of file in the current file pointer place - longlong_t get_size(); ///< Retrieves the size of a file - - void flush(); ///< Flushes the internal buffers -/**@}*/ - - -/** \name Buffering state functions - * Operations that allow manipulating the file buffering state. - */ -/**@{*/ - // buffered/unbuffered state management - /// Enables or disables the buffering - void set_buffering(bool bEnable=true, uint_t dwSize=4096); - /// Returns the buffering state - bool is_buffered() const { return m_bBuffered; }; - /// Returns the current buffer size (for buffered operations) - uint_t get_buffersize() const { return m_uiBufferSize; }; - - void switch_unbuffered(); ///< Stores current buffered/unbuffered state and switches to unbuffered - void switch_buffered(); ///< Stores current buffered/unbuffered state and switches to buffered - void restore_state(); ///< Restores (un)buffered last state -/**@}*/ - -/** \name Serialization functions - * Operations that allow manipulating the file buffering state. - */ -/**@{*/ - // serialization (block operation) - void datablock_begin(uint_t dwFlags=BF_NONE); ///< Begins the serialization data block - void datablock_end(); ///< Ends the serialization data block - - // serialization stuff - void swrite(ptr_t pData, uint_t dwSize); ///< Appends some data to the serialialization buffer - void sread(ptr_t pData, uint_t dwSize); ///< Reads some data from serialization buffer - - // state checking - /// Checks if the class is performing write-type serialization - bool is_storing() const { return (m_uiFlags & FA_WRITE) != 0; }; - /// Checks if the class is performing read-type serialization - bool is_loading() const { return (m_uiFlags & FA_READ) != 0; }; - - // storing&reading data - file& operator<<(bool val); ///< Stores a given 'val' parameter in the file - file& operator>>(bool& val); ///< Reads a value of a given type from the file - file& operator<<(tchar_t val); ///< Stores a given 'val' parameter in the file - file& operator>>(tchar_t& val); ///< Reads a value of a given type from the file - file& operator<<(uchar_t val); ///< Stores a given 'val' parameter in the file - file& operator>>(uchar_t& val); ///< Reads a value of a given type from the file - file& operator<<(short_t val); ///< Stores a given 'val' parameter in the file - file& operator>>(short_t& val); ///< Reads a value of a given type from the file - file& operator<<(ushort_t val); ///< Stores a given 'val' parameter in the file - file& operator>>(ushort_t& val); ///< Reads a value of a given type from the file - file& operator<<(int_t val); ///< Stores a given 'val' parameter in the file - file& operator>>(int_t& val); ///< Reads a value of a given type from the file - file& operator<<(uint_t val); ///< Stores a given 'val' parameter in the file - file& operator>>(uint_t& val); ///< Reads a value of a given type from the file - file& operator<<(ll_t val); ///< Stores a given 'val' parameter in the file - file& operator>>(ll_t& val); ///< Reads a value of a given type from the file - file& operator<<(ull_t val); ///< Stores a given 'val' parameter in the file - file& operator>>(ull_t& val); ///< Reads a value of a given type from the file - -/* /// Stores some integral type as a part of serialization data block - template file& operator<<(T tData) { swrite(&tData, sizeof(T)); return *this; }; - /// Reads some integral type from a serialization data block - template file& operator>>(T& tData) { sread(&tData, sizeof(T)); return *this; };*/ - - // specialized serialization stuff -// file& operator<<(icpf::string& str); ///< Stores a CString object in this file (only usable when used in an MFC program) -// file& operator>>(icpf::string& str); ///< Reads a CString object from this file (only usable when used in an mfc program) -/**@}*/ - -protected: - // serialization related internal functions - void _sbuf_append(ptr_t pData, uint_t dwCount); ///< Adds some data to the end of serialization buffer - void _sbuf_resize(uint_t dwNewLen); ///< Resizes the serialization buffer to make some more additional space - void _sbuf_read(ptr_t pData, uint_t dwLen); ///< Gets some data from the serialization buffer - void _clear_serialization(); ///< Cancels the serialization - - // file-buffering related operations - uint_t _read_packet(); ///< Reads next packet of data into the internal buffer - uint_t _write_packet(); ///< Writes next packet of data into a file - - bool _read_string(tchar_t* pszStr, uint_t dwMaxLen); ///< Reads a string from an internal buffer - longlong_t _seek(longlong_t llOffset, uint_t uiFrom); ///< A standard seek command done wo any flushing - -protected: -#ifdef _WIN32 - HANDLE m_hFile; ///< Handle to a real file -#else - intptr_t m_hFile; ///< Handle to a real file -#endif - tchar_t* m_pszPath; ///< Path to the opened file as passed to file::open() - uint_t m_uiFlags; ///< File flags as passed to file::open() - - bool m_bLastOperation; ///< States the last operation performed - false=>READ, true=>WRITE - - // read/write buffering - bool m_bBuffered; ///< States if the file is currently in buffered state - uint_t m_uiBufferSize; ///< Internal buffer size for buffering - byte_t* m_pbyBuffer; ///< Ptr to the internal buffer - uint_t m_uiCurrentPos; ///< Current position in the internal buffer - uint_t m_uiDataCount; ///< Count of data in the internal buffer (counting from beginning) - - // state - bool m_bRememberedState; ///< Specifies if the buffering state was saved - - // serialization stuff - bool m_bSerializing; ///< States if the serialization is in progress - byte_t* m_pbySerialBuffer; ///< Serialization buffer - uint_t m_uiSerialBufferSize; ///< Current size of the serialization buffer - uint_t m_uiSerialBufferPos; ///< Current position in the serialization buffer - uint_t m_uiDataBlockFlags; ///< Flags of the current serialization block -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/gen_types.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/gen_types.h (revision 0) +++ ext/libicpf/src/libicpf/gen_types.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,329 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file gen_types.h + * \brief Contains some compile-time settings for the whole engine. + */ +#ifndef __GENTYPES_H__ +#define __GENTYPES_H__ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifdef HAVE_INTTYPES_H + #include +#else + #include +#endif + +#if defined (_WIN32) || defined (_WIN64) + #include +#endif + +#include + +// standard types and formats used throughout the library +// exactly 1 byte +/// Byte type (8bit unsigned int) +typedef unsigned char byte_t; + +// chars +/// 8bit signed char +typedef char char_t; +/// 8bit unsigned char +typedef unsigned char uchar_t; + +// system/configuration dependent chars +#if (defined(_WIN32) || defined(_WIN64)) && defined(_UNICODE) + /// System/configuration dependent character (either wide char or normal one) + typedef wchar_t tchar_t; + typedef std::wstring tstring_t; + /// Macro to be appended to each text in code to be either composed of wide characters or normal ones + #define __t(text) L##text + #define _t(text) __t(text) + /// String formatting string - depending on configuration could display wide char string or normal one. + #define TSTRFMT WSTRFMT + #define TCHRFMT CHRFMT +#else + // description as above + typedef char_t tchar_t; + typedef std::string tstring_t; + #define _t(text) text + #define TSTRFMT STRFMT + #define TCHRFMT CHRFMT +#endif + +// 16-bit integers +/// 16bit short integer +typedef short short_t; +/// 16bit unsigned short integer +typedef unsigned short ushort_t; + +// 32-bit integers +#ifdef _WIN32 + #ifdef _WIN64 + /// 32bit integer + typedef long int_t; + /// 32bit integer + typedef long long_t; + /// 32bit unsigned integer + typedef unsigned long uint_t; + /// 32bit unsigned long + typedef unsigned long ulong_t; + #else + /// 32bit integer + typedef int int_t; + /// 32bit integer + typedef long long_t; + /// 32bit unsigned integer + typedef unsigned int uint_t; + /// 32bit unsigned integer + typedef unsigned long ulong_t; + #endif +#else + /// 32bit integer + typedef int int_t; + /// 32bit integer + typedef int long_t; + /// 32bit unsigned integer + typedef unsigned int uint_t; + /// 32bit unsigned integer + typedef unsigned int ulong_t; +#endif + +// 64-bit integers; +/// 64bit; +typedef long long longlong_t; +/// 64bit unsigned long long +typedef unsigned long long ulonglong_t; +/// 64bit long long +typedef longlong_t ll_t; +/// 64bit unsigned long long +typedef ulonglong_t ull_t; + +// double and float +/// Float type +typedef float float_t; +/// Double type +typedef double double_t; + +// platform dependent integers (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) +#ifdef _WIN32 + /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) +// typedef int intptr_t; + /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) + typedef intptr_t longptr_t; + /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) +// typedef unsigned int uintptr_t; + /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) + typedef uintptr_t ulongptr_t; +#else + // linux and other + /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) +// typedef long intptr_t; + /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) + typedef intptr_t longptr_t; + /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) +// typedef unsigned long uintptr_t; + /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) + typedef uintptr_t ulongptr_t; +#endif + +// pointer +/// untyped pointer +typedef void* ptr_t; + +/// std::string or std::wstring dependent on _UNICODE macro +#ifdef _UNICODE + #define tstring std::wstring +#else + #define tstring std::string +#endif + +// formatting-related macros +// chars +/// Printf-style format string for displaying char_t value (as char) +#define CHARFMT _t("%c") +/// Printf-style format string for displaying uchar_t value (as char) +#define UCHARFMT CHARFMT + +// char related numbers (workaround for (u)chars - values are(should be) converted to (u)short_t) +/// Printf-style format string for displaying char_t as a number (the number has to be converted to short_t) +#define CFMT _t("%hd") +/// Printf-style format string for displaying char_t as a hexadecimal number (the number has to be converted to short_t) +#define CXFMT _t("0x%.2hx") +/// Printf-style format string for displaying uchar_t as a number (the number has to be converted to ushort_t) +#define UCFMT _t("%hu") +/// Printf-style format string for displaying uchar_t as a hexadecimal number (the number has to be converted to ushort_t) +#define UCXFMT CXFMT + +// numbers +// 16-bit +/// Printf-style format string for displaying short_t as a number +#define SFMT _t("%hd") +/// Printf-style format string for displaying short_t as a hex number +#define SXFMT _t("0x%.4hx") +/// Printf-style format string for displaying ushort_t as a number +#define USFMT _t("%hu") +/// Printf-style format string for displaying ushort_t as a hex number +#define USXFMT SXFMT + +// 32-bit +#ifdef _WIN32 + /// Printf-style format string for displaying long_t + #define LFMT _t("%ld") + /// Printf-style format string for displaying long_t as a hex number + #define LXFMT _t("0x%.8lx") + /// Printf-style format string for displaying ulong_t + #define ULFMT _t("%lu") +#else + /// Printf-style format string for displaying long_t + #define LFMT _t("%d") + /// Printf-style format string for displaying long_t as a hex number + #define LXFMT _t("0x%.8x") + /// Printf-style format string for displaying ulong_t + #define ULFMT _t("%u") +#endif + +/// Printf-style format string for displaying int_t +#define IFMT LFMT +/// Printf-style format string for displaying int_t as a hex number +#define IXFMT LXFMT +/// Printf-style format string for displaying uint_t +#define UIFMT ULFMT +/// Printf-style format string for displaying ulong_t as a hex number +#define ULXFMT LXFMT +/// Printf-style format string for displaying uint_t as a hex number +#define UIXFMT ULXFMT + +// 64-bit & system dependent +#ifdef _WIN32 + /// Printf-style format string for displaying ulonglong_t as a number + #define ULLFMT _t("%I64u") + /// Printf-style format string for displaying ulonglong_t as a hex number + #define ULLXFMT _t("0x%.16I64x") + /// Printf-style format string for displaying longlong_t + #define LLFMT _t("%I64d") + /// Printf-style format string for displaying longlong_t as a hex number + #define LLXFMT ULLXFMT + + #ifdef _WIN64 + /// Printf-style format string for displaying intptr_t + #define IPTRFMT LLFMT + /// Printf-style format string for displaying longptr_t + #define LPTRFMT LLFMT + /// Printf-style format string for displaying intptr_t as a hex number + #define IPTRXFMT LLXFMT + /// Printf-style format string for displaying longptr_t as a hex number + #define LPTRXFMT LLXFMT + /// Printf-style format string for displaying uintptr_t + #define UIPTRFMT ULLFMT + /// Printf-style format string for displaying ulongptr_t + #define ULPTRFMT ULLFMT + /// Printf-style format string for displaying uintptr_t as a hex number + #define UIPTRXFMT ULLXFMT + /// Printf-style format string for displaying ulongptr_t as a hex number + #define ULPTRXFMT ULLXFMT + #else + /// Printf-style format string for displaying intptr_t + #define IPTRFMT LFMT + /// Printf-style format string for displaying longptr_t + #define LPTRFMT LFMT + /// Printf-style format string for displaying intptr_t as a hex number + #define IPTRXFMT LXFMT + /// Printf-style format string for displaying longptr_t as a hex number + #define LPTRXFMT LXFMT + /// Printf-style format string for displaying uintptr_t + #define UIPTRFMT ULFMT + /// Printf-style format string for displaying ulongptr_t + #define ULPTRFMT ULFMT + /// Printf-style format string for displaying uintptr_t as a hex number + #define UIPTRXFMT ULXFMT + /// Printf-style format string for displaying ulongptr_t as a hex number + #define ULPTRXFMT ULXFMT + #endif +#else + /// Printf-style format string for displaying ulonglong_t as a number + #define ULLFMT _t("%llu") + /// Printf-style format string for displaying ulonglong_t as a hex number + #define ULLXFMT _t("0x%.16llx") + /// Printf-style format string for displaying longlong_t + #define LLFMT _t("%lld") + /// Printf-style format string for displaying longlong_t as a hex number + #define LLXFMT ULLXFMT + + // FIXME: distinguish between linux 32-bit architecture and 64-bit architecture here + /// Printf-style format string for displaying intptr_t + #define IPTRFMT _t("%ld") + /// Printf-style format string for displaying longptr_t + #define LPTRFMT IPTRFMT + /// Printf-style format string for displaying intptr_t as a hex number + #define IPTRXFMT _t("0x%.8lx") + /// Printf-style format string for displaying longptr_t as a hex number + #define LPTRXFMT IPTRXFMT + /// Printf-style format string for displaying uintptr_t + #define UIPTRFMT _t("%lu") + /// Printf-style format string for displaying ulongptr_t + #define ULPTRFMT UIPTRFMT + /// Printf-style format string for displaying uintptr_t as a hex number + #define UIPTRXFMT _t("0x%.8lx") + /// Printf-style format string for displaying ulongptr_t as a hex number + #define ULPTRXFMT UIPTRXFMT +#endif + +// double (not checked for linux) +/// Printf-style format string for displaying float_t +#define FLOATFMT _t("%.2f") +/// Printf-style format string for displaying double_t +#define DOUBLEFMT _t("%.2f") + +// strings + +// NOTE: below are the specifications for strings, however win32/64 specified the +// formatting strings to be dependent on the function used - %s used in printf +// formats an ascii string, while the same %s used in wprintf gives a wide string. +// So, basically, those macros should be modified in some way - either by making +// a dependence on _UNICODE define or by creating additional set of macros to be used +// with wprintf() and use the current ones for printf(). + +/// Printf-style format string for displaying ansi strings (char_t based strings) +#define STRFMT _t("%s") +/// Printf-style format string for displaying ascii char +#define CHRFMT _t("%c") + +#if defined(_WIN32) || defined(_WIN64) + /// Printf-style format string for displaying wide strings (wchar_t based strings) + #define WSTRFMT _t("%S") + /// Printf-style format string for displaying wide char + #define WCHRFMT _t("%C") +#else + /// Printf-style format string for displaying wide strings (wchar_t based strings) + #define WSTRFMT _t("%ls") + /// Printf-style format string for displaying wide char (WARNING: untested) + #define WCHRFMT _t("%lc") +#endif + +// pointer +/// Printf-style format string for displaying pointers +#define PTRFMT _t("%p") +/// Printf-style format string for displaying pointers (with 0x prefix) +#define PTRXFMT _t("0x%p") + +#endif Index: ext/libicpf/src/gen_types.h =================================================================== diff -u -N --- ext/libicpf/src/gen_types.h (revision d5bb2e19e22f57bd018e9db355108b54dfbc364c) +++ ext/libicpf/src/gen_types.h (revision 0) @@ -1,329 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2007 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file gen_types.h - * \brief Contains some compile-time settings for the whole engine. - */ -#ifndef __GENTYPES_H__ -#define __GENTYPES_H__ - -#if defined(HAVE_CONFIG_H) - #include "config.h" -#endif - -#ifdef HAVE_INTTYPES_H - #include -#else - #include -#endif - -#if defined (_WIN32) || defined (_WIN64) - #include -#endif - -#include - -// standard types and formats used throughout the library -// exactly 1 byte -/// Byte type (8bit unsigned int) -typedef unsigned char byte_t; - -// chars -/// 8bit signed char -typedef char char_t; -/// 8bit unsigned char -typedef unsigned char uchar_t; - -// system/configuration dependent chars -#if (defined(_WIN32) || defined(_WIN64)) && defined(_UNICODE) - /// System/configuration dependent character (either wide char or normal one) - typedef wchar_t tchar_t; - typedef std::wstring tstring_t; - /// Macro to be appended to each text in code to be either composed of wide characters or normal ones - #define __t(text) L##text - #define _t(text) __t(text) - /// String formatting string - depending on configuration could display wide char string or normal one. - #define TSTRFMT WSTRFMT - #define TCHRFMT CHRFMT -#else - // description as above - typedef char_t tchar_t; - typedef std::string tstring_t; - #define _t(text) text - #define TSTRFMT STRFMT - #define TCHRFMT CHRFMT -#endif - -// 16-bit integers -/// 16bit short integer -typedef short short_t; -/// 16bit unsigned short integer -typedef unsigned short ushort_t; - -// 32-bit integers -#ifdef _WIN32 - #ifdef _WIN64 - /// 32bit integer - typedef long int_t; - /// 32bit integer - typedef long long_t; - /// 32bit unsigned integer - typedef unsigned long uint_t; - /// 32bit unsigned long - typedef unsigned long ulong_t; - #else - /// 32bit integer - typedef int int_t; - /// 32bit integer - typedef long long_t; - /// 32bit unsigned integer - typedef unsigned int uint_t; - /// 32bit unsigned integer - typedef unsigned long ulong_t; - #endif -#else - /// 32bit integer - typedef int int_t; - /// 32bit integer - typedef int long_t; - /// 32bit unsigned integer - typedef unsigned int uint_t; - /// 32bit unsigned integer - typedef unsigned int ulong_t; -#endif - -// 64-bit integers; -/// 64bit; -typedef long long longlong_t; -/// 64bit unsigned long long -typedef unsigned long long ulonglong_t; -/// 64bit long long -typedef longlong_t ll_t; -/// 64bit unsigned long long -typedef ulonglong_t ull_t; - -// double and float -/// Float type -typedef float float_t; -/// Double type -typedef double double_t; - -// platform dependent integers (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) -#ifdef _WIN32 - /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) -// typedef int intptr_t; - /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) - typedef intptr_t longptr_t; - /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) -// typedef unsigned int uintptr_t; - /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) - typedef uintptr_t ulongptr_t; -#else - // linux and other - /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) -// typedef long intptr_t; - /// platform-dependent size signed integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) - typedef intptr_t longptr_t; - /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) -// typedef unsigned long uintptr_t; - /// platform-dependent size unsigned integer (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) - typedef uintptr_t ulongptr_t; -#endif - -// pointer -/// untyped pointer -typedef void* ptr_t; - -/// std::string or std::wstring dependent on _UNICODE macro -#ifdef _UNICODE - #define tstring std::wstring -#else - #define tstring std::string -#endif - -// formatting-related macros -// chars -/// Printf-style format string for displaying char_t value (as char) -#define CHARFMT _t("%c") -/// Printf-style format string for displaying uchar_t value (as char) -#define UCHARFMT CHARFMT - -// char related numbers (workaround for (u)chars - values are(should be) converted to (u)short_t) -/// Printf-style format string for displaying char_t as a number (the number has to be converted to short_t) -#define CFMT _t("%hd") -/// Printf-style format string for displaying char_t as a hexadecimal number (the number has to be converted to short_t) -#define CXFMT _t("0x%.2hx") -/// Printf-style format string for displaying uchar_t as a number (the number has to be converted to ushort_t) -#define UCFMT _t("%hu") -/// Printf-style format string for displaying uchar_t as a hexadecimal number (the number has to be converted to ushort_t) -#define UCXFMT CXFMT - -// numbers -// 16-bit -/// Printf-style format string for displaying short_t as a number -#define SFMT _t("%hd") -/// Printf-style format string for displaying short_t as a hex number -#define SXFMT _t("0x%.4hx") -/// Printf-style format string for displaying ushort_t as a number -#define USFMT _t("%hu") -/// Printf-style format string for displaying ushort_t as a hex number -#define USXFMT SXFMT - -// 32-bit -#ifdef _WIN32 - /// Printf-style format string for displaying long_t - #define LFMT _t("%ld") - /// Printf-style format string for displaying long_t as a hex number - #define LXFMT _t("0x%.8lx") - /// Printf-style format string for displaying ulong_t - #define ULFMT _t("%lu") -#else - /// Printf-style format string for displaying long_t - #define LFMT _t("%d") - /// Printf-style format string for displaying long_t as a hex number - #define LXFMT _t("0x%.8x") - /// Printf-style format string for displaying ulong_t - #define ULFMT _t("%u") -#endif - -/// Printf-style format string for displaying int_t -#define IFMT LFMT -/// Printf-style format string for displaying int_t as a hex number -#define IXFMT LXFMT -/// Printf-style format string for displaying uint_t -#define UIFMT ULFMT -/// Printf-style format string for displaying ulong_t as a hex number -#define ULXFMT LXFMT -/// Printf-style format string for displaying uint_t as a hex number -#define UIXFMT ULXFMT - -// 64-bit & system dependent -#ifdef _WIN32 - /// Printf-style format string for displaying ulonglong_t as a number - #define ULLFMT _t("%I64u") - /// Printf-style format string for displaying ulonglong_t as a hex number - #define ULLXFMT _t("0x%.16I64x") - /// Printf-style format string for displaying longlong_t - #define LLFMT _t("%I64d") - /// Printf-style format string for displaying longlong_t as a hex number - #define LLXFMT ULLXFMT - - #ifdef _WIN64 - /// Printf-style format string for displaying intptr_t - #define IPTRFMT LLFMT - /// Printf-style format string for displaying longptr_t - #define LPTRFMT LLFMT - /// Printf-style format string for displaying intptr_t as a hex number - #define IPTRXFMT LLXFMT - /// Printf-style format string for displaying longptr_t as a hex number - #define LPTRXFMT LLXFMT - /// Printf-style format string for displaying uintptr_t - #define UIPTRFMT ULLFMT - /// Printf-style format string for displaying ulongptr_t - #define ULPTRFMT ULLFMT - /// Printf-style format string for displaying uintptr_t as a hex number - #define UIPTRXFMT ULLXFMT - /// Printf-style format string for displaying ulongptr_t as a hex number - #define ULPTRXFMT ULLXFMT - #else - /// Printf-style format string for displaying intptr_t - #define IPTRFMT LFMT - /// Printf-style format string for displaying longptr_t - #define LPTRFMT LFMT - /// Printf-style format string for displaying intptr_t as a hex number - #define IPTRXFMT LXFMT - /// Printf-style format string for displaying longptr_t as a hex number - #define LPTRXFMT LXFMT - /// Printf-style format string for displaying uintptr_t - #define UIPTRFMT ULFMT - /// Printf-style format string for displaying ulongptr_t - #define ULPTRFMT ULFMT - /// Printf-style format string for displaying uintptr_t as a hex number - #define UIPTRXFMT ULXFMT - /// Printf-style format string for displaying ulongptr_t as a hex number - #define ULPTRXFMT ULXFMT - #endif -#else - /// Printf-style format string for displaying ulonglong_t as a number - #define ULLFMT _t("%llu") - /// Printf-style format string for displaying ulonglong_t as a hex number - #define ULLXFMT _t("0x%.16llx") - /// Printf-style format string for displaying longlong_t - #define LLFMT _t("%lld") - /// Printf-style format string for displaying longlong_t as a hex number - #define LLXFMT ULLXFMT - - // FIXME: distinguish between linux 32-bit architecture and 64-bit architecture here - /// Printf-style format string for displaying intptr_t - #define IPTRFMT _t("%ld") - /// Printf-style format string for displaying longptr_t - #define LPTRFMT IPTRFMT - /// Printf-style format string for displaying intptr_t as a hex number - #define IPTRXFMT _t("0x%.8lx") - /// Printf-style format string for displaying longptr_t as a hex number - #define LPTRXFMT IPTRXFMT - /// Printf-style format string for displaying uintptr_t - #define UIPTRFMT _t("%lu") - /// Printf-style format string for displaying ulongptr_t - #define ULPTRFMT UIPTRFMT - /// Printf-style format string for displaying uintptr_t as a hex number - #define UIPTRXFMT _t("0x%.8lx") - /// Printf-style format string for displaying ulongptr_t as a hex number - #define ULPTRXFMT UIPTRXFMT -#endif - -// double (not checked for linux) -/// Printf-style format string for displaying float_t -#define FLOATFMT _t("%.2f") -/// Printf-style format string for displaying double_t -#define DOUBLEFMT _t("%.2f") - -// strings - -// NOTE: below are the specifications for strings, however win32/64 specified the -// formatting strings to be dependent on the function used - %s used in printf -// formats an ascii string, while the same %s used in wprintf gives a wide string. -// So, basically, those macros should be modified in some way - either by making -// a dependence on _UNICODE define or by creating additional set of macros to be used -// with wprintf() and use the current ones for printf(). - -/// Printf-style format string for displaying ansi strings (char_t based strings) -#define STRFMT _t("%s") -/// Printf-style format string for displaying ascii char -#define CHRFMT _t("%c") - -#if defined(_WIN32) || defined(_WIN64) - /// Printf-style format string for displaying wide strings (wchar_t based strings) - #define WSTRFMT _t("%S") - /// Printf-style format string for displaying wide char - #define WCHRFMT _t("%C") -#else - /// Printf-style format string for displaying wide strings (wchar_t based strings) - #define WSTRFMT _t("%ls") - /// Printf-style format string for displaying wide char (WARNING: untested) - #define WCHRFMT _t("%lc") -#endif - -// pointer -/// Printf-style format string for displaying pointers -#define PTRFMT _t("%p") -/// Printf-style format string for displaying pointers (with 0x prefix) -#define PTRXFMT _t("0x%p") - -#endif Index: ext/libicpf/src/libicpf/libicpf.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/libicpf.cpp (revision 0) +++ ext/libicpf/src/libicpf/libicpf.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +// libicpf.cpp : Defines the entry point for the DLL application. +// + +#ifdef _WIN32 +#include + +BOOL APIENTRY DllMain( HANDLE /*hModule*/, + DWORD ul_reason_for_call, + LPVOID /*lpReserved*/ + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + default: + break; + } + return TRUE; +} + +#endif Index: ext/libicpf/src/libicpf.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf.cpp (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/libicpf.cpp (revision 0) @@ -1,44 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -// libicpf.cpp : Defines the entry point for the DLL application. -// - -#ifdef _WIN32 -#include - -BOOL APIENTRY DllMain( HANDLE /*hModule*/, - DWORD ul_reason_for_call, - LPVOID /*lpReserved*/ - ) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - default: - break; - } - return TRUE; -} - -#endif Index: ext/libicpf/src/libicpf/libicpf.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/libicpf.h (revision 0) +++ ext/libicpf/src/libicpf/libicpf.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __LIBICPF_H__ +#define __LIBICPF_H__ + +/** \brief Allows unicode handling throughout the files + * + * It means that the engine would process fs object's paths + * in the better standard - if possible then with current ANSI code page (one-byte + * chars) or with UNICODE strings (with 2-byte per char strings). + * \note if this is disabled (#undef) then the data saved by ie. unicode windows + * system may not be readable (because we won't use the iconv package on linux + * systems nor use any of the unicode functions in windows systems). + * Recommended setting is 'defined'. + */ +#define ALLOW_UNICODE + +/** \brief Enables the mutex debugging code throughout this library. + * + * Enables compiling the d_mutex class, so external or internal code could use mutex + * debugging. + */ +//#define ENABLE_MUTEX_DEBUGGING + +/** \brief Enables mutex debugging/tracking in the internal and external code. + */ +//#define DEBUG_MUTEX + +/** \brief Enables use of encryption throughout this library. + * + * Enabling this macro enables usage of the encryption in some modules. + */ +#define USE_ENCRYPTION + +// import/export macros +#ifdef _WIN32 + #ifdef LIBICPF_EXPORTS + /** \brief Import/export macros + * + * These macros are being used throughout the whole code. They are meant to + * export symbols (if the LIBICPF_EXPORTS is defined) from this library + * (also for importing (when LIBICPF_EXPORTS macro is undefined) in other apps). + */ + #define LIBICPF_API __declspec(dllexport) + #define ICPFTEMPL_EXTERN + #else + /** \brief Import/export macros + * + * These macros are being used throughout the whole code. They are meant to + * export symbols (if the LIBICPF_EXPORTS is defined) from this library + * (also for importing (when LIBICPF_EXPORTS macro is undefined) in other apps). + */ + #define LIBICPF_API __declspec(dllimport) + #define ICPFTEMPL_EXTERN extern + #endif +#else + /** \brief Import/export macros + * + * These macros are being used throughout the whole code. They are meant to + * export symbols (if the LIBICPF_EXPORTS is defined) from this library + * (also for importing (when LIBICPF_EXPORTS macro is undefined) in other apps). + */ + #define LIBICPF_API +#endif + +/// Begins ch namespace +#define BEGIN_ICPF_NAMESPACE namespace icpf { +/// Ends ch namespace +#define END_ICPF_NAMESPACE } + +#endif Index: ext/libicpf/src/libicpf.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf.h (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/libicpf.h (revision 0) @@ -1,88 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef __LIBICPF_H__ -#define __LIBICPF_H__ - -/** \brief Allows unicode handling throughout the files - * - * It means that the engine would process fs object's paths - * in the better standard - if possible then with current ANSI code page (one-byte - * chars) or with UNICODE strings (with 2-byte per char strings). - * \note if this is disabled (#undef) then the data saved by ie. unicode windows - * system may not be readable (because we won't use the iconv package on linux - * systems nor use any of the unicode functions in windows systems). - * Recommended setting is 'defined'. - */ -#define ALLOW_UNICODE - -/** \brief Enables the mutex debugging code throughout this library. - * - * Enables compiling the d_mutex class, so external or internal code could use mutex - * debugging. - */ -//#define ENABLE_MUTEX_DEBUGGING - -/** \brief Enables mutex debugging/tracking in the internal and external code. - */ -//#define DEBUG_MUTEX - -/** \brief Enables use of encryption throughout this library. - * - * Enabling this macro enables usage of the encryption in some modules. - */ -#define USE_ENCRYPTION - -// import/export macros -#ifdef _WIN32 - #ifdef LIBICPF_EXPORTS - /** \brief Import/export macros - * - * These macros are being used throughout the whole code. They are meant to - * export symbols (if the LIBICPF_EXPORTS is defined) from this library - * (also for importing (when LIBICPF_EXPORTS macro is undefined) in other apps). - */ - #define LIBICPF_API __declspec(dllexport) - #define ICPFTEMPL_EXTERN - #else - /** \brief Import/export macros - * - * These macros are being used throughout the whole code. They are meant to - * export symbols (if the LIBICPF_EXPORTS is defined) from this library - * (also for importing (when LIBICPF_EXPORTS macro is undefined) in other apps). - */ - #define LIBICPF_API __declspec(dllimport) - #define ICPFTEMPL_EXTERN extern - #endif -#else - /** \brief Import/export macros - * - * These macros are being used throughout the whole code. They are meant to - * export symbols (if the LIBICPF_EXPORTS is defined) from this library - * (also for importing (when LIBICPF_EXPORTS macro is undefined) in other apps). - */ - #define LIBICPF_API -#endif - -/// Begins ch namespace -#define BEGIN_ICPF_NAMESPACE namespace icpf { -/// Ends ch namespace -#define END_ICPF_NAMESPACE } - -#endif Index: ext/libicpf/src/libicpf/libicpf.vc71.vcproj =================================================================== diff -u -N --- ext/libicpf/src/libicpf/libicpf.vc71.vcproj (revision 0) +++ ext/libicpf/src/libicpf/libicpf.vc71.vcproj (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: ext/libicpf/libicpf.vc71.vcproj =================================================================== diff -u -N --- ext/libicpf/libicpf.vc71.vcproj (revision 6dae57f5e7aeeb965bc018024d8360069f6e15c1) +++ ext/libicpf/libicpf.vc71.vcproj (revision 0) @@ -1,348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Index: ext/libicpf/src/libicpf/libicpf.vc80.vcproj =================================================================== diff -u -N --- ext/libicpf/src/libicpf/libicpf.vc80.vcproj (revision 0) +++ ext/libicpf/src/libicpf/libicpf.vc80.vcproj (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,798 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: ext/libicpf/libicpf.vc80.vcproj =================================================================== diff -u -N --- ext/libicpf/libicpf.vc80.vcproj (revision d5bb2e19e22f57bd018e9db355108b54dfbc364c) +++ ext/libicpf/libicpf.vc80.vcproj (revision 0) @@ -1,798 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Index: ext/libicpf/src/libicpf/log.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/log.cpp (revision 0) +++ ext/libicpf/src/libicpf/log.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,578 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file log.cpp + * \brief Contains the implamentation of a log class. + */ +#include "log.h" +#include "exception.h" +#include +#include +#include +#include +#include "macros.h" + +#if defined(_WIN32) || defined(_WIN64) + #include + #include + #include +#else + #include +#endif + +BEGIN_ICPF_NAMESPACE + +/// Table of strings representing the log message types +const tchar_t* __logtype_str[] = { _t("debug"), _t("info"), _t("warning"), _t("error") }; + +/** Constructs a log_file object. + * \param[in] bGlobal - states if this should be treates as a global instance of the log_file. + * Only one global log_file instance could exist in the application. + */ +log_file::log_file() : + m_pszPath(NULL), + m_iMaxSize(262144), + m_bLogStd(false), + m_iLogLevel(level_debug), + m_lock() +{ +#ifdef WIN32 + _fmode=_O_BINARY; +#endif +} + +/** Standard destructor + */ +log_file::~log_file() +{ + delete [] m_pszPath; +} + +/** Initializes the constructed log file. + * \param[in] pszPath - path to a log file to write to + * \param[in] iMaxSize - maximum size of a log file + * \param[in] iLogLevel - minimum log level of the messages to log + * \param[in] bLogStd - log the messages also to stdout/stderr + * \param[in] bClean - cleans the log file upon opening + */ +void log_file::init(const tchar_t* pszPath, int_t iMaxSize, int_t iLogLevel, bool bLogStd, bool bClean) +{ + // store the path and other params + delete [] m_pszPath; + m_pszPath=new tchar_t[_tcslen(pszPath)+1]; + _tcscpy(m_pszPath, pszPath); + + m_iMaxSize=iMaxSize; + m_bLogStd=bLogStd; + m_iLogLevel=iLogLevel; + + // try to open a file + FILE* pFile=_tfopen(pszPath, bClean ? _t("w") : _t("a")); + if (pFile == NULL) + THROW(exception::format(_t("[log_file::init()] Could not open the specified file (") TSTRFMT _t(")")), 0, 0, 0); + + fclose(pFile); +} + +/** Retrieves the current size of a log file. + * Quite slow function - have to access the file by opening and closing it. + * \return Current file size. + */ +int_t log_file::size() const +{ + assert(m_pszPath); + + int_t iSize=-1; + FILE* pFile=_tfopen(m_pszPath, _t("r")); + if (pFile != NULL) + { + if (fseek(pFile, 0, SEEK_END) == 0) + iSize=ftell(pFile); + + fclose(pFile); + } + + return iSize; +} + +// @lAdd - count of bytes that would be appended to the file +/** Truncates the current log file content so when adding some new text the + * file size won't exceed the maximum size specified in init(). + * \param[in] iAdd - size of the new string to be added to the log file + * \return True if truncate succeeded or false if not. + */ +bool log_file::truncate(int_t iAdd) const +{ + assert(m_pszPath); + + // if we doesn't need to truncate anything + if (m_iMaxSize <= 0) + return true; + + // make some checks + int_t iSize=size(); + if (iSize <= 0 || iSize+iAdd < m_iMaxSize) + return false; + + // establish the new file size (1/3rd of the current size or max_size-add_size) + int_t iNewSize=minval((int_t)(iSize*0.66), m_iMaxSize-iAdd) & ~1; + +#ifdef _WIN32 + // win32 does not have the ftruncate function, so we have to make some API calls + HANDLE hFile=CreateFile(m_pszPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + // seek + if (SetFilePointer(hFile, iSize-iNewSize, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER) + { + // read the string to the eol + DWORD dwRD; + tchar_t szBuffer[4096/sizeof(tchar_t)]; + if (ReadFile(hFile, szBuffer, 4096, &dwRD, NULL)) + { + dwRD/=sizeof(tchar_t); + szBuffer[(dwRD > 0) ? dwRD-1 : 0]=_t('\0'); + + // replace the /r and /n in the log to the \0 + for (DWORD i=0;i 0) + { + // seek to the dst + fseek(pFile, iDst, SEEK_SET); + + fflush(pFile); + // write the buffer to the dest offset + tWR=fwrite(szBuffer, 1, tRD, pFile); + iDst+=tWR; + } + + iSrc+=tRD; + } + while(tRD != 0); + + // now truncate the file to the needed size + ftruncate(fileno(pFile), iDst); + + fclose(pFile); + return true; + } + + fclose(pFile); + } +#endif + + return false; +} + +/** Logs a formatted message to a log file. + * \param[in] iType - type of the log message (LT_*) + * \param[in] bStd - log also to stdout/stderr if true + * \param[in] pszStr - format string for the following parameters + */ +void log_file::log(int_t iType, bool bStd, const tchar_t* pszStr, ...) +{ + if (iType < m_iLogLevel) + return; + + va_list va; + va_start(va, pszStr); + logv(iType, bStd, pszStr, va); + va_end(va); +} + +/** Logs a formatted message to a log file. + * \param[in] iType - type of the log message (LT_*) + * \param[in] bStd - log also to stdout/stderr if true + * \param[in] pszStr - format string for the following parameters + * \param[in] va - variable argument list + */ +void log_file::logv(int_t iType, bool bStd, const tchar_t* pszStr, va_list va) +{ + if (iType < m_iLogLevel) + return; + + tchar_t szBuf1[2048]; + _vsntprintf(szBuf1, 2048, pszStr, va); // user passed stuff + + logs(iType, bStd, szBuf1); +} + +/** Logs an unformatted message to a log file. + * \param[in] iType - type of the log message (LT_*) + * \param[in] bStd - log also to stdout/stderr if true + * \param[in] pszStr - message string + */ +void log_file::logs(int_t iType, bool bStd, const tchar_t* pszStr) +{ + assert(m_pszPath); + + if (iType < m_iLogLevel) + return; + + // log time + time_t t=time(NULL); + tchar_t szData[128]; + _tcscpy(szData, _tctime(&t)); + size_t tLen=_tcslen(szData)-1; + while(szData[tLen] == _t('\n')) + szData[tLen--]=_t('\0'); + + m_lock.lock(); + + // check the size constraints + truncate((int_t)(_tcslen(pszStr)+1)); + FILE* pFile=_tfopen(m_pszPath, _t("a")); + bool bFailed=false; + if (pFile) + { + if (_ftprintf(pFile, _t("[") STRFMT _t("] [") STRFMT _t("] ") STRFMT _t("\n"), szData, __logtype_str[iType], pszStr) < 0) + bFailed=true; + fclose(pFile); + } + else + bFailed=true; + if (bFailed || (m_bLogStd && !bStd)) + { + switch(iType) + { + case level_error: + _ftprintf(stderr, _t("[") STRFMT _t("] [") STRFMT _t("] ") STRFMT _t("\n"), szData, __logtype_str[iType], pszStr); + break; + default: + _ftprintf(stdout, _t("[") STRFMT _t("] [") STRFMT _t("] ") STRFMT _t("\n"), szData, __logtype_str[iType], pszStr); + } + } + else if (bStd) + { + switch(iType) + { + case level_error: + _ftprintf(stderr, STRFMT _t(": ") STRFMT _t("\n"), __logtype_str[iType], pszStr); + break; + case level_info: + _ftprintf(stdout, STRFMT _t("\n"), pszStr); + break; + default: + _ftprintf(stdout, STRFMT _t(": ") STRFMT _t("\n"), __logtype_str[iType], pszStr); + } + } + + m_lock.unlock(); +} + +#ifndef SKIP_LEVEL_DEBUG +/** Logs a formatted debug message to a log file. + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logd(const tchar_t* pszStr, ...) +{ + if (m_iLogLevel > level_debug) + return; + + va_list va; + va_start(va, pszStr); + logv(level_debug, false, pszStr, va); + va_end(va); +} + +/** Logs a formatted debug message to a log file(also outputs to stdout). + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logds(const tchar_t* pszStr, ...) +{ + if (m_iLogLevel > level_debug) + return; + + va_list va; + va_start(va, pszStr); + logv(level_debug, true, pszStr, va); + va_end(va); +} + +#else +void log_file::logd(const tchar_t* /*pszStr*/, ...) +{ +} + +void log_file::logds(const tchar_t* /*pszStr*/, ...) +{ +} +#endif + +#ifdef SKIP_LEVEL_INFO +/** Logs a formatted informational message to a log file. + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logi(const tchar_t* pszStr, ...) +{ + if (m_iLogLevel > level_info) + return; + + va_list va; + va_start(va, pszStr); + logv(level_info, false, pszStr, va); + va_end(va); +} + +/** Logs a formatted informational message to a log file(also outputs to stdout). + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logis(const tchar_t* pszStr, ...) +{ + if (m_iLogLevel > level_info) + return; + + va_list va; + va_start(va, pszStr); + logv(level_info, true, pszStr, va); + va_end(va); +} +#else +void log_file::logi(const tchar_t* /*pszStr*/, ...) +{ +} + +void log_file::logis(const tchar_t* /*pszStr*/, ...) +{ +} + +#endif + +#ifndef SKIP_LEVEL_WARNING +/** Logs a formatted warning message to a log file. + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logw(const tchar_t* pszStr, ...) +{ + if (m_iLogLevel > level_warning) + return; + + va_list va; + va_start(va, pszStr); + logv(level_warning, false, pszStr, va); + va_end(va); +} + +/** Logs a formatted warning message to a log file(also outputs to stdout). + * \param[in] pszStr - format string for the given parameters + */ +void log_file::logws(const tchar_t* pszStr, ...) +{ + if (m_iLogLevel > level_warning) + return; + va_list va; + va_start(va, pszStr); + logv(level_warning, true, pszStr, va); + va_end(va); +} + +#else +void log_file::logw(const tchar_t* /*pszStr*/, ...) +{ +} + +void log_file::logws(const tchar_t* /*pszStr*/, ...) +{ +} + +#endif + +/** Logs a formatted error message to a log file. + * \param[in] pszStr - format string for the given parameters + */ +void log_file::loge(const tchar_t* pszStr, ...) +{ + va_list va; + va_start(va, pszStr); + logv(level_error, false, pszStr, va); + va_end(va); +} + +/** Logs a formatted error message to a log file(also outputs to stderr). + * \param[in] pszStr - format string for the given parameters + */ +void log_file::loges(const tchar_t* pszStr, ...) +{ + va_list va; + va_start(va, pszStr); + logv(level_error, true, pszStr, va); + va_end(va); +} + +/** Logs a formatted error message to a log file(also outputs to stderr). + * As an addition the first string %err is replaced with a given error + * followed by the error description (system-based). + * \param[in] pszStr - format string for the given parameters + * \param[in] iSysErr - system error to be shown + */ +void log_file::logerr(const tchar_t* pszStr, int_t iSysErr, ...) +{ + tchar_t szNewFmt[2048]; + if (prepare_fmt(pszStr, iSysErr, szNewFmt)) + { + va_list va; + va_start(va, iSysErr); + logv(level_error, false, szNewFmt, va); + va_end(va); + } + else + { + va_list va; + va_start(va, iSysErr); + logv(level_error, false, pszStr, va); + va_end(va); + } +} + +/** Logs a formatted error message to a log file(also outputs to stderr). + * As an addition the first string %err is replaced with a given error + * followed by the error description (system-based). + * This function differ from logerr() with logging the output string + * also to the stderr. + * \param[in] pszStr - format string for the given parameters + * \param[in] iSysErr - system error to be shown + */ +void log_file::logerrs(const tchar_t* pszStr, int_t iSysErr, ...) +{ + tchar_t szNewFmt[2048]; + if (prepare_fmt(pszStr, iSysErr, szNewFmt)) + { + va_list va; + va_start(va, iSysErr); + logv(level_error, true, szNewFmt, va); + va_end(va); + } + else + { + va_list va; + va_start(va, iSysErr); + logv(level_error, true, pszStr, va); + va_end(va); + } +} + +/** Function prepares a format string with error number and an error message + * for use with logerr() and logerrs() functions. + * \param[in] pszStr - input format string (%err will be replaced with a 0x%lx (error message) + * \param[in] iSysError - system error to parse + * \param[out] pszOut - pointer to a buffer that will receive the data (must be 2048 bytes in size) + * \return If the %err string was found and replaced within a given format string. + */ +bool log_file::prepare_fmt(const tchar_t* pszStr, int_t iSysErr, tchar_t* pszOut) const +{ + // find the %err in pszStr + const tchar_t* pszFnd=_tcsstr(pszStr, _t("%err")); + if (pszFnd) + { + // find an error description for the error + tchar_t* pszErrDesc=NULL; +#ifdef _WIN32 + tchar_t szErrDesc[512]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, (DWORD)iSysErr, 0, szErrDesc, 512, NULL); + pszErrDesc=szErrDesc; +#else + pszErrDesc=strerror(iSysErr); +#endif + + // format a string with err no and desc + tchar_t szError[1024]; + _sntprintf(szError, 1024, _t("0x%lx (%s)"), iSysErr, pszErrDesc); + + // replace %err with the new data + pszOut[0]=_t('\0'); + _tcsncat(pszOut, pszStr, (size_t)(pszFnd-pszStr)); + _tcscat(pszOut, szError); + _tcscat(pszOut, pszFnd+4); + + return true; + } + else + return false; +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/log.cpp =================================================================== diff -u -N --- ext/libicpf/src/log.cpp (revision d5bb2e19e22f57bd018e9db355108b54dfbc364c) +++ ext/libicpf/src/log.cpp (revision 0) @@ -1,578 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file log.cpp - * \brief Contains the implamentation of a log class. - */ -#include "log.h" -#include "exception.h" -#include -#include -#include -#include -#include "macros.h" - -#if defined(_WIN32) || defined(_WIN64) - #include - #include - #include -#else - #include -#endif - -BEGIN_ICPF_NAMESPACE - -/// Table of strings representing the log message types -const tchar_t* __logtype_str[] = { _t("debug"), _t("info"), _t("warning"), _t("error") }; - -/** Constructs a log_file object. - * \param[in] bGlobal - states if this should be treates as a global instance of the log_file. - * Only one global log_file instance could exist in the application. - */ -log_file::log_file() : - m_pszPath(NULL), - m_iMaxSize(262144), - m_bLogStd(false), - m_iLogLevel(level_debug), - m_lock() -{ -#ifdef WIN32 - _fmode=_O_BINARY; -#endif -} - -/** Standard destructor - */ -log_file::~log_file() -{ - delete [] m_pszPath; -} - -/** Initializes the constructed log file. - * \param[in] pszPath - path to a log file to write to - * \param[in] iMaxSize - maximum size of a log file - * \param[in] iLogLevel - minimum log level of the messages to log - * \param[in] bLogStd - log the messages also to stdout/stderr - * \param[in] bClean - cleans the log file upon opening - */ -void log_file::init(const tchar_t* pszPath, int_t iMaxSize, int_t iLogLevel, bool bLogStd, bool bClean) -{ - // store the path and other params - delete [] m_pszPath; - m_pszPath=new tchar_t[_tcslen(pszPath)+1]; - _tcscpy(m_pszPath, pszPath); - - m_iMaxSize=iMaxSize; - m_bLogStd=bLogStd; - m_iLogLevel=iLogLevel; - - // try to open a file - FILE* pFile=_tfopen(pszPath, bClean ? _t("w") : _t("a")); - if (pFile == NULL) - THROW(exception::format(_t("[log_file::init()] Could not open the specified file (") TSTRFMT _t(")")), 0, 0, 0); - - fclose(pFile); -} - -/** Retrieves the current size of a log file. - * Quite slow function - have to access the file by opening and closing it. - * \return Current file size. - */ -int_t log_file::size() const -{ - assert(m_pszPath); - - int_t iSize=-1; - FILE* pFile=_tfopen(m_pszPath, _t("r")); - if (pFile != NULL) - { - if (fseek(pFile, 0, SEEK_END) == 0) - iSize=ftell(pFile); - - fclose(pFile); - } - - return iSize; -} - -// @lAdd - count of bytes that would be appended to the file -/** Truncates the current log file content so when adding some new text the - * file size won't exceed the maximum size specified in init(). - * \param[in] iAdd - size of the new string to be added to the log file - * \return True if truncate succeeded or false if not. - */ -bool log_file::truncate(int_t iAdd) const -{ - assert(m_pszPath); - - // if we doesn't need to truncate anything - if (m_iMaxSize <= 0) - return true; - - // make some checks - int_t iSize=size(); - if (iSize <= 0 || iSize+iAdd < m_iMaxSize) - return false; - - // establish the new file size (1/3rd of the current size or max_size-add_size) - int_t iNewSize=minval((int_t)(iSize*0.66), m_iMaxSize-iAdd) & ~1; - -#ifdef _WIN32 - // win32 does not have the ftruncate function, so we have to make some API calls - HANDLE hFile=CreateFile(m_pszPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile != INVALID_HANDLE_VALUE) - { - // seek - if (SetFilePointer(hFile, iSize-iNewSize, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER) - { - // read the string to the eol - DWORD dwRD; - tchar_t szBuffer[4096/sizeof(tchar_t)]; - if (ReadFile(hFile, szBuffer, 4096, &dwRD, NULL)) - { - dwRD/=sizeof(tchar_t); - szBuffer[(dwRD > 0) ? dwRD-1 : 0]=_t('\0'); - - // replace the /r and /n in the log to the \0 - for (DWORD i=0;i 0) - { - // seek to the dst - fseek(pFile, iDst, SEEK_SET); - - fflush(pFile); - // write the buffer to the dest offset - tWR=fwrite(szBuffer, 1, tRD, pFile); - iDst+=tWR; - } - - iSrc+=tRD; - } - while(tRD != 0); - - // now truncate the file to the needed size - ftruncate(fileno(pFile), iDst); - - fclose(pFile); - return true; - } - - fclose(pFile); - } -#endif - - return false; -} - -/** Logs a formatted message to a log file. - * \param[in] iType - type of the log message (LT_*) - * \param[in] bStd - log also to stdout/stderr if true - * \param[in] pszStr - format string for the following parameters - */ -void log_file::log(int_t iType, bool bStd, const tchar_t* pszStr, ...) -{ - if (iType < m_iLogLevel) - return; - - va_list va; - va_start(va, pszStr); - logv(iType, bStd, pszStr, va); - va_end(va); -} - -/** Logs a formatted message to a log file. - * \param[in] iType - type of the log message (LT_*) - * \param[in] bStd - log also to stdout/stderr if true - * \param[in] pszStr - format string for the following parameters - * \param[in] va - variable argument list - */ -void log_file::logv(int_t iType, bool bStd, const tchar_t* pszStr, va_list va) -{ - if (iType < m_iLogLevel) - return; - - tchar_t szBuf1[2048]; - _vsntprintf(szBuf1, 2048, pszStr, va); // user passed stuff - - logs(iType, bStd, szBuf1); -} - -/** Logs an unformatted message to a log file. - * \param[in] iType - type of the log message (LT_*) - * \param[in] bStd - log also to stdout/stderr if true - * \param[in] pszStr - message string - */ -void log_file::logs(int_t iType, bool bStd, const tchar_t* pszStr) -{ - assert(m_pszPath); - - if (iType < m_iLogLevel) - return; - - // log time - time_t t=time(NULL); - tchar_t szData[128]; - _tcscpy(szData, _tctime(&t)); - size_t tLen=_tcslen(szData)-1; - while(szData[tLen] == _t('\n')) - szData[tLen--]=_t('\0'); - - m_lock.lock(); - - // check the size constraints - truncate((int_t)(_tcslen(pszStr)+1)); - FILE* pFile=_tfopen(m_pszPath, _t("a")); - bool bFailed=false; - if (pFile) - { - if (_ftprintf(pFile, _t("[") STRFMT _t("] [") STRFMT _t("] ") STRFMT _t("\n"), szData, __logtype_str[iType], pszStr) < 0) - bFailed=true; - fclose(pFile); - } - else - bFailed=true; - if (bFailed || (m_bLogStd && !bStd)) - { - switch(iType) - { - case level_error: - _ftprintf(stderr, _t("[") STRFMT _t("] [") STRFMT _t("] ") STRFMT _t("\n"), szData, __logtype_str[iType], pszStr); - break; - default: - _ftprintf(stdout, _t("[") STRFMT _t("] [") STRFMT _t("] ") STRFMT _t("\n"), szData, __logtype_str[iType], pszStr); - } - } - else if (bStd) - { - switch(iType) - { - case level_error: - _ftprintf(stderr, STRFMT _t(": ") STRFMT _t("\n"), __logtype_str[iType], pszStr); - break; - case level_info: - _ftprintf(stdout, STRFMT _t("\n"), pszStr); - break; - default: - _ftprintf(stdout, STRFMT _t(": ") STRFMT _t("\n"), __logtype_str[iType], pszStr); - } - } - - m_lock.unlock(); -} - -#ifndef SKIP_LEVEL_DEBUG -/** Logs a formatted debug message to a log file. - * \param[in] pszStr - format string for the given parameters - */ -void log_file::logd(const tchar_t* pszStr, ...) -{ - if (m_iLogLevel > level_debug) - return; - - va_list va; - va_start(va, pszStr); - logv(level_debug, false, pszStr, va); - va_end(va); -} - -/** Logs a formatted debug message to a log file(also outputs to stdout). - * \param[in] pszStr - format string for the given parameters - */ -void log_file::logds(const tchar_t* pszStr, ...) -{ - if (m_iLogLevel > level_debug) - return; - - va_list va; - va_start(va, pszStr); - logv(level_debug, true, pszStr, va); - va_end(va); -} - -#else -void log_file::logd(const tchar_t* /*pszStr*/, ...) -{ -} - -void log_file::logds(const tchar_t* /*pszStr*/, ...) -{ -} -#endif - -#ifdef SKIP_LEVEL_INFO -/** Logs a formatted informational message to a log file. - * \param[in] pszStr - format string for the given parameters - */ -void log_file::logi(const tchar_t* pszStr, ...) -{ - if (m_iLogLevel > level_info) - return; - - va_list va; - va_start(va, pszStr); - logv(level_info, false, pszStr, va); - va_end(va); -} - -/** Logs a formatted informational message to a log file(also outputs to stdout). - * \param[in] pszStr - format string for the given parameters - */ -void log_file::logis(const tchar_t* pszStr, ...) -{ - if (m_iLogLevel > level_info) - return; - - va_list va; - va_start(va, pszStr); - logv(level_info, true, pszStr, va); - va_end(va); -} -#else -void log_file::logi(const tchar_t* /*pszStr*/, ...) -{ -} - -void log_file::logis(const tchar_t* /*pszStr*/, ...) -{ -} - -#endif - -#ifndef SKIP_LEVEL_WARNING -/** Logs a formatted warning message to a log file. - * \param[in] pszStr - format string for the given parameters - */ -void log_file::logw(const tchar_t* pszStr, ...) -{ - if (m_iLogLevel > level_warning) - return; - - va_list va; - va_start(va, pszStr); - logv(level_warning, false, pszStr, va); - va_end(va); -} - -/** Logs a formatted warning message to a log file(also outputs to stdout). - * \param[in] pszStr - format string for the given parameters - */ -void log_file::logws(const tchar_t* pszStr, ...) -{ - if (m_iLogLevel > level_warning) - return; - va_list va; - va_start(va, pszStr); - logv(level_warning, true, pszStr, va); - va_end(va); -} - -#else -void log_file::logw(const tchar_t* /*pszStr*/, ...) -{ -} - -void log_file::logws(const tchar_t* /*pszStr*/, ...) -{ -} - -#endif - -/** Logs a formatted error message to a log file. - * \param[in] pszStr - format string for the given parameters - */ -void log_file::loge(const tchar_t* pszStr, ...) -{ - va_list va; - va_start(va, pszStr); - logv(level_error, false, pszStr, va); - va_end(va); -} - -/** Logs a formatted error message to a log file(also outputs to stderr). - * \param[in] pszStr - format string for the given parameters - */ -void log_file::loges(const tchar_t* pszStr, ...) -{ - va_list va; - va_start(va, pszStr); - logv(level_error, true, pszStr, va); - va_end(va); -} - -/** Logs a formatted error message to a log file(also outputs to stderr). - * As an addition the first string %err is replaced with a given error - * followed by the error description (system-based). - * \param[in] pszStr - format string for the given parameters - * \param[in] iSysErr - system error to be shown - */ -void log_file::logerr(const tchar_t* pszStr, int_t iSysErr, ...) -{ - tchar_t szNewFmt[2048]; - if (prepare_fmt(pszStr, iSysErr, szNewFmt)) - { - va_list va; - va_start(va, iSysErr); - logv(level_error, false, szNewFmt, va); - va_end(va); - } - else - { - va_list va; - va_start(va, iSysErr); - logv(level_error, false, pszStr, va); - va_end(va); - } -} - -/** Logs a formatted error message to a log file(also outputs to stderr). - * As an addition the first string %err is replaced with a given error - * followed by the error description (system-based). - * This function differ from logerr() with logging the output string - * also to the stderr. - * \param[in] pszStr - format string for the given parameters - * \param[in] iSysErr - system error to be shown - */ -void log_file::logerrs(const tchar_t* pszStr, int_t iSysErr, ...) -{ - tchar_t szNewFmt[2048]; - if (prepare_fmt(pszStr, iSysErr, szNewFmt)) - { - va_list va; - va_start(va, iSysErr); - logv(level_error, true, szNewFmt, va); - va_end(va); - } - else - { - va_list va; - va_start(va, iSysErr); - logv(level_error, true, pszStr, va); - va_end(va); - } -} - -/** Function prepares a format string with error number and an error message - * for use with logerr() and logerrs() functions. - * \param[in] pszStr - input format string (%err will be replaced with a 0x%lx (error message) - * \param[in] iSysError - system error to parse - * \param[out] pszOut - pointer to a buffer that will receive the data (must be 2048 bytes in size) - * \return If the %err string was found and replaced within a given format string. - */ -bool log_file::prepare_fmt(const tchar_t* pszStr, int_t iSysErr, tchar_t* pszOut) const -{ - // find the %err in pszStr - const tchar_t* pszFnd=_tcsstr(pszStr, _t("%err")); - if (pszFnd) - { - // find an error description for the error - tchar_t* pszErrDesc=NULL; -#ifdef _WIN32 - tchar_t szErrDesc[512]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, (DWORD)iSysErr, 0, szErrDesc, 512, NULL); - pszErrDesc=szErrDesc; -#else - pszErrDesc=strerror(iSysErr); -#endif - - // format a string with err no and desc - tchar_t szError[1024]; - _sntprintf(szError, 1024, _t("0x%lx (%s)"), iSysErr, pszErrDesc); - - // replace %err with the new data - pszOut[0]=_t('\0'); - _tcsncat(pszOut, pszStr, (size_t)(pszFnd-pszStr)); - _tcscat(pszOut, szError); - _tcscat(pszOut, pszFnd+4); - - return true; - } - else - return false; -} - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/log.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/log.h (revision 0) +++ ext/libicpf/src/libicpf/log.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file log.h + * \brief Contains the log class. + */ +#ifndef __LOG_H__ +#define __LOG_H__ + +#include +#include "mutex.h" +#include "libicpf.h" +#include "gen_types.h" + +BEGIN_ICPF_NAMESPACE + +/** \brief Class provides the message logging capability. + * + * Class used to perform message logging to the external file. Provides a possibility + * of limiting the max size of a file and to cut the log message types below a specific + * level. + * Class is thread safe. + */ +class LIBICPF_API log_file +{ +public: + /// Supported log levels + enum log_levels + { + level_debug, /// Debug level (the most detailed one) + level_info, /// Informational level + level_warning, /// Warning level + level_error /// Error level (the least detailed one) + }; + +public: +/** \name Construction/destruction */ +/**@{*/ + explicit log_file(); ///< Standard constructor + ~log_file(); ///< Standard destructor +/**@}*/ + +/** \name Initialization */ +/**@{*/ + void init(const tchar_t* pszPath, int_t iMaxSize, int_t iLogLevel, bool bLogStd, bool bClean); ///< Initializes the logging object +/**@}*/ + +/** \name Logging functions */ +/**@{*/ + void logs(int_t iType, bool bStd, const tchar_t* pszStr); ///< Logs a string without formatting + void log(int_t iType, bool bStd, const tchar_t* pszStr, ...); ///< Logs a string with formatting + void logv(int_t iType, bool bStd, const tchar_t* pszStr, va_list va); ///< Logs a string using va_list + + void logd(const tchar_t* pszStr, ...); ///< Logs a debug message with formatting + void logds(const tchar_t* pszStr, ...); ///< Logs a debug message with formatting (also prints to stdout) + + void logi(const tchar_t* pszStr, ...); ///< Logs an informational message with formatting + void logis(const tchar_t* pszStr, ...); ///< Logs an informational message with formatting(also prints to stdout) + + void logw(const tchar_t* pszStr, ...); ///< Logs a warning message with formatting + void logws(const tchar_t* pszStr, ...); ///< Logs a warning message with formatting(also prints to stdout) + + void loge(const tchar_t* pszStr, ...); ///< Logs an error message with formatting + void loges(const tchar_t* pszStr, ...); ///< Logs an error message with formatting(also prints to stderr) + + void logerr(const tchar_t* pszStr, int_t iSysErr, ...); ///< Logs an error message with system error number and error description + void logerrs(const tchar_t* pszStr, int_t iSysErr, ...); ///< Logs an error message with system error number and error description (also prints to stderr) +/**@}*/ + +protected: + /// Truncates a log file not to exceed the max file size + bool truncate(int_t iAdd) const; + /// Returns the size of a log file + int_t size() const; + +private: + /// Prepares a new format string for logerr(s) functions + bool prepare_fmt(const tchar_t* pszStr, int_t iSysErr, tchar_t* pszOut) const; + +protected: + tchar_t* m_pszPath; ///< Path to the log file + int_t m_iMaxSize; ///< Maximum size of the log file + bool m_bLogStd; ///< Log also to stdout/stderr + int_t m_iLogLevel; ///< Log level (similar to the _LOG_LEVEL, but change'able after compilation) + +protected: + mutex m_lock; ///< Lock for making the class thread safe +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/log.h =================================================================== diff -u -N --- ext/libicpf/src/log.h (revision 6dae57f5e7aeeb965bc018024d8360069f6e15c1) +++ ext/libicpf/src/log.h (revision 0) @@ -1,108 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file log.h - * \brief Contains the log class. - */ -#ifndef __LOG_H__ -#define __LOG_H__ - -#include -#include "mutex.h" -#include "libicpf.h" -#include "gen_types.h" - -BEGIN_ICPF_NAMESPACE - -/** \brief Class provides the message logging capability. - * - * Class used to perform message logging to the external file. Provides a possibility - * of limiting the max size of a file and to cut the log message types below a specific - * level. - * Class is thread safe. - */ -class LIBICPF_API log_file -{ -public: - /// Supported log levels - enum log_levels - { - level_debug, /// Debug level (the most detailed one) - level_info, /// Informational level - level_warning, /// Warning level - level_error /// Error level (the least detailed one) - }; - -public: -/** \name Construction/destruction */ -/**@{*/ - explicit log_file(); ///< Standard constructor - ~log_file(); ///< Standard destructor -/**@}*/ - -/** \name Initialization */ -/**@{*/ - void init(const tchar_t* pszPath, int_t iMaxSize, int_t iLogLevel, bool bLogStd, bool bClean); ///< Initializes the logging object -/**@}*/ - -/** \name Logging functions */ -/**@{*/ - void logs(int_t iType, bool bStd, const tchar_t* pszStr); ///< Logs a string without formatting - void log(int_t iType, bool bStd, const tchar_t* pszStr, ...); ///< Logs a string with formatting - void logv(int_t iType, bool bStd, const tchar_t* pszStr, va_list va); ///< Logs a string using va_list - - void logd(const tchar_t* pszStr, ...); ///< Logs a debug message with formatting - void logds(const tchar_t* pszStr, ...); ///< Logs a debug message with formatting (also prints to stdout) - - void logi(const tchar_t* pszStr, ...); ///< Logs an informational message with formatting - void logis(const tchar_t* pszStr, ...); ///< Logs an informational message with formatting(also prints to stdout) - - void logw(const tchar_t* pszStr, ...); ///< Logs a warning message with formatting - void logws(const tchar_t* pszStr, ...); ///< Logs a warning message with formatting(also prints to stdout) - - void loge(const tchar_t* pszStr, ...); ///< Logs an error message with formatting - void loges(const tchar_t* pszStr, ...); ///< Logs an error message with formatting(also prints to stderr) - - void logerr(const tchar_t* pszStr, int_t iSysErr, ...); ///< Logs an error message with system error number and error description - void logerrs(const tchar_t* pszStr, int_t iSysErr, ...); ///< Logs an error message with system error number and error description (also prints to stderr) -/**@}*/ - -protected: - /// Truncates a log file not to exceed the max file size - bool truncate(int_t iAdd) const; - /// Returns the size of a log file - int_t size() const; - -private: - /// Prepares a new format string for logerr(s) functions - bool prepare_fmt(const tchar_t* pszStr, int_t iSysErr, tchar_t* pszOut) const; - -protected: - tchar_t* m_pszPath; ///< Path to the log file - int_t m_iMaxSize; ///< Maximum size of the log file - bool m_bLogStd; ///< Log also to stdout/stderr - int_t m_iLogLevel; ///< Log level (similar to the _LOG_LEVEL, but change'able after compilation) - -protected: - mutex m_lock; ///< Lock for making the class thread safe -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/macros.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/macros.h (revision 0) +++ ext/libicpf/src/libicpf/macros.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __MACROS_H__ +#define __MACROS_H__ + +/** \file macros.h + * \brief Contains some helper macros used throughout other files + */ + +// macros for rounding up and down some values to the nearest ?*chunk +/// Rounding up value to the nearest chunk multiplicity +#define ROUNDUP(val,chunk) ((val + chunk - 1) & ~(chunk-1)) +/// Rounding down value to the nearest chunk multiplicity +#define ROUNDDOWN(val,chunk) (val & ~(chunk-1)) + +// cross-platform __FUNCTION__ macro +#ifndef _WIN32 + /// Some helper for non-windoze systems (unified cross-platform __FUNCTION__ macro) + #define __FUNCTION__ __PRETTY_FUNCTION__ +#endif + +// minimum/maximum macros +/// Returns the lesser value from two given as params +#define minval(a,b) ((a) < (b) ? (a) : (b)) +/// Returns the greater value from two given as params +#define maxval(a,b) ((a) > (b) ? (a) : (b)) + +#endif Index: ext/libicpf/src/macros.h =================================================================== diff -u -N --- ext/libicpf/src/macros.h (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/macros.h (revision 0) @@ -1,45 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef __MACROS_H__ -#define __MACROS_H__ - -/** \file macros.h - * \brief Contains some helper macros used throughout other files - */ - -// macros for rounding up and down some values to the nearest ?*chunk -/// Rounding up value to the nearest chunk multiplicity -#define ROUNDUP(val,chunk) ((val + chunk - 1) & ~(chunk-1)) -/// Rounding down value to the nearest chunk multiplicity -#define ROUNDDOWN(val,chunk) (val & ~(chunk-1)) - -// cross-platform __FUNCTION__ macro -#ifndef _WIN32 - /// Some helper for non-windoze systems (unified cross-platform __FUNCTION__ macro) - #define __FUNCTION__ __PRETTY_FUNCTION__ -#endif - -// minimum/maximum macros -/// Returns the lesser value from two given as params -#define minval(a,b) ((a) < (b) ? (a) : (b)) -/// Returns the greater value from two given as params -#define maxval(a,b) ((a) > (b) ? (a) : (b)) - -#endif Index: ext/libicpf/src/libicpf/module.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/module.cpp (revision 0) +++ ext/libicpf/src/libicpf/module.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,1186 @@ +///*************************************************************************** +// * Copyright (C) 2004-2006 by J�zef Starosczyk * +// * ixen@copyhandler.com * +// * * +// * This program is free software; you can redistribute it and/or modify * +// * it under the terms of the GNU Library General Public License as * +// * published by the Free Software Foundation; either version 2 of the * +// * License, or (at your option) any later version. * +// * * +// * This program 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 General Public License for more details. * +// * * +// * You should have received a copy of the GNU Library General Public * +// * License along with this program; if not, write to the * +// * Free Software Foundation, Inc., * +// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +// ***************************************************************************/ +///** \file module.cpp +// * \brief File contain an implementation of the module (and related) classes. +// */ +// +#include "module.h" +//#include +//#include "err_codes.h" +// +//#ifndef _WIN32 +// #include +//#endif +// +BEGIN_ICPF_NAMESPACE +// +//#define m_pmMods ((std::map*)m_pMods) +// +///** Constructs a module_param class and initializes all the internal members +// * to their initial values. +// */ +//module_param::module_param() +//{ +// m_midModuleID=NULL_MODULE; +// m_uiPropStart=0; +//} +// +///** Destructs the module_param class. +// */ +//module_param::~module_param() +//{ +//} +// +///** Locks the class (multi-threaded access). +// */ +//void module_param::lock() +//{ +// m_lock.lock(); +//} +// +///** Unlocks the class (multi-threaded access). +// */ +//void module_param::unlock() +//{ +// m_lock.unlock(); +//} +// +///** Returns a module id associated with this class. +// * \return Module ID +// * \note The usage of mutex inside of this function is unnecessary, because +// * the module id is not supposed to change. +// */ +//moduleid_t module_param::get_moduleid() const +//{ +// return m_midModuleID; +//} +// +///** Reads the properties from the configuration object (config class). Function +// * implemented as virtual - it does not do anything in this (base) class. Should +// * be implemented in the derived classes. Function should read the properties registered +// * earlier with register_properties() from a given config object and initialize +// * the internal structure data (m_pParams). The given structure should be allocated +// * earlier (ie. in the constructor of the derived class). +// * Calling this function should be the first operation done in the derived class' function. +// * \param[in] pcfg - pointer to the config object to read the properties from +// */ +//void module_param::read_config(config* /*pcfg*/) +//{ +//} +// +///** Function writes the internal configuration options to the given configuration +// * object (config class). Declared virtual and the base implementation does not +// * do anything. Should be implemented in the derived classes. The purpose of this +// * function is to write data from the internal data structure (m_pParams) to the +// * given config class. The structure should be allocated and initialized earlier. +// * Calling this function should be the first operation done in the derived class' function. +// * \param[in] pcfg - pointer to the config object to write the properties to +// */ +//void module_param::write_config(config* /*pcfg*/) +//{ +//} +// +///** Function registers the properties used in the internal data structure (m_pParams) +// * to the given configuration object (config class). Function declared as virtual and +// * the base implementation does not do anything. In derived classes this function should +// * register the properties with the config object and store the first returned property ID +// * in the m_ulPropStart internal member. +// * Calling this function should be the first operation done in the derived class' function. +// * \note When registering properties user should lock the config object to make sure +// * the ID's will be the subsequent numbers and not pseudo-random ones. +// * \param[in] pcfg - pointer to the configuration object with which the props should be registered. +// */ +//void module_param::register_properties(config* /*pcfg*/) +//{ +//} +// +//// store/restore from/to a file (serializer) +///** Function stores the internal data structure settings to the external file (file class). +// * Declared as virtual - base implementation does not do anything. In derived classes this +// * function should store the members of the internal structure (m_pParams) in the given +// * file object in some order (that must be used also in load() function). +// * Calling this function should be the first operation done in the derived class' function. +// * \param[in] ser - serialization object to write the data to +// */ +//void module_param::store(file& /*ser*/) +//{ +//} +// +///** Function loads the internal data structure from a file (file class). Declared as +// * virtual - base implementation does not do anything. In derived classes function +// * should read the properties from a given file object (in the order used in store() function). +// * Calling this function should be the first operation done in the derived class' function. +// * \param[in] ser - serialization object that contains the data to be read +// */ +//void module_param::load(file& /*ser*/) +//{ +//} +// +///** Standard constructor - does nothing currently. +// */ +//modparam_list::modparam_list() +//{ +// m_pMods=new std::map; +//} +// +///** Standard destructor - clears the internal list of module_params. Also, each entry +// * is being deleted before clearing. If you want to preserve the elements from being deleted - +// * use the clear(false) method before destrying this object. +// */ +//modparam_list::~modparam_list() +//{ +// clear(true); +// delete m_pmMods; +//} +// +///** Inserts a module_param to this list. +// * \param[in] pEntry - address of a module_param class to be inserted. It should be allocated by +// * the 'new' operator if you would like to use bDelete parameter set in other +// * methods. +// */ +//void modparam_list::insert(module_param* pEntry) +//{ +// assert(pEntry); +// m_lock.lock(); +// m_pmMods->insert(std::pair(pEntry->get_moduleid(), pEntry)); +// m_lock.unlock(); +//} +// +///** Removes a module from the list. Also delete a module_param if specified. +// * \param[in] tEntry - module id associated with an entry to remove +// * \param[in] bDelete - specifies, if the delete operator should be called on an entry +// * before removing it from the list. +// * \return If the entry was successfully removed (true) or not (false). +// */ +//bool modparam_list::remove(moduleid_t tEntry, bool bDelete) +//{ +// m_lock.lock(); +// std::map::iterator it = m_pmMods->find(tEntry); +// if (it != m_pmMods->end()) +// { +// // delete if needed +// if (bDelete) +// delete it->second; +// m_pmMods->erase(it); +// m_lock.unlock(); +// return true; +// } +// else +// { +// m_lock.unlock(); +// return false; +// } +//} +// +///** Removes all the items from this list. +// * \param[in] bDelete - if true, then all the items will be 'delete''d before removing. +// */ +//void modparam_list::clear(bool bDelete) +//{ +// m_lock.lock(); +// if (bDelete) +// { +// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) +// { +// delete it->second; +// } +// } +// +// m_pmMods->clear(); +// m_lock.unlock(); +//} +// +///** Searches for a module_param associated with a given module id. +// * \param[in] mid - module id to search for +// * \return Pointer to a module_param class, or NULL if not found. +// */ +//module_param* modparam_list::find(moduleid_t mid) +//{ +// m_lock.lock(); +// std::map::iterator it = m_pmMods->find(mid); +// if (it != m_pmMods->end()) +// { +// m_lock.unlock(); +// return it->second; +// } +// else +// { +// m_lock.unlock(); +// return NULL; +// } +//} +// +///** A group wrapper over the module_param::read_config(). Calls the method for each of the module_param's. +// * \param[in] pcfg - pointer to a configuration object to read the data from. +// */ +//void modparam_list::read_config(config* pcfg) +//{ +// // read the config for all entries +// m_lock.lock(); +// try +// { +// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) +// { +// it->second->read_config(pcfg); +// } +// } +// catch(...) +// { +// m_lock.unlock(); +// throw; +// } +// m_lock.unlock(); +//} +// +///** A group wrapper over the module_param::write_config(). Calls the method for each of the module_param's. +// * \param[in] pcfg - pointer to a configuration object to write the data to. +// */ +//void modparam_list::write_config(config* pcfg) +//{ +// m_lock.lock(); +// try +// { +// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) +// { +// it->second->write_config(pcfg); +// } +// } +// catch(...) +// { +// m_lock.unlock(); +// throw; +// } +// m_lock.unlock(); +//} +// +///** A group wrapper over the module_param::register_properties(). Calls the method for each of the module_param's. +// * \param[in] pcfg - pointer to a configuration object to register the properties with. +// */ +//void modparam_list::register_properties(config* pcfg) +//{ +// m_lock.lock(); +// try +// { +// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) +// { +// it->second->register_properties(pcfg); +// } +// } +// catch(...) +// { +// m_lock.unlock(); +// throw; +// } +// m_lock.unlock(); +//} +// +///** A group wrapper over the module_param::store(). Calls the method for each of the module_param's. +// * \param[in] ser - a serialization object to write the data to +// */ +//void modparam_list::store(file& ser) +//{ +// m_lock.lock(); +// try +// { +// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) +// { +// it->second->store(ser); +// } +// } +// catch(...) +// { +// m_lock.unlock(); +// throw; +// } +// m_lock.unlock(); +//} +// +///** A group wrapper over the module_param::load(). Calls the method for each of the module_param's. +// * \param[in] ser - a serialization object to read the data from +// */ +//void modparam_list::load(file& ser) +//{ +// m_lock.lock(); +// try +// { +// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) +// { +// it->second->load(ser); +// } +// } +// catch(...) +// { +// m_lock.unlock(); +// throw; +// } +// m_lock.unlock(); +//} +// +///////////////////////////////////////////////////////////////////////////// +///** Constructor - makes a copy of the MODULE_INITDATA passed as the parameter +// * and stores the given flags in the internal member. Also nullifies all the other class +// * members. The module information is initialized with NULL values and for internal +// * modules this should be corrected in the constructor of the derived class. +// * \param[in] pData - pointer to the structure with some parameters (the copy of it +// * will be stored in the internal member - not the pointer itself). +// * \param[in] uiFlags - module flags that are about to be stored in the internal member (MF_*) +// */ +//module::module(const MODULE_INITDATA* pData, uint_t uiFlags) +//{ +// m_pmp=NULL; +// m_pmid=pData; +// m_ulFlags=uiFlags; +// m_lRefCount=0; +// +// // module information +// m_mi.uiInfoLen=sizeof(MODULE_INFO); +// m_mi.midID=NULL_MODULE; +// m_mi.szAuthor[0]='\0'; +// m_mi.szName[0]='\0'; +// m_mi.szVersion[0]='\0'; +// m_mi.uiType=MT_NONE; +// +// m_hModule=NULL; +// m_pszPath=NULL; +// m_pfnGetInfo=NULL; +// m_pfnInit=NULL; +// m_pfnUninit=NULL; +// m_pfnAllocModparam=NULL; +//} +// +///** Destructor. Tries to close the module (close(true) function). If the closing +// * function throws an exception it is caught, logged to the log file (MODULE_INITDATA) +// * and the exception is removed. +// */ +//module::~module() +//{ +// try +// { +// close(true); +// } +// catch(exception* e) +// { +// LOG_EXCEPTION(e, m_pmid->plog); +// e->del(); +// } +//} +// +//// external modules support (called only for the external modules) +///** Function opens the external file as the program module. After successful +// * file opening this function loads all exports from the module (using load_exports() +// * function) and caches the module information in the internal member if all goes ok. +// * If something goes wrong the exception is thrown. All information (excluding exceptions +// * are logged to the log file (MODULE_INITDATA)). +// * \param[in] pszPath - full path to the module that is about to be loaded +// */ +//void module::open(const char_t* pszPath) +//{ +// assert(m_ulFlags & MF_EXTERNAL); // only for the external modules +// +// m_pmid->plog->logi("[module] Loading external module " STRFMT, pszPath); +// +// // try to load external library +//#ifdef _WIN32 +// if ( (m_hModule=::LoadLibrary(pszPath)) == NULL) +// THROW(exception::format("Cannot load external module " STRFMT, pszPath), PE_CANNOTLOAD, GetLastError(), 0); +//#else +// if ( (m_hModule=dlopen(pszPath, RTLD_LAZY)) == NULL) +// THROW(exception::format("Cannot load external module " STRFMT " (" STRFMT ")", pszPath, dlerror()), PE_CANNOTLOAD, 0, 0); +//#endif +// +// m_pmid->plog->logi("[module] External module loaded successfully (handle " PTRFMT ")", m_hModule); +// +// // load all needed exports (function must throw if export does not exist) +// m_pmid->plog->logd("[module] Loading exports for the module (handle " PTRFMT ")", m_hModule); +// load_exports(); +// m_pmid->plog->logd("[module] Exports loaded for the module (handle " PTRFMT ")", m_hModule); +// +// // cache the module information +// m_pmid->plog->logd("[module] Caching module (handle " PTRFMT ") information", m_hModule); +// (*m_pfnGetInfo)(&m_mi); +// m_pmid->plog->logd("[module] Cached module (handle " PTRFMT ") information - id: " MODIDFMT ", type: " ULFMT ", name: " STRFMT ", version: " STRFMT ", author: " STRFMT "", m_hModule, m_mi.midID, m_mi.uiType, m_mi.szName, m_mi.szVersion, m_mi.szAuthor); +// +// // store the path +// m_pszPath=new char_t[strlen(pszPath)+1]; +// strcpy(m_pszPath, pszPath); +//} +// +//// close the module - it's safe to call it more than once +///** Closes the external module. At first it uninitializes the module that is about to +// * be unloaded and then closes the module and resets all(except the module info) the +// * internal data. Function is safe to be called more than once. If any problem occur +// * there is the exception thrown. +// * \param[in] bFullDestruct - should be true only in destructor. Means deleting the path string +// * before uninitialization (and not after as with false). +// */ +//void module::close(bool bFullDestruct) +//{ +// // if called from a destructor - release some of the memory allocated +// if (bFullDestruct) +// { +// // delete the path allocated earlier +// delete [] m_pszPath; +// m_pszPath=NULL; +// } +// +// // uninit the module if wasn't already +// uninit(); +// +// // release stuff related to external module +// if (m_hModule != NULL) +// { +// m_pmid->plog->logd("[module] Unloading an external module (handle " PTRFMT ")", m_hModule); +// +//#ifdef _WIN32 +// if (!::FreeLibrary(m_hModule)) +// THROW(exception::format("Cannot unload the external module (handle " PTRFMT ")", m_hModule), PE_CANNOTUNLOAD, GetLastError(), 0); +//#else +// if (dlclose(m_hModule) != 0) +// THROW(exception::format("Cannot unload the external module - " STRFMT " (handle " PTRFMT ")", dlerror(), m_hModule), PE_CANNOTUNLOAD, 0, 0); +//#endif +// m_pmid->plog->logd("[module] ...external module unloaded (handle " PTRFMT ")", m_hModule); +// } +// +// m_hModule=NULL; +// m_pfnGetInfo=NULL; +// m_pfnInit=NULL; +// m_pfnUninit=NULL; +// +// // release a memory when sure the module has been succesfully freed +// if (!bFullDestruct) +// { +// delete [] m_pszPath; +// m_pszPath=NULL; +// } +//} +// +///** Retrieves the module information (author, ... as in MODULE_INFO struct). This function +// * does not use the internal cache for external modules - there is always a call made to the +// * module. Internal modules always use caching (it's their only info source). +// * \param[out] pInfo - receives the module information +// */ +//void module::get_info(MODULE_INFO* pInfo) +//{ +// if (m_ulFlags & MF_EXTERNAL) +// { +// assert(m_hModule); +// +// (*m_pfnGetInfo)(pInfo); +// } +// else +// *pInfo=m_mi; +//} +// +///** Function initializes the module. For external modules the module's init() function will be +// * called. For internal modules this should be the first function called from within the init() +// * function of the derived class. If the function fails it can return false or throw an exception. +// * Function is safe to be called multiple times - the real init() functions will be called +// * only once. +// * \note In the internal modules the init() function in the derived classes should check for +// * the MF_INITIALIZED flag and do not perform any initialization if flag is set to 0. +// * \param[in] pData - module initialization data - should be the same as in constructor +// * \return True if the function succeeds, false otherwise. +// */ +//bool module::init(const MODULE_INITDATA* pData) +//{ +// // return if already initialized +// if (m_ulFlags & MF_INITIALIZED) +// return true; +// +// if (m_ulFlags & MF_EXTERNAL) +// { +// m_pmid->plog->logi("[module] Making external module initialization (id=" MODIDXFMT ")...", get_id()); +// if ((*m_pfnInit)(pData, &m_pmp)) +// { +// m_pmid->plog->logi("[module] ...external module initialized successfully (id=" MODIDXFMT ").", get_id()); +// m_ulFlags |= MF_INITIALIZED; +// return true; +// } +// else +// { +// m_pmid->plog->logi("[module] ...external module initialization failed (id=" MODIDXFMT ").", get_id()); +// return false; +// } +// } +// else +// { +// m_ulFlags |= MF_INITIALIZED; +// return true; +// } +//} +// +//// uninitializes a module +//// safe to call multiple times (ext module uninit() func will be called only once) +///** Uninitializes a module. This is the first function to be called in uninit() function +// * of the derived classes (internal modules). For external modules this function calls the +// * module's init() function. This function is safe to be called multiple times - the real +// * initialization functions will be called only once. On error either false value can be returned +// * or exception will be thrown. +// * \note For internal modules - this function at first should check if the module has been +// * initialized (by checking the MF_INITIALIZED flag - it must be set). If it is not then +// * no uninitialization should be done. +// * \return True if all went ok, false otherwise. +// */ +//bool module::uninit() +//{ +// if (m_ulFlags & MF_INITIALIZED) +// { +// if (m_ulFlags & MF_EXTERNAL) +// { +// m_pmid->plog->logi("[module] Making external module uninitialization (id=" MODIDXFMT ")...", get_id()); +// if ((*m_pfnUninit)(&m_pmp)) +// { +// m_pmid->plog->logi("[module] ...external module uninitialization succeeded (id=" MODIDXFMT ").", get_id()); +// +// // delete the module parameters/informations if allocated +// cleanup(); +// +// return true; +// } +// else +// { +// m_pmid->plog->logi("[module] ...external module uninitialization failed (id=" MODIDXFMT ").", get_id()); +// return false; +// } +// } +// else +// { +// // delete the module parameters/informations if allocated +// cleanup(); +// +// return true; +// } +// } +// else +// return true; // already uninitialized +//} +// +///** Allocates a module_param for this module. External modules should allocate the needed class +// * and return it in the alloc_modparam(). Internal modules do not need to call this function. +// * And overloaded function should just alloc the class and return it. +// * \return Allocated class. Note that the returned pointer is being cast to module_param, but most +// * likely this will be another class that has module_param as a base class. +// */ +//module_param* module::alloc_modparam() +//{ +// assert(m_ulFlags & MF_INITIALIZED); +// if (m_ulFlags & MF_EXTERNAL) +// return (*m_pfnAllocModparam)(); +// else +// return NULL; +//} +// +//// called to load all exported functions (must be called for any derived load_exports()) +///** Loads the exports associated with a given type of module. This should be the first function +// * to be called in load_exports() of derived classes. If a specified exports does not +// * exist in a module an exception is thrown. +// * \note Use the MAP_EXPORT macro here to assign together the function name to the +// * function address. +// */ +//void module::load_exports() +//{ +// MAP_EXPORT(m_hModule, m_pfnGetInfo, "get_info"); +// MAP_EXPORT(m_hModule, m_pfnInit, "init"); +// MAP_EXPORT(m_hModule, m_pfnUninit, "uninit"); +// MAP_EXPORT(m_hModule, m_pfnAllocModparam, "alloc_modparam"); +//} +// +///** Cleanup function used in uninit() to make sure the module_param stuff +// * is freed if needed. Also resets the MF_INITIALIZED flag. +// */ +//void module::cleanup() +//{ +// // delete the module parameters/informations if allocated +// if (m_pmp) +// { +// m_pmp->write_config(m_pmid->pcfg); +// delete m_pmp; +// m_pmp=NULL; +// } +// +// m_ulFlags &= ~MF_INITIALIZED; +//} +// +/////////////////////////////////////////////////////////////////// +//#define m_pvModules ((std::vector*)m_vModules) +//#define m_pmModules ((std::map*)m_mModules) +// +///** Constructor - makes a copy of the MODULE_INITDATA structure and +// * stores it in the internal member. +// */ +//module_list::module_list(const MODULE_INITDATA* pData) +//{ +// m_pmid=pData; +// m_vModules=(void*)new std::vector; +// m_mModules=(void*)new std::map; +//} +// +///** Destructor - calls the remove_all(true) to get rid of all modules before +// * class is destroyed. Any exception thrown in the remove_all() function is being +// * logged to a log file (MODULE_INITDATA) and the exception is deleted. +// */ +//module_list::~module_list() +//{ +// try +// { +// remove_all(true); +// } +// catch(exception& e) +// { +// LOG_EXCEPTION(e, m_pmid->plog); +// e->del(); +// } +// +// delete m_pvModules; +// delete m_pmModules; +//} +// +//#ifndef _WIN32 +///** Helper function for filtering filesystem entries. It allows selecting only the +// * filesystem entries that appears to be the proper modules. Function used in linux. +// * \param[in] pent - directory entry to process +// * \return >0 for the entry to be accepted, 0 if not. +// */ +//int_t module_list::mod_filter(const struct dirent *pent) +//{ +// size_t tLen=strlen(pent->d_name), tExtLen=strlen(MODULE_EXT); +// if (tLen >= tExtLen && strcmp(pent->d_name+tLen-tExtLen, MODULE_EXT) == 0) +// return 1; +// else +// return 0; +//} +//#endif +// +///** Function scans a specified directory for the files that looks like modules. +// * Macro MODULE_EXT specifies the file extension (in format ".ext") used in modules. +// * Only modules that types matches (even partially) the specified type are added to +// * the list. All the performed operations are logged into the log file. +// * There are no exception throws or return values. +// * \param[in] pszPath - path to the directory with modules (must be trailed with '\\' or '/' - system dependent) +// * \param[in] uiType - types of modules to be added to the list +// */ +//void module_list::scan(const char_t* pszPath, uint_t uiType) +//{ +// m_pmid->plog->logi("[module_list] Scanning directory " STRFMT " for external modules of type " ULFMT, pszPath, uiType); +// uint_t uiCount=0; // count of modules found +// +//#ifdef _WIN32 +// // create full search path +// char_t sz[_MAX_PATH]; +// _snprintf(sz, _MAX_PATH, STRFMT "*" STRFMT, pszPath, MODULE_EXT); +// size_t tLen=strlen(pszPath); +// +// WIN32_FIND_DATA wfd; +// HANDLE hFind=::FindFirstFile(sz, &wfd); +// if (hFind != INVALID_HANDLE_VALUE) +// { +// BOOL bFound=TRUE; +// while (bFound) +// { +// // append a name to the input path (NOTE: it's a small optimization so it looks like there's something's missing). +// strcpy(sz+tLen, wfd.cFileName); +//#else +// dirent **ppde; +// char_t sz[PATH_MAX]; +// strcpy(sz, pszPath); +// size_t tLen=strlen(pszPath); +// +// int_t iCnt=scandir(pszPath, &ppde, mod_filter, NULL); +// while (iCnt--) +// { +// strcpy(sz+tLen, ppde[iCnt]->d_name); +//#endif +// module* pmod=new module(m_pmid, true); +// try +// { +// pmod->open(sz); +// +// if (pmod->get_type() & uiType) +// { +// push_back(pmod); +// uiCount++; +// } +// else +// delete pmod; // also calls module::close(), but does not throw an exception +// } +// catch(exception e) +// { +// m_pmid->plog->logw("[module_list] Caught an exception while trying to open a module (path=" STRFMT ").Ignoring module.", sz); +// LOG_EXCEPTION(e, m_pmid->plog); +// +// e->del(); +// delete pmod; +// } +//#ifdef _WIN32 +// bFound=::FindNextFile(hFind, &wfd); +// } +// +// if (!::FindClose(hFind)) +// m_pmid->plog->logd("[module_list] Cannot close a find handle in module::open(), system error " ULFMT ". Ignoring.", GetLastError()); +// } +// +//#else +// free(ppde[iCnt]); +// } +// free(ppde); +//#endif +// m_pmid->plog->logi("[module_list] Completed scanning for external modules in directory " STRFMT ". Found " ULFMT " modules with type matching " ULFMT, pszPath, uiCount, uiType); +//} +// +//// getting a module from a vector +///** Searches for a module in a list given it's ID. When using this function +// * user should fully lock the module_list and before releasing the lock he should +// * use module::acquire() to make sure the module won't be unloaded when being used. +// * \param[in] mid - module ID to find in the list +// * \return Pointer to the module or NULL if module not found. +// */ +//module* module_list::find(moduleid_t mid) +//{ +// module* mod; +// +// m_lock.lock(); +// std::map::iterator it=m_pmModules->find(mid); +// if (it != m_pmModules->end()) +// mod=(*it).second; +// else +// mod=NULL; +// m_lock.unlock(); +// +// return mod; +//} +// +///** Function returns a module at a specified position. When using this function +// * user should lock the entire module_list and before releasing lock he should +// * use module::acquire() function to ensure the module to remain loaded. +// * \param[in] tPos - index of the module to return address of; the position must +// * be in range. The debug version of program asserts if range exceeded. +// * \return Address of a module. +// */ +//module* module_list::at(size_t tPos) +//{ +// assert(tPos < m_pvModules->size()); +// +// m_lock.lock(); +// module* mod=m_pvModules->at(tPos); +// m_lock.unlock(); +// +// return mod; +//} +// +//// adding a new items (modules) +///** Function inserts a module into the list at the specified position. Module is being +// * initialized before insertion (if not already initialized). An exception* is thrown +// * if any error occurs. +// * \param[in] tPos - position in the list to insert the module at (-1 = at the end) +// * \param[in] tModule - address of a module to be inserted into the list +// */ +//void module_list::insert(size_t tPos, module* tModule) +//{ +// m_pmid->plog->logd("[module_list] Initializing the module (id=" MODIDXFMT ")", tModule->get_id()); +// tModule->init(m_pmid); // can throw an exception +// +// m_pmid->plog->logd("[module_list] Inserting the module (id=" MODIDXFMT ") to the module list at the position " ULPTRXFMT, tModule->get_id(), tPos); +// +// m_lock.lock(); +// +// try +// { +// std::map::iterator it=m_pmModules->find(tModule->get_id()); +// if (it != m_pmModules->end()) +// { +// THROW(exception::format("Module with a specified id=" MODIDXFMT " (name: " STRFMT ", version: " STRFMT ", author: " STRFMT ") already exists (name: " STRFMT ", version: " STRFMT ", author: " STRFMT ")", +// tModule->get_id(), tModule->get_name(), tModule->get_version(), tModule->get_author(), +// (*it).second->get_name(), (*it).second->get_version(), (*it).second->get_author()), +// PE_DUPLICATEPLUG, 0, 0); +// } +// else +// { +// if (tPos != (size_t)-1) +// { +// assert(tPos <= m_pvModules->size()); +// m_pvModules->insert(m_pvModules->begin()+tPos, tModule); +// } +// else +// m_pvModules->push_back(tModule); +// +// m_pmModules->insert(std::pair(tModule->get_id(), tModule)); +// } +// +// m_lock.unlock(); +// } +// catch(...) +// { +// m_lock.unlock(); +// throw; +// } +//} +// +///** Adds a module at the beginning of the list. Function uses the insert() function. +// * \param[in] tModule - address of the module to add +// */ +//void module_list::push_front(module* tModule) +//{ +// insert(0, tModule); +//} +// +///** Adds a module at the end of a list. Function uses the insert() function to perform +// * the requested operation. +// * \param[in] tModule - address of a module to add +// */ +//void module_list::push_back(module* tModule) +//{ +// insert((size_t)-1, tModule); +//} +// +//// repositioning modules in a vector +///** Changes the positions of the 2 modules (given by their ID's) - swaps them. +// * \param[in] t1, t2 - module ID's of the modules to be swapped +// */ +//void module_list::swap(moduleid_t t1, moduleid_t t2) +//{ +// m_lock.lock(); +// std::vector::iterator it1, it2, it; +// +// // enum through the all modules +// if (find_module(t1, t2, &it1, &it2)) +// swap(it1, it2); +// else +// m_pmid->plog->logd("[module_list] Swapping modules failed - one of the modules not found (id1=" MODIDXFMT ", id2=" MODIDXFMT ")", t1, t2); +// +// m_lock.unlock(); +//} +// +///** Changes the positions of the 2 modules (given by their positions) - swaps them. +// * \param[in] tPos1, tPos2 - positions of the modules to be swapped +// */ +//void module_list::swap(size_t tPos1, size_t tPos2) +//{ +// assert(tPos1 <= m_pvModules->size() && tPos2 <= m_pvModules->size()); +// +// m_lock.lock(); +// swap(m_pvModules->begin()+tPos1, m_pvModules->begin()+tPos2); +// m_lock.unlock(); +//} +// +///** Moves the module (given by it's ID) to the position given as a second parameter. +// * \param[in] tID - ID of a module to move +// * \param[in] tNewPos - new position at which the module should appear +// */ +//void module_list::move(moduleid_t tID, size_t tNewPos) +//{ +// assert(tNewPos < m_pvModules->size()); +// +// m_lock.lock(); +// +// std::vector::iterator it; +// if (find_module(tID, &it)) +// { +// module* mod=(*it); +// m_pvModules->erase(it); +// m_pvModules->insert(m_pvModules->begin()+tNewPos, mod); +// } +// +// m_lock.unlock(); +//} +// +///** Sorts the modules in order given by the vector passed as the parameter. +// * \param[in] vIDs - address of a vector that contains sorted (in the requested way) +// * module ID's. +// */ +//void module_list::sort(std::vector* vIDs) +//{ +// m_lock.lock(); +// +// // clear the vector +// m_pvModules->clear(); +// +// // and now process the data from map +// module* mod; +// for (std::vector::iterator it=vIDs->begin();it != vIDs->end();it++) +// { +// if ( (mod=find(*it)) != NULL_MODULE ) +// m_pvModules->push_back(mod); +// } +// +// m_lock.unlock(); +//} +// +///** Function fills the vector given as the parameter with the modules ID's +// * with the order as in the current list. +// * \param[in] vIDs - address of a vector that will receive the module ID's. +// */ +//void module_list::get_positions(std::vector* vIDs) +//{ +// m_lock.lock(); +// +// for (std::vector::iterator it=m_pvModules->begin();it != m_pvModules->end();it++) +// { +// vIDs->push_back((*it)->get_id()); +// } +// +// m_lock.unlock(); +//} +// +///** Returns the current count of modules contained in the list. +// * \return Count of modules. +// */ +//size_t module_list::size() +//{ +// m_lock.lock(); +// size_t tLen=m_pvModules->size(); +// m_lock.unlock(); +// +// return tLen; +//} +// +//// removing +///** Removes a module from a list (given it's ID). It means uninitializing the module +// * and then closing it. If the module is being currently used (see module::acquire() and module::release()) +// * then it is not removed (except when the bForce flag is specified). In case of error +// * the exception is thrown or false is returned. +// * \param[in] tID - id of a module to remove +// * \param[in] bForce - if true then the module reference count >0 does not block removing. +// * \return True if everything went ok, false otherwise. +// */ +//bool module_list::remove(moduleid_t tID, bool bForce) +//{ +// // find the tID module iterator +// bool bRes; +// +// m_lock.lock(); +// +// try +// { +// std::vector::iterator it; +// if (find_module(tID, &it)) +// bRes=remove(it, bForce); +// else +// { +// m_pmid->plog->logd("[module_list] Cannot remove module (id=" MODIDXFMT ") - it does not exist", tID); +// bRes=false; +// } +// +// m_lock.unlock(); +// } +// catch(...) +// { +// m_lock.unlock(); +// throw; +// } +// +// return bRes; +//} +// +///** Removes a module from a list (given it's position). It means uninitializing the module +// * and then closing it. If the module is being currently used (see module::acquire() and module::release()) +// * then it is not removed (except when the bForce flag is specified). In case of error +// * the exception is thrown or false is returned. +// * \param[in] tPos - position of a module to remove +// * \param[in] bForce - if true then the module reference count >0 does not block removing. +// * \return True if everything went ok, false otherwise. +// */ +//bool module_list::remove(size_t tPos, bool bForce) +//{ +// assert(tPos <= m_pvModules->size()); +// +// m_lock.lock(); +// +// bool bRes; +// try +// { +// bRes=remove(m_pvModules->begin()+tPos, bForce); +// m_lock.unlock(); +// } +// catch(...) +// { +// m_lock.unlock(); +// throw; +// } +// +// return bRes; +//} +// +///** Removes all the modules from a list. Depending the bForce parameter either all +// * modules are removed or only the unused ones. When error is encountered while removing +// * individual modules then it is logged to the log file and removed. +// * \param[in] bForce - specifies if the modules should be removed only if they are unused (false) +// * or always (true). +// */ +//void module_list::remove_all(bool bForce) +//{ +// m_lock.lock(); +// std::vector::iterator it=m_pvModules->end(); +// while (it != m_pvModules->begin()) +// { +// try +// { +// remove(--it, bForce); +// } +// catch(exception& e) +// { +// m_pmid->plog->logd("[module_list] Caught an exception in module_list::remove_all() while removing module from a list.Ignoring."); +// LOG_EXCEPTION(e, m_pmid->plog); +// e->del(); +// } +// } +// m_lock.unlock(); +//} +// +//////////////////////////////////////// +///** Removes a module from a list (given it's internal iterator). It means uninitializing the module +// * and then closing it. If the module is being currently used (see module::acquire() and module::release()) +// * then it is not removed (except when the bForce flag is specified). In case of error +// * the exception is thrown or false is returned. +// * \param[in] it - iterator that specifies position of a module in the internal vector +// * \param[in] bForce - if true then the module reference count >0 does not block removing +// * \return True if everything went ok, false otherwise. +// */ +//bool module_list::remove(std::vector::iterator it, bool bForce) +//{ +// module* mod=(*it); +// moduleid_t tid=mod->get_id(); +// +// m_pmid->plog->logi("[module_list] Trying to remove module (id=" MODIDXFMT ")", tid); +// +// if (mod->get_refcount() != 0) +// { +// if (!bForce) +// { +// m_pmid->plog->logw("[module_list] Cannot remove module (id=" MODIDXFMT ") due to module's reference count=" LFMT, tid, mod->get_refcount()); +// return false; // cannot unload +// } +// else +// m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") with reference count=" LFMT, tid, mod->get_refcount()); +// } +// +// // uninit&close the module - both can throw an exception +// try +// { +// if (!mod->uninit()) +// { +// // cannot uninit module +// if (!bForce) +// { +// m_pmid->plog->logw("[module_list] Cannot remove module (id=" MODIDXFMT ") due to uninit problems", tid); +// return false; +// } +// else +// m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") knowing that module uninit proc failed", tid); +// } +// } +// catch(exception& e) +// { +// if (!bForce) +// throw; // rethrow the exception - will be reported by some other func +// else +// { +// m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") knowing that module uninit proc had thrown an exception", tid); +// LOG_EXCEPTION(e, m_pmid->plog); +// e->del(); +// } +// } +// +// // try to close module +// try +// { +// mod->close(); +// } +// catch(exception& e) +// { +// if (!bForce) +// throw; +// else +// { +// m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") knowing that module close proc had thrown an exception", tid); +// LOG_EXCEPTION(e, m_pmid->plog); +// e->del(); +// } +// } +// +// // remove the module from the list +// m_pvModules->erase(it); +// std::map::iterator mit=m_pmModules->find(tid); +// if (mit != m_pmModules->end()) +// m_pmModules->erase(mit); +// +// m_pmid->plog->logi("[module_list] Module (id=" MODIDXFMT ") removed successfully", tid); +// return true; +//} +// +///** Changes the placement of the two modules (given by their iterators in the internal vector). +// * \param[in] it1, it2 - positions of the modules in the internal vector +// */ +//void module_list::swap(std::vector::iterator it1, std::vector::iterator it2) +//{ +// module* mod=(*it1); +// (*it1)=(*it2); +// (*it2)=mod; +//} +// +///** Searches for a specified module (by it's ID) and stores the iterator in the iterator +// * passed as the parameter. +// * \param[in] tID - ID of the module to search for +// * \param[out] pit - address of an iterator that is about to receive the module position +// * \return True if the module was found, false otherwise. +// */ +//bool module_list::find_module(moduleid_t tID, std::vector::iterator* pit) +//{ +// // find the requested module +// std::vector::iterator it; +// (*pit)=m_pvModules->end(); +// +// for (it=m_pvModules->begin();it != m_pvModules->end();it++) +// { +// // check if this is one of the requested modules +// if ((*it)->get_id() == tID) +// { +// (*pit)=it; +// break; +// } +// } +// +// return ((*pit) != m_pvModules->end()); +//} +// +///** Searches for a specified modules (by their ID's) and stores the iterators in the iterators +// * passed as the parameters. +// * \param[in] tID1, tID2 - ID's of the modules to search for +// * \param[out] pit1, pit2 - address of an iterators that are about to receive the module positions +// * \return True if the module was found, false otherwise. +// */ +//bool module_list::find_module(moduleid_t tID1, moduleid_t tID2, std::vector::iterator* pit1, std::vector::iterator* pit2) +//{ +// // find the requested module +// std::vector::iterator it; +// (*pit1)=(*pit2)=m_pvModules->end(); +// +// for (it=m_pvModules->begin();it != m_pvModules->end();it++) +// { +// // check if this is one of the requested modules +// if ((*it)->get_id() == tID1) +// (*pit1)=it; +// else if ((*it)->get_id() == tID2) +// (*pit2)=it; +// } +// +// return ((*pit1) != m_pvModules->end() && (*pit2) != m_pvModules->end()); +//} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/module.cpp =================================================================== diff -u -N --- ext/libicpf/src/module.cpp (revision 6dae57f5e7aeeb965bc018024d8360069f6e15c1) +++ ext/libicpf/src/module.cpp (revision 0) @@ -1,1186 +0,0 @@ -///*************************************************************************** -// * Copyright (C) 2004-2006 by J�zef Starosczyk * -// * ixen@copyhandler.com * -// * * -// * This program is free software; you can redistribute it and/or modify * -// * it under the terms of the GNU Library General Public License as * -// * published by the Free Software Foundation; either version 2 of the * -// * License, or (at your option) any later version. * -// * * -// * This program 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 General Public License for more details. * -// * * -// * You should have received a copy of the GNU Library General Public * -// * License along with this program; if not, write to the * -// * Free Software Foundation, Inc., * -// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * -// ***************************************************************************/ -///** \file module.cpp -// * \brief File contain an implementation of the module (and related) classes. -// */ -// -#include "module.h" -//#include -//#include "err_codes.h" -// -//#ifndef _WIN32 -// #include -//#endif -// -BEGIN_ICPF_NAMESPACE -// -//#define m_pmMods ((std::map*)m_pMods) -// -///** Constructs a module_param class and initializes all the internal members -// * to their initial values. -// */ -//module_param::module_param() -//{ -// m_midModuleID=NULL_MODULE; -// m_uiPropStart=0; -//} -// -///** Destructs the module_param class. -// */ -//module_param::~module_param() -//{ -//} -// -///** Locks the class (multi-threaded access). -// */ -//void module_param::lock() -//{ -// m_lock.lock(); -//} -// -///** Unlocks the class (multi-threaded access). -// */ -//void module_param::unlock() -//{ -// m_lock.unlock(); -//} -// -///** Returns a module id associated with this class. -// * \return Module ID -// * \note The usage of mutex inside of this function is unnecessary, because -// * the module id is not supposed to change. -// */ -//moduleid_t module_param::get_moduleid() const -//{ -// return m_midModuleID; -//} -// -///** Reads the properties from the configuration object (config class). Function -// * implemented as virtual - it does not do anything in this (base) class. Should -// * be implemented in the derived classes. Function should read the properties registered -// * earlier with register_properties() from a given config object and initialize -// * the internal structure data (m_pParams). The given structure should be allocated -// * earlier (ie. in the constructor of the derived class). -// * Calling this function should be the first operation done in the derived class' function. -// * \param[in] pcfg - pointer to the config object to read the properties from -// */ -//void module_param::read_config(config* /*pcfg*/) -//{ -//} -// -///** Function writes the internal configuration options to the given configuration -// * object (config class). Declared virtual and the base implementation does not -// * do anything. Should be implemented in the derived classes. The purpose of this -// * function is to write data from the internal data structure (m_pParams) to the -// * given config class. The structure should be allocated and initialized earlier. -// * Calling this function should be the first operation done in the derived class' function. -// * \param[in] pcfg - pointer to the config object to write the properties to -// */ -//void module_param::write_config(config* /*pcfg*/) -//{ -//} -// -///** Function registers the properties used in the internal data structure (m_pParams) -// * to the given configuration object (config class). Function declared as virtual and -// * the base implementation does not do anything. In derived classes this function should -// * register the properties with the config object and store the first returned property ID -// * in the m_ulPropStart internal member. -// * Calling this function should be the first operation done in the derived class' function. -// * \note When registering properties user should lock the config object to make sure -// * the ID's will be the subsequent numbers and not pseudo-random ones. -// * \param[in] pcfg - pointer to the configuration object with which the props should be registered. -// */ -//void module_param::register_properties(config* /*pcfg*/) -//{ -//} -// -//// store/restore from/to a file (serializer) -///** Function stores the internal data structure settings to the external file (file class). -// * Declared as virtual - base implementation does not do anything. In derived classes this -// * function should store the members of the internal structure (m_pParams) in the given -// * file object in some order (that must be used also in load() function). -// * Calling this function should be the first operation done in the derived class' function. -// * \param[in] ser - serialization object to write the data to -// */ -//void module_param::store(file& /*ser*/) -//{ -//} -// -///** Function loads the internal data structure from a file (file class). Declared as -// * virtual - base implementation does not do anything. In derived classes function -// * should read the properties from a given file object (in the order used in store() function). -// * Calling this function should be the first operation done in the derived class' function. -// * \param[in] ser - serialization object that contains the data to be read -// */ -//void module_param::load(file& /*ser*/) -//{ -//} -// -///** Standard constructor - does nothing currently. -// */ -//modparam_list::modparam_list() -//{ -// m_pMods=new std::map; -//} -// -///** Standard destructor - clears the internal list of module_params. Also, each entry -// * is being deleted before clearing. If you want to preserve the elements from being deleted - -// * use the clear(false) method before destrying this object. -// */ -//modparam_list::~modparam_list() -//{ -// clear(true); -// delete m_pmMods; -//} -// -///** Inserts a module_param to this list. -// * \param[in] pEntry - address of a module_param class to be inserted. It should be allocated by -// * the 'new' operator if you would like to use bDelete parameter set in other -// * methods. -// */ -//void modparam_list::insert(module_param* pEntry) -//{ -// assert(pEntry); -// m_lock.lock(); -// m_pmMods->insert(std::pair(pEntry->get_moduleid(), pEntry)); -// m_lock.unlock(); -//} -// -///** Removes a module from the list. Also delete a module_param if specified. -// * \param[in] tEntry - module id associated with an entry to remove -// * \param[in] bDelete - specifies, if the delete operator should be called on an entry -// * before removing it from the list. -// * \return If the entry was successfully removed (true) or not (false). -// */ -//bool modparam_list::remove(moduleid_t tEntry, bool bDelete) -//{ -// m_lock.lock(); -// std::map::iterator it = m_pmMods->find(tEntry); -// if (it != m_pmMods->end()) -// { -// // delete if needed -// if (bDelete) -// delete it->second; -// m_pmMods->erase(it); -// m_lock.unlock(); -// return true; -// } -// else -// { -// m_lock.unlock(); -// return false; -// } -//} -// -///** Removes all the items from this list. -// * \param[in] bDelete - if true, then all the items will be 'delete''d before removing. -// */ -//void modparam_list::clear(bool bDelete) -//{ -// m_lock.lock(); -// if (bDelete) -// { -// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) -// { -// delete it->second; -// } -// } -// -// m_pmMods->clear(); -// m_lock.unlock(); -//} -// -///** Searches for a module_param associated with a given module id. -// * \param[in] mid - module id to search for -// * \return Pointer to a module_param class, or NULL if not found. -// */ -//module_param* modparam_list::find(moduleid_t mid) -//{ -// m_lock.lock(); -// std::map::iterator it = m_pmMods->find(mid); -// if (it != m_pmMods->end()) -// { -// m_lock.unlock(); -// return it->second; -// } -// else -// { -// m_lock.unlock(); -// return NULL; -// } -//} -// -///** A group wrapper over the module_param::read_config(). Calls the method for each of the module_param's. -// * \param[in] pcfg - pointer to a configuration object to read the data from. -// */ -//void modparam_list::read_config(config* pcfg) -//{ -// // read the config for all entries -// m_lock.lock(); -// try -// { -// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) -// { -// it->second->read_config(pcfg); -// } -// } -// catch(...) -// { -// m_lock.unlock(); -// throw; -// } -// m_lock.unlock(); -//} -// -///** A group wrapper over the module_param::write_config(). Calls the method for each of the module_param's. -// * \param[in] pcfg - pointer to a configuration object to write the data to. -// */ -//void modparam_list::write_config(config* pcfg) -//{ -// m_lock.lock(); -// try -// { -// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) -// { -// it->second->write_config(pcfg); -// } -// } -// catch(...) -// { -// m_lock.unlock(); -// throw; -// } -// m_lock.unlock(); -//} -// -///** A group wrapper over the module_param::register_properties(). Calls the method for each of the module_param's. -// * \param[in] pcfg - pointer to a configuration object to register the properties with. -// */ -//void modparam_list::register_properties(config* pcfg) -//{ -// m_lock.lock(); -// try -// { -// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) -// { -// it->second->register_properties(pcfg); -// } -// } -// catch(...) -// { -// m_lock.unlock(); -// throw; -// } -// m_lock.unlock(); -//} -// -///** A group wrapper over the module_param::store(). Calls the method for each of the module_param's. -// * \param[in] ser - a serialization object to write the data to -// */ -//void modparam_list::store(file& ser) -//{ -// m_lock.lock(); -// try -// { -// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) -// { -// it->second->store(ser); -// } -// } -// catch(...) -// { -// m_lock.unlock(); -// throw; -// } -// m_lock.unlock(); -//} -// -///** A group wrapper over the module_param::load(). Calls the method for each of the module_param's. -// * \param[in] ser - a serialization object to read the data from -// */ -//void modparam_list::load(file& ser) -//{ -// m_lock.lock(); -// try -// { -// for (std::map::iterator it=m_pmMods->begin();it != m_pmMods->end();it++) -// { -// it->second->load(ser); -// } -// } -// catch(...) -// { -// m_lock.unlock(); -// throw; -// } -// m_lock.unlock(); -//} -// -///////////////////////////////////////////////////////////////////////////// -///** Constructor - makes a copy of the MODULE_INITDATA passed as the parameter -// * and stores the given flags in the internal member. Also nullifies all the other class -// * members. The module information is initialized with NULL values and for internal -// * modules this should be corrected in the constructor of the derived class. -// * \param[in] pData - pointer to the structure with some parameters (the copy of it -// * will be stored in the internal member - not the pointer itself). -// * \param[in] uiFlags - module flags that are about to be stored in the internal member (MF_*) -// */ -//module::module(const MODULE_INITDATA* pData, uint_t uiFlags) -//{ -// m_pmp=NULL; -// m_pmid=pData; -// m_ulFlags=uiFlags; -// m_lRefCount=0; -// -// // module information -// m_mi.uiInfoLen=sizeof(MODULE_INFO); -// m_mi.midID=NULL_MODULE; -// m_mi.szAuthor[0]='\0'; -// m_mi.szName[0]='\0'; -// m_mi.szVersion[0]='\0'; -// m_mi.uiType=MT_NONE; -// -// m_hModule=NULL; -// m_pszPath=NULL; -// m_pfnGetInfo=NULL; -// m_pfnInit=NULL; -// m_pfnUninit=NULL; -// m_pfnAllocModparam=NULL; -//} -// -///** Destructor. Tries to close the module (close(true) function). If the closing -// * function throws an exception it is caught, logged to the log file (MODULE_INITDATA) -// * and the exception is removed. -// */ -//module::~module() -//{ -// try -// { -// close(true); -// } -// catch(exception* e) -// { -// LOG_EXCEPTION(e, m_pmid->plog); -// e->del(); -// } -//} -// -//// external modules support (called only for the external modules) -///** Function opens the external file as the program module. After successful -// * file opening this function loads all exports from the module (using load_exports() -// * function) and caches the module information in the internal member if all goes ok. -// * If something goes wrong the exception is thrown. All information (excluding exceptions -// * are logged to the log file (MODULE_INITDATA)). -// * \param[in] pszPath - full path to the module that is about to be loaded -// */ -//void module::open(const char_t* pszPath) -//{ -// assert(m_ulFlags & MF_EXTERNAL); // only for the external modules -// -// m_pmid->plog->logi("[module] Loading external module " STRFMT, pszPath); -// -// // try to load external library -//#ifdef _WIN32 -// if ( (m_hModule=::LoadLibrary(pszPath)) == NULL) -// THROW(exception::format("Cannot load external module " STRFMT, pszPath), PE_CANNOTLOAD, GetLastError(), 0); -//#else -// if ( (m_hModule=dlopen(pszPath, RTLD_LAZY)) == NULL) -// THROW(exception::format("Cannot load external module " STRFMT " (" STRFMT ")", pszPath, dlerror()), PE_CANNOTLOAD, 0, 0); -//#endif -// -// m_pmid->plog->logi("[module] External module loaded successfully (handle " PTRFMT ")", m_hModule); -// -// // load all needed exports (function must throw if export does not exist) -// m_pmid->plog->logd("[module] Loading exports for the module (handle " PTRFMT ")", m_hModule); -// load_exports(); -// m_pmid->plog->logd("[module] Exports loaded for the module (handle " PTRFMT ")", m_hModule); -// -// // cache the module information -// m_pmid->plog->logd("[module] Caching module (handle " PTRFMT ") information", m_hModule); -// (*m_pfnGetInfo)(&m_mi); -// m_pmid->plog->logd("[module] Cached module (handle " PTRFMT ") information - id: " MODIDFMT ", type: " ULFMT ", name: " STRFMT ", version: " STRFMT ", author: " STRFMT "", m_hModule, m_mi.midID, m_mi.uiType, m_mi.szName, m_mi.szVersion, m_mi.szAuthor); -// -// // store the path -// m_pszPath=new char_t[strlen(pszPath)+1]; -// strcpy(m_pszPath, pszPath); -//} -// -//// close the module - it's safe to call it more than once -///** Closes the external module. At first it uninitializes the module that is about to -// * be unloaded and then closes the module and resets all(except the module info) the -// * internal data. Function is safe to be called more than once. If any problem occur -// * there is the exception thrown. -// * \param[in] bFullDestruct - should be true only in destructor. Means deleting the path string -// * before uninitialization (and not after as with false). -// */ -//void module::close(bool bFullDestruct) -//{ -// // if called from a destructor - release some of the memory allocated -// if (bFullDestruct) -// { -// // delete the path allocated earlier -// delete [] m_pszPath; -// m_pszPath=NULL; -// } -// -// // uninit the module if wasn't already -// uninit(); -// -// // release stuff related to external module -// if (m_hModule != NULL) -// { -// m_pmid->plog->logd("[module] Unloading an external module (handle " PTRFMT ")", m_hModule); -// -//#ifdef _WIN32 -// if (!::FreeLibrary(m_hModule)) -// THROW(exception::format("Cannot unload the external module (handle " PTRFMT ")", m_hModule), PE_CANNOTUNLOAD, GetLastError(), 0); -//#else -// if (dlclose(m_hModule) != 0) -// THROW(exception::format("Cannot unload the external module - " STRFMT " (handle " PTRFMT ")", dlerror(), m_hModule), PE_CANNOTUNLOAD, 0, 0); -//#endif -// m_pmid->plog->logd("[module] ...external module unloaded (handle " PTRFMT ")", m_hModule); -// } -// -// m_hModule=NULL; -// m_pfnGetInfo=NULL; -// m_pfnInit=NULL; -// m_pfnUninit=NULL; -// -// // release a memory when sure the module has been succesfully freed -// if (!bFullDestruct) -// { -// delete [] m_pszPath; -// m_pszPath=NULL; -// } -//} -// -///** Retrieves the module information (author, ... as in MODULE_INFO struct). This function -// * does not use the internal cache for external modules - there is always a call made to the -// * module. Internal modules always use caching (it's their only info source). -// * \param[out] pInfo - receives the module information -// */ -//void module::get_info(MODULE_INFO* pInfo) -//{ -// if (m_ulFlags & MF_EXTERNAL) -// { -// assert(m_hModule); -// -// (*m_pfnGetInfo)(pInfo); -// } -// else -// *pInfo=m_mi; -//} -// -///** Function initializes the module. For external modules the module's init() function will be -// * called. For internal modules this should be the first function called from within the init() -// * function of the derived class. If the function fails it can return false or throw an exception. -// * Function is safe to be called multiple times - the real init() functions will be called -// * only once. -// * \note In the internal modules the init() function in the derived classes should check for -// * the MF_INITIALIZED flag and do not perform any initialization if flag is set to 0. -// * \param[in] pData - module initialization data - should be the same as in constructor -// * \return True if the function succeeds, false otherwise. -// */ -//bool module::init(const MODULE_INITDATA* pData) -//{ -// // return if already initialized -// if (m_ulFlags & MF_INITIALIZED) -// return true; -// -// if (m_ulFlags & MF_EXTERNAL) -// { -// m_pmid->plog->logi("[module] Making external module initialization (id=" MODIDXFMT ")...", get_id()); -// if ((*m_pfnInit)(pData, &m_pmp)) -// { -// m_pmid->plog->logi("[module] ...external module initialized successfully (id=" MODIDXFMT ").", get_id()); -// m_ulFlags |= MF_INITIALIZED; -// return true; -// } -// else -// { -// m_pmid->plog->logi("[module] ...external module initialization failed (id=" MODIDXFMT ").", get_id()); -// return false; -// } -// } -// else -// { -// m_ulFlags |= MF_INITIALIZED; -// return true; -// } -//} -// -//// uninitializes a module -//// safe to call multiple times (ext module uninit() func will be called only once) -///** Uninitializes a module. This is the first function to be called in uninit() function -// * of the derived classes (internal modules). For external modules this function calls the -// * module's init() function. This function is safe to be called multiple times - the real -// * initialization functions will be called only once. On error either false value can be returned -// * or exception will be thrown. -// * \note For internal modules - this function at first should check if the module has been -// * initialized (by checking the MF_INITIALIZED flag - it must be set). If it is not then -// * no uninitialization should be done. -// * \return True if all went ok, false otherwise. -// */ -//bool module::uninit() -//{ -// if (m_ulFlags & MF_INITIALIZED) -// { -// if (m_ulFlags & MF_EXTERNAL) -// { -// m_pmid->plog->logi("[module] Making external module uninitialization (id=" MODIDXFMT ")...", get_id()); -// if ((*m_pfnUninit)(&m_pmp)) -// { -// m_pmid->plog->logi("[module] ...external module uninitialization succeeded (id=" MODIDXFMT ").", get_id()); -// -// // delete the module parameters/informations if allocated -// cleanup(); -// -// return true; -// } -// else -// { -// m_pmid->plog->logi("[module] ...external module uninitialization failed (id=" MODIDXFMT ").", get_id()); -// return false; -// } -// } -// else -// { -// // delete the module parameters/informations if allocated -// cleanup(); -// -// return true; -// } -// } -// else -// return true; // already uninitialized -//} -// -///** Allocates a module_param for this module. External modules should allocate the needed class -// * and return it in the alloc_modparam(). Internal modules do not need to call this function. -// * And overloaded function should just alloc the class and return it. -// * \return Allocated class. Note that the returned pointer is being cast to module_param, but most -// * likely this will be another class that has module_param as a base class. -// */ -//module_param* module::alloc_modparam() -//{ -// assert(m_ulFlags & MF_INITIALIZED); -// if (m_ulFlags & MF_EXTERNAL) -// return (*m_pfnAllocModparam)(); -// else -// return NULL; -//} -// -//// called to load all exported functions (must be called for any derived load_exports()) -///** Loads the exports associated with a given type of module. This should be the first function -// * to be called in load_exports() of derived classes. If a specified exports does not -// * exist in a module an exception is thrown. -// * \note Use the MAP_EXPORT macro here to assign together the function name to the -// * function address. -// */ -//void module::load_exports() -//{ -// MAP_EXPORT(m_hModule, m_pfnGetInfo, "get_info"); -// MAP_EXPORT(m_hModule, m_pfnInit, "init"); -// MAP_EXPORT(m_hModule, m_pfnUninit, "uninit"); -// MAP_EXPORT(m_hModule, m_pfnAllocModparam, "alloc_modparam"); -//} -// -///** Cleanup function used in uninit() to make sure the module_param stuff -// * is freed if needed. Also resets the MF_INITIALIZED flag. -// */ -//void module::cleanup() -//{ -// // delete the module parameters/informations if allocated -// if (m_pmp) -// { -// m_pmp->write_config(m_pmid->pcfg); -// delete m_pmp; -// m_pmp=NULL; -// } -// -// m_ulFlags &= ~MF_INITIALIZED; -//} -// -/////////////////////////////////////////////////////////////////// -//#define m_pvModules ((std::vector*)m_vModules) -//#define m_pmModules ((std::map*)m_mModules) -// -///** Constructor - makes a copy of the MODULE_INITDATA structure and -// * stores it in the internal member. -// */ -//module_list::module_list(const MODULE_INITDATA* pData) -//{ -// m_pmid=pData; -// m_vModules=(void*)new std::vector; -// m_mModules=(void*)new std::map; -//} -// -///** Destructor - calls the remove_all(true) to get rid of all modules before -// * class is destroyed. Any exception thrown in the remove_all() function is being -// * logged to a log file (MODULE_INITDATA) and the exception is deleted. -// */ -//module_list::~module_list() -//{ -// try -// { -// remove_all(true); -// } -// catch(exception& e) -// { -// LOG_EXCEPTION(e, m_pmid->plog); -// e->del(); -// } -// -// delete m_pvModules; -// delete m_pmModules; -//} -// -//#ifndef _WIN32 -///** Helper function for filtering filesystem entries. It allows selecting only the -// * filesystem entries that appears to be the proper modules. Function used in linux. -// * \param[in] pent - directory entry to process -// * \return >0 for the entry to be accepted, 0 if not. -// */ -//int_t module_list::mod_filter(const struct dirent *pent) -//{ -// size_t tLen=strlen(pent->d_name), tExtLen=strlen(MODULE_EXT); -// if (tLen >= tExtLen && strcmp(pent->d_name+tLen-tExtLen, MODULE_EXT) == 0) -// return 1; -// else -// return 0; -//} -//#endif -// -///** Function scans a specified directory for the files that looks like modules. -// * Macro MODULE_EXT specifies the file extension (in format ".ext") used in modules. -// * Only modules that types matches (even partially) the specified type are added to -// * the list. All the performed operations are logged into the log file. -// * There are no exception throws or return values. -// * \param[in] pszPath - path to the directory with modules (must be trailed with '\\' or '/' - system dependent) -// * \param[in] uiType - types of modules to be added to the list -// */ -//void module_list::scan(const char_t* pszPath, uint_t uiType) -//{ -// m_pmid->plog->logi("[module_list] Scanning directory " STRFMT " for external modules of type " ULFMT, pszPath, uiType); -// uint_t uiCount=0; // count of modules found -// -//#ifdef _WIN32 -// // create full search path -// char_t sz[_MAX_PATH]; -// _snprintf(sz, _MAX_PATH, STRFMT "*" STRFMT, pszPath, MODULE_EXT); -// size_t tLen=strlen(pszPath); -// -// WIN32_FIND_DATA wfd; -// HANDLE hFind=::FindFirstFile(sz, &wfd); -// if (hFind != INVALID_HANDLE_VALUE) -// { -// BOOL bFound=TRUE; -// while (bFound) -// { -// // append a name to the input path (NOTE: it's a small optimization so it looks like there's something's missing). -// strcpy(sz+tLen, wfd.cFileName); -//#else -// dirent **ppde; -// char_t sz[PATH_MAX]; -// strcpy(sz, pszPath); -// size_t tLen=strlen(pszPath); -// -// int_t iCnt=scandir(pszPath, &ppde, mod_filter, NULL); -// while (iCnt--) -// { -// strcpy(sz+tLen, ppde[iCnt]->d_name); -//#endif -// module* pmod=new module(m_pmid, true); -// try -// { -// pmod->open(sz); -// -// if (pmod->get_type() & uiType) -// { -// push_back(pmod); -// uiCount++; -// } -// else -// delete pmod; // also calls module::close(), but does not throw an exception -// } -// catch(exception e) -// { -// m_pmid->plog->logw("[module_list] Caught an exception while trying to open a module (path=" STRFMT ").Ignoring module.", sz); -// LOG_EXCEPTION(e, m_pmid->plog); -// -// e->del(); -// delete pmod; -// } -//#ifdef _WIN32 -// bFound=::FindNextFile(hFind, &wfd); -// } -// -// if (!::FindClose(hFind)) -// m_pmid->plog->logd("[module_list] Cannot close a find handle in module::open(), system error " ULFMT ". Ignoring.", GetLastError()); -// } -// -//#else -// free(ppde[iCnt]); -// } -// free(ppde); -//#endif -// m_pmid->plog->logi("[module_list] Completed scanning for external modules in directory " STRFMT ". Found " ULFMT " modules with type matching " ULFMT, pszPath, uiCount, uiType); -//} -// -//// getting a module from a vector -///** Searches for a module in a list given it's ID. When using this function -// * user should fully lock the module_list and before releasing the lock he should -// * use module::acquire() to make sure the module won't be unloaded when being used. -// * \param[in] mid - module ID to find in the list -// * \return Pointer to the module or NULL if module not found. -// */ -//module* module_list::find(moduleid_t mid) -//{ -// module* mod; -// -// m_lock.lock(); -// std::map::iterator it=m_pmModules->find(mid); -// if (it != m_pmModules->end()) -// mod=(*it).second; -// else -// mod=NULL; -// m_lock.unlock(); -// -// return mod; -//} -// -///** Function returns a module at a specified position. When using this function -// * user should lock the entire module_list and before releasing lock he should -// * use module::acquire() function to ensure the module to remain loaded. -// * \param[in] tPos - index of the module to return address of; the position must -// * be in range. The debug version of program asserts if range exceeded. -// * \return Address of a module. -// */ -//module* module_list::at(size_t tPos) -//{ -// assert(tPos < m_pvModules->size()); -// -// m_lock.lock(); -// module* mod=m_pvModules->at(tPos); -// m_lock.unlock(); -// -// return mod; -//} -// -//// adding a new items (modules) -///** Function inserts a module into the list at the specified position. Module is being -// * initialized before insertion (if not already initialized). An exception* is thrown -// * if any error occurs. -// * \param[in] tPos - position in the list to insert the module at (-1 = at the end) -// * \param[in] tModule - address of a module to be inserted into the list -// */ -//void module_list::insert(size_t tPos, module* tModule) -//{ -// m_pmid->plog->logd("[module_list] Initializing the module (id=" MODIDXFMT ")", tModule->get_id()); -// tModule->init(m_pmid); // can throw an exception -// -// m_pmid->plog->logd("[module_list] Inserting the module (id=" MODIDXFMT ") to the module list at the position " ULPTRXFMT, tModule->get_id(), tPos); -// -// m_lock.lock(); -// -// try -// { -// std::map::iterator it=m_pmModules->find(tModule->get_id()); -// if (it != m_pmModules->end()) -// { -// THROW(exception::format("Module with a specified id=" MODIDXFMT " (name: " STRFMT ", version: " STRFMT ", author: " STRFMT ") already exists (name: " STRFMT ", version: " STRFMT ", author: " STRFMT ")", -// tModule->get_id(), tModule->get_name(), tModule->get_version(), tModule->get_author(), -// (*it).second->get_name(), (*it).second->get_version(), (*it).second->get_author()), -// PE_DUPLICATEPLUG, 0, 0); -// } -// else -// { -// if (tPos != (size_t)-1) -// { -// assert(tPos <= m_pvModules->size()); -// m_pvModules->insert(m_pvModules->begin()+tPos, tModule); -// } -// else -// m_pvModules->push_back(tModule); -// -// m_pmModules->insert(std::pair(tModule->get_id(), tModule)); -// } -// -// m_lock.unlock(); -// } -// catch(...) -// { -// m_lock.unlock(); -// throw; -// } -//} -// -///** Adds a module at the beginning of the list. Function uses the insert() function. -// * \param[in] tModule - address of the module to add -// */ -//void module_list::push_front(module* tModule) -//{ -// insert(0, tModule); -//} -// -///** Adds a module at the end of a list. Function uses the insert() function to perform -// * the requested operation. -// * \param[in] tModule - address of a module to add -// */ -//void module_list::push_back(module* tModule) -//{ -// insert((size_t)-1, tModule); -//} -// -//// repositioning modules in a vector -///** Changes the positions of the 2 modules (given by their ID's) - swaps them. -// * \param[in] t1, t2 - module ID's of the modules to be swapped -// */ -//void module_list::swap(moduleid_t t1, moduleid_t t2) -//{ -// m_lock.lock(); -// std::vector::iterator it1, it2, it; -// -// // enum through the all modules -// if (find_module(t1, t2, &it1, &it2)) -// swap(it1, it2); -// else -// m_pmid->plog->logd("[module_list] Swapping modules failed - one of the modules not found (id1=" MODIDXFMT ", id2=" MODIDXFMT ")", t1, t2); -// -// m_lock.unlock(); -//} -// -///** Changes the positions of the 2 modules (given by their positions) - swaps them. -// * \param[in] tPos1, tPos2 - positions of the modules to be swapped -// */ -//void module_list::swap(size_t tPos1, size_t tPos2) -//{ -// assert(tPos1 <= m_pvModules->size() && tPos2 <= m_pvModules->size()); -// -// m_lock.lock(); -// swap(m_pvModules->begin()+tPos1, m_pvModules->begin()+tPos2); -// m_lock.unlock(); -//} -// -///** Moves the module (given by it's ID) to the position given as a second parameter. -// * \param[in] tID - ID of a module to move -// * \param[in] tNewPos - new position at which the module should appear -// */ -//void module_list::move(moduleid_t tID, size_t tNewPos) -//{ -// assert(tNewPos < m_pvModules->size()); -// -// m_lock.lock(); -// -// std::vector::iterator it; -// if (find_module(tID, &it)) -// { -// module* mod=(*it); -// m_pvModules->erase(it); -// m_pvModules->insert(m_pvModules->begin()+tNewPos, mod); -// } -// -// m_lock.unlock(); -//} -// -///** Sorts the modules in order given by the vector passed as the parameter. -// * \param[in] vIDs - address of a vector that contains sorted (in the requested way) -// * module ID's. -// */ -//void module_list::sort(std::vector* vIDs) -//{ -// m_lock.lock(); -// -// // clear the vector -// m_pvModules->clear(); -// -// // and now process the data from map -// module* mod; -// for (std::vector::iterator it=vIDs->begin();it != vIDs->end();it++) -// { -// if ( (mod=find(*it)) != NULL_MODULE ) -// m_pvModules->push_back(mod); -// } -// -// m_lock.unlock(); -//} -// -///** Function fills the vector given as the parameter with the modules ID's -// * with the order as in the current list. -// * \param[in] vIDs - address of a vector that will receive the module ID's. -// */ -//void module_list::get_positions(std::vector* vIDs) -//{ -// m_lock.lock(); -// -// for (std::vector::iterator it=m_pvModules->begin();it != m_pvModules->end();it++) -// { -// vIDs->push_back((*it)->get_id()); -// } -// -// m_lock.unlock(); -//} -// -///** Returns the current count of modules contained in the list. -// * \return Count of modules. -// */ -//size_t module_list::size() -//{ -// m_lock.lock(); -// size_t tLen=m_pvModules->size(); -// m_lock.unlock(); -// -// return tLen; -//} -// -//// removing -///** Removes a module from a list (given it's ID). It means uninitializing the module -// * and then closing it. If the module is being currently used (see module::acquire() and module::release()) -// * then it is not removed (except when the bForce flag is specified). In case of error -// * the exception is thrown or false is returned. -// * \param[in] tID - id of a module to remove -// * \param[in] bForce - if true then the module reference count >0 does not block removing. -// * \return True if everything went ok, false otherwise. -// */ -//bool module_list::remove(moduleid_t tID, bool bForce) -//{ -// // find the tID module iterator -// bool bRes; -// -// m_lock.lock(); -// -// try -// { -// std::vector::iterator it; -// if (find_module(tID, &it)) -// bRes=remove(it, bForce); -// else -// { -// m_pmid->plog->logd("[module_list] Cannot remove module (id=" MODIDXFMT ") - it does not exist", tID); -// bRes=false; -// } -// -// m_lock.unlock(); -// } -// catch(...) -// { -// m_lock.unlock(); -// throw; -// } -// -// return bRes; -//} -// -///** Removes a module from a list (given it's position). It means uninitializing the module -// * and then closing it. If the module is being currently used (see module::acquire() and module::release()) -// * then it is not removed (except when the bForce flag is specified). In case of error -// * the exception is thrown or false is returned. -// * \param[in] tPos - position of a module to remove -// * \param[in] bForce - if true then the module reference count >0 does not block removing. -// * \return True if everything went ok, false otherwise. -// */ -//bool module_list::remove(size_t tPos, bool bForce) -//{ -// assert(tPos <= m_pvModules->size()); -// -// m_lock.lock(); -// -// bool bRes; -// try -// { -// bRes=remove(m_pvModules->begin()+tPos, bForce); -// m_lock.unlock(); -// } -// catch(...) -// { -// m_lock.unlock(); -// throw; -// } -// -// return bRes; -//} -// -///** Removes all the modules from a list. Depending the bForce parameter either all -// * modules are removed or only the unused ones. When error is encountered while removing -// * individual modules then it is logged to the log file and removed. -// * \param[in] bForce - specifies if the modules should be removed only if they are unused (false) -// * or always (true). -// */ -//void module_list::remove_all(bool bForce) -//{ -// m_lock.lock(); -// std::vector::iterator it=m_pvModules->end(); -// while (it != m_pvModules->begin()) -// { -// try -// { -// remove(--it, bForce); -// } -// catch(exception& e) -// { -// m_pmid->plog->logd("[module_list] Caught an exception in module_list::remove_all() while removing module from a list.Ignoring."); -// LOG_EXCEPTION(e, m_pmid->plog); -// e->del(); -// } -// } -// m_lock.unlock(); -//} -// -//////////////////////////////////////// -///** Removes a module from a list (given it's internal iterator). It means uninitializing the module -// * and then closing it. If the module is being currently used (see module::acquire() and module::release()) -// * then it is not removed (except when the bForce flag is specified). In case of error -// * the exception is thrown or false is returned. -// * \param[in] it - iterator that specifies position of a module in the internal vector -// * \param[in] bForce - if true then the module reference count >0 does not block removing -// * \return True if everything went ok, false otherwise. -// */ -//bool module_list::remove(std::vector::iterator it, bool bForce) -//{ -// module* mod=(*it); -// moduleid_t tid=mod->get_id(); -// -// m_pmid->plog->logi("[module_list] Trying to remove module (id=" MODIDXFMT ")", tid); -// -// if (mod->get_refcount() != 0) -// { -// if (!bForce) -// { -// m_pmid->plog->logw("[module_list] Cannot remove module (id=" MODIDXFMT ") due to module's reference count=" LFMT, tid, mod->get_refcount()); -// return false; // cannot unload -// } -// else -// m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") with reference count=" LFMT, tid, mod->get_refcount()); -// } -// -// // uninit&close the module - both can throw an exception -// try -// { -// if (!mod->uninit()) -// { -// // cannot uninit module -// if (!bForce) -// { -// m_pmid->plog->logw("[module_list] Cannot remove module (id=" MODIDXFMT ") due to uninit problems", tid); -// return false; -// } -// else -// m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") knowing that module uninit proc failed", tid); -// } -// } -// catch(exception& e) -// { -// if (!bForce) -// throw; // rethrow the exception - will be reported by some other func -// else -// { -// m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") knowing that module uninit proc had thrown an exception", tid); -// LOG_EXCEPTION(e, m_pmid->plog); -// e->del(); -// } -// } -// -// // try to close module -// try -// { -// mod->close(); -// } -// catch(exception& e) -// { -// if (!bForce) -// throw; -// else -// { -// m_pmid->plog->logw("[module_list] Removing module (id=" MODIDXFMT ") knowing that module close proc had thrown an exception", tid); -// LOG_EXCEPTION(e, m_pmid->plog); -// e->del(); -// } -// } -// -// // remove the module from the list -// m_pvModules->erase(it); -// std::map::iterator mit=m_pmModules->find(tid); -// if (mit != m_pmModules->end()) -// m_pmModules->erase(mit); -// -// m_pmid->plog->logi("[module_list] Module (id=" MODIDXFMT ") removed successfully", tid); -// return true; -//} -// -///** Changes the placement of the two modules (given by their iterators in the internal vector). -// * \param[in] it1, it2 - positions of the modules in the internal vector -// */ -//void module_list::swap(std::vector::iterator it1, std::vector::iterator it2) -//{ -// module* mod=(*it1); -// (*it1)=(*it2); -// (*it2)=mod; -//} -// -///** Searches for a specified module (by it's ID) and stores the iterator in the iterator -// * passed as the parameter. -// * \param[in] tID - ID of the module to search for -// * \param[out] pit - address of an iterator that is about to receive the module position -// * \return True if the module was found, false otherwise. -// */ -//bool module_list::find_module(moduleid_t tID, std::vector::iterator* pit) -//{ -// // find the requested module -// std::vector::iterator it; -// (*pit)=m_pvModules->end(); -// -// for (it=m_pvModules->begin();it != m_pvModules->end();it++) -// { -// // check if this is one of the requested modules -// if ((*it)->get_id() == tID) -// { -// (*pit)=it; -// break; -// } -// } -// -// return ((*pit) != m_pvModules->end()); -//} -// -///** Searches for a specified modules (by their ID's) and stores the iterators in the iterators -// * passed as the parameters. -// * \param[in] tID1, tID2 - ID's of the modules to search for -// * \param[out] pit1, pit2 - address of an iterators that are about to receive the module positions -// * \return True if the module was found, false otherwise. -// */ -//bool module_list::find_module(moduleid_t tID1, moduleid_t tID2, std::vector::iterator* pit1, std::vector::iterator* pit2) -//{ -// // find the requested module -// std::vector::iterator it; -// (*pit1)=(*pit2)=m_pvModules->end(); -// -// for (it=m_pvModules->begin();it != m_pvModules->end();it++) -// { -// // check if this is one of the requested modules -// if ((*it)->get_id() == tID1) -// (*pit1)=it; -// else if ((*it)->get_id() == tID2) -// (*pit2)=it; -// } -// -// return ((*pit1) != m_pvModules->end() && (*pit2) != m_pvModules->end()); -//} - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/module.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/module.h (revision 0) +++ ext/libicpf/src/libicpf/module.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,419 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file module.h + * \brief File contain declaration of the module (and related) classes. + */ + +#ifndef __MODULE_H__ +#define __MODULE_H__ + +#include "libicpf.h" +#include "gen_types.h" +/*#include "mutex.h" +#include "cfg.h" +#include "log.h" +#include "file.h" +#include +#include + +// inclusion of dirent.h +#if HAVE_DIRENT_H + #include + #define NAMLEN(dirent) strlen((dirent)->d_name) +#else + #define dirent direct + #define NAMLEN(dirent) (dirent)->d_namlen + #if HAVE_SYS_NDIR_H + #include + #endif + #if HAVE_SYS_DIR_H + #include + #endif + #if HAVE_NDIR_H + #include + #endif +#endif + +#ifndef MODULE_EXT + /// File extension to use with modules + #define MODULE_EXT "" +#endif +*/ +BEGIN_ICPF_NAMESPACE +/* +/// NULL module ID +#define NULL_MODULE 0x00000000 + +// module types +/// Module type NONE +#define MT_NONE 0x00000000 +/// Module type ALL +#define MT_ALL 0xffffffff + +// module flags +/// Module flag NONE +#define MF_NONE 0x00000000 +/// The module is an external one +#define MF_EXTERNAL 0x00000001 + +/** \brief States that the init() func for the module has been successfully called. + * + * If the flag is set it means that the module function init() has been called succesfully + * and the uninit() call may be executed. Flag used to make sure there will be only one + * subsequent call to init() and uninit() functions in the external module even if they + * will be called more than once in a program. + */ +/*#define MF_INITIALIZED 0x00000002 + +/// Type describes the module id. +typedef ulonglong_t moduleid_t; +/// Module ID formatting text to be used in formatting routines +#define MODIDFMT ULLFMT +/// Module ID (hex) formatting text to be used in formatting routines +#define MODIDXFMT ULLXFMT + +/** Makes a module ID from a given parameters. + * \param[in] internal - bool that specifies if this is the internal module + * \param[in] type - module type(could be a bitmask) - only the lower 28 bits will be used + * \param[in] unique_id - 32-bit unique id (should be randomly generated) + */ +/*#define MAKE_MODID(internal,type,unique_id)\ + ((internal ? 0ULL : 0x8000000000000000ULL) | (((ulonglong_t)type & 0x0fffffff) << 32) | unique_id) + +/** \brief Class for managing the parameters of a module. + * + * Class provides support for a module parameters. It could be used outside the module (ie. after + * module destruction) to store module settings to a file or to configuration. + * \todo This class needs some more clarification - how to use it, the purpose, ... + */ +/*class LIBICPF_API module_param +{ +public: +/** \name Construction/destruction */ +/**@{*/ +/* module_param(); ///< Standard constructor + virtual ~module_param(); ///< Standard destructor +/**@}*/ + +/** \name Locking/unlocking */ +/**@{*/ +/* void lock(); ///< Locks the class (gets exclusive ownership of this object) + void unlock(); ///< Unlocks the class (releases the ownership) +/**@}*/ + +/** \name Informations */ +/**@*/ +/* moduleid_t get_moduleid() const; ///< Returns a module id associated with this class +/**@}*/ + +/** \name Configuration support */ +/**@{*/ +/* virtual void read_config(config* pcfg); ///< Reads the configuration properties from a config object + virtual void write_config(config* pcfg); ///< Writes the internal properties to the config object + virtual void register_properties(config* pcfg); ///< Registers properties for use with the config object +/**@}*/ + +/** \name Serialization support */ +/**@{*/ +/* virtual void store(file& ser); ///< Stores the internal properties in the serialization object (file) + virtual void load(file& ser); ///< Loads the internal properties from a serialization object (file) +/**@}*/ +/* +protected: + moduleid_t m_midModuleID; ///< ID of a module that owns this parameters + uint_t m_uiPropStart; ///< ID of the first registered property (see register_properties()) + mutex m_lock; ///< Access lock for performing safe multi-threaded operations +}; + +/** \brief Class handling lists of module_param's. + * + * Class handles the management of lists of module_param classes. One module can have only + * one module_param (or derived) class associated with it. + */ +/*class LIBICPF_API modparam_list +{ +public: +/** \name Construction/destruction */ +/**@{*/ +/* modparam_list(); ///< Standard constructor + ~modparam_list(); ///< Standard destructor +/**@}*/ + +/** \name Standard operations */ +/**@{*/ +/* void insert(module_param* pEntry); ///< Inserts a new module_param to this container + bool remove(moduleid_t tEntry, bool bDelete=true); ///< Removes a module_param associated with a given module id + void clear(bool bDelete=true); ///< Removes all the entries from the list + module_param* find(moduleid_t mid); ///< Searches for a module_param associated with a given module id +/**@}*/ + +/** \name Configuration support */ +/**@{*/ +/* void read_config(config* pcfg); ///< Reads the configuration properties from a config object + void write_config(config* pcfg); ///< Writes the internal properties to the config object + void register_properties(config* pcfg); ///< Registers properties for use with the config object +/**@}*/ + +/** \name Serialization support */ +/**@{*/ +/* void store(file& ser); ///< Stores the internal properties in the serialization object (file) + void load(file& ser); ///< Loads the internal properties from a serialization object (file) +/**@}*/ +/* +protected: + void* m_pMods; ///< Internal map of module parameters +// std::map m_mMods; + mutex m_lock; ///< A locking mutex +}; + +/** \brief Module information struct + * + * Structure contains some fields used to identify a module (module name, + * id, type, author information and so on). + */ +/*struct MODULE_INFO +{ + uint_t uiInfoLen; ///< Count of bytes contained in this struct (filled by plugin) + char_t szAuthor[128]; ///< Author's full name + char_t szName[128]; ///< Plugin name + char_t szVersion[32]; ///< Version string + moduleid_t midID; ///< 64-bit module ID + uint_t uiType; ///< Type of a module (app-dependent) +}; + +/** \brief Structure with initialization data for a module + * + * Structure contains init parameters passed into the constructor and + * the init() function of a module and module_list class. + */ +/*struct MODULE_INITDATA +{ + config *pcfg; ///< Global configuration object + log_file *plog; ///< Log file object to perform logging to +}; + +// external functions typedefs +/// Prototype of the external module get_info() function +typedef void(*PFNMGETINFO)(MODULE_INFO*); +/// Prototype of the external module init() function +typedef bool(*PFNMINIT)(const MODULE_INITDATA*, module_param**); +/// Prototype of the external module uninit() function +typedef bool(*PFNMUNINIT)(module_param**); +/// Allocates a new module_param-derived parameter +typedef module_param*(*PFNALLOCMODPARAM)(); + +// module handle definition +#ifdef _WIN32 + /// System dependent module handle definition + #define MHANDLE HMODULE +#else + /// System dependent module handle definition + #define MHANDLE ptr_t +#endif + +// helper for loading exports +#ifdef _WIN32 + /** \brief Maps a module exported function to some class member + * + * Macro used to simplify loading function exported from an external + * modules (see module::load_exports()). + * \param[in] module - external module handle + * \param[in] var - variable that will receive the function address + * \param[in] fn_name - string with the function name to get addres of + * \note Macro throws an exception if the export cannot be loaded. + */ +/* #define MAP_EXPORT(module,var,fn_name)\ + (FARPROC&)var=::GetProcAddress(module, fn_name);\ + if (var == NULL)\ + THROW(exception::format("Cannot load an export " STRFMT " from the external module (handle " PTRFMT ")", fn_name, module), PE_CALLNOTIMPLEMENTED, GetLastError(), 0); +#else + /** \brief Maps a module exported function to some class member + * + * Macro used to simplify loading function exported from an external + * modules (see module::load_exports()). + * \param[in] module - external module handle + * \param[in] var - variable that will receive the function address + * \param[in] fn_name - string with the function name to get addres of + * \note Macro throws an exception if the export cannot be loaded. + */ +/* #define MAP_EXPORT(module,var,fn_name)\ + *((ptr_t*)&var)=dlsym(module, fn_name);\ + if (var == NULL)\ + THROW(exception::format("Cannot load an export " STRFMT " from the external module - " STRFMT " (handle " PTRFMT ")", fn_name, dlerror(), module), PE_CALLNOTIMPLEMENTED, 0, 0); +#endif + +/** \brief Module handling class + * + * This class allows handling of the internal and external modules. This is a base class + * from which should be derived any other module classes that handle different types + * of modules. + */ +/*class LIBICPF_API module +{ +public: +/** \name Construction/destruction */ +/**@{*/ +/* module(const MODULE_INITDATA* pData, uint_t uiFlags=MF_EXTERNAL); ///< Standard constructor + virtual ~module(); ///< Standard destructor +/**@}*/ + +/** \name External modules support */ +/**@{*/ +/* void open(const char_t* pszPath); ///< Opens an external module (file) + void close(bool bFullDestruct=false); ///< Closes an external module (uninitializes if needed) +/**@}*/ + +/** \name Module information */ +/**@{*/ +/* /// Retrieves the module information directly from the module + void get_info(MODULE_INFO* pInfo); + /// Returns an address of the cached module information structure + const MODULE_INFO* get_info() { return &m_mi; }; + /// Returns module ID from the cached information struct + moduleid_t get_id() const { return m_mi.midID; }; + /// Returns author string address from the cached information struct + const char_t* get_author() const { return m_mi.szAuthor; }; + /// Returns version string address from the cached information struct + const char_t* get_version() const { return m_mi.szVersion; }; + /// Returns module name string address from the cached information struct + const char_t* get_name() const { return m_mi.szName; }; + /// Returns module type from the cached information struct + uint_t get_type() const { return m_mi.uiType; }; +/**@}*/ + +/** \name Module parameters */ +/**@{*/ +/* virtual module_param* alloc_modparam(); ///< Allocates a module_param (or derived) class - should be overloaded. +/**@}*/ + +/** \name Initialization/uninitialization */ +/**@{*/ +/* virtual bool init(const MODULE_INITDATA* pData); ///< Initializes the module (if not initialized yet) + virtual bool uninit(); ///< Uninitializes the module (if not uninitialized yet) +/**@}*/ + +/** \name Reference counting */ +/**@{*/ +/* /// Retrieves the current reference count + int_t get_refcount() const { return m_lRefCount; }; + /// Increases the reference count + void acquire() { ++m_lRefCount; }; + /// Decreases the reference count + int_t release() { return --m_lRefCount; }; +/**@}*/ + +//protected: +/* /// Loads all needed exports from an external module + virtual void load_exports(); + + /// Cleans up the internal stuff + void cleanup(); + +protected: + const MODULE_INITDATA* m_pmid; ///< Module data struct ptr passed in the constructor + module_param* m_pmp; ///< Pointer to a module parameters class (managed by a module). + + MODULE_INFO m_mi; ///< Module information struct (cached for external modules, filled in constructor for internal) + + int_t m_lRefCount; ///< Current reference count + + // external stuff + uint_t m_ulFlags; ///< Module flags (MF_*) + char_t* m_pszPath; ///< Full file path for an external module + MHANDLE m_hModule; ///< Handle to the loaded external module (NULL_MODULE if not loaded) + PFNMGETINFO m_pfnGetInfo; ///< Pointer to the module's get_info() function + PFNMINIT m_pfnInit; ///< Pointer to the module's init() function + PFNMUNINIT m_pfnUninit; ///< Pointer to the module's uninit() function + PFNALLOCMODPARAM m_pfnAllocModparam; ///< Pointer to the module's alloc_modparam() function +}; + +/** \brief Module management class + * + * Class was designed to allow easier handling of a module lists. Provides + * a basic operations on a list of modules (searching, inserting, removing, ...). + * Should be a base for any module management class. + */ +/*class LIBICPF_API module_list +{ +public: +/** \name Construction/destruction */ +/**@{*/ +/* module_list(const MODULE_INITDATA* pData); ///< Standard constructor + ~module_list(); ///< Standard destructor +/**@}*/ + +/** \name Adding/removing */ +/**@{*/ +/* void scan(const char_t* pszPath, uint_t uiType=MT_ALL); ///< Scans a directory for some modules + + // adding a new items (modules) + void insert(size_t tPos, module* tModule); ///< Inserts a module at a specified position + void push_front(module* tModule); ///< Adds a module at the beginning of a list + void push_back(module* tModule); ///< Adds a module at the end of a list + + // removing + bool remove(moduleid_t tID, bool bForce=false); ///< Removes a module from the list by its ID + bool remove(size_t tPos, bool bForce=false); ///< Removes a module from the list by its position + void remove_all(bool bForce=false); ///< Removes all the modules from the list +/**@}*/ + +/** \name Searching */ +/**@{*/ +/* module* find(moduleid_t mid); ///< Searches a list for the module with the specified ID + module* at(size_t tPos); ///< Gets the module at a specified position on the list +/**@}*/ + +/** \name Module repositioning */ +/**@{*/ +/* void swap(moduleid_t t1, moduleid_t t2); ///< Swaps two modules positions by their ID's + void swap(size_t tPos1, size_t tPos2); ///< Swaps two modules positions by their positions + void move(moduleid_t tID, size_t tNewPos); ///< Moves the specified module to a new position + void sort(std::vector* vIDs); ///< Sorts the modules using a module id vector + void get_positions(std::vector* vIDs); ///< Retrieves the current modules positions +/**@}*/ + +/** \name Other */ +/**@{*/ +/* size_t size(); ///< Retrieves a count of modules in a list +/**@}*/ +/* +protected: + void swap(std::vector::iterator it1, std::vector::iterator it2); ///< Swaps two modules positions by their vector iterators + bool find_module(moduleid_t tID, std::vector::iterator* pit); ///< Searches for the module by it's ID and returns an iterator + bool find_module(moduleid_t tID1, moduleid_t tID2, std::vector::iterator* pit1, std::vector::iterator* pit2); ///< Searches for two modules by their ID's - returns iterators + bool remove(std::vector::iterator it, bool bForce=false); ///< Removes a module from this list given the vector iterator + +#ifndef _WIN32 + static int_t mod_filter(const struct dirent *pent); ///< Helper function to filter directory entries under linux +#endif + +protected: +// std::vector m_vModules; +// std::map m_mModules; + void* m_vModules; ///< Array of modules (used to make this class preserve the module positions) - internal. + void* m_mModules; ///< Mapping module id->module pointer (internal) + const MODULE_INITDATA* m_pmid; ///< Module initialization data (used for module::init() functions and/or constructors) + + mutex m_lock; ///< Thread-safe access guarantee +}; +*/ +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/module.h =================================================================== diff -u -N --- ext/libicpf/src/module.h (revision e553b1c870c6974c1bbab69390b6e720eaf89e55) +++ ext/libicpf/src/module.h (revision 0) @@ -1,419 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file module.h - * \brief File contain declaration of the module (and related) classes. - */ - -#ifndef __MODULE_H__ -#define __MODULE_H__ - -#include "libicpf.h" -#include "gen_types.h" -/*#include "mutex.h" -#include "cfg.h" -#include "log.h" -#include "file.h" -#include -#include - -// inclusion of dirent.h -#if HAVE_DIRENT_H - #include - #define NAMLEN(dirent) strlen((dirent)->d_name) -#else - #define dirent direct - #define NAMLEN(dirent) (dirent)->d_namlen - #if HAVE_SYS_NDIR_H - #include - #endif - #if HAVE_SYS_DIR_H - #include - #endif - #if HAVE_NDIR_H - #include - #endif -#endif - -#ifndef MODULE_EXT - /// File extension to use with modules - #define MODULE_EXT "" -#endif -*/ -BEGIN_ICPF_NAMESPACE -/* -/// NULL module ID -#define NULL_MODULE 0x00000000 - -// module types -/// Module type NONE -#define MT_NONE 0x00000000 -/// Module type ALL -#define MT_ALL 0xffffffff - -// module flags -/// Module flag NONE -#define MF_NONE 0x00000000 -/// The module is an external one -#define MF_EXTERNAL 0x00000001 - -/** \brief States that the init() func for the module has been successfully called. - * - * If the flag is set it means that the module function init() has been called succesfully - * and the uninit() call may be executed. Flag used to make sure there will be only one - * subsequent call to init() and uninit() functions in the external module even if they - * will be called more than once in a program. - */ -/*#define MF_INITIALIZED 0x00000002 - -/// Type describes the module id. -typedef ulonglong_t moduleid_t; -/// Module ID formatting text to be used in formatting routines -#define MODIDFMT ULLFMT -/// Module ID (hex) formatting text to be used in formatting routines -#define MODIDXFMT ULLXFMT - -/** Makes a module ID from a given parameters. - * \param[in] internal - bool that specifies if this is the internal module - * \param[in] type - module type(could be a bitmask) - only the lower 28 bits will be used - * \param[in] unique_id - 32-bit unique id (should be randomly generated) - */ -/*#define MAKE_MODID(internal,type,unique_id)\ - ((internal ? 0ULL : 0x8000000000000000ULL) | (((ulonglong_t)type & 0x0fffffff) << 32) | unique_id) - -/** \brief Class for managing the parameters of a module. - * - * Class provides support for a module parameters. It could be used outside the module (ie. after - * module destruction) to store module settings to a file or to configuration. - * \todo This class needs some more clarification - how to use it, the purpose, ... - */ -/*class LIBICPF_API module_param -{ -public: -/** \name Construction/destruction */ -/**@{*/ -/* module_param(); ///< Standard constructor - virtual ~module_param(); ///< Standard destructor -/**@}*/ - -/** \name Locking/unlocking */ -/**@{*/ -/* void lock(); ///< Locks the class (gets exclusive ownership of this object) - void unlock(); ///< Unlocks the class (releases the ownership) -/**@}*/ - -/** \name Informations */ -/**@*/ -/* moduleid_t get_moduleid() const; ///< Returns a module id associated with this class -/**@}*/ - -/** \name Configuration support */ -/**@{*/ -/* virtual void read_config(config* pcfg); ///< Reads the configuration properties from a config object - virtual void write_config(config* pcfg); ///< Writes the internal properties to the config object - virtual void register_properties(config* pcfg); ///< Registers properties for use with the config object -/**@}*/ - -/** \name Serialization support */ -/**@{*/ -/* virtual void store(file& ser); ///< Stores the internal properties in the serialization object (file) - virtual void load(file& ser); ///< Loads the internal properties from a serialization object (file) -/**@}*/ -/* -protected: - moduleid_t m_midModuleID; ///< ID of a module that owns this parameters - uint_t m_uiPropStart; ///< ID of the first registered property (see register_properties()) - mutex m_lock; ///< Access lock for performing safe multi-threaded operations -}; - -/** \brief Class handling lists of module_param's. - * - * Class handles the management of lists of module_param classes. One module can have only - * one module_param (or derived) class associated with it. - */ -/*class LIBICPF_API modparam_list -{ -public: -/** \name Construction/destruction */ -/**@{*/ -/* modparam_list(); ///< Standard constructor - ~modparam_list(); ///< Standard destructor -/**@}*/ - -/** \name Standard operations */ -/**@{*/ -/* void insert(module_param* pEntry); ///< Inserts a new module_param to this container - bool remove(moduleid_t tEntry, bool bDelete=true); ///< Removes a module_param associated with a given module id - void clear(bool bDelete=true); ///< Removes all the entries from the list - module_param* find(moduleid_t mid); ///< Searches for a module_param associated with a given module id -/**@}*/ - -/** \name Configuration support */ -/**@{*/ -/* void read_config(config* pcfg); ///< Reads the configuration properties from a config object - void write_config(config* pcfg); ///< Writes the internal properties to the config object - void register_properties(config* pcfg); ///< Registers properties for use with the config object -/**@}*/ - -/** \name Serialization support */ -/**@{*/ -/* void store(file& ser); ///< Stores the internal properties in the serialization object (file) - void load(file& ser); ///< Loads the internal properties from a serialization object (file) -/**@}*/ -/* -protected: - void* m_pMods; ///< Internal map of module parameters -// std::map m_mMods; - mutex m_lock; ///< A locking mutex -}; - -/** \brief Module information struct - * - * Structure contains some fields used to identify a module (module name, - * id, type, author information and so on). - */ -/*struct MODULE_INFO -{ - uint_t uiInfoLen; ///< Count of bytes contained in this struct (filled by plugin) - char_t szAuthor[128]; ///< Author's full name - char_t szName[128]; ///< Plugin name - char_t szVersion[32]; ///< Version string - moduleid_t midID; ///< 64-bit module ID - uint_t uiType; ///< Type of a module (app-dependent) -}; - -/** \brief Structure with initialization data for a module - * - * Structure contains init parameters passed into the constructor and - * the init() function of a module and module_list class. - */ -/*struct MODULE_INITDATA -{ - config *pcfg; ///< Global configuration object - log_file *plog; ///< Log file object to perform logging to -}; - -// external functions typedefs -/// Prototype of the external module get_info() function -typedef void(*PFNMGETINFO)(MODULE_INFO*); -/// Prototype of the external module init() function -typedef bool(*PFNMINIT)(const MODULE_INITDATA*, module_param**); -/// Prototype of the external module uninit() function -typedef bool(*PFNMUNINIT)(module_param**); -/// Allocates a new module_param-derived parameter -typedef module_param*(*PFNALLOCMODPARAM)(); - -// module handle definition -#ifdef _WIN32 - /// System dependent module handle definition - #define MHANDLE HMODULE -#else - /// System dependent module handle definition - #define MHANDLE ptr_t -#endif - -// helper for loading exports -#ifdef _WIN32 - /** \brief Maps a module exported function to some class member - * - * Macro used to simplify loading function exported from an external - * modules (see module::load_exports()). - * \param[in] module - external module handle - * \param[in] var - variable that will receive the function address - * \param[in] fn_name - string with the function name to get addres of - * \note Macro throws an exception if the export cannot be loaded. - */ -/* #define MAP_EXPORT(module,var,fn_name)\ - (FARPROC&)var=::GetProcAddress(module, fn_name);\ - if (var == NULL)\ - THROW(exception::format("Cannot load an export " STRFMT " from the external module (handle " PTRFMT ")", fn_name, module), PE_CALLNOTIMPLEMENTED, GetLastError(), 0); -#else - /** \brief Maps a module exported function to some class member - * - * Macro used to simplify loading function exported from an external - * modules (see module::load_exports()). - * \param[in] module - external module handle - * \param[in] var - variable that will receive the function address - * \param[in] fn_name - string with the function name to get addres of - * \note Macro throws an exception if the export cannot be loaded. - */ -/* #define MAP_EXPORT(module,var,fn_name)\ - *((ptr_t*)&var)=dlsym(module, fn_name);\ - if (var == NULL)\ - THROW(exception::format("Cannot load an export " STRFMT " from the external module - " STRFMT " (handle " PTRFMT ")", fn_name, dlerror(), module), PE_CALLNOTIMPLEMENTED, 0, 0); -#endif - -/** \brief Module handling class - * - * This class allows handling of the internal and external modules. This is a base class - * from which should be derived any other module classes that handle different types - * of modules. - */ -/*class LIBICPF_API module -{ -public: -/** \name Construction/destruction */ -/**@{*/ -/* module(const MODULE_INITDATA* pData, uint_t uiFlags=MF_EXTERNAL); ///< Standard constructor - virtual ~module(); ///< Standard destructor -/**@}*/ - -/** \name External modules support */ -/**@{*/ -/* void open(const char_t* pszPath); ///< Opens an external module (file) - void close(bool bFullDestruct=false); ///< Closes an external module (uninitializes if needed) -/**@}*/ - -/** \name Module information */ -/**@{*/ -/* /// Retrieves the module information directly from the module - void get_info(MODULE_INFO* pInfo); - /// Returns an address of the cached module information structure - const MODULE_INFO* get_info() { return &m_mi; }; - /// Returns module ID from the cached information struct - moduleid_t get_id() const { return m_mi.midID; }; - /// Returns author string address from the cached information struct - const char_t* get_author() const { return m_mi.szAuthor; }; - /// Returns version string address from the cached information struct - const char_t* get_version() const { return m_mi.szVersion; }; - /// Returns module name string address from the cached information struct - const char_t* get_name() const { return m_mi.szName; }; - /// Returns module type from the cached information struct - uint_t get_type() const { return m_mi.uiType; }; -/**@}*/ - -/** \name Module parameters */ -/**@{*/ -/* virtual module_param* alloc_modparam(); ///< Allocates a module_param (or derived) class - should be overloaded. -/**@}*/ - -/** \name Initialization/uninitialization */ -/**@{*/ -/* virtual bool init(const MODULE_INITDATA* pData); ///< Initializes the module (if not initialized yet) - virtual bool uninit(); ///< Uninitializes the module (if not uninitialized yet) -/**@}*/ - -/** \name Reference counting */ -/**@{*/ -/* /// Retrieves the current reference count - int_t get_refcount() const { return m_lRefCount; }; - /// Increases the reference count - void acquire() { ++m_lRefCount; }; - /// Decreases the reference count - int_t release() { return --m_lRefCount; }; -/**@}*/ - -//protected: -/* /// Loads all needed exports from an external module - virtual void load_exports(); - - /// Cleans up the internal stuff - void cleanup(); - -protected: - const MODULE_INITDATA* m_pmid; ///< Module data struct ptr passed in the constructor - module_param* m_pmp; ///< Pointer to a module parameters class (managed by a module). - - MODULE_INFO m_mi; ///< Module information struct (cached for external modules, filled in constructor for internal) - - int_t m_lRefCount; ///< Current reference count - - // external stuff - uint_t m_ulFlags; ///< Module flags (MF_*) - char_t* m_pszPath; ///< Full file path for an external module - MHANDLE m_hModule; ///< Handle to the loaded external module (NULL_MODULE if not loaded) - PFNMGETINFO m_pfnGetInfo; ///< Pointer to the module's get_info() function - PFNMINIT m_pfnInit; ///< Pointer to the module's init() function - PFNMUNINIT m_pfnUninit; ///< Pointer to the module's uninit() function - PFNALLOCMODPARAM m_pfnAllocModparam; ///< Pointer to the module's alloc_modparam() function -}; - -/** \brief Module management class - * - * Class was designed to allow easier handling of a module lists. Provides - * a basic operations on a list of modules (searching, inserting, removing, ...). - * Should be a base for any module management class. - */ -/*class LIBICPF_API module_list -{ -public: -/** \name Construction/destruction */ -/**@{*/ -/* module_list(const MODULE_INITDATA* pData); ///< Standard constructor - ~module_list(); ///< Standard destructor -/**@}*/ - -/** \name Adding/removing */ -/**@{*/ -/* void scan(const char_t* pszPath, uint_t uiType=MT_ALL); ///< Scans a directory for some modules - - // adding a new items (modules) - void insert(size_t tPos, module* tModule); ///< Inserts a module at a specified position - void push_front(module* tModule); ///< Adds a module at the beginning of a list - void push_back(module* tModule); ///< Adds a module at the end of a list - - // removing - bool remove(moduleid_t tID, bool bForce=false); ///< Removes a module from the list by its ID - bool remove(size_t tPos, bool bForce=false); ///< Removes a module from the list by its position - void remove_all(bool bForce=false); ///< Removes all the modules from the list -/**@}*/ - -/** \name Searching */ -/**@{*/ -/* module* find(moduleid_t mid); ///< Searches a list for the module with the specified ID - module* at(size_t tPos); ///< Gets the module at a specified position on the list -/**@}*/ - -/** \name Module repositioning */ -/**@{*/ -/* void swap(moduleid_t t1, moduleid_t t2); ///< Swaps two modules positions by their ID's - void swap(size_t tPos1, size_t tPos2); ///< Swaps two modules positions by their positions - void move(moduleid_t tID, size_t tNewPos); ///< Moves the specified module to a new position - void sort(std::vector* vIDs); ///< Sorts the modules using a module id vector - void get_positions(std::vector* vIDs); ///< Retrieves the current modules positions -/**@}*/ - -/** \name Other */ -/**@{*/ -/* size_t size(); ///< Retrieves a count of modules in a list -/**@}*/ -/* -protected: - void swap(std::vector::iterator it1, std::vector::iterator it2); ///< Swaps two modules positions by their vector iterators - bool find_module(moduleid_t tID, std::vector::iterator* pit); ///< Searches for the module by it's ID and returns an iterator - bool find_module(moduleid_t tID1, moduleid_t tID2, std::vector::iterator* pit1, std::vector::iterator* pit2); ///< Searches for two modules by their ID's - returns iterators - bool remove(std::vector::iterator it, bool bForce=false); ///< Removes a module from this list given the vector iterator - -#ifndef _WIN32 - static int_t mod_filter(const struct dirent *pent); ///< Helper function to filter directory entries under linux -#endif - -protected: -// std::vector m_vModules; -// std::map m_mModules; - void* m_vModules; ///< Array of modules (used to make this class preserve the module positions) - internal. - void* m_mModules; ///< Mapping module id->module pointer (internal) - const MODULE_INITDATA* m_pmid; ///< Module initialization data (used for module::init() functions and/or constructors) - - mutex m_lock; ///< Thread-safe access guarantee -}; -*/ -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/mutex.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/mutex.cpp (revision 0) +++ ext/libicpf/src/libicpf/mutex.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "mutex.h" + +BEGIN_ICPF_NAMESPACE + +mutex::mutex() +{ +#ifdef _WIN32 + ::InitializeCriticalSection(&m_cs); +#else + pthread_mutexattr_t mta; + pthread_mutexattr_init(&mta); +//#warning Recursive mutexes are disabled; Make sure you use them the right way. + pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE_NP); + pthread_mutex_init(&m_mutex, &mta); + + pthread_mutexattr_destroy(&mta); +#endif +} + +mutex::mutex(const char_t* /*pszStr*/) +{ +#ifdef _WIN32 + ::InitializeCriticalSection(&m_cs); +#else + pthread_mutexattr_t mta; + pthread_mutexattr_init(&mta); +//#warning Recursive mutexes are disabled; Make sure you use them the right way. + pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE_NP); + pthread_mutex_init(&m_mutex, &mta); + + pthread_mutexattr_destroy(&mta); +#endif +} + +mutex::~mutex() +{ +#ifdef _WIN32 + ::DeleteCriticalSection(&m_cs); +#else + pthread_mutex_destroy(&m_mutex); +#endif +} + +#ifdef ENABLE_MUTEX_DEBUGGING +void mutex::lock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction) +{ + lock(); +} + +void mutex::unlock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction) +{ + unlock(); +} +#endif + +END_ICPF_NAMESPACE Index: ext/libicpf/src/mutex.cpp =================================================================== diff -u -N --- ext/libicpf/src/mutex.cpp (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/mutex.cpp (revision 0) @@ -1,75 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "mutex.h" - -BEGIN_ICPF_NAMESPACE - -mutex::mutex() -{ -#ifdef _WIN32 - ::InitializeCriticalSection(&m_cs); -#else - pthread_mutexattr_t mta; - pthread_mutexattr_init(&mta); -//#warning Recursive mutexes are disabled; Make sure you use them the right way. - pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE_NP); - pthread_mutex_init(&m_mutex, &mta); - - pthread_mutexattr_destroy(&mta); -#endif -} - -mutex::mutex(const char_t* /*pszStr*/) -{ -#ifdef _WIN32 - ::InitializeCriticalSection(&m_cs); -#else - pthread_mutexattr_t mta; - pthread_mutexattr_init(&mta); -//#warning Recursive mutexes are disabled; Make sure you use them the right way. - pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE_NP); - pthread_mutex_init(&m_mutex, &mta); - - pthread_mutexattr_destroy(&mta); -#endif -} - -mutex::~mutex() -{ -#ifdef _WIN32 - ::DeleteCriticalSection(&m_cs); -#else - pthread_mutex_destroy(&m_mutex); -#endif -} - -#ifdef ENABLE_MUTEX_DEBUGGING -void mutex::lock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction) -{ - lock(); -} - -void mutex::unlock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction) -{ - unlock(); -} -#endif - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/mutex.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/mutex.h (revision 0) +++ ext/libicpf/src/libicpf/mutex.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file mutex.h + * \brief Contains mutex class for thread safe access. + */ +#ifndef __MUTEX_H__ +#define __MUTEX_H__ + +#ifdef _WIN32 + #include +#else + #include +#endif + +#include "libicpf.h" +#include "gen_types.h" + +BEGIN_ICPF_NAMESPACE + +#if defined(ENABLE_MUTEX_DEBUGGING) && defined(DEBUG_MUTEX) + #define MLOCK(mutex) (mutex).lock(__FILE__, __LINE__, __FUNCTION__) + #define MUNLOCK(mutex) (mutex).unlock(__FILE__, __LINE__, __FUNCTION__) +#else + #define MLOCK(mutex) (mutex).lock() + #define MUNLOCK(mutex) (mutex).unlock() +#endif + +/** \brief Class provides the locking and unlocking capabilities for use with threads. + * + * Class is a simple wrapper over the system related thread locking functions. In linux + * those functions are pthread_mutex_* and in windoze the functions related to CRITICAL_SECTION + * structure. + */ +class LIBICPF_API mutex +{ +public: +/** \name Construction/destruction */ +/**@{*/ + /** \brief Standard constructor + */ + mutex(); + explicit mutex(const char_t* pszStr); + + /** \brief Standard destructor + */ + ~mutex(); +/**@}*/ + + // standard locking +/** \name Locking/unlocking */ +/**@{*/ + + /** \brief Locks access to some part of code for the current thread + * + * Locks access to some code using the platform specific functions. + * \return True if succeeded or false if not. + * \note The call under windows always return true. + */ + inline void lock() + { +#ifdef _WIN32 + ::EnterCriticalSection(&m_cs); +#else + pthread_mutex_lock(&m_mutex); +#endif + } + + + /** \brief Unlock access to some locked part of code + * + * Unlocks access to some code using the platform specific functions. + * \return True if succeeded or false if not. + * \note The call under windows always return true. + */ + inline void unlock() + { +#ifdef _WIN32 + ::LeaveCriticalSection(&m_cs); +#else + pthread_mutex_unlock(&m_mutex); // return 0 on success +#endif + } + +/**@}*/ + +#ifdef ENABLE_MUTEX_DEBUGGING + void lock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction); + void unlock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction); +#endif +private: +#ifdef _WIN32 + /// Underlying windows locking structure + CRITICAL_SECTION m_cs; +#else + /// Underlying linux locking structure/handle + pthread_mutex_t m_mutex; +#endif +}; + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/mutex.h =================================================================== diff -u -N --- ext/libicpf/src/mutex.h (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/mutex.h (revision 0) @@ -1,119 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file mutex.h - * \brief Contains mutex class for thread safe access. - */ -#ifndef __MUTEX_H__ -#define __MUTEX_H__ - -#ifdef _WIN32 - #include -#else - #include -#endif - -#include "libicpf.h" -#include "gen_types.h" - -BEGIN_ICPF_NAMESPACE - -#if defined(ENABLE_MUTEX_DEBUGGING) && defined(DEBUG_MUTEX) - #define MLOCK(mutex) (mutex).lock(__FILE__, __LINE__, __FUNCTION__) - #define MUNLOCK(mutex) (mutex).unlock(__FILE__, __LINE__, __FUNCTION__) -#else - #define MLOCK(mutex) (mutex).lock() - #define MUNLOCK(mutex) (mutex).unlock() -#endif - -/** \brief Class provides the locking and unlocking capabilities for use with threads. - * - * Class is a simple wrapper over the system related thread locking functions. In linux - * those functions are pthread_mutex_* and in windoze the functions related to CRITICAL_SECTION - * structure. - */ -class LIBICPF_API mutex -{ -public: -/** \name Construction/destruction */ -/**@{*/ - /** \brief Standard constructor - */ - mutex(); - explicit mutex(const char_t* pszStr); - - /** \brief Standard destructor - */ - ~mutex(); -/**@}*/ - - // standard locking -/** \name Locking/unlocking */ -/**@{*/ - - /** \brief Locks access to some part of code for the current thread - * - * Locks access to some code using the platform specific functions. - * \return True if succeeded or false if not. - * \note The call under windows always return true. - */ - inline void lock() - { -#ifdef _WIN32 - ::EnterCriticalSection(&m_cs); -#else - pthread_mutex_lock(&m_mutex); -#endif - } - - - /** \brief Unlock access to some locked part of code - * - * Unlocks access to some code using the platform specific functions. - * \return True if succeeded or false if not. - * \note The call under windows always return true. - */ - inline void unlock() - { -#ifdef _WIN32 - ::LeaveCriticalSection(&m_cs); -#else - pthread_mutex_unlock(&m_mutex); // return 0 on success -#endif - } - -/**@}*/ - -#ifdef ENABLE_MUTEX_DEBUGGING - void lock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction); - void unlock(const char_t* pszFile, ulong_t ulLine, const char_t* pszFunction); -#endif -private: -#ifdef _WIN32 - /// Underlying windows locking structure - CRITICAL_SECTION m_cs; -#else - /// Underlying linux locking structure/handle - pthread_mutex_t m_mutex; -#endif -}; - -END_ICPF_NAMESPACE - -#endif Index: ext/libicpf/src/libicpf/str_help.cpp =================================================================== diff -u -N --- ext/libicpf/src/libicpf/str_help.cpp (revision 0) +++ ext/libicpf/src/libicpf/str_help.cpp (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file str_help.cpp + * \brief Contain implementation of some string helper functions. + */ +#include "str_help.h" + +BEGIN_ICPF_NAMESPACE + +/** Checks if the character is a whitespace. + * \param[in] ch - character to check + * \return True if the character is a whitespace one, false otherwise. + */ +LIBICPF_API bool is_whitespace(char_t ch) +{ + return ((ch >= 0x09) && (ch <= 0x0d)) || (ch == 0x20); +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/str_help.cpp =================================================================== diff -u -N --- ext/libicpf/src/str_help.cpp (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/str_help.cpp (revision 0) @@ -1,36 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file str_help.cpp - * \brief Contain implementation of some string helper functions. - */ -#include "str_help.h" - -BEGIN_ICPF_NAMESPACE - -/** Checks if the character is a whitespace. - * \param[in] ch - character to check - * \return True if the character is a whitespace one, false otherwise. - */ -LIBICPF_API bool is_whitespace(char_t ch) -{ - return ((ch >= 0x09) && (ch <= 0x0d)) || (ch == 0x20); -} - -END_ICPF_NAMESPACE Index: ext/libicpf/src/libicpf/str_help.h =================================================================== diff -u -N --- ext/libicpf/src/libicpf/str_help.h (revision 0) +++ ext/libicpf/src/libicpf/str_help.h (revision b337c059691a6940b52a86388ff427c734be8eb6) @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by J�zef Starosczyk * + * ixen@copyhandler.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/** \file str_help.h + * \brief Contain some string helper functions. + */ +#ifndef __STRHELP_H__ +#define __STRHELP_H__ + +#include "libicpf.h" +#include "gen_types.h" + +BEGIN_ICPF_NAMESPACE + +// some cross-platform compatibility macros +#ifndef _WIN32 + #define stricmp strcasecmp + #define wcsicmp wcscasecmp + #define strnicmp strncasecmp + #define wcsnicmp wcsncasecmp +#endif + +/// Checks if a given character is a whitespace character +LIBICPF_API bool is_whitespace(char_t ch); + +END_ICPF_NAMESPACE + +#endif Index: ext/libicpf/src/str_help.h =================================================================== diff -u -N --- ext/libicpf/src/str_help.h (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/str_help.h (revision 0) @@ -1,44 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2006 by J�zef Starosczyk * - * ixen@copyhandler.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library General Public License as * - * published by the Free Software Foundation; either version 2 of the * - * License, or (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -/** \file str_help.h - * \brief Contain some string helper functions. - */ -#ifndef __STRHELP_H__ -#define __STRHELP_H__ - -#include "libicpf.h" -#include "gen_types.h" - -BEGIN_ICPF_NAMESPACE - -// some cross-platform compatibility macros -#ifndef _WIN32 - #define stricmp strcasecmp - #define wcsicmp wcscasecmp - #define strnicmp strncasecmp - #define wcsnicmp wcsncasecmp -#endif - -/// Checks if a given character is a whitespace character -LIBICPF_API bool is_whitespace(char_t ch); - -END_ICPF_NAMESPACE - -#endif