Index: trunk/doc/doxyfile
===================================================================
--- trunk/doc/doxyfile	(revision 4)
+++ trunk/doc/doxyfile	(revision 4)
@@ -0,0 +1,1876 @@
+# Doxyfile 1.8.3.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should 
+# identify the project. Note that if you do not use Doxywizard you need 
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME           = "libcf++"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 0.1dev
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description 
+# for a project that appears at the top of each page and should give viewer 
+# a quick idea about the purpose of the project. Keep the description short.
+
+#PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is 
+# included in the documentation. The maximum height of the logo should not 
+# exceed 55 pixels and the maximum width should not exceed 200 pixels. 
+# Doxygen will copy the logo to the output directory.
+
+#PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ../_doc/
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = YES
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, 
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = Korean-en
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip. Note that you specify absolute paths here, but also 
+# relative paths, which will be relative from the directory where doxygen is 
+# started.
+
+STRIP_FROM_PATH        = ../include/cf	\
+						 ../src			\
+						 ../doc			\
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful if your file system 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only). 
+# A mapping has the form "name=value". For example adding 
+# "class=itcl::class" will allow you to use the command class in the 
+# itcl::class meaning.
+
+#TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it 
+# parses. With this tag you can assign which parser to use for a given 
+# extension. Doxygen has a built-in mapping, but you can override or extend it 
+# using this tag. The format is ext=language, where ext is a file extension, 
+# and language is one of the parsers supported by doxygen: IDL, Java, 
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, 
+# C++. For instance to make doxygen treat .inc files as Fortran files (default 
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note 
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the 
+# files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all 
+# comments according to the Markdown format, which allows for more readable 
+# documentation. See http://daringfireball.net/projects/markdown/ for details. 
+# The output of markdown processing is further processed by doxygen, so you 
+# can mix doxygen, HTML, and XML commands with Markdown formatting. 
+# Disable only in case of backward compatibilities issues.
+
+#MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented classes, 
+# or namespaces to their corresponding documentation. Such a link can be 
+# prevented in individual cases by by putting a % sign in front of the word or 
+# globally by setting AUTOLINK_SUPPORT to NO.
+
+#AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also makes the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate 
+# getter and setter methods for a property. Setting this option to YES (the 
+# default) will make doxygen replace the get and set methods by a property in 
+# the documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and 
+# unions are shown inside the group in which they are included (e.g. using 
+# @ingroup) instead of on a separate page (for HTML and Man pages) or 
+# section (for LaTeX and RTF).
+
+#INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and 
+# unions with only public data fields will be shown inline in the documentation 
+# of the scope in which they are defined (i.e. file, namespace, or group 
+# documentation), provided this scope is documented. If set to NO (the default), 
+# structs, classes, and unions are shown on a separate page (for HTML and Man 
+# pages) or section (for LaTeX and RTF).
+
+#INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = YES
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penalty. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will roughly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+#SYMBOL_CACHE_SIZE      = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be 
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given 
+# their name and scope. Since this can be an expensive process and often the 
+# same symbol appear multiple times in the code, doxygen keeps a cache of 
+# pre-resolved symbols. If the cache is too small doxygen will become slower. 
+# If the cache is too large, memory is wasted. The cache size is given by this 
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+#LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal 
+# scope will be included in the documentation.
+
+#EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = YES
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = YES
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 
+# will list include files with double quotes in the documentation 
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 
+# will sort the (brief and detailed) documentation of class members so that 
+# constructors and destructors are listed first. If set to NO (the default) 
+# the constructors will appear in the respective orders defined by 
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to 
+# do proper type resolution of all parameters of a function it will reject a 
+# match between the prototype and the implementation of a member function even 
+# if there is only one candidate or it is obvious which candidate to choose 
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen 
+# will still accept a match between prototype and implementation in such cases.
+
+#STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if section-label ... \endif 
+# and \cond section-label ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or macro consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and macros in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = NO
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 
+# by doxygen. The layout file controls the global structure of the generated 
+# output files in an output format independent way. To create the layout file 
+# that represents doxygen's defaults, run doxygen with the -l option. 
+# You can optionally specify a file name after the option, if omitted 
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files 
+# containing the references data. This must be a list of .bib files. The 
+# .bib extension is automatically appended if omitted. Using this command 
+# requires the bibtex tool to be installed. See also 
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style 
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this 
+# feature you need bibtex and perl available in the search path. Do not use 
+# file names with spaces, bibtex cannot handle them.
+
+#CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ../include/cf	\
+						 ../src			\
+						 ../doc			\
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          = *.h	\
+						 *.hpp	\
+						 *.cpp	\
+						 *.dox	\
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag. 
+# Note that relative paths are relative to the directory from which doxygen is 
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 
+# directories that are symbolic links (a Unix file system feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = ../example
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty or if 
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file 
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) 
+# and it is also possible to disable source filtering for a specific pattern 
+# using *.ext= (so without naming a filter). This option only has effect when 
+# FILTER_SOURCE_FILES is enabled.
+
+#FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that 
+# is part of the input, its contents will be placed on the main page (index.html). 
+# This can be useful if you have a project on for instance GitHub and want reuse 
+# the introduction page also for the doxygen output.
+
+#USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header. Note that when using a custom header you are responsible  
+# for the proper inclusion of any scripts and style sheets that doxygen 
+# needs, which is dependent on the configuration options used. 
+# It is advised to generate a default header using "doxygen -w html 
+# header.html footer.html stylesheet.css YourConfigFile" and then modify 
+# that header. Note that the header is subject to change so you typically 
+# have to redo this when upgrading to a newer version of doxygen or when 
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If left blank doxygen will 
+# generate a default style sheet. Note that it is recommended to use 
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this 
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional 
+# user-defined cascading style sheet that is included after the standard 
+# style sheets created by doxygen. Using this option one can overrule 
+# certain style aspects. This is preferred over using HTML_STYLESHEET 
+# since it does not replace the standard style sheet and is therefor more 
+# robust against future updates. Doxygen will copy the style sheet file to 
+# the output directory.
+
+#HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or 
+# other source files which should be copied to the HTML output directory. Note 
+# that these files will be copied to the base HTML output directory. Use the 
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these 
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that 
+# the files will be copied as-is; there are no commands or markers available.
+
+#HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 
+# Doxygen will adjust the colors in the style sheet and background images 
+# according to this color. Hue is specified as an angle on a colorwheel, 
+# see http://en.wikipedia.org/wiki/Hue for more information. 
+# For instance the value 0 represents red, 60 is yellow, 120 is green, 
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 
+# the colors in the HTML output. For a value of 0 the output will use 
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 
+# the luminance component of the colors in the HTML output. Values below 
+# 100 gradually make the output lighter, whereas values above 100 make 
+# the output darker. The value divided by 100 is the actual gamma applied, 
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 
+# page will contain the date and time when the page was generated. Setting 
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of 
+# entries shown in the various tree structured indices initially; the user 
+# can expand and collapse entries dynamically later on. Doxygen will expand 
+# the tree to such a level that at most the specified number of entries are 
+# visible (unless a fully collapsed tree already exceeds this amount). 
+# So setting the number of entries 1 will produce a full collapsed tree by 
+# default. 0 is a special value representing an infinite number of entries 
+# and will result in a full expanded tree by default.
+
+#HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely 
+# identify the documentation publisher. This should be a reverse domain-name 
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 
+# that can be used as input for Qt's qhelpgenerator to generate a 
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 
+# add. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 
+# custom filter to add. For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> 
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 
+# project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> 
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  
+# will be generated, which together with the HTML files, form an Eclipse help 
+# plugin. To install this plugin and make it available under the help contents 
+# menu in Eclipse, the contents of the directory containing the HTML and XML 
+# files needs to be copied into the plugins directory of eclipse. The name of 
+# the directory within the plugins directory should be the same as 
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin 
+# the directory name containing the HTML and XML files should also have 
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) 
+# at top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it. Since the tabs have the same information as the 
+# navigation tree you can set this option to NO if you already set 
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to YES, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
+# Windows users are probably better off using the HTML help feature. 
+# Since the tree basically has the same information as the tab index you 
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML 
+# documentation. Note that a value of 0 will completely suppress the enum 
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images 
+# generated for formulas are transparent PNGs. Transparent PNGs are 
+# not supported properly for IE 6.0, but are supported on all modern browsers. 
+# Note that when changing this option you need to delete any form_*.png files 
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 
+# (see http://www.mathjax.org) which uses client side Javascript for the 
+# rendering instead of using prerendered bitmaps. Use this if you do not 
+# have LaTeX installed or if you want to formulas look prettier in the HTML 
+# output. When enabled you may also need to install MathJax separately and 
+# configure the path to it using the MATHJAX_RELPATH option.
+
+#USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for 
+# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and 
+# SVG. The default value is HTML-CSS, which is slower, but has the best 
+# compatibility.
+
+#MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the 
+# HTML output directory using the MATHJAX_RELPATH option. The destination 
+# directory should contain the MathJax.js script. For instance, if the mathjax 
+# directory is located at the same level as the HTML output directory, then 
+# MATHJAX_RELPATH should be ../mathjax. The default value points to 
+# the MathJax Content Delivery Network so you can quickly see the result without 
+# installing MathJax.  However, it is strongly recommended to install a local 
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+#MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension 
+# names that should be enabled during MathJax rendering.
+
+#MATHJAX_EXTENSIONS     = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box 
+# for the HTML output. The underlying search engine uses javascript 
+# and DHTML and should work on any modern browser. Note that when using 
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 
+# (GENERATE_DOCSET) there is already a search function so this one should 
+# typically be disabled. For large projects the javascript based search engine 
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be 
+# implemented using a web server instead of a web client using Javascript. 
+# There are two flavours of web server based search depending on the 
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for 
+# searching and an index file used by the script. When EXTERNAL_SEARCH is 
+# enabled the indexing and searching needs to be provided by external tools. 
+# See the manual for details.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP 
+# script for searching. Instead the search results are written to an XML file 
+# which needs to be processed by an external indexer. Doxygen will invoke an 
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain 
+# the search results. Doxygen ships with an example indexer (doxyindexer) and 
+# search engine (doxysearch.cgi) which are based on the open source search engine 
+# library Xapian. See the manual for configuration details.
+
+#EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server 
+# which will returned the search results when EXTERNAL_SEARCH is enabled. 
+# Doxygen ships with an example search engine (doxysearch) which is based on 
+# the open source search engine library Xapian. See the manual for configuration 
+# details.
+
+#SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed 
+# search data is written to a file for indexing by an external tool. With the 
+# SEARCHDATA_FILE tag the name of this file can be specified.
+
+#SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the 
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is 
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple 
+# projects and redirect the results back to the right project.
+
+#EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen 
+# projects other than the one defined by this configuration file, but that are 
+# all added to the same external search index. Each project needs to have a 
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id 
+# of to a relative location where the documentation can be found. 
+# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
+
+#EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name. 
+# Note that when enabling USE_PDFLATEX this option is only used for 
+# generating bitmaps for formulas in the HTML output, but not in the 
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for 
+# the generated latex document. The footer should contain everything after 
+# the last chapter. If it is left blank doxygen will generate a 
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+#LATEX_FOOTER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include 
+# source code with syntax highlighting in the LaTeX output. 
+# Note that which sources are shown also depends on other settings 
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the 
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See 
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+#LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = _DEBUG
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition that 
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all references to function-like macros 
+# that are alone on a line, have an all uppercase name, and do not end with a 
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each 
+# tag file the location of the external documentation should be added. The 
+# format of a tag file without this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths 
+# or URLs. Note that each tag file must have a unique name (where the name does 
+# NOT include the path). If a tag file is not located in the directory in which 
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option also works with HAVE_DOT disabled, but it is recommended to 
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 
+# allowed to run in parallel. When set to 0 (the default) doxygen will 
+# base this on the number of processors available in the system. You can set it 
+# explicitly to a value larger than 0 to get control over the balance 
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will use the Helvetica font for all dot files that 
+# doxygen generates. When you want a differently looking font you can specify 
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find 
+# the font, which can be done by putting it in a standard location or by setting 
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the 
+# directory containing the font.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the Helvetica font. 
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to 
+# set the path where dot can find it.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside 
+# the class node. If there are many fields or methods and many nodes the 
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS 
+# threshold limits the number of items for each type to make the size more 
+# managable. Set this to 0 for no limit. Note that the threshold may be 
+# exceeded by 50% before the limit is enforced.
+
+#UML_LIMIT_NUM_FIELDS   = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are svg, png, jpg, or gif. 
+# If left blank png will be used. If you choose svg you need to set 
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to 
+# enable generation of interactive SVG images that allow zooming and panning. 
+# Note that this requires a modern browser other than Internet Explorer. 
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you 
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# visible. Older versions of IE do not have SVG support.
+
+#INTERACTIVE_SVG        = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that 
+# contain msc files that are included in the documentation (see the 
+# \mscfile command).
+
+#MSCFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
Index: trunk/doc/makefile
===================================================================
--- trunk/doc/makefile	(revision 4)
+++ trunk/doc/makefile	(revision 4)
@@ -0,0 +1,44 @@
+#----------------------------------------------------------
+# platform
+#----------------------------------------------------------
+include ../makeinclude/userdefine.mk
+include ../makeinclude/platform.mk
+
+#----------------------------------------------------------
+# env
+#----------------------------------------------------------
+DOXYGEN			:= $(shell which doxygen)
+
+DOXYGEN_FILE	= doxyfile
+DOXYGEN_LOG		= warning.log
+DOXYGEN_LATEX	= $(DOCUMENT_PATH)/latex
+
+JAVA_BIN		= $(JAVA_HOME)/bin
+JAVADOC_OPT		= -locale ko_KR -encoding UTF-8 -charset UTF-8 -docencoding UTF-8 -quiet -public
+
+#----------------------------------------------------------
+# label
+#----------------------------------------------------------
+all: doxygen
+	@echo ========== Complete compilation ==========
+
+doxygen: $(DOCUMENT_PATH)
+ifeq ($(DOXYGEN),)
+	@echo "doxygen was not found."
+else
+	@echo "========== DOXYGEN DOCUMENTATION =========="
+	$(DOXYGEN) $(DOXYGEN_FILE)
+endif
+
+$(DOCUMENT_PATH): dummy
+	@if [ ! -d $@ ] ; then mkdir $@ ; fi
+
+pdf: dummy
+	./fixPDFLaTeX.sh $(DOXYGEN_LATEX)
+	cd $(DOXYGEN_LATEX); make
+
+clean:
+	rm -rf $(DOCUMENT_PATH) $(DOXYGEN_LOG)
+
+dummy:
+
Index: trunk/include/cf/bin.h
===================================================================
--- trunk/include/cf/bin.h	(revision 4)
+++ trunk/include/cf/bin.h	(revision 4)
@@ -0,0 +1,164 @@
+/**
+ * @file bin.h
+ * @author myusgun@gmail.com
+ * @brief bin
+ */
+#ifndef __bin_h__
+#define __bin_h__
+
+#include "cf/types.h"
+#include "cf/exception.h"
+
+#include <vector>
+#include <stdio.h>
+
+namespace cf
+{
+	/**
+	 * binary
+	 */
+	class bin
+	{
+	private:
+		typedef std::vector<cf::uint8_t> bin_t;
+
+		bin_t mBin;
+
+	public:
+		/**
+		 * shallow-copy constructor(default constructor)
+		 * @param in binary
+		 * @param size binary size
+		 */
+		bin(const cf::uint8_t * in = NULL,
+			const cf::size_t size = 0);
+
+		/**
+		 * asciiz-byte shallow-copy constructor
+		 * @param in asciiz-byte
+		 */
+		bin(const cf::char_t * in);
+
+		/**
+		 * copy constructor
+		 * @param in an instance of bin(not constant)
+		 */
+		bin(const bin & in);
+
+		/**
+		 * reset binary. fill with zero
+		 */
+		cf::void_t clear();
+
+		/**
+		 * get binary
+		 * @return address of binary
+		 */
+		cf::uint8_t * buffer() const;
+
+		/**
+		 * get binary size
+		 * @return size of binary
+		 */
+		cf::size_t size() const;
+
+		/**
+		 * is empty
+		 * @return is empty ?
+		 */
+		cf::bool_t empty() const;
+
+		/**
+		 * resize
+		 * @param size new size
+		 */
+		cf::void_t resize(const cf::size_t size);
+
+		/**
+		 * set 
+		 * @param in data
+		 * @param size size
+		 */
+		cf::void_t set(const cf::uint8_t * in,
+					   const cf::size_t size);
+
+		/**
+		 * copy to rear of buffer
+		 * @param in binary
+		 * @param appendedSize binary size
+		 */
+		cf::void_t append(const cf::uint8_t * in,
+						  const cf::size_t appendedSize);
+
+		/**
+		 * copy to rear of buffer
+		 * @param in bin instance
+		 * @see bin::operator +=()
+		 */
+		cf::void_t append(const bin & in);
+
+		/**
+		 * compare binary
+		 * @return true; false
+		 * @param in bin instance
+		 * @see bin::operator ==()
+		 */
+		cf::bool_t equal(const bin & in) const;
+
+		/**
+		 * find in binary
+		 * @return on success, position; otherwise, (cf::size_t)-1
+		 * @param in binary
+		 * @param size binary size
+		 */
+		cf::size_t find(const cf::uint8_t * in,
+						const cf::size_t size) const;
+
+		/**
+		 * set 
+		 * @param in bin
+		 */
+		bin & operator =(const bin & in);
+
+		/**
+		 * copy to rear of buffer
+		 * @param in bin instance
+		 * @see bin::append()
+		 */
+		cf::void_t operator +=(const bin & in);
+
+		/**
+		 * combine binary
+		 * @return combined instance
+		 */
+		bin operator +(const bin & in) const;
+
+		/**
+		 * compare binary
+		 * @return true; false
+		 * @param in bin instance
+		 * @see bin::equal()
+		 */
+		cf::bool_t operator ==(const bin & in) const;
+
+		/**
+		 * compare binary
+		 * @return true; false
+		 * @param in bin instance
+		 * @see bin::equal()
+		 */
+		cf::bool_t operator !=(const bin & in) const;
+
+		/**
+		 * dump binary to file-pointer
+		 * @param prefix prefix for output
+		 * @param limit [option] limit
+		 * @param fp [option] file-pointer
+		 */
+		cf::void_t print(const cf::char_t * prefix = "",
+						 const cf::size_t limit = -1,
+						 FILE * fp = stdout) const;
+	};
+}
+
+#endif // #ifndef __bin_h__
Index: trunk/include/cf/codec.h
===================================================================
--- trunk/include/cf/codec.h	(revision 4)
+++ trunk/include/cf/codec.h	(revision 4)
@@ -0,0 +1,110 @@
+/**
+ * @file codec.h
+ * @author myusgun@gmail.com
+ * @brief codec
+ */
+#ifndef __codec_h__
+#define __codec_h__
+
+#include "cf/bin.h"
+#include "cf/exception.h"
+
+#include <string>
+
+namespace cf
+{
+	/**
+	 * codec
+	 */
+	namespace codec
+	{
+		/**
+		 * interface
+		 */
+		class ICodec
+		{
+		public:
+			/**
+			 * encode(virtual)
+			 * @return encoded string
+			 * @param in input
+			 * @throw cf::exception
+			 */
+			virtual std::string encode(const bin & in) const
+				throw (cf::exception) = 0;
+
+			/**
+			 * decode(virtual)
+			 * @return decoded binary
+			 * @param in input
+			 * @throw cf::exception
+			 */
+			virtual bin decode(const std::string & in) const
+				throw (cf::exception) = 0;
+		};
+
+		/**
+		 * base64 encoder/decoder
+		 */
+		class base64 : public ICodec
+		{
+		public:
+			/**
+			 * get instance
+			 * @return base64 instance
+			 */
+			static base64 * getInstance();
+
+			/**
+			 * base64 encode
+			 * @return base64 encoded string
+			 * @param in input
+			 * @throw cf::exception
+			 */
+			std::string encode(const bin & in) const
+				throw (cf::exception);
+
+			/**
+			 * base64 decode
+			 * @return base64 decoded binary
+			 * @param in base64 string
+			 * @throw cf::exception
+			 */
+			bin decode(const std::string & in) const
+				throw (cf::exception);
+		};
+
+		/**
+		 * hex encoder/decoder
+		 */
+		class hex : public ICodec
+		{
+		public:
+			/**
+			 * get instance
+			 * @return hex instance
+			 */
+			static hex * getInstance();
+
+			/**
+			 * hex encode
+			 * @return hex encoded string
+			 * @param in input
+			 * @throw cf::exception
+			 */
+			std::string encode(const bin & in) const
+				throw (cf::exception);
+
+			/**
+			 * hex decode
+			 * @return hex decoded binary
+			 * @param in hex string
+			 * @throw cf::exception
+			 */
+			bin decode(const std::string & in) const
+				throw (cf::exception);
+		};
+	};
+}
+
+#endif // #ifndef __codec_h__
Index: trunk/include/cf/exception.h
===================================================================
--- trunk/include/cf/exception.h	(revision 4)
+++ trunk/include/cf/exception.h	(revision 4)
@@ -0,0 +1,115 @@
+/**
+ * @file exception.h
+ * @author myusgun@gmail.com
+ * @brief exception
+ */
+#ifndef __exception_h__
+#define __exception_h__
+
+#include "cf/types.h"
+#include "cf/formatter.hpp"
+
+#include <string>
+#include <vector>
+#include <exception>
+
+#define _SOURCE_INFO			__FILE__, __LINE__, __func__
+#define THROW_EXCEPTION(_m)		throw cf::exception(STR(_m).c_str(), _SOURCE_INFO)
+#define FORWARD_EXCEPTION(_e)	throw cf::exception(_e, _SOURCE_INFO)
+
+namespace cf
+{
+	/**
+	 * exception
+	 */
+	class exception : public std::exception
+	{
+	private:
+		std::string mMessage;
+		std::string mFile;
+		cf::int32_t mLine;
+		std::string mFunction;
+#ifndef _HPUX
+		std::vector<exception> mStack;
+#endif
+
+	public:
+		/**
+		 * constructor
+		 * @param message error message
+		 * @param file source filename
+		 * @param func function
+		 * @param line source line
+		 * @see THROW_EXCEPTION
+		 */
+		exception(const cf::char_t * message,
+				  const cf::char_t * file,
+				  const cf::int32_t line,
+				  const cf::char_t * func);
+
+		/**
+		 * constructor(for stack)
+		 * @param ex previous exception
+		 * @param file source filename
+		 * @param func function
+		 * @param line source line
+		 * @see FORWARD_EXCEPTION
+		 * @remarks make thrown-stack
+		 */
+		exception(const exception & ex,
+				  const cf::char_t * file,
+				  const cf::int32_t line,
+				  const cf::char_t * func);
+
+		/**
+		 * destructor derived from std::exception::~exception()
+		 */
+		~exception()
+			throw ();
+
+		/**
+		 * std::exception::what()
+		 * @return error message
+		 */
+		const cf::char_t * what() const
+			throw ();
+
+		/**
+		 * get source file name
+		 * @return source file name
+		 */
+		const cf::char_t * file() const;
+
+		/**
+		 * get source line
+		 * @return source line
+		 */
+		cf::int32_t line() const;
+
+		/**
+		 * get function name
+		 * @return function name
+		 */
+		const cf::char_t * function() const;
+
+		/**
+		 * get stack of thrown-exceptions
+		 * @return stack of thrown-exceptions
+		 */
+		std::string stackTrace() const;
+
+		/**
+		 * get GetLastError() in windows; otherwise, errno
+		 * @return system error code
+		 */
+		static cf::int32_t systemCode();
+
+		/**
+		 * get error message for system error code
+		 * @return error message for system error code
+		 */
+		static std::string systemMessage();
+	};
+}
+
+#endif // #ifndef __exception_h__
Index: trunk/include/cf/file.h
===================================================================
--- trunk/include/cf/file.h	(revision 4)
+++ trunk/include/cf/file.h	(revision 4)
@@ -0,0 +1,215 @@
+/**
+ * @file file.h
+ * @author myusgun@gmail.com
+ * @brief file
+ */
+#ifndef __file_h__
+#define __file_h__
+
+#include "cf/exception.h"
+#include "cf/bin.h"
+
+#include <string>
+#include <list>
+
+namespace cf
+{
+	/**
+	 * file
+	 */
+	class file
+	{
+	public:
+		/** file flag */
+		enum FILE_FLAG
+		{
+			READ	= 0x00000001,	/**< read-only */
+			WRITE	= 0x00000002,	/**< write-only */
+			RW		= 0x00000004,	/**< read & write */
+			CREATE	= 0x00000008,	/**< create */
+			TRUNC	= 0x00000010,	/**< truncate */
+			APPEND	= 0x00000020,	/**< append */
+			EXCL	= 0x00000040,	/**< exclusive */
+			LOCK	= 0x00010000	/**< lock */
+		};
+
+		/** whence for seeking */
+		enum FILE_WHENCE
+		{
+			BEGIN,		/**< from begin */
+			CURRENT,	/**< from current position */
+			END			/**< from end */
+		};
+
+		/** type of dir/file entry */
+		enum ENTRY_TYPE
+		{
+			UNDEFINED,		/**< undefined in file::ENTRY_TYPE */
+			DIRECTORY,		/**< directory */
+			REGULAR_FILE	/**< regular file */
+		};
+
+		/** dir/file entry */
+		typedef struct ENTRY
+		{
+			std::string mName;	/**< name */
+			ENTRY_TYPE mType;	/**< @see ENTRY_TYPE */
+		} ENTRY;
+
+		typedef std::list<file::ENTRY> EntryList;
+
+	private:
+		cf::int32_t mFD;
+		std::string mPath;
+		cf::bool_t mIsLocked;
+
+	public:
+		/**
+		 * constructor
+		 * @param path file path
+		 * @throw cf::exception
+		 */
+		file(const cf::char_t * path)
+			throw (cf::exception);
+
+		/**
+		 * destructor
+		 */
+		~file();
+
+		/**
+		 * get path delimiter of system
+		 * @return delimiter
+		 * @remarks on windows, "\\"; on *nix, "/"
+		 */
+		static const cf::char_t * getDelimiter();
+
+		/**
+		 * open
+		 * @param flag flag
+		 * @throw cf::exception
+		 */
+		cf::void_t open(const cf::int32_t flag)
+			throw (cf::exception);
+
+		/**
+		 * close
+		 * @throw cf::exception
+		 * @remarks if lock-file was not removed, an exception is thrown
+		 */
+		cf::void_t close()
+			throw (cf::exception);
+
+		/**
+		 * is opened ?
+		 * @return true; false
+		 */
+		cf::bool_t isOpened();
+
+		/**
+		 * set position
+		 * @return offset
+		 * @param offset offset
+		 * @param whence whence
+		 * @throw cf::exception
+		 */
+		cf::int32_t seek(const cf::int32_t offset,
+						 const cf::int32_t whence = cf::file::BEGIN)
+			throw (cf::exception);
+
+		/**
+		 * get current file position
+		 * @return get position
+		 * @throw cf::exception
+		 */
+		cf::int32_t tell()
+			throw (cf::exception);
+
+		/**
+		 * get size
+		 * @return file size
+		 * @throw cf::exception
+		 */
+		cf::int32_t size()
+			throw (cf::exception);
+
+		/**
+		 * exists ?
+		 * @return true; false
+		 */
+		cf::bool_t exists() const;
+
+		/**
+		 * read
+		 * @param out a buffer, allocated ahead
+		 * @throw cf::exception
+		 */
+		cf::void_t read(bin & out)
+			throw (cf::exception);
+
+		/**
+		 * read
+		 * @return RawStub
+		 * @param len read bytes
+		 * @throw cf::exception
+		 */
+		bin read(const cf::int32_t len = 0)
+			throw (cf::exception);
+
+		/**
+		 * write
+		 * @param in RawStub instance
+		 * @throw cf::exception
+		 */
+		cf::void_t write(const bin & in)
+			throw (cf::exception);
+
+		/**
+		 * remove file
+		 * @throw cf::exception
+		 */
+		cf::void_t remove()
+			throw (cf::exception);
+
+		/**
+		 * rename file
+		 * @param path new path
+		 * @throw cf::exception
+		 */
+		cf::void_t rename(const cf::char_t * path)
+			throw (cf::exception);
+
+		/**
+		 * get path
+		 * @return path
+		 */
+		const cf::char_t * getPath() const;
+
+		/**
+		 * is locked ?
+		 * @return true; false
+		 */
+		cf::bool_t isLocked() const;
+
+		/**
+		 * make directory
+		 * @param path directory path
+		 * @throw cf::exception
+		 */
+		static cf::void_t makedir(const cf::char_t * path)
+			throw (cf::exception);
+
+		/**
+		 * get directory entry-list
+		 * @param path directory entry-list
+		 * @param exceptDots except . and .. from list ? (as default, true)
+		 * @throw cf::exception
+		 * @see EntryList, ENTRY, ENTRY_TYPE
+		 */
+		static EntryList getEntryList(const cf::char_t * path,
+									  const cf::bool_t exceptDots = true)
+			throw (cf::exception);
+	};
+}
+
+#endif // #ifndef __file_h__
Index: trunk/include/cf/formatter.hpp
===================================================================
--- trunk/include/cf/formatter.hpp	(revision 4)
+++ trunk/include/cf/formatter.hpp	(revision 4)
@@ -0,0 +1,57 @@
+/**
+ * @file formatter.hpp
+ * @author myusgun@gmail.com
+ * @brief Formatter
+ */
+#ifndef __formatter_hpp__
+#define __formatter_hpp__
+
+#include <sstream>
+#include <string>
+
+/**
+ * make string using Formatter
+ * @see Formatter
+ */
+#define STR(_x)	(cf::formatter() << _x).str()
+
+namespace cf
+{
+	/**
+	 * a wrapper-class of std::ostringstream for temporary instance
+	 * @see STR() macro
+	 * @remarks http://stackoverflow.com/questions/303562/c-format-macro-inline-ostringstream
+	 */
+	class formatter
+	{
+	private:
+		std::ostringstream mOSS;
+
+	public:
+		template<typename T>
+		formatter & operator << (const T & v)
+		{
+			mOSS << v;
+			return *this;
+		}
+
+		formatter & operator << (cf::char_t * v)
+		{
+			mOSS << (v ? v : "null");
+			return *this;
+		}
+
+		formatter & operator << (const cf::char_t * v)
+		{
+			mOSS << (v ? v : "null");
+			return *this;
+		}
+
+		std::string str()
+		{
+			return mOSS.str();
+		}
+	};
+}
+
+#endif // #ifndef __formatter_hpp__
Index: trunk/include/cf/jni.h
===================================================================
--- trunk/include/cf/jni.h	(revision 4)
+++ trunk/include/cf/jni.h	(revision 4)
@@ -0,0 +1,50 @@
+/**
+ * @file jni.h
+ * @author myusgun@gmail.com
+ * @brief JNI
+ */
+#ifndef __jni_h__
+#define __jni_h__
+
+#include "cf/bin.h"
+#include "cf/exception.h"
+
+#include <jni.h>
+#include <string>
+
+namespace cf
+{
+	/**
+	 * jni
+	 */
+	class jni
+	{
+	private:
+		JNIEnv * mJNIEnv;
+
+		cf::void_t releaseString(jstring jinput,
+								 cf::char_t * in);
+
+		cf::void_t releaseByteArray(jbyteArray jinput,
+									cf::char_t * in);
+
+		cf::void_t releaseLocalMemory(jobject in);
+
+	public:
+		/* from java */
+		bin getByteArray(jbyteArray jinput)
+			throw (cf::exception);
+
+		std::string getString(jstring jinput)
+			throw (cf::exception);
+
+		/* to java */
+		cf::void_t throwException(const char * message);
+
+		jbyteArray newByteArray(const bin & in);
+
+		jstring newString(const std::string & in);
+	};
+}
+
+#endif // #ifndef __jni_h__
Index: trunk/include/cf/logger.h
===================================================================
--- trunk/include/cf/logger.h	(revision 4)
+++ trunk/include/cf/logger.h	(revision 4)
@@ -0,0 +1,195 @@
+/**
+ * @file logger.h
+ * @author myusgun@gmail.com
+ * @brief logger
+ */
+#ifndef __logger_h__
+#define __logger_h__
+
+#include "cf/exception.h"
+#include "cf/task.h"
+#include "cf/util.h"
+
+#include <stdio.h>
+
+#include <string>
+#include <vector>
+
+namespace cf
+{
+	/**
+	 * singleton logger
+	 */
+	class logger
+	{
+	private:
+		/* log file management */
+		std::string mPath;
+		cf::int32_t mLogLevel;
+		task::mutex mOpenMutex;
+		task::mutex mRenameMutex;
+
+		typedef struct _LOG_CTX
+		{
+			cf::int32_t mOption;
+			struct
+			{
+				cf::int32_t mMaxLogSize;		/**< mega-bytes */
+				cf::int32_t mCurrentDateTime;	/**< yyyymmdd */
+			} mOptionParam;
+
+			std::string mPrefix;
+			std::string mDescription;
+			std::string mFullPath;
+			FILE * mFP;
+		} LOG_CTX;
+
+		/* level == index-of-vector */
+		std::vector<LOG_CTX> mLogPool;
+
+		/**
+		 * constructor
+		 * @throw cf::exception
+		 */
+		logger()
+			throw (cf::exception);
+
+		/**
+		 * destructor
+		 */
+		~logger();
+
+		/**
+		 * open log file
+		 * @param level level to open file
+		 * @throw cf::exception
+		 */
+		cf::void_t open(const cf::int32_t level)
+			throw (cf::exception);
+
+		/**
+		 * rename for rotation
+		 * @param level log level
+		 * @throw cf::exception
+		 */
+		cf::void_t rename(const cf::int32_t level)
+			throw (cf::exception);
+
+		/**
+		 * overwrite newfp to fp for fullpath
+		 * @param prefix prefix of fileprefix
+		 * @param option option
+		 * @param newfp new fp
+		 */
+		cf::void_t replace(const std::string & prefix,
+						   const cf::int32_t option,
+						   FILE * newfp);
+
+		/**
+		 * date rotation
+		 * @param level log level
+		 * @param dt datetime
+		 * @throw cf::exception
+		 */
+		cf::void_t rotateByDate(const cf::int32_t level,
+								const util::datetime & dt)
+			throw (cf::exception);
+
+		/**
+		 * size rotation
+		 * @param level log level
+		 * @throw cf::exception
+		 */
+		cf::void_t rotateBySize(const cf::int32_t level)
+			throw (cf::exception);
+
+	public:
+		/**
+		 * log option
+		 */
+		enum _LOG_OPTION
+		{
+			NO_OPTION	= 0x00000000,	/**< no option */
+			FORCED		= 0x00000001,	/**< forced write */
+			DAILY		= 0x00000010,	/**< daily rotation */
+			SIZE		= 0x00000020,	/**< size rotation */
+			SECURE		= 0x00000100	/**< encrypt message */
+		};
+
+		/**
+		 * get instance
+		 * @return global instance
+		 */
+		static logger * getInstance();
+
+		/**
+		 * initialize
+		 * @param path directory path for log
+		 * @throw cf::exception
+		 */
+		cf::void_t init(const std::string & path);
+
+		/**
+		 * add log level
+		 * @param prefix file prefix
+		 * @param level log level
+		 * @param description description for log level
+		 * @param option option(i.e., forced, rotation)
+		 * @param rotationSize rotation parameter(i.e., size)
+		 * @throw cf::exception
+		 * @see _LOG_OPTION
+		 * @remarks start from 1
+		 */
+		cf::void_t add(const std::string & prefix,
+					   const cf::int32_t level,
+					   const std::string & description,
+					   const cf::int32_t option,
+					   const cf::int32_t rotationSize = 0)
+			throw (cf::exception);
+
+		/**
+		 * get log level
+		 * @return log level
+		 */
+		cf::int32_t getLevel();
+
+		/**
+		 * set log level
+		 * @param level log level
+		 */
+		cf::void_t setLevel(const cf::int32_t level);
+
+		/**
+		 * get file path
+		 * @return file path
+		 * @param level log level
+		 * @throw cf::exception
+		 */
+		std::string getPath(const cf::int32_t level) const
+			throw (cf::exception);
+
+		/**
+		 * is log level registered ?
+		 * @return true; false
+		 * @param level log level
+		 */
+		cf::bool_t isRegistered(const cf::int32_t level) const;
+
+		/**
+		 * is log level enabled ?
+		 * @return true; false
+		 * @param level log level
+		 */
+		cf::bool_t isEnabled(const cf::int32_t level) const;
+
+		/**
+		 * write
+		 * @param level level
+		 * @param msg message
+		 */
+		cf::void_t write(const cf::int32_t level,
+						 const std::string & msg);
+	};
+}
+
+#endif // #ifndef __logger_h__
Index: trunk/include/cf/memory.h
===================================================================
--- trunk/include/cf/memory.h	(revision 4)
+++ trunk/include/cf/memory.h	(revision 4)
@@ -0,0 +1,66 @@
+/**
+ * @file memory.h
+ * @author myusgun@gmail.com
+ * @brief memory
+ */
+#ifndef __memory_h__
+#define __memory_h__
+
+#include "cf/types.h"
+#include "cf/exception.h"
+
+namespace cf
+{
+	/**
+	 * memory
+	 */
+	class memory
+	{
+	private:
+		cf::void_t * mMemory;
+
+	public:
+		/**
+		 * constructor. allocate memory
+		 * @param size memory size
+		 * @throw cf::exception
+		 */
+		memory(const cf::size_t size = 0)
+			throw (cf::exception);
+
+		/**
+		 * destructor. free memory
+		 */
+		~memory();
+
+		/**
+		 * get buffer memory address
+		 */
+		cf::void_t * buffer();
+
+		/**
+		 * static member function to get an address of allocated memory
+		 * @param size memory size
+		 * @throw cf::exception
+		 */
+		static cf::void_t * alloc(const cf::size_t size)
+			throw (cf::exception);
+
+		/**
+		 * static member function to free a memory allocated from cf::memory::alloc()
+		 * @param mem memory address
+		 * @throw cf::exception
+		 */
+		static cf::void_t free(cf::void_t * mem)
+			throw (cf::exception);
+
+		/**
+		 * static member function to check the memory is valid
+		 * @return true; false
+		 * @param mem memory address
+		 */
+		static cf::bool_t valid(const cf::void_t * mem);
+	};
+}
+
+#endif
Index: trunk/include/cf/network.h
===================================================================
--- trunk/include/cf/network.h	(revision 4)
+++ trunk/include/cf/network.h	(revision 4)
@@ -0,0 +1,178 @@
+/**
+ * @file network.h
+ * @author myusgun@gmail.com
+ * @brief network
+ */
+#ifndef __tcp_h__
+#define __tcp_h__
+
+#include "cf/exception.h"
+#include "cf/bin.h"
+
+#include <string>
+
+namespace cf
+{
+	/**
+	 * network
+	 */
+	namespace network
+	{
+		/**
+		 * TCP Socket
+		 */
+		class tcp
+		{
+		private:
+			cf::socket_t mSocket;
+			cf::int32_t mTimeout;
+			std::string mHost;
+			cf::uint16_t mPort;
+
+			/**
+			 * receive
+			 * @param out created-bin
+			 * @throw cf::exception
+			 */
+			cf::void_t receive(bin & out)
+				throw (cf::exception);
+
+		public:
+			/**
+			 * constructor
+			 * @param attachedSocket [option] socket descriptor for attachment
+			 * @throw cf::exception
+			 */
+			tcp(const cf::socket_t attachedSocket = -1)
+				throw (cf::exception);
+
+			/**
+			 * destructor
+			 */
+			~tcp();
+
+			/**
+			 * close connection
+			 */
+			cf::void_t close();
+
+			/**
+			 * connect to host:port
+			 * @param host host
+			 * @param port port
+			 * @param timeout timeout
+			 * @throw cf::exception
+			 */
+			cf::void_t connect(const cf::char_t * host,
+							   const cf::uint16_t port,
+							   const cf::int32_t timeout = 0)
+				throw (cf::exception);
+
+			/**
+			 * server ready
+			 * @param port port
+			 * @param backlog [option] backlog
+			 * @throw cf::exception
+			 */
+			cf::void_t listen(const cf::uint16_t port,
+							  const cf::int32_t backlog = 5)
+				throw (cf::exception);
+
+			/**
+			 * accept client
+			 * @return an instance of tcp client
+			 * @throw cf::exception
+			 */
+			tcp accept()
+				throw (cf::exception);
+
+			/**
+			 * attach socket
+			 * @param sock socket descriptor
+			 * @throw cf::exception
+			 */
+			cf::void_t attach(const cf::socket_t sock)
+				throw (cf::exception);
+
+			/**
+			 * detach socket
+			 * @return socket descriptor
+			 * @throw cf::exception
+			 */
+			cf::socket_t detach()
+				throw (cf::exception);
+
+			/**
+			 * send
+			 * @param in data
+			 * @throw cf::exception
+			 */
+			cf::void_t send(const bin & in)
+				throw (cf::exception);
+
+			/**
+			 * receive
+			 * @return received data
+			 * @param size expected data length
+			 * @throw cf::exception
+			 */
+			bin receive(const cf::int32_t size)
+				throw (cf::exception);
+
+			/**
+			 * receive
+			 * @return received all of data
+			 * @throw cf::exception
+			 */
+			bin receive()
+				throw (cf::exception);
+
+			/**
+			 * get socket option
+			 */
+			cf::void_t getOption(const cf::int32_t optname,
+								 cf::void_t * optval,
+								 cf::int32_t * optlen)
+				throw (cf::exception);
+
+			/**
+			 * set socket option
+			 */
+			cf::void_t setOption(const cf::int32_t optname,
+								 const cf::void_t * optval,
+								 const cf::int32_t optlen)
+				throw (cf::exception);
+
+			/**
+			 * set non-blocking
+			 * @param flag true; false
+			 * @see setTimeout
+			 */
+			cf::void_t setNonBlocking(const cf::bool_t flag);
+
+			/**
+			 * set timeout
+			 * @param seconds timeout seconds
+			 * @see setNonBlocking()
+			 */
+			cf::void_t setTimeout(const cf::int32_t seconds);
+		};
+
+		/**
+		 * NIC(Network Interface Card)
+		 */
+		class nic
+		{
+		public:
+			/**
+			 * get mac address
+			 * @return mac address
+			 * @throw cf::exception
+			 */
+			static std::string getMACAddress()
+				throw (cf::exception);
+		};
+	}
+}
+
+#endif // #ifndef __tcp_h__
Index: trunk/include/cf/task.h
===================================================================
--- trunk/include/cf/task.h	(revision 4)
+++ trunk/include/cf/task.h	(revision 4)
@@ -0,0 +1,206 @@
+/**
+ * @file task.h
+ * @author myusgun@gmail.com
+ * @brief task
+ */
+#ifndef __task_h__
+#define __task_h__
+
+#include "cf/exception.h"
+
+#define SYNCHRONIZED(_s)	for (cf::task::scopedLock _sl(&_s) ; _sl.synchronizer()->locked() ; _sl.synchronizer()->unlock())
+
+namespace cf
+{
+	/**
+	 * task
+	 */
+	namespace task
+	{
+		/**
+		 * interface of synchronizer, like a mutex
+		 */
+		class ISynchronizer
+		{
+		public:
+			/**
+			 * lock
+			 * @throw cf::exception
+			 */
+			virtual cf::void_t lock() throw (cf::exception) = 0;
+
+			/**
+			 * unlock
+			 * @throw cf::exception
+			 */
+			virtual cf::void_t unlock() throw (cf::exception) = 0;
+
+			/**
+			 * is locked ?
+			 * @return true; false
+			 */
+			virtual cf::bool_t locked() const = 0;
+		};
+
+		/**
+		 * mutex
+		 */
+		class mutex : public ISynchronizer
+		{
+		private:
+			cf::bool_t mIsLocked;
+			cf::void_t * mMutex;
+
+		public:
+			/**
+			 * constructor
+			 * @throw cf::exception
+			 */
+			mutex()
+				throw (cf::exception);
+
+			/**
+			 * destructor
+			 */
+			~mutex();
+
+			/**
+			 * lock
+			 * @throw cf::exception
+			 */
+			cf::void_t lock()
+				throw (cf::exception);
+
+			/**
+			 * unlock
+			 * @throw cf::exception
+			 */
+			cf::void_t unlock()
+				throw (cf::exception);
+
+			/**
+			 * trylock
+			 * @return true; false
+			 */
+			cf::bool_t trylock()
+				throw (cf::exception);
+
+			/**
+			 * is locked ?
+			 * @return true; false
+			 */
+			cf::bool_t locked() const;
+		};
+
+		/**
+		 * scoped lock
+		 * @see SYNCHRONIZE
+		 */
+		class scopedLock
+		{
+		private:
+			ISynchronizer * mSynchronizer;
+
+		public:
+			/**
+			 * constructor for locking
+			 * @throw cf::exception
+			 */
+			scopedLock(ISynchronizer * inst)
+				throw (cf::exception);
+
+			/**
+			 * destructor for unlocking
+			 */
+			~scopedLock();
+
+			/**
+			 * get synchronizer
+			 * @return an instance of synchronizer
+			 */
+			ISynchronizer * synchronizer();
+		};
+
+		/**
+		 * thread
+		 */
+		class thread
+		{
+		public:
+			/** a prototype of worker function */
+			typedef cf::int32_t(*ThreadFunction)(cf::void_t *);
+
+			typedef struct _THREAD_CTX
+			{
+				cf::bool_t mIsRunning;
+				ThreadFunction mCallback;
+				cf::void_t * mArgument;
+				cf::int32_t mReturned;
+			} THREAD_CTX;
+
+		private:
+			THREAD_CTX mCtx;
+			cf::void_t * mThreadID;
+			mutex mMutex;
+
+		public:
+			/**
+			 * constructor
+			 * @param callback thread worker function
+			 */
+			thread(const ThreadFunction callback)
+				throw (cf::exception);
+
+			/**
+			 * destructor
+			 */
+			~thread();
+
+			/**
+			 * start thread
+			 * @param arg thread argument
+			 * @throw cf::exception
+			 */
+			cf::void_t start(cf::void_t * arg)
+				throw (cf::exception);
+
+			/**
+			 * join thread
+			 */
+			cf::void_t join();
+
+			/**
+			 * is running ?
+			 * @return true; false
+			 */
+			cf::bool_t isRunning() const;
+
+			/**
+			 * get thread id
+			 * @return thread id
+			 */
+			static cf::uint32_t id();
+
+			/**
+			 * sleep
+			 * @param milliseconds milliseconds
+			 */
+			static cf::void_t sleep(const cf::int32_t milliseconds);
+		};
+
+		/**
+		 * process
+		 */
+		class process
+		{
+		public:
+			/**
+			 * get process id
+			 * @return process id
+			 */
+			static cf::uint32_t id();
+		};
+	}
+}
+
+#endif // #ifndef __task_h__
Index: trunk/include/cf/test.hpp
===================================================================
--- trunk/include/cf/test.hpp	(revision 4)
+++ trunk/include/cf/test.hpp	(revision 4)
@@ -0,0 +1,116 @@
+/**
+ * @file test.hpp
+ * @author myusgun@gmail.com
+ * @brief Testing Macros
+ */
+#ifndef __test_hpp__
+#define __test_hpp__
+
+#include "cf/exception.h"
+#include "cf/util.h"
+
+#include <iostream>
+#include <stdio.h>
+
+#define _SOURCE	"[" << __FILE__ << ":" << __LINE__ << "] "
+#define P_ERROR(_e)	std::cout << _SOURCE << _e.stackTrace() << std::endl
+
+#define TEST_CLASS_NAME(_TESTCASE,_TEST)		_TESTCASE##_##_TEST##_Test
+#define TEST_FUNC_NAME(_TESTCASE,_TEST)		_TESTCASE##_##_TEST##_Run
+
+class cfTest
+{
+private:
+	cf::int32_t mArgc;
+	cf::char_t ** mArgv;
+	cf::int32_t mNumberOfTest;
+	cf::int32_t mFailed;
+	cf::int32_t mTime;
+	cf::bool_t mIsStackPrint;
+
+	cfTest() : mArgc(0), mArgv(NULL), mNumberOfTest(0), mFailed(0), mTime(0), mIsStackPrint(false) {
+		std::cout << "[==========] Begin" << std::endl;
+		std::cout << "[----------] Preparing" << std::endl;
+	}
+
+	~cfTest() {
+		std::cout << "[----------] " << mTime << " ms total" << std::endl;
+		std::cout << "[  PASSED  ] " << mNumberOfTest - mFailed << " tests" << std::endl;
+		std::cout << "[  FAILED  ] " << mFailed << " tests " << std::endl;
+		std::cout << "[==========] End" << std::endl;
+	}
+
+public:
+	static cfTest & getInstance() {
+		static cfTest instance;
+		return instance;
+	}
+
+	cf::void_t init(cf::int32_t argc, cf::char_t ** argv) { mArgc = argc; mArgv = argv; }
+	cf::void_t regist() { ++mNumberOfTest; }
+	cf::void_t failed() { ++mFailed; }
+	cf::void_t time(cf::int32_t ms) { mTime += ms; }
+	cf::int32_t result() const { return mFailed; }
+	cf::void_t printStack(const cf::bool_t flag) { mIsStackPrint = flag; }
+	cf::bool_t printStack() { return mIsStackPrint; }
+	cf::int32_t getArgumentCount() { return mArgc; }
+	cf::char_t * getArgumentValue(int idx) { return mArgv[idx]; }
+};
+
+#define TEST_INIT(_c,_v)	cfTest::getInstance().init(_c,_v)
+#define TEST_RESULT()		cfTest::getInstance().result()
+#define TEST_ARGC			cfTest::getInstance().getArgumentCount()
+#define TEST_ARGV(_i)		cfTest::getInstance().getArgumentValue(_i)
+
+#define GET_TIME(_c)		(_c.mHour * (60 * 60 * 1000) + _c.mMin * (60 * 1000) + _c.mSec * 1000 + _c.mUsec)
+
+#define TEST(_TESTCASE,_TEST)	\
+	cf::void_t TEST_FUNC_NAME(_TESTCASE,_TEST)() throw (cf::exception);	\
+	class TEST_CLASS_NAME(_TESTCASE,_TEST) {	\
+	private:	\
+		cf::bool_t mStatus;	\
+		cf::util::datetime mBegin;	\
+		cf::util::datetime mEnd;	\
+		cf::int32_t mRunTime;	\
+	public:	\
+		TEST_CLASS_NAME(_TESTCASE,_TEST)() : mStatus(true), mRunTime(0) {	\
+			cfTest::getInstance().regist();	\
+			std::cout << "[ RUN      ] " << #_TESTCASE << "." << #_TEST << std::endl;	\
+			try { mBegin = cf::util::getInstance()->getDateTime(); } catch (cf::exception &e) { P_ERROR(e); }	\
+			try { TEST_FUNC_NAME(_TESTCASE, _TEST)();              } catch (cf::exception &e) { P_ERROR(e); mStatus = false; }	\
+			try { mEnd = cf::util::getInstance()->getDateTime();   } catch (cf::exception &e) { P_ERROR(e); }	\
+			cf::int32_t begin = GET_TIME(mBegin);	\
+			cf::int32_t end = GET_TIME(mEnd);	\
+			mRunTime = end - begin;	\
+			cfTest::getInstance().time(mRunTime);	\
+			if (mStatus) {	\
+				std::cout << "[       OK ] ";	\
+			} else {	\
+				std::cout << "[  FAILED  ] ";	\
+				cfTest::getInstance().failed();	\
+			}	\
+			std::cout << #_TESTCASE << "." << #_TEST << " (" << mRunTime << " ms)" << std::endl;	\
+		}	\
+		cf::int32_t getTime() const { return mRunTime; }	\
+	};	\
+	cf::void_t TEST_FUNC_NAME(_TESTCASE,_TEST)() throw (cf::exception)
+
+#define TEST_RUN(_TESTCASE,_TEST)	\
+	TEST_CLASS_NAME(_TESTCASE,_TEST)	_TESTCASE##_TEST##_inst;	\
+
+#define GET_TIME_OF_TEST(_TESTCASE,_TEST)	\
+	_TESTCASE##_TEST##_inst.getTime()
+
+#define ASSERT_NO_throw (_SENTENCE)	\
+	try { _SENTENCE; } catch(cf::exception &e) { P_ERROR(e); return; }
+
+#define ASSERT_EXCEPTION(_SENTENCE)	\
+	try { _SENTENCE; } catch(cf::exception &e) { if(cfTest::getInstance().printStack()) P_ERROR(e); else std::cout << _SOURCE << e.what() << std::endl; }
+
+#define PRINT_STACK(_b)	\
+	cfTest::getInstance().printStack(_b)
+
+#define ASSERT_EQ(_lhs,_rhs)	\
+	if ((_lhs) != (_rhs))	CF_THROW(#_lhs << " != " << #_rhs)
+
+#endif // #ifndef __test_hpp__
Index: trunk/include/cf/types.h
===================================================================
--- trunk/include/cf/types.h	(revision 4)
+++ trunk/include/cf/types.h	(revision 4)
@@ -0,0 +1,50 @@
+/**
+ * @file types.h
+ * @author myusgun@gmail.com
+ * @brief common header
+ */
+#ifndef __types_h__
+#define __types_h__
+
+#if defined(WIN32) || defined(_WIN32) || defined(_WIN64)
+# define _ON_WINDOWS
+# define __func__	__FUNCTION__
+# define snprintf	_snprintf
+#endif
+
+namespace cf
+{
+	typedef void				void_t;
+	typedef char				char_t;
+	typedef unsigned char		uchar_t;
+	typedef signed char			int8_t;
+	typedef uchar_t				uint8_t;
+	typedef signed short		int16_t;
+	typedef unsigned short		uint16_t;
+	typedef signed int			int32_t;
+	typedef unsigned int		uint32_t;
+	typedef long				long_t;
+	typedef unsigned long		ulong_t;
+	typedef bool				bool_t;
+#ifdef _ON_WINDOWS
+	typedef signed __int64		int64_t;
+	typedef unsigned __int64	uint64_t;
+#else
+	typedef signed long long	int64_t;
+	typedef unsigned long long	uint64_t;
+#endif
+
+#ifdef _ON_WINDOWS
+	typedef uint32_t			size_t;
+# ifdef _WIN64
+	typedef uint64_t			socket_t;
+# else
+	typedef uint32_t			socket_t;
+# endif
+#else
+	typedef ulong_t				size_t;
+	typedef int32_t				socket_t;
+#endif
+};
+
+#endif // #ifndef __types_h__
Index: trunk/include/cf/util.h
===================================================================
--- trunk/include/cf/util.h	(revision 4)
+++ trunk/include/cf/util.h	(revision 4)
@@ -0,0 +1,58 @@
+/**
+ * @file util.h
+ * @author myusgun@gmail.com
+ * @brief util
+ */
+#ifndef __util_h__
+#define __util_h__
+
+#include "cf/exception.h"
+
+namespace cf
+{
+	/**
+	 * util
+	 */
+	class util
+	{
+	public:
+		/** date/time/week */
+		typedef struct datetime
+		{
+			cf::int32_t mYear;		/**< year */
+			cf::int32_t mMonth;		/**< month */
+			cf::int32_t mDay;		/**< day */
+			cf::int32_t mWeek;		/**< weekday (0:SUN ~ 6:SAT) */
+			std::string mWeekName;	/**< string representation of weekday (SUN ~ SAT) */
+
+			cf::int32_t mHour;		/**< hour */
+			cf::int32_t mMin;		/**< minute */
+			cf::int32_t mSec;		/**< second */
+			cf::int32_t mUsec;		/**< micro second */
+		} datetime;
+
+	public:
+		/**
+		 * get instance
+		 * @return instance
+		 */
+		static util * getInstance();
+
+		/**
+		 * get current time
+		 * @return datetime structure
+		 * @throw cf::exception
+		 * @see struct datetime
+		 */
+		datetime getDateTime() const
+			throw (cf::exception);
+
+		/**
+		 * get current timestamp
+		 * @return time_t
+		 */
+		cf::int64_t getTimeStamp() const;
+	};
+}
+
+#endif // #ifndef __util_h__
Index: trunk/jni/makefile
===================================================================
--- trunk/jni/makefile	(revision 4)
+++ trunk/jni/makefile	(revision 4)
@@ -0,0 +1,41 @@
+#----------------------------------------------------------
+# platform
+#----------------------------------------------------------
+include ../makeinclude/userdefine.mk
+include ../makeinclude/platform.mk
+
+#----------------------------------------------------------
+# env
+#----------------------------------------------------------
+JAVA_BIN		= $(JAVA_HOME)/bin
+
+JAVA_PACKAGE	= com/softforum/dxp
+
+SRCS			= $(shell find . -name "*.java")
+OBJS			= $(addprefix $(BUILD_PATH)/$(JAVA_PACKAGE)/,$(SRCS:.java=.class))
+
+TARGET			= $(BUILD_PATH)/xdb.jar
+
+Z_PACKAGE		= ../z_package
+
+#----------------------------------------------------------
+# label
+#----------------------------------------------------------
+all: $(BUILD_PATH) $(TARGET)
+	@echo ========== Complete JNI compilation ==========
+
+# mkdir
+$(BUILD_PATH):
+	@if [ ! -d $@ ] ; then mkdir $@ ; fi
+
+$(TARGET): $(SRCS)
+	$(JAVA_BIN)/javac -d $(BUILD_PATH) $?
+	cd $(BUILD_PATH); $(JAVA_BIN)/jar cf $@ com
+	$(JAVA_BIN)/javah -jni -classpath $(BUILD_PATH) com.softforum.dxp.DXP
+	$(JAVA_BIN)/javah -jni -classpath $(BUILD_PATH) com.softforum.xdb.XDB
+
+clean: dummy
+	rm -rf $(TARGET) *.h
+
+dummy:
+
Index: trunk/makefile
===================================================================
--- trunk/makefile	(revision 4)
+++ trunk/makefile	(revision 4)
@@ -0,0 +1,24 @@
+#----------------------------------------------------------
+# platform
+#----------------------------------------------------------
+include ./makeinclude/userdefine.mk
+include ./makeinclude/platform.mk
+
+TARGET	= \
+		  src	\
+		  doc	\
+
+#----------------------------------------------------------
+# label
+#----------------------------------------------------------
+.PHONY: $(TARGET)
+
+all:
+	make $(TARGET) mode=$@
+
+clean:
+	make $(TARGET) mode=$@
+
+$(TARGET):
+	cd $@; make ${mode}
+
Index: trunk/makeinclude/c-native-compiler.platform.mk
===================================================================
--- trunk/makeinclude/c-native-compiler.platform.mk	(revision 4)
+++ trunk/makeinclude/c-native-compiler.platform.mk	(revision 4)
@@ -0,0 +1,221 @@
+#------------------------------------------------------------
+# set command to check os
+#------------------------------------------------------------
+UNAME_S := $(shell uname -s)
+UNAME_M := $(shell uname -m)
+UNAME_R := $(shell uname -r)
+UNAME_V := $(shell uname -v)
+UNAME_A := $(shell uname -a)
+
+#------------------------------------------------------------
+# set options
+#------------------------------------------------------------
+ifeq ($(DEBUG), yes)
+	DEFS = -D_DEBUG
+	FLAG = -g
+else
+	DEFS = 
+	FLAG = -O2
+endif
+
+EXT_SHARED	= so
+EXT_STATIC	= a
+EXT_EXECUTE	= ex
+
+#------------------------------------------------------------
+# set platform
+#------------------------------------------------------------
+ifeq ($(UNAME_S), SunOS)
+	OS_FAMILY = solaris
+	ifeq ($(UNAME_M), i86pc)
+		ifeq ($(VER), 32)
+			OS_DEF = solaris_x86
+		else
+			OS_DEF = solaris_x86_64
+		endif
+	else
+		ifeq ($(VER), 32)
+			OS_DEF = solaris
+		else
+			OS_DEF = solaris64
+		endif
+	endif
+# java
+	ifeq ($(UNAME_M), i86pc)
+		JAVA_HOME = /usr/j2se
+	else
+		JAVA_HOME = /usr/java1.4.2
+	endif
+endif
+
+ifeq ($(UNAME_S), AIX)
+	OS_FAMILY = aix
+	ifeq ($(VER), 32)
+		OS_DEF = aix
+		JAVA_HOME = /usr/java14
+	else
+		OS_DEF = aix64
+		JAVA_HOME = /usr/java14_64
+	endif
+# java
+endif
+
+ifeq ($(UNAME_S), HP-UX)
+	OS_FAMILY = hp-ux
+	ifeq ($(UNAME_M), ia64)
+		UNAME_S := HP-UX_IA
+		ifeq ($(VER), 32)
+			OS_DEF = hp_ia
+		else
+			OS_DEF = hp_ia64
+		endif
+	else
+		ifeq ($(VER), 32)
+			OS_DEF = hp
+		else
+			OS_DEF = hp64
+		endif
+	endif
+# java
+	JAVA_HOME = /opt/java1.4
+endif
+
+ifeq ($(UNAME_S), Linux)
+	OS_FAMILY = linux
+	ifeq ($(UNAME_M), ppc64)
+		OS_DEF = linux_ppc64
+	else
+		ifeq ($(VER), 32)
+			OS_DEF = linux
+		else
+			OS_DEF = linux_x86_64
+		endif
+	endif
+# java
+	#----------------------------------------
+	# for [myusgun@dev.softforum.com] -_-;
+	#----------------------------------------
+	ifeq ($(VER), 32)
+		JAVA_HOME = ${HOME}/java/j2sdk1.4.2_19
+	endif
+endif
+
+ifeq ($(UNAME_S), Darwin)
+	OS_FAMILY = mac
+	ifeq ($(VER), 32)
+		OS_DEF = mac
+	else
+		OS_DEF = mac_x86_64
+	endif
+endif
+
+ifeq ($(filter $(UNAME_A),Cygwin),Cygwin)
+	# forced
+	VER			= 32
+	EXT_SHARED	= dll
+	EXT_STATIC	= lib
+	EXT_EXECUTE	= exe
+
+	# run as linux
+	OS_DEF		= linux
+endif
+
+ifeq ($(JAVA_HOME),)
+	JAVA_HOME = $(USER_JAVA_HOME)
+endif
+ifeq ($(JAVA_HOME),)
+$(error JAVA_HOME=\'\'.)
+endif
+
+#------------------------------------------------------------
+# set build env.
+#------------------------------------------------------------
+#ifeq ($(OS_DEF), $(filter $(OS_DEF),solaris solaris64 solaris_x86 solaris_x86_64))
+ifeq ($(OS_FAMILY), solaris)
+CC				= gcc
+LD				= gcc
+AR				= ar
+CDEFS			= $(DEFS) -D_SOLARIS -D_REENTRANT
+CFLAGS			= $(FLAG) -m$(VER) -Wall -Wconversion -Wpointer-arith -Wcast-align -fPIC
+LDFLAGS			= -m$(VER)
+SHARED_FLAGS	= $(LDFLAGS)
+ARFLAGS			= rc
+LIBS			= -lnsl -lsocket -lpthread
+LIBENV			= LD_LIBRARY_PATH
+
+	ifeq ($(OS_DEF), solaris_x86_64)
+		SHARED_FLAGS	+= -shared
+	else
+		SHARED_FLAGS	+= -G
+	endif
+endif
+
+ifeq ($(OS_FAMILY), aix)
+CC				= cc_r
+LD				= ld
+AR				= ar
+CDEFS			= $(DEFS) -D_AIX -D_REENTRANT -D__STDC__=1
+CFLAGS			= $(FLAG) -q$(VER) -qcpluscmt
+LDFLAGS			= -b$(VER) -brtl
+SHARED_FLAGS	= $(LDFLAGS) -bnoentry -bM:SRE -bexpall
+ARFLAGS			= cru
+LIBS			= -lc -lpthread
+LIBENV			= LIBPATH
+endif
+
+ifeq ($(OS_FAMILY), hp-ux)
+CC				= cc
+LD				= ld
+AR				= ar
+CDEFS			= $(DEFS) -D_HPUX -D_REENTRANT
+CFLAGS			= $(FLAG) +z -q -n -w1 -Ae -z +s
+LDFLAGS			= 
+SHARED_FLAGS	= $(LDFLAGS) -b +s
+ARFLAGS			= cru
+LIBS			= -lc -lpthread
+LIBENV			= SHLIB_PATH
+
+	ifeq ($(OS_DEF), hp)
+		CFLAGS		+= +DAportable
+		EXT_SHARED	= sl
+	endif
+
+	ifeq ($(OS_DEF), hp64)
+		CFLAGS		+= +DA2.0W
+		EXT_SHARED	= sl
+	endif
+
+	ifeq ($(OS_DEF), hp_ia)
+		CFLAGS		+= +DA1.1 +s
+	endif
+
+	ifeq ($(OS_DEF), hp_ia64)
+		CFLAGS	+= +DD64 +w1 -Ae -z +u4
+	endif
+endif
+
+ifeq ($(OS_FAMILY), linux)
+CC				= gcc
+LD				= gcc
+AR				= ar
+CDEFS			= $(DEFS) -D_LINUX -D_REENTRANT
+CFLAGS			= $(FLAG) -m$(VER) -Wall -Wconversion -Wpointer-arith -Wcast-align -fPIC
+LDFLAGS			= -m$(VER)
+SHARED_FLAGS	= $(LDFLAGS) -shared
+ARFLAGS			= rc
+LIBS			= -lpthread
+LIBENV			= LD_LIBRARY_PATH
+endif
+
+ifeq ($(OS_FAMILY), mac)
+CC				= gcc
+LD				= gcc
+AR				= ar
+CDEFS			= $(DEFS) -D_MAC -D_REENTRANT
+CFLAGS			= $(FLAG) -m$(VER) -Wall -Wconversion -Wpointer-arith -Wcast-align -fPIC
+LDFLAGS			= -m$(VER)
+SHARED_FLAGS	= $(LDFLAGS) -shared
+ARFLAGS			= rc
+LIBS			= 
+LIBENV			= 
+endif
Index: trunk/makeinclude/platform.mk
===================================================================
--- trunk/makeinclude/platform.mk	(revision 4)
+++ trunk/makeinclude/platform.mk	(revision 4)
@@ -0,0 +1,316 @@
+#------------------------------------------------------------
+# set command to check os
+#------------------------------------------------------------
+UNAME_S := $(shell uname -s)
+UNAME_M := $(shell uname -m)
+UNAME_R := $(shell uname -r)
+UNAME_V := $(shell uname -v)
+UNAME_A := $(shell uname -a)
+
+#------------------------------------------------------------
+# additional info.
+#------------------------------------------------------------
+MACHINE_INFO		= $(UNAME_S).$(UNAME_R)
+ifeq ($(UNAME_S),AIX)
+	MACHINE_INFO	= $(UNAME_S).$(UNAME_V).$(UNAME_R)
+endif
+ifeq ($(UNAME_S),Linux)
+	MACHINE_INFO	= $(UNAME_S).$(UNAME_M)
+endif
+
+DATETIME			:= $(shell date +%Y%m%d)
+
+#------------------------------------------------------------
+# set options
+#------------------------------------------------------------
+ifeq ($(DEBUG),yes)
+	DEFS = -D_DEBUG
+	FLAG = -g
+else
+	DEFS = 
+	FLAG = -O2
+endif
+
+EXT_SHARED	= so
+EXT_STATIC	= a
+EXT_EXECUTE	= ex
+
+#------------------------------------------------------------
+# set platform
+#------------------------------------------------------------
+ifeq ($(UNAME_S),SunOS)
+	OS_FAMILY = solaris
+	ifeq ($(UNAME_M),i86pc)
+		ifeq ($(VER),32)
+			OS_DEF = solaris_x86
+		else
+			OS_DEF = solaris_x86_64
+		endif
+	else
+		ifeq ($(VER),32)
+			OS_DEF = solaris
+		else
+			OS_DEF = solaris64
+		endif
+	endif
+# java
+	ifeq ($(UNAME_M),i86pc)
+		JAVA_HOME = /usr/j2se
+	else
+		JAVA_HOME = /usr/java1.4.2
+	endif
+endif
+
+ifeq ($(UNAME_S),AIX)
+	OS_FAMILY = aix
+	ifeq ($(VER),32)
+		OS_DEF = aix
+		JAVA_HOME = /usr/java14
+	else
+		OS_DEF = aix64
+		JAVA_HOME = /usr/java14_64
+	endif
+# java
+endif
+
+ifeq ($(UNAME_S),HP-UX)
+	OS_FAMILY = hp-ux
+	ifeq ($(UNAME_M),ia64)
+		UNAME_S := HP-UX_IA
+		ifeq ($(VER),32)
+			OS_DEF = hp_ia
+		else
+			OS_DEF = hp_ia64
+		endif
+	else
+		ifeq ($(VER),32)
+			OS_DEF = hp
+		else
+			OS_DEF = hp64
+		endif
+	endif
+# java
+	JAVA_HOME = /opt/java1.4
+endif
+
+ifeq ($(UNAME_S),Linux)
+	OS_FAMILY = linux
+	ifeq ($(UNAME_M),ppc64)
+		OS_DEF = linux_ppc64
+	else
+		ifeq ($(VER),32)
+			OS_DEF = linux
+		else
+			OS_DEF = linux_x86_64
+		endif
+	endif
+# java
+	ifeq ($(VER),32)
+		JAVA_HOME := ${JAVA_HOME}
+	endif
+endif
+
+ifeq ($(UNAME_S),Darwin)
+	OS_FAMILY = mac
+	ifeq ($(VER),32)
+		OS_DEF = mac
+	else
+		OS_DEF = mac_x86_64
+	endif
+endif
+
+ifeq ($(filter $(UNAME_A),Cygwin),Cygwin)
+	# forced
+	VER			= 32
+	EXT_SHARED	= dll
+	EXT_STATIC	= lib
+	EXT_EXECUTE	= exe
+
+	# run as linux
+	OS_DEF		= linux
+endif
+
+ifeq ($(JAVA_HOME),)
+	JAVA_HOME = $(USER_JAVA_HOME)
+endif
+ifeq ($(JAVA_HOME),)
+$(error JAVA_HOME=\'\'.)
+endif
+
+#------------------------------------------------------------
+# set build env.
+#------------------------------------------------------------
+#ifeq ($(OS_DEF),$(filter $(OS_DEF),solaris solaris64 solaris_x86 solaris_x86_64))
+ifeq ($(OS_FAMILY),solaris)
+	ifeq ($(OS_DEF),solaris_x86_64)
+		OPT_SHARED_LDFLAGS	+= -shared
+	else
+		OPT_SHARED_LDFLAGS	+= -G
+	endif
+
+CC				= gcc
+CXX				= g++
+LD				= $(CXX)
+AR				= ar
+CDEFS			= -D_SOLARIS -D_REENTRANT $(DEFS)
+CFLAGS			= $(FLAG) -m$(VER) -Wall -fPIC -Wconversion -Wpointer-arith -Wcast-align
+LDFLAGS			= $(FLAG) -m$(VER) -Wall
+SHARED_LDFLAGS	= $(LDFLAGS) $(OPT_SHARED_LDFLAGS) -shared
+ARFLAGS			= rc
+LIBS			= -lnsl -lsocket -lpthread
+LIBENV			= LD_LIBRARY_PATH
+COMPILER_VER	= $(CXX) --version | awk 'NR==1'
+endif
+
+ifeq ($(OS_FAMILY),aix)
+# -Wl,-brtl
+# => http://durgaprasad.wordpress.com/2006/09/28/problems-with-linking-of-shared-libraries-in-aix/
+CC				= /usr/vac/bin/xlc_r
+CXX				= /usr/vacpp/bin/xlC_r
+LD				= $(CXX)
+AR				= ar
+CDEFS			= -D_AIX -D_REENTRANT -D_POSIX_THREADS=1 -D_PTHREADS -D_THREAD_SAFE -D_POSIX_C_SOURCE=199506L $(DEFS)
+CFLAGS			= $(FLAG) -q$(VER) -qpic=large -qflag=w:w -qeh=v6 -qchars=signed -qstaticinline
+LDFLAGS			= $(FLAG) -q$(VER) -qpic=large -brtl
+SHARED_LDFLAGS	= $(LDFLAGS) -G -qmkshrobj -bnoentry -bM:SRE
+ARFLAGS			= -X64 -ruv
+LIBS			= -lc -lpthread
+LIBENV			= LIBPATH
+COMPILER_VER	= lslpp -l | grep xlC | grep rte | grep -v msg
+
+# g++ {{{
+ifeq ($(compiler),g++)
+CC				= g++
+CXX				= g++
+LD				= $(CXX)
+AR				= ar
+CDEFS			= -D_AIX -D_REENTRANT -D_POSIX_THREADS=1 -D_PTHREADS -D_THREAD_SAFE -D_POSIX_C_SOURCE=199506L $(DEFS)
+CFLAGS			= $(FLAG) -maix$(VER)
+LDFLAGS			= $(FLAG) -maix$(VER) -Wl,-brtl
+SHARED_LDFLAGS	= $(LDFLAGS) -shared
+ARFLAGS			= -X64 -ruv
+LIBS			= -lc -lpthread
+LIBENV			= LIBPATH
+COMPILER_VER	= $(CXX) --version | awk 'NR==1'
+endif
+# }}} g++
+endif
+
+ifeq ($(OS_FAMILY),hp-ux)
+
+	ifneq ($(DEBUG),yes)
+		FLAG = +O2
+	endif
+
+# in pa-risc, +W690 option is disable a warning about header without line-feed.
+	ifeq ($(OS_DEF),hp)
+		EXT_SHARED			= sl
+		HP_LD				= /opt/aCC/bin/aCC
+		FLAG				+= -AA -mt +W690 +Z +DAportable
+		OPT_SHARED_LDFLAGS	= +DAportable
+	endif
+
+	ifeq ($(OS_DEF),hp64)
+		EXT_SHARED			= sl
+		HP_LD				= /opt/aCC/bin/aCC
+		FLAG				+= -AA -mt +W690 +z +DA2.0W
+		OPT_SHARED_LDFLAGS	= +DA2.0W
+	endif
+
+# in itanium64, +W2001 option is disable a warning about header without line-feed.
+	ifeq ($(OS_DEF),hp_ia)
+		HP_LD				= ld
+		FLAG				+= +DD32 +W2001
+		OPT_SHARED_LDFLAGS	= +s +vallcompatwarnings -B symbolic
+	endif
+
+	ifeq ($(OS_DEF),hp_ia64)
+		HP_LD				= ld
+		FLAG				+= +DD64 +W2001
+		OPT_SHARED_LDFLAGS	= +s +vallcompatwarnings -B symbolic
+	endif
+
+CC				= cc
+CXX				= /opt/aCC/bin/aCC
+LD				= $(HP_LD)
+AR				= ar
+CDEFS			= -D_HPUX -D_HPUX_SOURCE -D_REENTRANT -D_POSIX_THREADS=1 -D_POSIX_C_SOURCE=199506L $(DEFS)
+CFLAGS			= $(FLAG) -q -n -z
+LDFLAGS			= $(FLAG) -q -n -Wl,+s
+SHARED_LDFLAGS	= $(HP_SHARED_LDFLAGS) -b
+ARFLAGS			= cru
+LIBS			= -lnsl -lc -lpthread -lstd_v2 -lCsup
+LIBENV			= SHLIB_PATH
+COMPILER_VER	= $(CXX) -V
+
+# g++ {{{
+ifeq ($(compiler),g++)
+
+	ifeq ($(OS_DEF),hp)
+		EXT_SHARED	= sl
+	endif
+
+	ifeq ($(OS_DEF),hp64)
+		EXT_SHARED	= sl
+	endif
+
+	ifeq ($(OS_DEF),hp_ia)
+		FLAG		= -milp32
+		LDFLAGS		= 
+	endif
+
+	ifeq ($(OS_DEF),hp_ia64)
+		FLAG		= -mlp64
+		LDFLAGS		= 
+	endif
+
+CC				= gcc
+CXX				= g++
+LD				= g++
+AR				= ar
+CDEFS			= -D_HPUX -D_REENTRANT -DMTHREAD -DPTHREAD -D_THREAD_SAFE -D_POSIX_C_SOURCE=199506L $(DEFS)
+CFLAGS			= $(FLAG) -Wall -fPIC -Wconversion -Wpointer-arith -Wcast-align
+LDFLAGS			= $(FLAG) -Wall
+SHARED_LDFLAGS	= $(LDFLAGS) -shared
+ARFLAGS			= cru
+LIBS			= -lnsl -lc -lpthread
+LIBENV			= SHLIB_PATH
+COMPILER_VER	= $(CXX) --version | awk 'NR==1'
+endif
+# }}} g++
+endif
+
+ifeq ($(OS_FAMILY),linux)
+
+	ifneq ($(shell find /usr/include -name "stropts.h"),)
+		DEFS	+= -D_HAVE_STROPTS_H
+	endif
+
+CC				= gcc
+CXX				= g++
+LD				= $(CXX)
+AR				= ar
+CDEFS			= -D_LINUX -D_REENTRANT $(DEFS)
+CFLAGS			= $(FLAG) -m$(VER) -Wall -fPIC -Wconversion -Wpointer-arith -Wcast-align
+LDFLAGS			= $(FLAG) -m$(VER) -Wall
+SHARED_LDFLAGS	= $(LDFLAGS) -shared -rdynamic
+ARFLAGS			= rc
+LIBS			= -lpthread $(USER_LIBS)
+LIBENV			= LD_LIBRARY_PATH
+COMPILER_VER	= $(CXX) --version | awk 'NR==1'
+endif
+
+ifeq ($(OS_FAMILY),mac)
+CC				= gcc
+CXX				= g++
+LD				= $(CXX)
+AR				= ar
+CDEFS			= -D_MAC -D_REENTRANT $(DEFS)
+CFLAGS			= $(FLAG) -m$(VER) -Wall -fPIC -Wconversion -Wpointer-arith -Wcast-align
+LDFLAGS			= $(FLAG) -m$(VER) -Wall
+SHARED_LDFLAGS	= $(LDFLAGS) -shared -rdynamic
+ARFLAGS			= rc
+LIBS			= -lpthread
+LIBENV			= LD_LIBRARY_PATH
+COMPILER_VER	= $(CXX) --version | awk 'NR==1'
+endif
Index: trunk/makeinclude/userdefine.mk
===================================================================
--- trunk/makeinclude/userdefine.mk	(revision 4)
+++ trunk/makeinclude/userdefine.mk	(revision 4)
@@ -0,0 +1,59 @@
+#------------------------------------------------------------
+# lower-case keys for lowercase-command-line option
+#------------------------------------------------------------
+
+#------------------------------------------------------------
+# xecuredb
+#------------------------------------------------------------ 
+# os-version
+# > 32 or 64
+ver					= 64
+VER					= $(ver)
+
+# compile with debugging flag and definition
+# > yes or no
+debug				= yes
+DEBUG				= $(debug)
+
+# product
+PRODUCT_NAME		= libcf++
+PRODUCT_VERSION		= 0.1dev
+
+# lib type
+# > shared or static
+libtype				= static
+LIBTYPE				= $(libtype)
+
+# documentation
+DOCUMENT_PATH		= ../_doc
+
+# path
+BUILD_PATH			= ../_build
+
+#------------------------------------------------------------
+# external tools or libraries
+#------------------------------------------------------------
+# java path
+with-jni			= no
+WITH_JNI			= $(with-jni)
+USER_JAVA_HOME		= ${HOME}/workspace/java/jdk1.5.0_12
+
+# link standard-library statically
+# ex) libstdc++, libgcc ?
+# > yes or no
+static-std			= no
+STATIC_STD			= $(static-std)
+
+#------------------------------------------------------------
+# user definitions and options
+#------------------------------------------------------------
+# options for exp
+# > yes or no
+
+# build-environment
+ifeq ($(STATIC_STD),yes)
+# not yet
+	USER_LDFLAGS	+= -static-libgcc
+	USER_LIBS		+= $(shell g++ -print-file-name=libstdc++.a)
+endif
+
Index: trunk/src/bin.cpp
===================================================================
--- trunk/src/bin.cpp	(revision 4)
+++ trunk/src/bin.cpp	(revision 4)
@@ -0,0 +1,176 @@
+/**
+ * @file bin.cpp
+ * @author myusgun@gmail.com
+ * @brief bin
+ */
+#include "cf/bin.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+cf::bin::bin(const cf::uint8_t * in,
+			 const cf::size_t size)
+{
+	set(in, size);
+}
+
+cf::bin::bin(const cf::char_t * in)
+{
+	if (!in)
+		return;
+
+	set(reinterpret_cast<const cf::uint8_t *>(in),
+		strlen(reinterpret_cast<const char *>(in)));
+}
+
+cf::bin::bin(const bin & in)
+	: mBin(in.mBin)
+{
+}
+
+cf::void_t cf::bin::clear()
+{
+	mBin.clear();
+}
+
+cf::uint8_t * cf::bin::buffer() const
+{
+	return const_cast<cf::uint8_t *>(&mBin[0]);
+}
+
+cf::size_t cf::bin::size() const
+{
+	return mBin.size();
+}
+
+cf::bool_t cf::bin::empty() const
+{
+	return mBin.empty();
+}
+
+cf::void_t cf::bin::resize(const cf::size_t size)
+{
+	mBin.resize(size);
+}
+
+cf::void_t cf::bin::set(const cf::uint8_t * in,
+						const cf::size_t size)
+{
+	if (!in)
+		return;
+
+	resize(size);
+	memcpy(buffer(), in, size);
+}
+
+cf::void_t cf::bin::append(const cf::uint8_t * in,
+						   const cf::size_t appendedSize)
+{
+	const cf::size_t position = size();
+
+	resize(size() + appendedSize);
+	memcpy(&buffer()[position], in, appendedSize);
+}
+
+cf::void_t cf::bin::append(const cf::bin & in)
+{
+	append((in.buffer()), in.size());
+}
+
+cf::bool_t cf::bin::equal(const cf::bin & in) const
+{
+	if (size() != in.size())
+		return false;
+
+	if (size() > 0)
+	{
+		if (memcmp(buffer(), in.buffer(), size()))
+			return false;
+	}
+
+	return true;
+}
+
+cf::bin & cf::bin::operator =(const cf::bin & in)
+{
+	mBin = in.mBin;
+	return *this;
+}
+
+cf::void_t cf::bin::operator +=(const cf::bin & in)
+{
+	append(in);
+}
+
+cf::bin cf::bin::operator +(const cf::bin & in) const
+{
+	bin out(in);
+
+	out.append(in);
+
+	return out;
+}
+
+cf::bool_t cf::bin::operator ==(const cf::bin & in) const
+{
+	return equal(in);
+}
+
+cf::bool_t cf::bin::operator !=(const cf::bin & in) const
+{
+	return !equal(in);
+}
+
+cf::size_t cf::bin::find(const cf::uint8_t * in,
+						 const cf::size_t size) const
+{
+	cf::size_t limit = this->size() - size;
+
+	if (limit < 0 || !in)
+		return -1;
+
+	for (cf::size_t iter = 0, iterIn = 0 ; iter <= limit ; iter++)
+	{
+		for (iterIn = 0 ; iterIn < size ; iterIn++)
+		{
+			if (*((buffer() + iter) + iterIn) != *(in + iterIn))
+				break;
+		}
+
+		if (iterIn == size)
+			return iter;
+	}
+
+	return -1;
+}
+
+cf::void_t cf::bin::print(const cf::char_t * prefix,
+						  const cf::size_t limit,
+						  FILE * fp) const
+{
+	cf::size_t i, j;
+	cf::size_t realsize = size() < limit ? size() : limit;
+
+	fprintf(fp, "[bin][%s] %lu bytes\n", prefix, size());
+	for (i = 0 ; i < realsize ; i += 16)
+	{
+		fprintf(fp, "%06lx : ", (cf::size_t)i);
+
+		for (j = 0; j < 16; j++)
+		{
+			if (i + j < realsize)
+				fprintf(fp, "%02x ", buffer()[i + j]);
+			else
+				fprintf(fp, "   ");
+		}
+		fprintf(fp, " ");
+
+		for (j = 0 ; j < 16 ; j++)
+		{
+#define IS_READABLE_CHAR(__c)		(' ' <= __c && __c <= '~')
+			if (i+j < realsize)
+				fprintf(fp, "%c", IS_READABLE_CHAR(buffer()[i + j]) ? buffer()[i + j] : '.');
+		}
+		fprintf(fp, "\n");
+	}
+}
Index: trunk/src/codec.cpp
===================================================================
--- trunk/src/codec.cpp	(revision 4)
+++ trunk/src/codec.cpp	(revision 4)
@@ -0,0 +1,298 @@
+/**
+ * @file codec.cpp
+ * @author myusgun@gmail.com
+ * @brief codec
+ */
+#include "cf/codec.h"
+#include "cf/memory.h"
+
+#define BASE64_PADDING_CHAR_INDEX 64
+
+cf::codec::base64 * cf::codec::base64::getInstance()
+{
+	static cf::codec::base64 instance;
+
+	return &instance;
+}
+
+std::string cf::codec::base64::encode(const cf::bin & in) const
+	throw (cf::exception)
+{
+	if (in.empty())
+		THROW_EXCEPTION("input is empty");
+	try
+	{
+		cf::size_t inlen = in.size();
+		cf::char_t * buf = NULL;
+		cf::size_t memsize = (((inlen + 2) / 3) * 4) + 1;
+		cf::memory mem(memsize);
+
+		buf = reinterpret_cast<cf::char_t *>(mem.buffer());
+
+		/*--------------------------------------------------------------*/
+		cf::char_t * dst = buf;
+		const cf::uint8_t * src = in.buffer();
+		const cf::uint8_t * ptr = src;
+
+		const static cf::char_t base64enc[] = {
+			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',	/* 00 - 07 */
+			'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',	/* 08 - 15 */
+			'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',	/* 16 - 23 */
+			'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',	/* 24 - 31 */
+			'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',	/* 32 - 39 */
+			'o', 'p', 'q', 'r', 's', 't', 'u', 'v',	/* 40 - 47 */
+			'w', 'x', 'y', 'z', '0', '1', '2', '3',	/* 48 - 55 */
+			'4', '5', '6', '7', '8', '9', '+', '/',	/* 56 - 63 */
+			'='										/* padding */
+		};
+
+#define SEXTUPLE_E_1(__x)	(((__x[0]) >> 2) & 0x3f)
+#define SEXTUPLE_E_2(__x)	(((__x[0]) << 4) & 0x30)
+#define SEXTUPLE_E_3(__x)	(((__x[1]) >> 4) & 0x0f)
+#define SEXTUPLE_E_4(__x)	(((__x[1]) << 2) & 0x3c)
+#define SEXTUPLE_E_5(__x)	(((__x[2]) >> 6) & 0x03)
+#define SEXTUPLE_E_6(__x)	(((__x[2])     ) & 0x3f)
+
+		for ( ; static_cast<cf::size_t>(ptr - src) < (inlen - 2) ; ptr += 3)
+		{
+			*dst++ = base64enc[SEXTUPLE_E_1 (ptr)];
+			*dst++ = base64enc[SEXTUPLE_E_2 (ptr) | SEXTUPLE_E_3 (ptr)];
+			*dst++ = base64enc[SEXTUPLE_E_4 (ptr) | SEXTUPLE_E_5 (ptr)];
+			*dst++ = base64enc[SEXTUPLE_E_6 (ptr)];
+		}
+
+		if (static_cast<cf::size_t>(ptr - src) < inlen)
+		{
+			*dst++ = base64enc[SEXTUPLE_E_1 (ptr)];
+
+			if (static_cast<cf::size_t>(ptr - src) == (inlen - 1))
+			{
+				*dst++ = base64enc[SEXTUPLE_E_2 (ptr)];
+				*dst++ = base64enc[BASE64_PADDING_CHAR_INDEX];
+			}
+			else
+			{
+				*dst++ = base64enc[SEXTUPLE_E_2 (ptr) | SEXTUPLE_E_3 (ptr)];
+				*dst++ = base64enc[SEXTUPLE_E_4 (ptr)];
+			}
+
+			*dst++ = base64enc[BASE64_PADDING_CHAR_INDEX];
+		}
+		*dst = '\0';
+		/*--------------------------------------------------------------*/
+
+		return std::string(buf);
+	}
+	catch (cf::exception &e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+cf::bin cf::codec::base64::decode(const std::string & in) const
+	throw (cf::exception)
+{
+	if (in.empty())
+		THROW_EXCEPTION("base64 string is empty");
+
+	try
+	{
+		cf::uint8_t * buf = NULL;
+		cf::long_t outlen = 0;
+		cf::size_t memsize = in.size() / 4 * 3;
+		cf::memory mem(memsize);
+
+		buf = reinterpret_cast<cf::uint8_t *>(mem.buffer());
+
+		/*--------------------------------------------------------------*/
+		const cf::char_t * src = in.c_str();
+		const cf::char_t * ptr = src;
+		cf::uint8_t * dst = buf;
+		cf::long_t remain = 0;
+		cf::long_t binlen = 0;
+
+		const static cf::uint8_t base64dec[] = {
+			0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,	/*  00 -  07 */
+			0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,	/*  08 -  15 */
+			0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,	/*  16 -  23 */
+			0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,	/*  24 -  31 */
+			0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,	/*  32 -  39 */
+			0xff,0xff,0xff,  62,0xff,0xff,0xff,  63,	/*  40 -  47 */
+			  52,  53,  54,  55,  56,  57,  58,  59,	/*  48 -  55 */
+			  60,  61,0xff,0xff,0xff,  64,0xff,0xff,	/*  56 -  63 */
+			0xff,   0,   1,   2,   3,   4,   5,   6,	/*  64 -  71 */
+			   7,   8,   9,  10,  11,  12,  13,  14,	/*  71 -  79 */
+			  15,  16,  17,  18,  19,  20,  21,  22,	/*  80 -  87 */
+			  23,  24,  25,0xff,0xff,0xff,0xff,0xff,	/*  88 -  95 */
+			0xff,  26,  27,  28,  29,  30,  31,  32,	/*  96 - 103 */
+			  33,  34,  35,  36,  37,  38,  39,  40,	/* 104 - 111 */
+			  41,  42,  43,  44,  45,  46,  47,  48,	/* 112 - 119 */
+			  49,  50,  51,0xff,0xff,0xff,0xff,0xff		/* 120 - 127 */
+		};
+
+		while (base64dec[(int)*ptr] < BASE64_PADDING_CHAR_INDEX) ptr++;
+
+		if (*ptr == 0xff)
+			THROW_EXCEPTION("input string is not base64-encoded");
+
+		remain = ptr - src;
+		binlen = ((remain + 2/* max padding length */) / 4) * 3;
+
+#define SEXTUPLE_D_1(src)	(base64dec[(int)src[0]] << 2)
+#define SEXTUPLE_D_2(src)	(base64dec[(int)src[1]] >> 4)
+#define SEXTUPLE_D_3(src)	(base64dec[(int)src[1]] << 4)
+#define SEXTUPLE_D_4(src)	(base64dec[(int)src[2]] >> 2)
+#define SEXTUPLE_D_5(src)	(base64dec[(int)src[2]] << 6)
+#define SEXTUPLE_D_6(src)	(base64dec[(int)src[3]]     )
+
+		for (ptr = src ; remain > 4 ; remain -= 4, ptr += 4)
+		{
+			*dst++ = (cf::uint8_t)(SEXTUPLE_D_1(ptr) | SEXTUPLE_D_2(ptr));
+			*dst++ = (cf::uint8_t)(SEXTUPLE_D_3(ptr) | SEXTUPLE_D_4(ptr));
+			*dst++ = (cf::uint8_t)(SEXTUPLE_D_5(ptr) | SEXTUPLE_D_6(ptr));
+		}
+
+		if (remain > 1)
+			*dst++ = (cf::uint8_t)(SEXTUPLE_D_1(ptr) | SEXTUPLE_D_2(ptr));
+		if (remain > 2)
+			*dst++ = (cf::uint8_t)(SEXTUPLE_D_3(ptr) | SEXTUPLE_D_4(ptr));
+		if (remain > 3)
+			*dst++ = (cf::uint8_t)(SEXTUPLE_D_5(ptr) | SEXTUPLE_D_6(ptr));
+
+		outlen = binlen - (4 - remain);
+		/*--------------------------------------------------------------*/
+
+		return cf::bin(buf, static_cast<cf::size_t>(outlen));
+	}
+	catch (cf::exception &e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+cf::codec::hex * cf::codec::hex::getInstance()
+{
+	static cf::codec::hex instance;
+
+	return &instance;
+}
+
+std::string cf::codec::hex::encode(const cf::bin & in) const
+	throw (cf::exception)
+{
+	if (in.empty())
+		THROW_EXCEPTION("input is empty");
+
+	try
+	{
+		cf::char_t * buf = NULL;
+		cf::size_t memsize = in.size() * 2 + 1;
+		cf::memory mem(memsize);
+
+		buf = reinterpret_cast<cf::char_t *>(mem.buffer());
+
+		/*--------------------------------------------------------------*/
+		const cf::uint8_t * src = in.buffer();
+		cf::char_t * dst = buf;
+
+		const static cf::char_t hexenc[] = {
+			'0', '1', '2', '3', '4', '5', '6', '7',
+			'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+		};
+
+		for ( ; static_cast<cf::size_t>(src - in.buffer()) < in.size() ; src++)
+		{
+			*dst++ = hexenc[((*src) >> 4) & 0x0f];
+			*dst++ = hexenc[((*src)     ) & 0x0f];
+		}
+		*dst = '\0';
+		/*--------------------------------------------------------------*/
+
+		return std::string(buf);
+	}
+	catch (cf::exception &e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+cf::bin cf::codec::hex::decode(const std::string & in) const
+	throw (cf::exception)
+{
+	if (in.empty())
+		THROW_EXCEPTION("hex string is empty");
+
+	try
+	{
+		cf::uint8_t * buf = NULL;
+		cf::int32_t len = 0;
+		cf::size_t memsize = in.size() / 2;
+		cf::memory mem(memsize);
+
+		buf = reinterpret_cast<cf::uint8_t *>(mem.buffer());
+
+		/*--------------------------------------------------------------*/
+		cf::int32_t length = 0; /* even-number */
+
+		const cf::char_t * src = in.c_str();
+		const cf::char_t * ptr = src;
+		cf::uint8_t * dst = buf;
+		cf::uint8_t val = 0;
+		cf::uint8_t sum = 0;
+		cf::uint8_t asciiHex = 0;
+
+		const static cf::uint8_t hexdec[] = {
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/*  00 -  07 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/*  08 -  15 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/*  16 -  23 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/*  24 -  31 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/*  32 -  39 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/*  40 -  47 */
+			 '0', '0', '0', '0', '0', '0', '0', '0',	/*  48 -  55 */
+			 '0', '0',0x00,0x00,0x00,0x00,0x00,0x00,	/*  56 -  63 */
+			0x00, 'A', 'A', 'A', 'A', 'A', 'A',0x00,	/*  64 -  71 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/*  71 -  79 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/*  80 -  87 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/*  88 -  95 */
+			0x00, 'a', 'a', 'a', 'a', 'a', 'a',0x00,	/*  96 - 103 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* 104 - 111 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* 112 - 119 */
+			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00		/* 120 - 127 */
+		};
+
+		for ( ; hexdec[(int)*ptr] && *ptr ; ptr++, length++);
+
+		if (*ptr)
+			THROW_EXCEPTION("input string is not hex-encoded");
+
+		for (ptr = src ; *ptr ; )
+		{
+			sum = 0; /* init/re-init decoding-buffer */
+
+			/* decode one character */
+#define DECODE_HEX(x)	\
+			do {	\
+			val = static_cast<cf::uint8_t>(*(x));	\
+			sum = (cf::uint8_t)(sum << 4);	\
+			asciiHex = hexdec[val];	\
+			\
+			sum |=	(cf::uint8_t)	\
+					(val - asciiHex + (asciiHex == '0' ? 0 : 10));	\
+			} while (0)
+
+			/* decode one byte by decode two character */
+			DECODE_HEX(ptr++);
+			DECODE_HEX(ptr++);
+
+			*dst++ = sum;
+		}
+		len = length / 2;
+		/*--------------------------------------------------------------*/
+
+		return cf::bin(buf, len);
+	}
+	catch (cf::exception &e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
Index: trunk/src/dirent.win32.hpp
===================================================================
--- trunk/src/dirent.win32.hpp	(revision 4)
+++ trunk/src/dirent.win32.hpp	(revision 4)
@@ -0,0 +1,840 @@
+/*
+ * dirent.h - dirent API for Microsoft Visual Studio
+ *
+ * Copyright (C) 2006-2012 Toni Ronkko
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * ``Software''), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * $Id: dirent.h,v 1.20 2014/03/19 17:52:23 tronkko Exp $
+ */
+#ifndef DIRENT_H
+#define DIRENT_H
+
+/*
+ * Define architecture flags so we don't need to include windows.h.
+ * Avoiding windows.h makes it simpler to use windows sockets in conjunction
+ * with dirent.h.
+ */
+#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
+#   define _X86_
+#endif
+#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
+#define _AMD64_
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <windef.h>
+#include <winbase.h>
+#include <wchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+/* Indicates that d_type field is available in dirent structure */
+#define _DIRENT_HAVE_D_TYPE
+
+/* Indicates that d_namlen field is available in dirent structure */
+#define _DIRENT_HAVE_D_NAMLEN
+
+/* Entries missing from MSVC 6.0 */
+#if !defined(FILE_ATTRIBUTE_DEVICE)
+#   define FILE_ATTRIBUTE_DEVICE 0x40
+#endif
+
+/* File type and permission flags for stat() */
+#if !defined(S_IFMT)
+#   define S_IFMT   _S_IFMT                     /* File type mask */
+#endif
+#if !defined(S_IFDIR)
+#   define S_IFDIR  _S_IFDIR                    /* Directory */
+#endif
+#if !defined(S_IFCHR)
+#   define S_IFCHR  _S_IFCHR                    /* Character device */
+#endif
+#if !defined(S_IFFIFO)
+#   define S_IFFIFO _S_IFFIFO                   /* Pipe */
+#endif
+#if !defined(S_IFREG)
+#   define S_IFREG  _S_IFREG                    /* Regular file */
+#endif
+#if !defined(S_IREAD)
+#   define S_IREAD  _S_IREAD                    /* Read permission */
+#endif
+#if !defined(S_IWRITE)
+#   define S_IWRITE _S_IWRITE                   /* Write permission */
+#endif
+#if !defined(S_IEXEC)
+#   define S_IEXEC  _S_IEXEC                    /* Execute permission */
+#endif
+#if !defined(S_IFIFO)
+#   define S_IFIFO _S_IFIFO                     /* Pipe */
+#endif
+#if !defined(S_IFBLK)
+#   define S_IFBLK   0                          /* Block device */
+#endif
+#if !defined(S_IFLNK)
+#   define S_IFLNK   0                          /* Link */
+#endif
+#if !defined(S_IFSOCK)
+#   define S_IFSOCK  0                          /* Socket */
+#endif
+
+#if 0 /* not used in dirent */
+#if defined(_MSC_VER)
+#   define S_IRUSR  S_IREAD                     /* Read user */
+#   define S_IWUSR  S_IWRITE                    /* Write user */
+#   define S_IXUSR  0                           /* Execute user */
+#   define S_IRGRP  0                           /* Read group */
+#   define S_IWGRP  0                           /* Write group */
+#   define S_IXGRP  0                           /* Execute group */
+#   define S_IROTH  0                           /* Read others */
+#   define S_IWOTH  0                           /* Write others */
+#   define S_IXOTH  0                           /* Execute others */
+#endif
+#endif
+
+/* Maximum length of file name */
+#if !defined(PATH_MAX)
+#   define PATH_MAX MAX_PATH
+#endif
+#if !defined(FILENAME_MAX)
+#   define FILENAME_MAX MAX_PATH
+#endif
+#if !defined(NAME_MAX)
+#   define NAME_MAX FILENAME_MAX
+#endif
+
+/* File type flags for d_type */
+#define DT_UNKNOWN  0
+#define DT_REG      S_IFREG
+#define DT_DIR      S_IFDIR
+#define DT_FIFO     S_IFIFO
+#define DT_SOCK     S_IFSOCK
+#define DT_CHR      S_IFCHR
+#define DT_BLK      S_IFBLK
+#define DT_LNK      S_IFLNK
+
+/* Macros for converting between st_mode and d_type */
+#define IFTODT(mode) ((mode) & S_IFMT)
+#define DTTOIF(type) (type)
+
+/*
+ * File type macros.  Note that block devices, sockets and links cannot be
+ * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
+ * only defined for compatibility.  These macros should always return false
+ * on Windows.
+ */
+#define	S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
+#define	S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
+#define	S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
+#define	S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
+#define	S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
+#define	S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
+#define	S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)
+
+/* Return the exact length of d_namlen without zero terminator */
+#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
+
+/* Return number of bytes needed to store d_namlen */
+#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Wide-character version */
+struct _wdirent {
+    long d_ino;                                 /* Always zero */
+    unsigned short d_reclen;                    /* Structure size */
+    size_t d_namlen;                            /* Length of name without \0 */
+    int d_type;                                 /* File type */
+    wchar_t d_name[PATH_MAX];                   /* File name */
+};
+typedef struct _wdirent _wdirent;
+
+struct _WDIR {
+    struct _wdirent ent;                        /* Current directory entry */
+    WIN32_FIND_DATAW data;                      /* Private file data */
+    int cached;                                 /* True if data is valid */
+    HANDLE handle;                              /* Win32 search handle */
+    wchar_t *patt;                              /* Initial directory name */
+};
+typedef struct _WDIR _WDIR;
+
+static _WDIR *_wopendir (const wchar_t *dirname);
+static struct _wdirent *_wreaddir (_WDIR *dirp);
+static int _wclosedir (_WDIR *dirp);
+static void _wrewinddir (_WDIR* dirp);
+
+
+/* For compatibility with Symbian */
+#define wdirent _wdirent
+#define WDIR _WDIR
+#define wopendir _wopendir
+#define wreaddir _wreaddir
+#define wclosedir _wclosedir
+#define wrewinddir _wrewinddir
+
+
+/* Multi-byte character versions */
+struct dirent {
+    long d_ino;                                 /* Always zero */
+    unsigned short d_reclen;                    /* Structure size */
+    size_t d_namlen;                            /* Length of name without \0 */
+    int d_type;                                 /* File type */
+    char d_name[PATH_MAX];                      /* File name */
+};
+typedef struct dirent dirent;
+
+struct DIR {
+    struct dirent ent;
+    struct _WDIR *wdirp;
+};
+typedef struct DIR DIR;
+
+static DIR *opendir (const char *dirname);
+static struct dirent *readdir (DIR *dirp);
+static int closedir (DIR *dirp);
+static void rewinddir (DIR* dirp);
+
+
+/* Internal utility functions */
+static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
+static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
+
+static int dirent_mbstowcs_s(
+    size_t *pReturnValue,
+    wchar_t *wcstr,
+    size_t sizeInWords,
+    const char *mbstr,
+    size_t count);
+
+static int dirent_wcstombs_s(
+    size_t *pReturnValue,
+    char *mbstr,
+    size_t sizeInBytes,
+    const wchar_t *wcstr,
+    size_t count);
+
+static void dirent_set_errno (int error);
+
+/*
+ * Open directory stream DIRNAME for read and return a pointer to the
+ * internal working area that is used to retrieve individual directory
+ * entries.
+ */
+static _WDIR*
+_wopendir(
+    const wchar_t *dirname)
+{
+    _WDIR *dirp = NULL;
+    int error;
+
+    /* Must have directory name */
+    if (dirname == NULL  ||  dirname[0] == '\0') {
+        dirent_set_errno (ENOENT);
+        return NULL;
+    }
+
+    /* Allocate new _WDIR structure */
+    dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
+    if (dirp != NULL) {
+        DWORD n;
+
+        /* Reset _WDIR structure */
+        dirp->handle = INVALID_HANDLE_VALUE;
+        dirp->patt = NULL;
+        dirp->cached = 0;
+
+        /* Compute the length of full path plus zero terminator */
+        n = GetFullPathNameW (dirname, 0, NULL, NULL);
+
+        /* Allocate room for absolute directory name and search pattern */
+        dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
+        if (dirp->patt) {
+
+            /*
+             * Convert relative directory name to an absolute one.  This
+             * allows rewinddir() to function correctly even when current
+             * working directory is changed between opendir() and rewinddir().
+             */
+            n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
+            if (n > 0) {
+                wchar_t *p;
+
+                /* Append search pattern \* to the directory name */
+                p = dirp->patt + n;
+                if (dirp->patt < p) {
+                    switch (p[-1]) {
+                    case '\\':
+                    case '/':
+                    case ':':
+                        /* Directory ends in path separator, e.g. c:\temp\ */
+                        /*NOP*/;
+                        break;
+
+                    default:
+                        /* Directory name doesn't end in path separator */
+                        *p++ = '\\';
+                    }
+                }
+                *p++ = '*';
+                *p = '\0';
+
+                /* Open directory stream and retrieve the first entry */
+                if (dirent_first (dirp)) {
+                    /* Directory stream opened successfully */
+                    error = 0;
+                } else {
+                    /* Cannot retrieve first entry */
+                    error = 1;
+                    dirent_set_errno (ENOENT);
+                }
+
+            } else {
+                /* Cannot retrieve full path name */
+                dirent_set_errno (ENOENT);
+                error = 1;
+            }
+
+        } else {
+            /* Cannot allocate memory for search pattern */
+            error = 1;
+        }
+
+    } else {
+        /* Cannot allocate _WDIR structure */
+        error = 1;
+    }
+
+    /* Clean up in case of error */
+    if (error  &&  dirp) {
+        _wclosedir (dirp);
+        dirp = NULL;
+    }
+
+    return dirp;
+}
+
+/*
+ * Read next directory entry.  The directory entry is returned in dirent
+ * structure in the d_name field.  Individual directory entries returned by
+ * this function include regular files, sub-directories, pseudo-directories
+ * "." and ".." as well as volume labels, hidden files and system files.
+ */
+static struct _wdirent*
+_wreaddir(
+    _WDIR *dirp)
+{
+    WIN32_FIND_DATAW *datap;
+    struct _wdirent *entp;
+
+    /* Read next directory entry */
+    datap = dirent_next (dirp);
+    if (datap) {
+        size_t n;
+        DWORD attr;
+        
+        /* Pointer to directory entry to return */
+        entp = &dirp->ent;
+
+        /* 
+         * Copy file name as wide-character string.  If the file name is too
+         * long to fit in to the destination buffer, then truncate file name
+         * to PATH_MAX characters and zero-terminate the buffer.
+         */
+        n = 0;
+        while (n + 1 < PATH_MAX  &&  datap->cFileName[n] != 0) {
+            entp->d_name[n] = datap->cFileName[n];
+            n++;
+        }
+        dirp->ent.d_name[n] = 0;
+
+        /* Length of file name excluding zero terminator */
+        entp->d_namlen = n;
+
+        /* File type */
+        attr = datap->dwFileAttributes;
+        if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
+            entp->d_type = DT_CHR;
+        } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+            entp->d_type = DT_DIR;
+        } else {
+            entp->d_type = DT_REG;
+        }
+
+        /* Reset dummy fields */
+        entp->d_ino = 0;
+        entp->d_reclen = sizeof (struct _wdirent);
+
+    } else {
+
+        /* Last directory entry read */
+        entp = NULL;
+
+    }
+
+    return entp;
+}
+
+/*
+ * Close directory stream opened by opendir() function.  This invalidates the
+ * DIR structure as well as any directory entry read previously by
+ * _wreaddir().
+ */
+static int
+_wclosedir(
+    _WDIR *dirp)
+{
+    int ok;
+    if (dirp) {
+
+        /* Release search handle */
+        if (dirp->handle != INVALID_HANDLE_VALUE) {
+            FindClose (dirp->handle);
+            dirp->handle = INVALID_HANDLE_VALUE;
+        }
+
+        /* Release search pattern */
+        if (dirp->patt) {
+            free (dirp->patt);
+            dirp->patt = NULL;
+        }
+
+        /* Release directory structure */
+        free (dirp);
+        ok = /*success*/0;
+
+    } else {
+        /* Invalid directory stream */
+        dirent_set_errno (EBADF);
+        ok = /*failure*/-1;
+    }
+    return ok;
+}
+
+/*
+ * Rewind directory stream such that _wreaddir() returns the very first
+ * file name again.
+ */
+static void
+_wrewinddir(
+    _WDIR* dirp)
+{
+    if (dirp) {
+        /* Release existing search handle */
+        if (dirp->handle != INVALID_HANDLE_VALUE) {
+            FindClose (dirp->handle);
+        }
+
+        /* Open new search handle */
+        dirent_first (dirp);
+    }
+}
+
+/* Get first directory entry (internal) */
+static WIN32_FIND_DATAW*
+dirent_first(
+    _WDIR *dirp)
+{
+    WIN32_FIND_DATAW *datap;
+
+    /* Open directory and retrieve the first entry */
+    dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
+    if (dirp->handle != INVALID_HANDLE_VALUE) {
+
+        /* a directory entry is now waiting in memory */
+        datap = &dirp->data;
+        dirp->cached = 1;
+
+    } else {
+
+        /* Failed to re-open directory: no directory entry in memory */
+        dirp->cached = 0;
+        datap = NULL;
+
+    }
+    return datap;
+}
+
+/* Get next directory entry (internal) */
+static WIN32_FIND_DATAW*
+dirent_next(
+    _WDIR *dirp)
+{
+    WIN32_FIND_DATAW *p;
+
+    /* Get next directory entry */
+    if (dirp->cached != 0) {
+
+        /* A valid directory entry already in memory */
+        p = &dirp->data;
+        dirp->cached = 0;
+
+    } else if (dirp->handle != INVALID_HANDLE_VALUE) {
+
+        /* Get the next directory entry from stream */
+        if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
+            /* Got a file */
+            p = &dirp->data;
+        } else {
+            /* The very last entry has been processed or an error occured */
+            FindClose (dirp->handle);
+            dirp->handle = INVALID_HANDLE_VALUE;
+            p = NULL;
+        }
+
+    } else {
+
+        /* End of directory stream reached */
+        p = NULL;
+
+    }
+
+    return p;
+}
+
+/* 
+ * Open directory stream using plain old C-string.
+ */
+static DIR*
+opendir(
+    const char *dirname) 
+{
+    struct DIR *dirp;
+    int error;
+
+    /* Must have directory name */
+    if (dirname == NULL  ||  dirname[0] == '\0') {
+        dirent_set_errno (ENOENT);
+        return NULL;
+    }
+
+    /* Allocate memory for DIR structure */
+    dirp = (DIR*) malloc (sizeof (struct DIR));
+    if (dirp) {
+        wchar_t wname[PATH_MAX];
+        size_t n;
+
+        /* Convert directory name to wide-character string */
+        error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
+        if (!error) {
+
+            /* Open directory stream using wide-character name */
+            dirp->wdirp = _wopendir (wname);
+            if (dirp->wdirp) {
+                /* Directory stream opened */
+                error = 0;
+            } else {
+                /* Failed to open directory stream */
+                error = 1;
+            }
+
+        } else {
+            /* 
+             * Cannot convert file name to wide-character string.  This
+             * occurs if the string contains invalid multi-byte sequences or
+             * the output buffer is too small to contain the resulting
+             * string.
+             */
+            error = 1;
+        }
+
+    } else {
+        /* Cannot allocate DIR structure */
+        error = 1;
+    }
+
+    /* Clean up in case of error */
+    if (error  &&  dirp) {
+        free (dirp);
+        dirp = NULL;
+    }
+
+    return dirp;
+}
+
+/*
+ * Read next directory entry.
+ *
+ * When working with text consoles, please note that file names returned by
+ * readdir() are represented in the default ANSI code page while any output to
+ * console is typically formatted on another code page.  Thus, non-ASCII
+ * characters in file names will not usually display correctly on console.  The
+ * problem can be fixed in two ways: (1) change the character set of console
+ * to 1252 using chcp utility and use Lucida Console font, or (2) use
+ * _cprintf function when writing to console.  The _cprinf() will re-encode
+ * ANSI strings to the console code page so many non-ASCII characters will
+ * display correcly.
+ */
+static struct dirent*
+readdir(
+    DIR *dirp) 
+{
+    WIN32_FIND_DATAW *datap;
+    struct dirent *entp;
+
+    /* Read next directory entry */
+    datap = dirent_next (dirp->wdirp);
+    if (datap) {
+        size_t n;
+        int error;
+
+        /* Attempt to convert file name to multi-byte string */
+        error = dirent_wcstombs_s(
+            &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
+
+        /* 
+         * If the file name cannot be represented by a multi-byte string,
+         * then attempt to use old 8+3 file name.  This allows traditional
+         * Unix-code to access some file names despite of unicode
+         * characters, although file names may seem unfamiliar to the user.
+         *
+         * Be ware that the code below cannot come up with a short file
+         * name unless the file system provides one.  At least
+         * VirtualBox shared folders fail to do this.
+         */
+        if (error  &&  datap->cAlternateFileName[0] != '\0') {
+            error = dirent_wcstombs_s(
+                &n, dirp->ent.d_name, PATH_MAX, 
+                datap->cAlternateFileName, PATH_MAX);
+        }
+
+        if (!error) {
+            DWORD attr;
+
+            /* Initialize directory entry for return */
+            entp = &dirp->ent;
+
+            /* Length of file name excluding zero terminator */
+            entp->d_namlen = n - 1;
+
+            /* File attributes */
+            attr = datap->dwFileAttributes;
+            if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
+                entp->d_type = DT_CHR;
+            } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+                entp->d_type = DT_DIR;
+            } else {
+                entp->d_type = DT_REG;
+            }
+
+            /* Reset dummy fields */
+            entp->d_ino = 0;
+            entp->d_reclen = sizeof (struct dirent);
+
+        } else {
+            /* 
+             * Cannot convert file name to multi-byte string so construct
+             * an errornous directory entry and return that.  Note that
+             * we cannot return NULL as that would stop the processing
+             * of directory entries completely.
+             */
+            entp = &dirp->ent;
+            entp->d_name[0] = '?';
+            entp->d_name[1] = '\0';
+            entp->d_namlen = 1;
+            entp->d_type = DT_UNKNOWN;
+            entp->d_ino = 0;
+            entp->d_reclen = 0;
+        }
+
+    } else {
+        /* No more directory entries */
+        entp = NULL;
+    }
+
+    return entp;
+}
+
+/*
+ * Close directory stream.
+ */
+static int
+closedir(
+    DIR *dirp) 
+{
+    int ok;
+    if (dirp) {
+
+        /* Close wide-character directory stream */
+        ok = _wclosedir (dirp->wdirp);
+        dirp->wdirp = NULL;
+
+        /* Release multi-byte character version */
+        free (dirp);
+
+    } else {
+
+        /* Invalid directory stream */
+        dirent_set_errno (EBADF);
+        ok = /*failure*/-1;
+
+    }
+    return ok;
+}
+
+/*
+ * Rewind directory stream to beginning.
+ */
+static void
+rewinddir(
+    DIR* dirp) 
+{
+    /* Rewind wide-character string directory stream */
+    _wrewinddir (dirp->wdirp);
+}
+
+/* Convert multi-byte string to wide character string */
+static int
+dirent_mbstowcs_s(
+    size_t *pReturnValue,
+    wchar_t *wcstr,
+    size_t sizeInWords,
+    const char *mbstr,
+    size_t count)
+{
+    int error;
+
+#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
+
+    /* Microsoft Visual Studio 2005 or later */
+    error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
+
+#else
+
+    /* Older Visual Studio or non-Microsoft compiler */
+    size_t n;
+
+    /* Convert to wide-character string (or count characters) */
+    n = mbstowcs (wcstr, mbstr, sizeInWords);
+    if (!wcstr  ||  n < count) {
+
+        /* Zero-terminate output buffer */
+        if (wcstr  &&  sizeInWords) {
+            if (n >= sizeInWords) {
+                n = sizeInWords - 1;
+            }
+            wcstr[n] = 0;
+        }
+
+        /* Length of resuting multi-byte string WITH zero terminator */
+        if (pReturnValue) {
+            *pReturnValue = n + 1;
+        }
+
+        /* Success */
+        error = 0;
+
+    } else {
+
+        /* Could not convert string */
+        error = 1;
+
+    }
+
+#endif
+
+    return error;
+}
+
+/* Convert wide-character string to multi-byte string */
+static int
+dirent_wcstombs_s(
+    size_t *pReturnValue,
+    char *mbstr,
+    size_t sizeInBytes, /* max size of mbstr */
+    const wchar_t *wcstr,
+    size_t count)
+{
+    int error;
+
+#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
+
+    /* Microsoft Visual Studio 2005 or later */
+    error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
+
+#else
+
+    /* Older Visual Studio or non-Microsoft compiler */
+    size_t n;
+
+    /* Convert to multi-byte string (or count the number of bytes needed) */
+    n = wcstombs (mbstr, wcstr, sizeInBytes);
+    if (!mbstr  ||  n < count) {
+
+        /* Zero-terminate output buffer */
+        if (mbstr  &&  sizeInBytes) {
+            if (n >= sizeInBytes) {
+                n = sizeInBytes - 1;
+            }
+            mbstr[n] = '\0';
+        }
+
+        /* Lenght of resulting multi-bytes string WITH zero-terminator */
+        if (pReturnValue) {
+            *pReturnValue = n + 1;
+        }
+
+        /* Success */
+        error = 0;
+
+    } else {
+
+        /* Cannot convert string */
+        error = 1;
+
+    }
+
+#endif
+
+    return error;
+}
+
+/* Set errno variable */
+static void
+dirent_set_errno(
+    int error)
+{
+#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
+
+    /* Microsoft Visual Studio 2005 and later */
+    _set_errno (error);
+
+#else
+
+    /* Non-Microsoft compiler or older Microsoft compiler */
+    errno = error;
+
+#endif
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*DIRENT_H*/
+
Index: trunk/src/exception.cpp
===================================================================
--- trunk/src/exception.cpp	(revision 4)
+++ trunk/src/exception.cpp	(revision 4)
@@ -0,0 +1,129 @@
+/**
+ * @file exception.cpp
+ * @author myusgun@gmail.com
+ * @brief exception
+ */
+#include "cf/exception.h"
+
+#include <string.h>
+
+#ifdef _ON_WINDOWS
+# include <windows.h>
+#else
+# include <errno.h>
+#endif
+
+cf::exception::exception(const cf::char_t * message,
+						 const cf::char_t * file,
+						 const cf::int32_t line,
+						 const cf::char_t * func)
+	: mMessage(message),
+	  mFile(file),
+	  mLine(line),
+	  mFunction(func)
+{
+#ifndef _HPUX
+	mStack.push_back(*this);
+#endif
+}
+
+cf::exception::exception(const cf::exception & ex,
+						 const cf::char_t * file,
+						 const cf::int32_t line,
+						 const cf::char_t * func)
+	: mMessage(ex.what()),
+	  mFile(file),
+	  mLine(line),
+	  mFunction(func)
+{
+#ifndef _HPUX
+	mStack = ex.mStack;
+	mStack.push_back(*this);
+#endif
+}
+
+cf::exception::~exception()
+	throw ()
+{
+}
+
+const cf::char_t * cf::exception::what() const
+	throw ()
+{
+	return mMessage.c_str();
+}
+
+const cf::char_t * cf::exception::file() const
+{
+	return mFile.c_str();
+}
+
+cf::int32_t cf::exception::line() const
+{
+	return mLine;
+}
+
+const cf::char_t * cf::exception::function() const
+{
+	return mFunction.c_str();
+}
+
+std::string cf::exception::stackTrace() const
+{
+#ifdef _HPUX
+	return mMessage;
+#else
+	cf::uint32_t iter = 0;
+	cf::formatter fmt;
+
+	fmt <<  mStack[0].what();
+	for ( ; iter < mStack.size() ; iter++)
+	{
+		const cf::exception & ex = mStack[iter];
+
+		fmt << "\n "
+			<< "#" << iter << " "
+			<< "[" << ex.file() << ":" << ex.line() << "]"
+			<< "[" << ex.function() << "()]";
+	}
+	fmt << "\n";
+
+	return fmt.str();
+#endif
+}
+
+cf::int32_t cf::exception::systemCode()
+{
+#ifdef _ON_WINDOWS
+# define SYSERR()	GetLastError()
+#else
+# define SYSERR()	errno
+#endif
+	return static_cast<cf::int32_t>(SYSERR());
+}
+
+std::string cf::exception::systemMessage()
+{
+	std::string msg;
+
+#ifdef _ON_WINDOWS
+	cf::char_t * ptr = NULL;
+	cf::size_t size = 0;
+	const cf::uint32_t flag = FORMAT_MESSAGE_ALLOCATE_BUFFER
+							| FORMAT_MESSAGE_FROM_SYSTEM
+							| FORMAT_MESSAGE_IGNORE_INSERTS;
+	const cf::uint32_t langID = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
+
+	size = FormatMessageA(flag, NULL, systemCode(), langID, (LPSTR)&ptr, 0, NULL);
+
+	if (ptr && size > 0)
+	{
+		msg.assign(ptr, size);
+		LocalFree(ptr);
+	}
+#else
+	msg = strerror(systemCode());
+#endif
+
+	return msg;
+}
Index: trunk/src/file.cpp
===================================================================
--- trunk/src/file.cpp	(revision 4)
+++ trunk/src/file.cpp	(revision 4)
@@ -0,0 +1,430 @@
+/**
+ * @file file.cpp
+ * @author myusgun@gmail.com
+ * @brief file
+ */
+#include "cf/file.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+/* for file system */
+#ifdef _ON_WINDOWS
+# include <io.h>
+# include <direct.h>
+# include "dirent.win32.hpp"
+
+# define DELIMITER		"\\"
+# define mkdir(a,b)		_mkdir(a)
+# define access(a,b)	_access(a,b)
+# define F_OK			0
+# define W_OK			2
+# define R_OK			4
+# define S_IWUSR		_S_IWRITE
+# define S_IRUSR		_S_IREAD
+# define S_IXUSR		_S_IEXEC
+# define S_IRGRP		0x00000000
+# define S_IWGRP		0x00000000
+# define S_IXGRP		0x00000000
+# define S_IROTH		0x00000000
+# define S_IWOTH		0x00000000
+# define S_IXOTH		0x00000000
+# define S_IRWXU		0x00000000
+#else
+# include <unistd.h>
+# include <dirent.h>
+
+# define DELIMITER		"/"
+# define O_BINARY		0x00000000
+#endif
+
+#define NO_FD			-1
+
+/*--------------------------------------------------------------*/
+
+static inline cf::int32_t getFlag(const cf::int32_t flag)
+{
+	cf::int32_t result = 0;
+
+	if      (flag & cf::file::READ)		result |= O_RDONLY;
+	else if (flag & cf::file::WRITE)	result |= O_WRONLY;
+
+	if (flag & cf::file::RW)			result |= O_RDWR;
+	if (flag & cf::file::CREATE)		result |= O_CREAT;
+	if (flag & cf::file::TRUNC)			result |= O_TRUNC;
+	if (flag & cf::file::APPEND)		result |= O_APPEND;
+	if (flag & cf::file::EXCL)			result |= O_EXCL;
+
+	return result;
+}
+
+static inline cf::int32_t getWhence(const cf::int32_t whence)
+	throw (cf::exception)
+{
+	switch(whence)
+	{
+		case cf::file::BEGIN:	return SEEK_SET;
+		case cf::file::CURRENT:	return SEEK_CUR;
+		case cf::file::END:		return SEEK_END;
+		default:
+			THROW_EXCEPTION("unknown whence");
+	}
+}
+
+static inline cf::void_t splitPath(const std::string & in,
+								   std::string & path,
+								   std::string & file)
+{
+	size_t found = in.find_last_of(cf::file::getDelimiter());
+
+	if (found == std::string::npos)
+	{
+		path = ".";
+		file = in;
+	}
+	else
+	{
+		path = in.substr(0, found);
+		file = in.substr(found + 1);
+	}
+}
+
+static inline std::string getLockfilePath(const std::string & path)
+{
+	std::string	parent;
+	std::string	file;
+	std::string	lockPath;
+
+	splitPath(path, parent, file);
+	lockPath = parent + cf::file::getDelimiter() + "." + file + ".lock";
+
+	return lockPath;
+}
+
+static inline cf::bool_t compareByName(const cf::file::ENTRY & lhs,
+									   const cf::file::ENTRY & rhs)
+{
+	std::size_t len = lhs.mName.length() < rhs.mName.length()
+					? lhs.mName.length()
+					: rhs.mName.length();
+	cf::int32_t smaller = static_cast<cf::int32_t>(len);
+
+	if (strncmp(lhs.mName.c_str(), rhs.mName.c_str(), smaller) < 0)
+		return true;
+	else
+		return false;
+}
+/*--------------------------------------------------------------*/
+
+cf::file::file(const cf::char_t * path)
+	throw (cf::exception)
+	: mFD(NO_FD),
+	  mIsLocked(false)
+{
+	if (!path)
+		THROW_EXCEPTION("file path is null");
+
+	mPath = path;
+}
+
+cf::file::~file()
+{
+	close();
+}
+
+const cf::char_t * cf::file::getDelimiter()
+{
+	return DELIMITER;
+}
+
+cf::void_t cf::file::open(const cf::int32_t flag)
+	throw (cf::exception)
+{
+#define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH|S_IREAD|S_IWRITE)
+	if (flag & file::LOCK)
+		mIsLocked = true;
+
+	/* lock */
+	std::string lockfile = getLockfilePath(mPath);
+	cf::int32_t lockfd = ::open(lockfile.c_str(), O_CREAT | O_EXCL, FILE_MODE);
+	if (lockfd < 0)
+	{
+		if (errno == EEXIST)
+			THROW_EXCEPTION("{" << mPath << "} is already locked");
+		else
+			THROW_EXCEPTION("cannot create locking file {"
+							<< lockfile << "} (" << errno << ":"
+							<< strerror(errno) << ")");
+	}
+	::close(lockfd);
+
+	if (!mIsLocked)
+		file(lockfile.c_str()).remove();
+
+	/* open */
+	cf::int32_t nativeFlag = getFlag(flag) | O_BINARY;
+	mFD = ::open(mPath.c_str(), nativeFlag, FILE_MODE);
+	if (mFD < 0)
+		THROW_EXCEPTION("cannot open file("
+						<< errno << ":" << strerror(errno) << ")");
+}
+
+cf::void_t cf::file::close()
+	throw (cf::exception)
+{
+	if (isOpened())
+	{
+		::close(mFD);
+		mFD = NO_FD;
+	}
+
+	if (mIsLocked)
+	{
+		file lockfile(getLockfilePath(mPath).c_str());
+		if (lockfile.exists())
+			lockfile.remove();
+
+		mIsLocked = false;
+	}
+}
+
+cf::bool_t cf::file::isOpened()
+{
+	return mFD > NO_FD ? true : false;
+}
+
+cf::int32_t cf::file::seek(const cf::int32_t offset,
+						   const cf::int32_t whence)
+	throw (cf::exception)
+{
+	off_t delta = ::lseek(mFD,
+						  static_cast<off_t>(offset),
+						  getWhence(whence));
+	if (delta < 0)
+		THROW_EXCEPTION("cannot seek in file("
+						<< errno << ":" << strerror(errno) << ")");
+
+	return static_cast<cf::int32_t>(delta);
+}
+
+cf::int32_t cf::file::tell()
+	throw (cf::exception)
+{
+	return seek(0, file::CURRENT);
+}
+
+cf::int32_t cf::file::size()
+	throw (cf::exception)
+{
+	struct stat statbuf;
+
+	if (stat(mPath.c_str(), &statbuf) < 0)
+		THROW_EXCEPTION("cannot get stat {" << mPath << "} ("
+						<< errno << ":" << strerror(errno) << ")");
+
+	return static_cast<cf::int32_t>(statbuf.st_size);
+}
+
+cf::bool_t cf::file::exists() const
+{
+	return access(mPath.c_str(), F_OK) ? false : true;
+}
+
+cf::void_t cf::file::read(cf::bin & out)
+	throw (cf::exception)
+{
+	if (out.size() <= 0)
+		THROW_EXCEPTION("read-buffer size is {" << out.size() << "}");
+
+	cf::uint8_t * buf = out.buffer();
+	cf::int32_t bufSize = static_cast<cf::int32_t>(out.size());
+	cf::int32_t readLen = static_cast<cf::int32_t>(::read(mFD, buf, bufSize));
+	if (readLen < 0)
+		THROW_EXCEPTION("cannot read from file("
+						<< errno << ":" << strerror(errno) << ")");
+
+	out.set(buf, readLen);
+}
+
+cf::bin cf::file::read(const cf::int32_t len)
+	throw (cf::exception)
+{
+	cf::bin out;
+	
+	out.resize(len > 0 ? len : size());
+	read(out);
+
+	return out;
+}
+
+cf::void_t cf::file::write(const cf::bin & in)
+	throw (cf::exception)
+{
+	cf::void_t * buf = reinterpret_cast<cf::void_t *>(in.buffer());
+	size_t len = static_cast<size_t>(in.size());
+	size_t writtenLen = 0;
+
+	if (!buf)
+		THROW_EXCEPTION("writing buffer is null");
+
+	writtenLen = ::write(mFD, buf, len);
+	if (writtenLen != len)
+		THROW_EXCEPTION("cannot write to file("
+						<< errno << ":" << strerror(errno) << ")");
+}
+
+cf::void_t cf::file::remove()
+	throw (cf::exception)
+{
+	close();
+
+	if (::remove(mPath.c_str()) < 0)
+		THROW_EXCEPTION("cannot remove file {" << mPath << "} ("
+						<< errno << ":" << strerror(errno) << ")");
+}
+
+cf::void_t cf::file::rename(const cf::char_t * path)
+	throw (cf::exception)
+{
+	if (!path)
+		THROW_EXCEPTION("new file path is null");
+
+	close();
+
+	if (::rename(mPath.c_str(), path) < 0)
+		THROW_EXCEPTION("cannot rename file from {" << mPath
+						<< "} to {" << path << "} ("
+						<< errno << ":" << strerror(errno) << ")");
+}
+
+const cf::char_t * cf::file::getPath() const
+{
+	return mPath.c_str();
+}
+
+cf::bool_t cf::file::isLocked() const
+{
+	return mIsLocked;
+}
+
+cf::void_t cf::file::makedir(const cf::char_t * path)
+	throw (cf::exception)
+{
+	if (!path)
+		THROW_EXCEPTION("directory path is null");
+
+	std::string fullpath = path;
+	std::string step;
+	std::string::iterator iter;
+
+	fullpath += getDelimiter();
+
+	for (iter = fullpath.begin() ; iter != fullpath.end() ; iter++)
+	{
+		step += *iter;
+
+		if (*iter != *getDelimiter())
+			continue;
+
+		if (file(step.c_str()).exists())
+			continue;
+
+#define DIRECTORY_MODE (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
+		cf::int32_t result = mkdir(step.c_str(), DIRECTORY_MODE);
+		if (result && errno != EEXIST)
+			THROW_EXCEPTION("cannot make directory {" << step
+							<< "} (" << errno << ":"
+							<< strerror(errno)
+							<< ")");
+	}
+}
+
+cf::file::EntryList cf::file::getEntryList(const cf::char_t * path,
+										   const cf::bool_t exceptDots)
+	throw (cf::exception)
+{
+	if (!path)
+		THROW_EXCEPTION("directory path is null");
+
+	if (!file(path).exists())
+		THROW_EXCEPTION("{" << path << "} does not exist");
+
+	DIR * dirp = NULL;
+	struct dirent * entp = NULL;
+	cf::int32_t error = 0;
+
+	file::EntryList	entryList;
+
+	dirp = opendir(path);
+	if (!dirp)
+		THROW_EXCEPTION("cannot open directory {" << path
+						<< "} (" << errno << ":"
+						<< strerror(errno)
+						<< ")");
+
+	error = errno;
+
+	/**
+	 * readdir manapge
+	 *--------------------------------------------------------------
+	 * command : man readdir
+	 *--------------------------------------------------------------
+	 * On success, readdir() returns a pointer to a dirent structure.
+	 * (This structure may be statically allocated; do not attempt to free(3) it.)
+	 * If the end of the directory stream is reached, NULL is returned and errno is not changed.
+	 * If an error occurs, NULL is returned and errno is set appropriately.
+	 *--------------------------------------------------------------
+	 * 
+	 * from. gnu-libc-manual
+	 *--------------------------------------------------------------
+	 * url : http://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html
+	 *--------------------------------------------------------------
+	 * In POSIX.1-2008, readdir is not thread-safe.
+	 * In the GNU C Library implementation,
+	 * it is safe to call readdir concurrently on different dirstreams,
+	 * but multiple threads accessing the same dirstream result in undefined behavior.
+	 * readdir_r is a fully thread-safe alternative, but suffers from poor portability(see below).
+	 * It is recommended that you use readdir, with external locking if multiple threads access the same dirstream. 
+	 *--------------------------------------------------------------
+	 */
+	while ((entp = readdir(dirp)))
+	{
+		/* success */
+		ENTRY ent;
+		ent.mName = entp->d_name;
+		if (exceptDots && (ent.mName == "." || ent.mName == ".."))
+			continue;
+
+		/**
+		 * FIXME : set entry type
+		 * @see http://stackoverflow.com/questions/3828192/checking-if-a-directory-exists-in-unix-system-call
+		 * @remarks
+		 *  do not use 'd_type' field in 'struct dirent'.
+		 *  'd_type' field is not supported in unix operating system(s) such as SunOS/Solaris.
+		 *  to support linux and unix, S_ISDIR() macro should be used.
+		 */
+#if 0
+		switch (entp->d_type)
+		{
+			case DT_DIR:	ent.mType = DIRECTORY;		break;
+			case DT_REG:	ent.mType = REGULAR_FILE;	break;
+			default:		ent.mType = UNDEFINED;		break;
+		}
+#endif
+
+		entryList.push_back(ent);
+	}
+
+	closedir(dirp);
+
+	if (error != errno)
+		THROW_EXCEPTION("cannot read directory {" << path
+						<< "} (" << errno << ":" << strerror(errno) << ")");
+
+	entryList.sort(compareByName);
+
+	return entryList;
+}
Index: trunk/src/jni.cpp
===================================================================
--- trunk/src/jni.cpp	(revision 4)
+++ trunk/src/jni.cpp	(revision 4)
@@ -0,0 +1,124 @@
+/**
+ * @file jni.cpp
+ * @author myusgun@gmail.com
+ * @brief JNI
+ */
+#ifdef _USE_JNI
+#include "cf/jni.h"
+#include "cf/types.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+using namespace cf;
+
+#define USE_JNI_PRIMITIVE
+
+cf::void_t jni::releaseByteArray(jbyteArray jinput,
+								 cf::char_t * in)
+{
+	if(!jinput || !in)
+		return;
+
+#ifdef USE_JNI_PRIMITIVE
+	mJNIEnv->ReleasePrimitiveArrayCritical((jarray)jinput, (cf::void_t *)in, JNI_ABORT);
+#else
+	mJNIEnv->ReleaseByteArrayElements(jinput, (jbyte *)in, JNI_ABORT);
+#endif
+}
+
+cf::void_t jni::releaseString(jstring jinput,
+							  cf::char_t * in)
+{
+	if(!jinput || !in)
+		return;
+
+	mJNIEnv->ReleaseStringUTFChars(jinput, in);
+}
+
+cf::void_t jni::releaseLocalMemory(jobject in)
+{
+	/* collected by GC */
+#if 0
+	mJNIEnv->DeleteLocalRef(in);
+#endif
+}
+
+bin jni::getByteArray(jbyteArray jinput)
+	throw (exception)
+{
+	jboolean isCopy;
+	bin out;
+
+	cf::char_t * buf = NULL;
+	cf::int32_t len = 0;
+
+	if(!jinput)
+		THROW_EXCEPTION("input from java is null");
+
+#ifdef USE_JNI_PRIMITIVE
+	/**
+	 * NOTE
+	 * read-only
+	 */
+	isCopy = JNI_FALSE;
+	buf = (cf::char_t *)mJNIEnv->GetPrimitiveArrayCritical((jarray)jinput, &isCopy);
+	if(!buf)
+		THROW_EXCEPTION("failed to GetPrimitiveArrayCritical");
+#else
+	buf = (cf::char_t *)mJNIEnv->GetByteArrayElements(jinput, &isCopy);
+#endif
+	len = (cf::int32_t)mJNIEnv->GetArrayLength(jinput);
+
+	out.copy((cf::uint8_t *)buf, len);
+
+	releaseByteArray(jinput, buf);
+
+	return out;
+}
+
+std::string jni::getString(jstring jinput)
+	throw (exception)
+{
+	if(!jinput)
+		THROW_EXCEPTION("input from java is null");
+
+	jboolean isCopy;
+	cf::char_t * buf = (cf::char_t *)mJNIEnv->GetStringUTFChars(jinput, &isCopy);
+	std::string out = buf;
+
+	releaseString(jinput, buf);
+
+	return out;
+}
+
+cf::void_t jni::throwException(const cf::char_t * message)
+{
+	jthrowable occurred = mJNIEnv->ExceptionOccurred();
+	if(occurred)
+		mJNIEnv->Throw(occurred);
+
+	jclass exClass = mJNIEnv->FindClass("java/lang/Exception");
+
+	mJNIEnv->ThrowNew(exClass, message);
+}
+
+jbyteArray jni::newByteArray(const bin & in)
+{
+	jbyteArray out = NULL;
+
+	out = mJNIEnv->NewByteArray((jsize)in.length());
+	if(!out)
+		return NULL;
+
+	mJNIEnv->SetByteArrayRegion(out, 0, (jsize)in.length(), (jbyte *)in.value());
+
+	return out;
+}
+
+jstring jni::newString(const std::string & in)
+{
+	return mJNIEnv->NewStringUTF(in.c_str());
+}
+
+#endif // #ifdef _USE_JNI
Index: trunk/src/logger.cpp
===================================================================
--- trunk/src/logger.cpp	(revision 4)
+++ trunk/src/logger.cpp	(revision 4)
@@ -0,0 +1,402 @@
+/**
+ * @file logger.cpp
+ * @author myusgun@gmail.com
+ * @brief logger
+ */
+#include "cf/logger.h"
+#include "cf/codec.h"
+#include "cf/file.h"
+#include "cf/task.h"
+#include "cf/util.h"
+
+#ifdef _ON_WINDOWS
+# include <direct.h>
+#else
+# include <sys/stat.h>
+# include <sys/types.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+
+#define LOG_SUFFIX		".log"
+#define DATE_NUM(_d)	((_d.mYear * 10000) + (_d.mMonth * 100) + (_d.mDay))
+
+/*--------------------------------------------------------------*/
+
+static std::string getFullPath(const std::string & path,
+							   const std::string & prefix,
+							   const cf::int32_t option)
+	throw (cf::exception)
+{
+	try
+	{
+		std::string	filepath = path + cf::file::getDelimiter() + prefix;
+
+		/* OPTINAL : append date if daily-rotated */
+		if (option & cf::logger::DAILY)
+		{
+			cf::util::datetime dt = cf::util::getInstance()->getDateTime();
+
+			cf::char_t buf[16] = {0x00,};
+			snprintf(buf, sizeof(buf) - 1,
+					 ".%04d%02d%02d",
+					 dt.mYear,
+					 dt.mMonth,
+					 dt.mDay);
+
+			filepath += buf;
+		}
+
+		filepath += STR("." << cf::task::process::id());
+
+		/* FORCED : append file-extension */
+		filepath += LOG_SUFFIX;
+
+		return filepath;
+	}
+	catch (cf::exception &e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+/*--------------------------------------------------------------*/
+
+cf::logger::logger()
+	throw (cf::exception)
+{
+	/* none : level 0 */
+	cf::logger::LOG_CTX ctx;
+
+	ctx.mOption = 0;
+	memset(&ctx.mOptionParam, 0x00, sizeof(ctx.mOptionParam));
+	ctx.mFP = NULL;
+
+	mLogPool.push_back(ctx);
+}
+
+cf::logger::~logger()
+{
+	/* close fp / release-vector-item */
+	std::vector<FILE *> fpPool;
+	std::vector<FILE *>::iterator fpIter;
+	std::vector<cf::logger::LOG_CTX>::iterator ctxIter;
+
+	for (ctxIter = mLogPool.begin() ; ctxIter != mLogPool.end() ; ctxIter++)
+	{
+		cf::bool_t found = false;
+		for (fpIter = fpPool.begin() ; fpIter != fpPool.end() ; fpIter++)
+		{
+			if (ctxIter->mFP == (*fpIter))
+			{
+				found = true;
+				break;
+			}
+		}
+
+		if (!found)
+			fpPool.push_back(ctxIter->mFP);
+	}
+
+	for (fpIter = fpPool.begin() ; fpIter != fpPool.end() ; fpIter++)
+	{
+		if (*fpIter)
+			fclose(*fpIter);
+	}
+}
+
+cf::logger * cf::logger::getInstance()
+{
+	static logger instance;
+
+	return &instance;
+}
+
+cf::void_t cf::logger::rotateByDate(const cf::int32_t level,
+									const cf::util::datetime & dt)
+	throw (cf::exception)
+{
+	try
+	{
+		/* check datetime */
+		cf::int32_t current = DATE_NUM(dt);
+
+		if (mLogPool[level].mOptionParam.mCurrentDateTime == current)
+			return;
+
+		open(level);
+
+		/* replace datetime */
+		std::vector<cf::logger::LOG_CTX>::iterator iter;
+		for (iter = mLogPool.begin() ; iter != mLogPool.end() ; iter++)
+		{
+			if (iter->mFullPath == mLogPool[level].mFullPath)
+				iter->mOptionParam.mCurrentDateTime = current;
+		}
+	}
+	catch (cf::exception &e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+cf::void_t cf::logger::rotateBySize(const cf::int32_t level)
+	throw (cf::exception)
+{
+	try
+	{
+		/* check size */
+		cf::file logFile(mLogPool[level].mFullPath.c_str());
+		if (logFile.size() < mLogPool[level].mOptionParam.mMaxLogSize)
+			return;
+
+		rename(level);
+		open(level);
+	}
+	catch (cf::exception &e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+cf::void_t cf::logger::open(const cf::int32_t level)
+	throw (cf::exception)
+{
+	try
+	{
+		if (!mOpenMutex.trylock())
+		{
+			while (mOpenMutex.locked())
+				/* waiting */;
+
+			return;
+		}
+
+		if (!cf::file(mPath.c_str()).exists())
+			cf::file::makedir(mPath.c_str());
+
+		std::string prefix = mLogPool[level].mPrefix;
+		const cf::int32_t option = mLogPool[level].mOption;
+
+		std::string fullpath = getFullPath(mPath, prefix, option);
+
+#ifdef _ON_WINDOWS
+# define FOPEN_MODE	"ab+"
+#else
+# define FOPEN_MODE	"a+"
+#endif
+		FILE * fp = fopen(fullpath.c_str(), FOPEN_MODE);
+		if (!fp)
+			THROW_EXCEPTION("cannot open logfile {" << fullpath << "} ("
+							<< errno << ":" << strerror(errno) << ")");
+
+		replace(prefix, option, fp);
+
+		mOpenMutex.unlock();
+	}
+	catch (cf::exception &e)
+	{
+		mOpenMutex.unlock();
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+cf::void_t cf::logger::rename(const cf::int32_t level)
+	throw (cf::exception)
+{
+	try
+	{
+		if (!mRenameMutex.trylock())
+		{
+			while (mRenameMutex.locked())
+				/* waiting */;
+
+			return;
+		}
+
+		std::string oldpath = mLogPool[level].mFullPath;
+		std::string newpath = oldpath;
+
+		cf::int32_t idx = 0;
+		cf::bool_t continued = true;
+
+		while (continued)
+		{
+			std::string name = newpath + "." + STR(++idx);
+
+			file file(name.c_str());
+
+			if (!file.exists())
+				break;
+		}
+
+		newpath += "." + STR(idx);
+
+		replace(mLogPool[level].mPrefix, mLogPool[level].mOption, NULL);
+
+		file(oldpath.c_str()).rename(newpath.c_str());
+
+		mRenameMutex.unlock();
+	}
+	catch (cf::exception &e)
+	{
+		mRenameMutex.unlock();
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+cf::void_t cf::logger::replace(const std::string & prefix,
+							   const cf::int32_t option,
+							   FILE * newfp)
+{
+	FILE * oldfp = NULL;
+
+	std::vector<cf::logger::LOG_CTX>::iterator iter;
+	for (iter = mLogPool.begin() ; iter != mLogPool.end() ; iter++)
+	{
+		if (iter->mPrefix == prefix && iter->mOption == option)
+		{
+			if (!oldfp)
+				oldfp = iter->mFP;
+
+			iter->mFP = newfp;
+		}
+	}
+
+	if (oldfp)
+		fclose(oldfp);
+}
+
+cf::void_t cf::logger::init(const std::string & path)
+{
+	mPath = path;
+}
+
+cf::void_t cf::logger::add(const std::string & prefix,
+						   const cf::int32_t level,
+						   const std::string & description,
+						   const cf::int32_t option,
+						   const cf::int32_t rotationSize)
+	throw (cf::exception)
+{
+	try
+	{
+		/* if already registered level */
+		if (level < static_cast<cf::int32_t>(mLogPool.size()))
+			return;
+
+		if (level > static_cast<cf::int32_t>(mLogPool.size()))
+			THROW_EXCEPTION("level {" << level
+							<< "} is not sequential(expected {"
+							<< mLogPool.size() << "}");
+
+		cf::logger::LOG_CTX ctx;
+
+		ctx.mOption = option;
+		ctx.mOptionParam.mMaxLogSize = rotationSize * 1024 * 1024;
+		ctx.mPrefix = prefix;
+		ctx.mDescription = description;
+		ctx.mFullPath = getFullPath(mPath, prefix, option);
+		ctx.mFP = NULL;
+
+		mLogPool.push_back(ctx);
+
+		open(level);
+	}
+	catch (cf::exception &e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+cf::int32_t cf::logger::getLevel()
+{
+	return mLogLevel;
+}
+
+cf::void_t cf::logger::setLevel(const cf::int32_t level)
+{
+	mLogLevel = level;
+}
+
+std::string cf::logger::getPath(const cf::int32_t level) const
+	throw (cf::exception)
+{
+	return mLogPool[level].mFullPath;
+}
+
+cf::bool_t cf::logger::isRegistered(const cf::int32_t level) const
+{
+	if (level >= static_cast<cf::int32_t>(mLogPool.size()))
+		return false;
+
+	return true;
+}
+
+cf::bool_t cf::logger::isEnabled(const cf::int32_t level) const
+{
+	/* check registered */
+	if (!isRegistered(level))
+		return false;
+
+	/* check option */
+	if (mLogPool[level].mOption & logger::FORCED)
+		return true;
+
+	/* check max level */
+	if (level > mLogLevel)
+		return false;
+
+	return true;
+}
+
+cf::void_t cf::logger::write(const cf::int32_t level,
+							 const std::string & msg)
+{
+	try
+	{
+		/* check level */
+		if (!isRegistered(level))
+			THROW_EXCEPTION("{" << level << "} not registered");
+
+		if (!isEnabled(level))
+			THROW_EXCEPTION("not enabled {" << level << "}");
+
+		/* ready */
+		cf::int32_t option = mLogPool[level].mOption;
+
+		cf::util::datetime dt = cf::util::getInstance()->getDateTime();
+
+		/* rotate */
+		if (option & logger::DAILY)
+			rotateByDate(level, dt);
+
+		if (option & logger::SIZE)
+			rotateBySize(level);
+
+		if (!cf::file(mLogPool[level].mFullPath.c_str()).exists())
+			open(level);
+
+		/* set current */
+		const cf::char_t * desc = mLogPool[level].mDescription.c_str();
+		cf::char_t info[64] = {0x00,};
+		snprintf(info, sizeof(info) - 1,
+				 "[%04d.%02d.%02d %02d:%02d:%02d.%03d][%u]",
+				 dt.mYear, dt.mMonth, dt.mDay,
+				 dt.mHour, dt.mMin, dt.mSec, dt.mUsec,
+				 task::thread::id());
+
+		/* write */
+		if (mLogPool[level].mFP)
+		{
+			fprintf(mLogPool[level].mFP, "%s [%s] %s\n", info, desc, msg.c_str());
+			fflush(mLogPool[level].mFP);
+		}
+	}
+	catch (cf::exception &e)
+	{
+		fprintf(stderr, "%s\n", e.stackTrace().c_str());
+		fprintf(stderr, "%s\n", msg.c_str());
+	}
+}
Index: trunk/src/macaddr.cpp
===================================================================
--- trunk/src/macaddr.cpp	(revision 4)
+++ trunk/src/macaddr.cpp	(revision 4)
@@ -0,0 +1,435 @@
+/**
+ * @file macaddr.cpp
+ * @author https://kldp.org/node/26319
+ * @brief getting mac address
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#ifndef WIN32
+#include <unistd.h>
+#include <sys/poll.h>
+
+#ifndef _LINUX
+#include <sys/dlpi.h>
+#include <sys/stropts.h>
+#else
+#ifdef _HAVE_STROPTS_H
+#include <sys/stropts.h>
+#endif
+#endif
+
+#else
+# pragma comment(lib, "iphlpapi.lib")
+#include <windows.h>
+#include <lm.h>
+#include <Lmwksta.h>
+#include <assert.h>
+#include <iphlpapi.h>
+#endif
+
+#include <signal.h>
+#include <ctype.h>
+
+#ifdef _LINUX
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <linux/if.h>
+#endif
+
+#ifdef _HPUX
+#include <netio.h>
+#include <sys/ioctl.h>
+#endif
+
+#ifdef _AIX
+#include <sys/ndd_var.h>
+#include <sys/kinfo.h>
+
+/* in C++, 'getkerninfo()' function is not declared automatically. */
+extern "C" int getkerninfo (int, char *, int *, int32long64_t);
+#endif
+
+#ifdef _SOLARIS
+#define BSD_COMP 
+#include <sys/types.h>
+#include <sys/ioctl.h> 
+#include <sys/socket.h>
+#include <sys/utsname.h> 
+#include <netinet/in.h> 
+#include <netdb.h> 
+#include <net/if_arp.h> 
+#include <net/if.h> 
+#include <net/if_dl.h> 
+#include <net/if_types.h> 
+#include <arpa/inet.h> 
+#include <stropts.h>
+#endif
+
+#ifndef WIN32
+
+#undef DLPI_DEV
+
+#ifdef HPUX
+static const char *dlpi_dev[] = {"/dev/dlpi", ""};
+#define DLPI_DEV
+#endif
+
+#ifdef AIX
+static const char *dlpi_dev[] = {"/dev/dlpi/et", "/dev/dlpi/en",
+"/dev/dlpi/tr", "/dev/dlpi/fddi", ""};
+#define DLPI_DEV
+/* AIX: remember to set up /etc/pse.conf or /etc/dlpi.conf */
+#endif
+
+#ifdef SunOS
+static const char *dlpi_dev[] = {"/dev/hme", "/dev/ie", "/dev/le", "/dev/eri"};
+#define DLPI_DEV
+#endif
+
+#if !defined(DLPI_DEV) && !defined(_LINUX)
+static const char *dlpi_dev[] = {"/dev/dlpi", ""};
+/* unknown OS - hope that this will work ??? */
+#define DLPI_DEV
+#endif
+
+/**********************************************************************/
+/*
+* implementation
+*/
+
+#define INSAP 22
+#define OUTSAP 24
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <ctype.h>
+
+#define bcopy(source, destination, length) memcpy(destination, source, length)
+
+#define AREA_SZ 5000 /*­=­* buffer length in bytes *­=­*/
+#define GOT_CTRL 1
+#define GOT_DATA 2
+#define GOT_BOTH 3
+#define GOT_INTR 4
+#define GOT_ERR 128
+
+#ifndef _LINUX
+static u_long ctl_area[AREA_SZ];
+static u_long dat_area[AREA_SZ];
+static struct strbuf ctl = {AREA_SZ, 0, (char *)ctl_area};
+static struct strbuf dat = {AREA_SZ, 0, (char *)dat_area};
+
+/*­=­* get a message from a stream; return type of message *­=­*/
+static int GetMsg (int fd)
+{
+	int flags = 0;
+	int res, ret;
+	ctl_area[0] = 0;
+	dat_area[0] = 0;
+	ret = 0;
+	res = getmsg(fd, &ctl, &dat, &flags);
+	if(res < 0) {
+		if(errno == EINTR) {
+			return(GOT_INTR);
+		} else {
+			return(GOT_ERR);
+		}
+	}
+	if(ctl.len > 0) {
+		ret |= GOT_CTRL;
+	}
+	if(dat.len > 0) {
+		ret |= GOT_DATA;
+	} return(ret);
+}
+
+/*­=­* verify that dl_primitive in ctl_area = prim *­=­*/
+static int CheckCtrl (unsigned int prim)
+{
+	dl_error_ack_t *err_ack = (dl_error_ack_t *)ctl_area;
+	if(err_ack->dl_primitive != prim) {
+		return GOT_ERR;
+	} return 0;
+}
+
+/*­=­* put a control message on a stream *­=­*/
+static int PutCtrl (int fd, int len, int pri)
+{
+	ctl.len = len;
+	if(putmsg(fd, &ctl, 0, pri) < 0) {
+		return GOT_ERR;
+	} return 0;
+}
+
+/*­=­* put a control + data message on a stream *­=­*/
+static int PutBoth (int fd, int clen, int dlen, int pri)
+{
+	ctl.len = clen;
+	dat.len = dlen;
+	if(putmsg(fd, &ctl, &dat, pri) < 0) {
+		return GOT_ERR;
+	} return 0;
+}
+
+/*­=­* open file descriptor and attach *­=­*/
+static int OpenDL (const char *dev, int ppa, int *fd)
+{
+	dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area;
+	if((*fd = open(dev, O_RDWR)) == -1) {
+		return GOT_ERR;
+	}
+	attach_req->dl_primitive = DL_ATTACH_REQ;
+	attach_req->dl_ppa = ppa;
+	PutCtrl (*fd, sizeof(dl_attach_req_t), 0);
+	GetMsg (*fd);
+	return CheckCtrl (DL_OK_ACK);
+}
+
+/*­=­* send DL_BIND_REQ *­=­*/
+static int BindDL (int fd, int sap, u_char *addr)
+{
+	dl_bind_req_t *bind_req = (dl_bind_req_t *)ctl_area;
+	dl_bind_ack_t *bind_ack = (dl_bind_ack_t *)ctl_area;
+	bind_req->dl_primitive = DL_BIND_REQ;
+	bind_req->dl_sap = sap;
+	bind_req->dl_max_conind = 1;
+	bind_req->dl_service_mode = DL_CLDLS;
+	bind_req->dl_conn_mgmt = 0;
+	bind_req->dl_xidtest_flg = 0;
+	PutCtrl (fd, sizeof(dl_bind_req_t), 0);
+	GetMsg (fd);
+	if (GOT_ERR == CheckCtrl (DL_BIND_ACK)) {
+		return GOT_ERR;
+	}
+	bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr,
+		bind_ack->dl_addr_length);
+	return 0;
+}
+
+/**********************************************************************/
+/*
+* interface:
+* function DLPI - get the mac address of the "first" interface
+*
+* parameter: addr: an array of six bytes, has to be allocated by the
+caller
+*
+* return: 0 if OK, -1 if the address could not be determined
+*
+*/
+
+static long DLPI ( char *addr)
+{
+	int fd;
+	int ppa;
+	u_char mac_addr[25];
+	
+	const char **dev;
+	
+	for (dev = dlpi_dev; **dev != '\0'; ++dev) {
+		for (ppa=0; ppa<10; ++ppa) {
+			if (GOT_ERR != OpenDL (*dev, ppa, &fd)) {
+				if (GOT_ERR != BindDL (fd, INSAP, mac_addr)) {
+					bcopy( mac_addr, addr, 6);
+					return 0;
+				}
+			}
+			close(fd);
+		}
+	} return -1;
+}
+#endif //#ifndef _LINUX
+
+
+#endif //#ifndef WIN32
+
+
+long GetMACAddress (char *addr)
+{
+
+#ifdef WIN32
+	
+	IP_ADAPTER_INFO AdapterInfo[16];       // Allocate information 
+	// for up to 16 NICs
+	DWORD dwBufLen = sizeof(AdapterInfo);  // Save memory size of buffer
+	PIP_ADAPTER_INFO pAdapterInfo;
+	
+	DWORD dwStatus = GetAdaptersInfo(      // Call GetAdapterInfo
+		AdapterInfo,                 // [out] buffer to receive data
+		&dwBufLen);                  // [in] size of receive data buffer
+	assert(dwStatus == ERROR_SUCCESS);  // Verify return value is 
+	// valid, no buffer overflow
+	
+	pAdapterInfo = AdapterInfo; // Contains pointer to
+	// current adapter info
+	do {
+		//    PrintMACaddress(pAdapterInfo->Address); // Print MAC address
+/*		
+		fprintf( stderr, "%02X %02X %02X %02X %02X %02X\n",
+			pAdapterInfo->Address[0], 
+			pAdapterInfo->Address[1], 
+			pAdapterInfo->Address[2], 
+			pAdapterInfo->Address[3], 
+			pAdapterInfo->Address[4], 
+			pAdapterInfo->Address[5]
+			); // Print MAC address
+*/		
+		memcpy (addr, pAdapterInfo->Address, 6);
+		if( addr[0] != '\0' || addr[1] != '\0' || addr[2] != '\0' || addr[3] != '\0' || addr[4] != '\0' || addr[5] != '\0' ) break;
+		
+		pAdapterInfo = pAdapterInfo->Next;    // Progress through 
+		// linked list
+	}
+	while(pAdapterInfo);                    // Terminate if last adapter
+	
+	
+	return 0;
+
+#else
+
+	/* implementation for Linux */
+#ifdef _LINUX
+	struct ifreq ifr;
+	struct ifreq *IFR;
+	struct ifconf ifc;
+	char buf[1024];
+	int s, i;
+	int ok = 0;
+
+	s = socket(AF_INET, SOCK_DGRAM, 0);
+	if (s==-1) {
+		return -1;
+	}
+
+	ifc.ifc_len = sizeof(buf);
+	ifc.ifc_buf = buf;
+	ioctl(s, SIOCGIFCONF, &ifc);
+
+	IFR = ifc.ifc_req;
+	for (i = ifc.ifc_len / (int)sizeof(struct ifreq); --i >= 0; IFR++) {
+
+		strcpy(ifr.ifr_name, IFR->ifr_name);
+		if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) {
+			if (! (ifr.ifr_flags & IFF_LOOPBACK)) {
+				if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) {
+					ok = 1;
+					break;
+				}
+			}
+		}
+	}
+
+	close(s);
+	if (ok) {
+		bcopy( ifr.ifr_hwaddr.sa_data, addr, 6);
+	}
+	else {
+		return -1;
+	}
+	return 0;
+#else
+
+	/* implementation for HP-UX */
+#ifdef _HPUX
+	return DLPI (addr);
+#endif /* HPUX */
+
+
+	/* implementation for AIX */
+#ifdef _AIX
+
+	int size;
+	struct kinfo_ndd *nddp;
+
+	size = getkerninfo(KINFO_NDD, 0, 0, 0);
+	if (size <= 0) {
+		goto DLPI;
+	}
+	nddp = (struct kinfo_ndd *)malloc(size);
+
+	if (!nddp) {
+		goto DLPI;
+	}
+	if (getkerninfo(KINFO_NDD, (char *)nddp, &size, 0) < 0) {
+		free(nddp);
+		goto DLPI;
+	}
+	bcopy(nddp->ndd_addr, addr, 6);
+	free(nddp);
+	return 0;
+#endif
+
+#ifdef _SOLARIS
+	int sockfd;
+	struct arpreq myarp;
+	struct sockaddr_in *sin;
+	struct utsname myname;
+	struct hostent *hp;
+
+	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sockfd == -1)
+		goto DLPI;
+
+	if (uname(&myname) < 0)
+		goto DLPI;
+
+	if ((hp = gethostbyname(myname.nodename)) == NULL)
+		goto DLPI;
+
+	sin = (struct sockaddr_in *) &myarp.arp_pa;
+	memset (sin, 0x00, sizeof(struct sockaddr_in));
+	memcpy (&sin->sin_addr, *hp->h_addr_list, sizeof(struct in_addr));
+
+	if (ioctl(sockfd, SIOCGARP, &myarp) != 0)
+		goto DLPI;
+
+	memcpy (addr, myarp.arp_ha.sa_data, 6);
+	return 0;
+#endif
+
+
+DLPI:
+	return DLPI (addr);
+#endif //#ifdef _LINUX
+
+
+#endif //#ifdef WIN32
+}
+
+/***********************************************************************/
+/*
+ * Main (only for testing)
+ */
+#ifdef _MAC_TEST
+int main( int argc, char **argv)
+{
+	long stat;
+	int i;
+	u_char addr[8] = {0,};
+
+	stat = GetMacAddress (addr);
+	if (0 == stat) {
+		printf( "MAC address = ");
+		for (i=0; i<6; ++i) {
+			printf("%2.2x", addr[i]);
+		}
+		printf( "\n");
+	}
+	else {
+		fprintf( stderr, "can't get MAC address\n");
+		exit( 1);
+	}
+	return 0;
+}
+#endif
Index: trunk/src/makefile
===================================================================
--- trunk/src/makefile	(revision 4)
+++ trunk/src/makefile	(revision 4)
@@ -0,0 +1,70 @@
+#----------------------------------------------------------
+# platform
+#----------------------------------------------------------
+include ../makeinclude/userdefine.mk
+include ../makeinclude/platform.mk
+
+#----------------------------------------------------------
+# env
+#----------------------------------------------------------
+TARGET_NAME		= cf++
+TARGET_SHARED	= $(BUILD_PATH)/lib$(TARGET_NAME).$(EXT_SHARED)
+TARGET_STATIC	= $(BUILD_PATH)/lib$(TARGET_NAME).$(EXT_STATIC)
+
+ifeq ($(LIBTYPE),shared)
+	TARGET		= $(TARGET_SHARED)
+else
+	TARGET		= $(TARGET_STATIC)
+endif
+
+INCLUDES		= -I../include -I.
+LIBRARIES		= $(LIBS)
+
+# object files
+SRCS			= $(shell find . -name "*.cpp")
+OBJS			= $(addprefix $(BUILD_PATH)/,			\
+					$(addsuffix .o,						\
+						$(shell find . -name "*.cpp" |	\
+							awk -F"/" '{print $$NF}' |	\
+						   	sed 's/\.cpp//')))
+
+ifeq ($(WITH_JNI),yes)
+	JAVA_INCLUDES	= -I../jni -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/$(OS_FAMILY)
+	CFLAGS			+= -D_USE_JNI
+endif
+
+ifeq ($(OS_FAMILY),aix)
+	AIX_EXPORT	= -bE:_export.list
+endif
+
+#----------------------------------------------------------
+# label
+#----------------------------------------------------------
+#.PRECIOUS: $(OBJS)
+
+all: $(BUILD_PATH) $(TARGET)
+	@echo --------------- Complete ---------------
+#	ldd $(TARGET) || echo cannot ldd;
+#	stat $(TARGET) || echo cannot stat;
+
+# mkdir
+$(BUILD_PATH):
+	@if [ ! -d $@ ] ; then mkdir $@ ; fi
+
+# compile
+$(BUILD_PATH)/%.o: %.cpp
+	$(CXX) $(CFLAGS) $(CDEFS) $(INCLUDES) $(JAVA_INCLUDES) -c -o $@ $<
+
+# link
+$(TARGET_SHARED): $(OBJS)
+	$(LD) $(SHARED_LDFLAGS) $(AIX_EXPORT) -o $@ $? $(LIBRARIES)
+
+$(TARGET_STATIC): $(OBJS)
+	$(AR) $(ARFLAGS) $@ $?
+
+# clean
+clean: dummy
+	rm -rf $(TARGET) $(OBJS)
+
+dummy:
+
Index: trunk/src/memory.cpp
===================================================================
--- trunk/src/memory.cpp	(revision 4)
+++ trunk/src/memory.cpp	(revision 4)
@@ -0,0 +1,73 @@
+/**
+ * @file memory.cpp
+ * @author myusgun@gmail.com
+ * @brief memory
+ */
+#include "cf/memory.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const cf::uint8_t gVerifier[4] = {0xcf, '+', '+', 0x00};
+
+cf::memory::memory(const cf::size_t size)
+	throw (cf::exception)
+	: mMemory(NULL)
+{
+	mMemory = cf::memory::alloc(size);
+}
+
+cf::memory::~memory()
+{
+	cf::memory::free(mMemory);
+	mMemory = NULL;
+}
+
+cf::void_t * cf::memory::buffer()
+{
+	return mMemory;
+}
+
+cf::void_t * cf::memory::alloc(const cf::size_t size)
+	throw (cf::exception)
+{
+	cf::uint8_t * mem = (cf::uint8_t *)::calloc(size + sizeof(gVerifier), 1);
+	if (!mem)
+		THROW_EXCEPTION("cannot allocate memory");
+
+	::memcpy(mem, gVerifier, sizeof(gVerifier));
+
+	return reinterpret_cast<cf::void_t *>(mem + sizeof(gVerifier));
+}
+
+cf::void_t cf::memory::free(cf::void_t * mem)
+	throw (cf::exception)
+{
+	if (!valid(mem))
+		THROW_EXCEPTION("invalid address or verification code");
+
+	cf::uint8_t * ptr = reinterpret_cast<cf::uint8_t *>(mem);
+   
+	ptr -= sizeof(gVerifier);
+
+	::memset(ptr, 0x00, sizeof(gVerifier));
+
+	::free(ptr);
+}
+
+cf::bool_t cf::memory::valid(const cf::void_t * mem)
+{
+	const cf::uint8_t * ptr = reinterpret_cast<const cf::uint8_t *>(mem);
+
+	/* include checking NULL */
+	if (ptr < (cf::uint8_t *)sizeof(gVerifier))
+		return false;
+
+	ptr -= sizeof(gVerifier);
+
+	if (::memcmp(ptr, gVerifier, sizeof(gVerifier)))
+		return false;
+
+	return true;
+}
Index: trunk/src/network.cpp
===================================================================
--- trunk/src/network.cpp	(revision 4)
+++ trunk/src/network.cpp	(revision 4)
@@ -0,0 +1,481 @@
+/**
+ * @file network.cpp
+ * @author myusgun@gmail.com
+ * @brief network
+ */
+#include "cf/network.h"
+
+#include <iostream>
+#include <sstream>
+#include <string.h>
+
+#ifdef _ON_WINDOWS
+# include <WinSock2.h>
+# pragma comment(lib, "ws2_32.lib")
+#else
+# include <netinet/in.h>
+# include <sys/socket.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+# include <unistd.h>
+# include <sys/un.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <sys/types.h>
+# include <sys/time.h>
+#endif
+
+#ifdef _ON_WINDOWS
+typedef cf::int32_t				socklen_t;
+# define sa_family_t			cf::uint16_t
+# define ERROR_INTR				WSAEINTR
+# define ERROR_CONNECTING		WSAEWOULDBLOCK
+#else
+# define closesocket(__sock)	::close(__sock)
+# define ERROR_INTR				EINTR
+# define ERROR_CONNECTING		EINPROGRESS
+#endif
+
+#define ALLOW_SOCKET_TIME_WAIT
+
+cf::socket_t gInvalidSocket	= -1;
+
+/*--------------------------------------------------------------*/
+/**
+ * do not include "cf/macaddr.[ch]pp"
+ * just declare and call
+ */
+long GetMACAddress(cf::char_t *addr);
+
+static cf::void_t waitForTimeout(const cf::socket_t sock,
+								 const cf::int32_t timeout,
+								 const cf::bool_t checkWriteFD)
+	throw (cf::exception)
+{
+	cf::int32_t result = 0;
+	fd_set rfds;
+	fd_set wfds;
+	fd_set * wfdsPtr = checkWriteFD ? &wfds : NULL;
+
+	struct timeval tv;
+
+	if (timeout <= 0)
+		return;
+
+	FD_ZERO(&rfds);
+	FD_SET(sock, &rfds);
+
+	FD_ZERO(&wfds);
+	FD_SET(sock, &wfds);
+
+	tv.tv_sec = timeout;
+	tv.tv_usec = 0;
+
+	result = select(sock + 1, &rfds, wfdsPtr, NULL, &tv);
+	if (result < 0)
+		THROW_EXCEPTION("select error");
+	else if (result == 0)
+		THROW_EXCEPTION("socket timed out");
+
+	if (!FD_ISSET(sock, &rfds))
+	{
+		if (!checkWriteFD)
+			THROW_EXCEPTION("read fd is not set");
+		else if (!FD_ISSET(sock, &wfds))
+			THROW_EXCEPTION("write fd is not set");
+	}
+}
+
+static cf::void_t setLinger(cf::network::tcp & tcp)
+	throw (cf::exception)
+{
+#ifdef ALLOW_SOCKET_TIME_WAIT
+	return;
+#else
+	try
+	{
+		struct linger linger;
+
+		linger.l_onoff = 1;
+		linger.l_linger = 0;
+
+		tcp.setOption(SO_LINGER, &linger, sizeof(linger));
+	}
+	catch (cf::exception & e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+#endif
+}
+
+static cf::void_t setReuseAddress(cf::network::tcp & tcp)
+	throw (cf::exception)
+{
+	try
+	{
+		cf::int32_t reuseaddr = 1;
+
+		tcp.setOption(SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr));
+	}
+	catch (cf::exception & e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
+/*--------------------------------------------------------------*/
+
+cf::network::tcp::tcp(const cf::socket_t attachedSocket)
+	throw (cf::exception)
+	: mSocket (attachedSocket),
+	  mTimeout(0)
+{
+	static cf::bool_t isInitialized = false;
+
+	/* initialize socket */
+	if (!isInitialized)
+	{
+#if defined(_WIN32) || defined(_WIN64)
+		WSADATA winsockData;
+		cf::int32_t result = WSAStartup(MAKEWORD(2, 0), &winsockData);
+		if (result)
+			THROW_EXCEPTION("cannot start-up winsock");
+#endif
+
+		isInitialized = true;
+	}
+
+	if (mSocket == gInvalidSocket)
+		mSocket = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+	if (mSocket < 0)
+		THROW_EXCEPTION("cannot create a socket");
+}
+
+cf::network::tcp::~tcp()
+{
+	close();
+}
+
+cf::void_t cf::network::tcp::close()
+{
+	if (mSocket == gInvalidSocket)
+		return;
+
+	closesocket(mSocket);
+
+	mSocket = gInvalidSocket;
+	mHost = "";
+	mPort = 0;
+}
+
+cf::void_t cf::network::tcp::connect(const cf::char_t * host,
+									 const cf::uint16_t port,
+									 const cf::int32_t timeout)
+	throw (cf::exception)
+{
+	if (!host || !port)
+		THROW_EXCEPTION("invalid host info");
+
+	cf::int32_t result = 0;
+	cf::int32_t retval = 0;
+	cf::int32_t length = 0;
+	struct sockaddr_in addr;
+	struct hostent * hostEnt;
+
+	/* 1. set data */
+	addr.sin_family			= AF_INET;
+	addr.sin_port			= htons(port);
+	addr.sin_addr.s_addr	= inet_addr(host);
+
+	/* 2. get ip from hostname if inet_addr() is failed */
+	if (addr.sin_addr.s_addr == (unsigned int)-1)
+	{
+		hostEnt = gethostbyname(host);
+		if (hostEnt == NULL)
+			THROW_EXCEPTION("cannot get host by name");
+
+		addr.sin_family = (sa_family_t)hostEnt->h_addrtype;
+		memcpy(&(addr.sin_addr.s_addr),
+			   hostEnt->h_addr,
+			   (size_t)hostEnt->h_length);
+	}
+
+	/* 3. set options */
+	try
+	{
+		setLinger(*this);
+		setReuseAddress(*this);
+	}
+	catch (cf::exception & e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+
+	if (timeout > 0)
+		setNonBlocking(true);
+
+	/* 4. connect */
+	result = ::connect(mSocket, (struct sockaddr *)&addr, sizeof(addr));
+	if (result < 0)
+	{
+		if (timeout > 0)
+		{
+			if (cf::exception::systemCode() != ERROR_CONNECTING)
+				THROW_EXCEPTION("socket connect error");
+
+			try
+			{
+				length = sizeof(retval);
+				waitForTimeout(mSocket, timeout, true);
+				getOption(SO_ERROR, &retval, &length);
+			}
+			catch (cf::exception & e)
+			{
+				FORWARD_EXCEPTION(e);
+			}
+
+			if (retval)
+				THROW_EXCEPTION("cannot get error from socket option");
+		}
+		else
+		{
+			THROW_EXCEPTION("cannot connect to " << host << ":" << port);
+		}
+	}
+
+	/* set */
+	mHost = host;
+	mPort = port;
+	mTimeout = timeout;
+}
+
+cf::void_t cf::network::tcp::listen(const cf::uint16_t port,
+									const cf::int32_t backlog)
+	throw (cf::exception)
+{
+	if (!port)
+		THROW_EXCEPTION("invalid port number");
+
+	cf::int32_t result = 0;
+	struct sockaddr_in addr;
+
+	/* 1. set data */
+	addr.sin_family			= AF_INET;
+	addr.sin_addr.s_addr	= htonl(INADDR_ANY);
+	addr.sin_port			= htons(port);
+
+	/* 2. set options */
+	try
+	{
+		setLinger(*this);
+		setReuseAddress(*this);
+	}
+	catch (cf::exception & e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+
+	result = ::bind(mSocket, (struct sockaddr *)&addr, sizeof(struct sockaddr));
+	if (result < 0)
+		THROW_EXCEPTION("cannot bind to " << port);
+
+	result = ::listen(mSocket, backlog);
+	if (result < 0)
+		THROW_EXCEPTION("cannot listen");
+}
+
+cf::network::tcp cf::network::tcp::accept()
+	throw (cf::exception)
+{
+	cf::socket_t sock = 0;
+	struct sockaddr_in addr;
+	socklen_t len = sizeof(addr);
+
+	sock = ::accept(mSocket, (struct sockaddr *)&addr, /* in/out */&len);
+	if (sock < 0)
+		THROW_EXCEPTION("cannot accept client");
+
+	return cf::network::tcp(sock).detach();
+}
+
+cf::void_t cf::network::tcp::attach(const cf::socket_t sock)
+	throw (exception)
+{
+	if (sock == gInvalidSocket)
+		THROW_EXCEPTION("has invalid socket");
+
+	close();
+
+	mSocket = sock;
+}
+
+cf::socket_t cf::network::tcp::detach()
+	throw (exception)
+{
+	if (mSocket == gInvalidSocket)
+		THROW_EXCEPTION("has invalid socket");
+
+	cf::socket_t sock = mSocket;
+
+	mSocket = gInvalidSocket;
+
+	return sock;
+}
+
+cf::void_t cf::network::tcp::send(const cf::bin & in)
+	throw (cf::exception)
+{
+	if (in.empty())
+		THROW_EXCEPTION("send data is null or zero-bytes");
+
+	cf::char_t * buf = reinterpret_cast<cf::char_t *>(in.buffer());
+	cf::int32_t	size = static_cast<cf::int32_t>(in.size());
+
+	cf::int32_t sentSize = (cf::int32_t)::send (mSocket, buf, size, 0);
+	if (sentSize != size)
+		THROW_EXCEPTION("cannot send (" << cf::exception::systemCode() << ")");
+}
+
+cf::void_t cf::network::tcp::receive(cf::bin & out)
+	throw (cf::exception)
+{
+	if (out.size() == 0)
+		THROW_EXCEPTION("binary buffer is not created");
+
+	try
+	{
+		waitForTimeout(mSocket, mTimeout, false);
+	}
+	catch (cf::exception & e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+
+	cf::char_t * buf = reinterpret_cast<cf::char_t *>(out.buffer());
+	cf::int32_t size = static_cast<cf::int32_t>(out.size());
+
+	cf::int32_t receivedSize = (cf::int32_t)::recv(mSocket, buf, size, 0);
+	if (receivedSize < 0)
+		THROW_EXCEPTION("cannot receive (" << cf::exception::systemCode() << ")");
+	else if (receivedSize == 0)
+		out.clear();
+	else if (receivedSize < size)
+		out.resize(receivedSize);
+}
+
+cf::bin cf::network::tcp::receive(const cf::int32_t size)
+	throw (cf::exception)
+{
+	cf::bin out;
+
+	out.resize(size);
+	receive(out);
+
+	return out;
+}
+
+cf::bin cf::network::tcp::receive()
+	throw (cf::exception)
+{
+	const cf::size_t bufferSize = 1024;
+
+	cf::bin	buffer;
+	cf::bin	out;
+
+	buffer.resize(bufferSize);
+
+	do
+	{
+		receive(buffer);
+		out.append(buffer);
+	} while (buffer.size() == bufferSize);
+
+	return out;
+}
+
+cf::void_t cf::network::tcp::getOption(const cf::int32_t optname,
+									   cf::void_t * optval,
+									   cf::int32_t * optlen)
+	throw (cf::exception)
+{
+	cf::int32_t result = getsockopt(mSocket,
+									SOL_SOCKET,
+									optname,
+#ifdef _ON_WINDOWS
+									(cf::char_t *)optval,
+#else
+									optval,
+#endif
+									(socklen_t *)optlen);
+	if (result < 0)
+		THROW_EXCEPTION("cannot get socket option ("
+						<< cf::exception::systemCode()
+						<< ")");
+}
+
+cf::void_t cf::network::tcp::setOption(const cf::int32_t optname,
+									   const cf::void_t * optval,
+									   const cf::int32_t optlen)
+	throw (cf::exception)
+{
+	cf::int32_t result = setsockopt(mSocket,
+									SOL_SOCKET,
+									optname,
+#ifdef _ON_WINDOWS
+									(cf::char_t *)optval,
+#else
+									optval,
+#endif
+									(socklen_t)optlen);
+	if (result < 0)
+		THROW_EXCEPTION("cannot set socket option ("
+						<< cf::exception::systemCode()
+						<< ")");
+}
+
+cf::void_t cf::network::tcp::setNonBlocking(const cf::bool_t flag)
+{
+#ifdef _ON_WINDOWS
+	cf::ulong_t mode = flag ? 1 : 0;
+	ioctlsocket(mSocket, FIONBIO, &mode);
+#else
+	cf::int32_t mode = fcntl(mSocket, F_GETFL, 0);
+
+	if (flag)	mode |=  O_NONBLOCK;
+	else		mode &= ~O_NONBLOCK;
+
+	fcntl(mSocket, F_SETFL, mode);
+#endif
+}
+
+cf::void_t cf::network::tcp::setTimeout(const cf::int32_t seconds)
+{
+	mTimeout = seconds;
+}
+
+std::string cf::network::nic::getMACAddress()
+	throw (cf::exception)
+{
+	static const cf::int32_t macSize = 6; /* = 48-bits */
+	static cf::bool_t isDone = false;
+	static cf::uint8_t bytes[macSize] = {0x00,};
+	static cf::char_t asciiz[macSize * 2 + 1] = {0x00,};
+
+	if (!isDone)
+	{
+		long result = 0;
+
+		result = GetMACAddress(reinterpret_cast<cf::char_t *>(bytes));
+		if (result)
+			THROW_EXCEPTION("cannot get mac-address");
+
+		for (cf::int32_t iter = 0 ; iter < macSize ; iter++)
+			snprintf(asciiz + (iter * 2), sizeof(asciiz) - 1,
+					 "%02x",
+					 bytes[iter]);
+
+		isDone = true;
+	}
+
+	return std::string(asciiz);
+}
Index: trunk/src/task.cpp
===================================================================
--- trunk/src/task.cpp	(revision 4)
+++ trunk/src/task.cpp	(revision 4)
@@ -0,0 +1,305 @@
+/**
+ * @file task.cpp
+ * @author myusgun@gmail.com
+ * @brief task
+ */
+#include "cf/task.h"
+#include "cf/memory.h"
+
+#ifdef _ON_WINDOWS
+# include <windows.h>
+# include <process.h>
+typedef HANDLE				thread_t;
+typedef CRITICAL_SECTION	mutex_t;
+# define THREAD_RETURN		cf::ulong_t	/**< return-type of thread worker */
+# define THREAD_CALL		__stdcall
+#else
+# include <string.h>
+# include <unistd.h>
+# include <pthread.h>
+# include <errno.h>
+typedef pthread_t			thread_t;
+typedef pthread_mutex_t		mutex_t;
+# define THREAD_RETURN		void *	/**< return-type of thread worker */
+# define THREAD_CALL
+#endif
+
+typedef THREAD_RETURN(THREAD_CALL * THREAD_WORKER)(cf::void_t *);
+
+/*--------------------------------------------------------------*/
+static inline THREAD_RETURN THREAD_CALL Runner(cf::void_t * arg)
+{
+	cf::task::thread::THREAD_CTX * ctx = reinterpret_cast<cf::task::thread::THREAD_CTX *>(arg);
+
+	ctx->mReturned = ctx->mCallback(ctx->mArgument);
+	ctx->mIsRunning = false;
+
+	return (THREAD_RETURN)(ctx->mReturned ? -1 : 0);
+}
+/*--------------------------------------------------------------*/
+
+cf::task::mutex::mutex()
+	throw (cf::exception)
+	: mIsLocked(false)
+{
+	mutex_t * inst = NULL;
+
+	try
+	{
+		inst = reinterpret_cast<mutex_t *>(cf::memory::alloc(sizeof(mutex_t)));
+
+#ifdef _ON_WINDOWS
+		InitializeCriticalSection(inst);
+#else
+		if (pthread_mutex_init(inst, NULL))
+			THROW_EXCEPTION("cannot create mutex("
+							<< errno << ":" << strerror(errno) << ")");
+#endif
+
+		mMutex = inst;
+	}
+	catch (cf::exception &e)
+	{
+		cf::memory::free(mMutex);
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+cf::task::mutex::~mutex()
+{
+	mutex_t * inst = reinterpret_cast<mutex_t *>(mMutex);
+
+#ifdef _ON_WINDOWS
+	DeleteCriticalSection(inst);
+#else
+	pthread_mutex_destroy(inst);
+#endif
+
+	cf::memory::free(mMutex);
+}
+
+cf::void_t cf::task::mutex::lock()
+	throw (cf::exception)
+{
+	mutex_t * inst = (mutex_t *)mMutex;
+
+#ifdef _ON_WINDOWS
+	EnterCriticalSection(inst);
+#else
+	cf::int32_t result = pthread_mutex_lock(inst);
+	if (result)
+		THROW_EXCEPTION("cannot lock {" << result << "}");
+#endif
+
+	mIsLocked = true;
+}
+
+cf::void_t cf::task::mutex::unlock()
+	throw (cf::exception)
+{
+	mutex_t * inst = reinterpret_cast<mutex_t *>(mMutex);
+
+#ifdef _ON_WINDOWS
+	LeaveCriticalSection(inst);
+#else
+	cf::int32_t result = pthread_mutex_unlock(inst);
+	if (result)
+		THROW_EXCEPTION("cannot unlock {" << result << "}");
+#endif
+
+	mIsLocked = false;
+}
+
+cf::bool_t cf::task::mutex::trylock()
+	throw (cf::exception)
+{
+	cf::bool_t getLocking = false;
+	mutex_t * inst = reinterpret_cast<mutex_t *>(mMutex);
+
+#ifdef _ON_WINDOWS
+	getLocking = TryEnterCriticalSection(inst) ? true : false;
+#else
+	cf::int32_t result = pthread_mutex_trylock(inst);
+	switch (result)
+	{
+		case 0:		getLocking = true;	break;
+		case EBUSY:	getLocking = false;	break;
+		default:
+			THROW_EXCEPTION("cannot trylock {" << result << "}");
+	}
+#endif
+
+	if (getLocking)
+		mIsLocked = true;
+
+	return getLocking;
+}
+
+cf::bool_t cf::task::mutex::locked() const
+{
+	return mIsLocked;
+}
+
+cf::task::scopedLock::scopedLock(ISynchronizer * inst)
+	throw (cf::exception)
+	: mSynchronizer(inst)
+{
+	if (!synchronizer())
+		THROW_EXCEPTION("invalid synchronizer");
+
+	synchronizer()->lock();
+}
+
+cf::task::scopedLock::~scopedLock()
+{
+	try
+	{
+		synchronizer()->unlock();
+	}
+	catch (...)
+	{
+	}
+}
+
+cf::task::ISynchronizer * cf::task::scopedLock::synchronizer()
+{
+	return mSynchronizer;
+}
+
+cf::task::thread::thread(const ThreadFunction callback)
+	throw (cf::exception)
+	: mThreadID(NULL)
+{
+	try
+	{
+		mCtx.mIsRunning = false;
+		mCtx.mCallback = callback;
+
+#ifndef _ON_WINDOWS
+		mThreadID = cf::memory::alloc(sizeof(thread_t));
+#endif
+	}
+	catch (cf::exception &e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+cf::task::thread::~thread()
+{
+#ifdef _ON_WINDOWS
+	if (!mThreadID)
+		return;
+
+	CloseHandle(mThreadID);
+#else
+	cf::memory::free(mThreadID);
+#endif
+}
+
+cf::void_t cf::task::thread::start(cf::void_t * arg)
+	throw (cf::exception)
+{
+	try
+	{
+		if (mCtx.mIsRunning)
+			return;
+
+		if (!mMutex.trylock())
+			return;
+
+		mCtx.mArgument = arg;
+
+#ifdef _ON_WINDOWS
+		mThreadID = CreateThread(NULL, 0, Runner, &mCtx, 0, NULL);
+		if (mThreadID == NULL)
+			THROW_EXCEPTION("cannot create thread");
+#else
+		cf::int32_t result = 0;
+
+		pthread_attr_t * attr = NULL;
+# if defined(_SOLARIS)
+		pthread_attr_t solarisAttr;
+		struct sched_param sched;
+
+		attr = &solarisAttr;
+
+		result = pthread_attr_init(attr);
+		if (result)
+			THROW_EXCEPTION("cannot init. thread-attr");
+
+		result = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
+		if (result)
+			THROW_EXCEPTION("cannot set thread-inherit-schedule-attr");
+
+		result = pthread_attr_setschedpolicy(attr, SCHED_RR);
+		if (result)
+			THROW_EXCEPTION("cannot set thread-schedule-policy-attr");
+
+		sched.sched_priority = 1;
+		result = pthread_attr_setschedparam(attr, &sched);
+		if (result)
+			THROW_EXCEPTION("cannot set thread-schedule-param-attr");
+# endif // # if defined(_SOLARIS)
+
+		result = pthread_create((thread_t *)mThreadID, attr, Runner, &mCtx);
+		if (result)
+			THROW_EXCEPTION("cannot create thread");
+#endif
+
+		mCtx.mIsRunning = true;
+
+		mMutex.unlock();
+	}
+	catch (cf::exception &e)
+	{
+		mMutex.unlock();
+		throw e;
+	}
+}
+
+cf::void_t cf::task::thread::join()
+{
+#ifdef _ON_WINDOWS
+	WaitForSingleObject(mThreadID, INFINITE);
+#else
+	cf::char_t status[16] = {0x00,};
+	pthread_join(*((thread_t *)mThreadID), (cf::void_t **)status);
+#endif
+}
+
+cf::bool_t cf::task::thread::isRunning() const
+{
+	return mCtx.mIsRunning;
+}
+
+cf::uint32_t cf::task::thread::id()
+{
+#ifdef _ON_WINDOWS
+	DWORD tid = GetCurrentThreadId();
+#else
+	pthread_t tid = pthread_self();
+#endif
+
+	return static_cast<cf::uint32_t>(tid);
+}
+
+cf::void_t cf::task::thread::sleep(cf::int32_t milliseconds)
+{
+#ifdef _ON_WINDOWS
+	Sleep(static_cast<DWORD>(milliseconds));
+#else
+	usleep(milliseconds * 1000);
+#endif
+}
+
+cf::uint32_t cf::task::process::id()
+{
+#ifdef _ON_WINDOWS
+	DWORD pid = GetCurrentProcessId();
+#else
+	pid_t pid = getpid();
+#endif
+
+	return static_cast<cf::uint32_t>(pid);
+}
Index: trunk/src/util.cpp
===================================================================
--- trunk/src/util.cpp	(revision 4)
+++ trunk/src/util.cpp	(revision 4)
@@ -0,0 +1,86 @@
+/**
+ * @file util.cpp
+ * @author myusgun@gmail.com
+ * @brief util
+ */
+#include "cf/util.h"
+
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+
+#ifdef _ON_WINDOWS
+# include <windows.h>
+# include <sys/timeb.h>
+#else
+# include <sys/time.h>
+# include <sys/types.h>
+# include <unistd.h>
+#endif
+
+/*--------------------------------------------------------------*/
+static const cf::char_t * getWeekName(const cf::int32_t week)
+{
+	static const cf::char_t * weekday[] = {
+		"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"
+	};
+
+	return weekday[week];
+}
+/*--------------------------------------------------------------*/
+
+cf::util * cf::util::getInstance()
+{
+	static cf::util instance;
+
+	return &instance;
+}
+
+cf::util::datetime cf::util::getDateTime() const
+	throw (cf::exception)
+{
+	cf::util::datetime dt;
+	struct timeval timeVal;
+	struct tm * timebuf = NULL;
+
+#ifdef _ON_WINDOWS
+	__time64_t	t64;
+	__timeb64	tb64;
+
+	_time64 (&t64);
+	_ftime64 (&tb64);
+	timebuf = _localtime64 (&t64);
+	timeVal.tv_usec = tb64.millitm;
+#else
+	gettimeofday(&timeVal, NULL);
+	timebuf = localtime((const time_t *)&timeVal.tv_sec);
+	timeVal.tv_usec /= 1000;
+#endif
+	if (!timebuf)
+		THROW_EXCEPTION("cannot get localtime(" << errno
+						<< ":" << strerror(errno) << ")");
+
+	dt.mYear		= timebuf->tm_year + 1900;
+	dt.mMonth		= timebuf->tm_mon + 1;
+	dt.mDay			= timebuf->tm_mday;
+	dt.mWeek		= timebuf->tm_wday;
+	dt.mWeekName	= getWeekName(dt.mWeek);
+
+	dt.mHour		= timebuf->tm_hour;
+	dt.mMin			= timebuf->tm_min;
+	dt.mSec			= timebuf->tm_sec;
+
+	dt.mUsec		= (cf::int32_t)timeVal.tv_usec;
+
+	return dt;
+}
+
+cf::int64_t cf::util::getTimeStamp() const
+{
+#ifdef _ON_WINDOWS
+	return _time64(NULL);
+#else
+	return time(NULL);
+#endif
+}
Index: trunk/test/makefile
===================================================================
--- trunk/test/makefile	(revision 4)
+++ trunk/test/makefile	(revision 4)
@@ -0,0 +1,104 @@
+#----------------------------------------------------------
+# platform
+#----------------------------------------------------------
+include ../makeinclude/userdefine.mk
+include ../makeinclude/platform.mk
+
+memcheck		= no
+profiling		= no
+execute			= yes
+
+#----------------------------------------------------------
+# env
+#----------------------------------------------------------
+ifeq ($(LIBTYPE),shared)
+	EXT			= $(EXT_SHARED)
+else
+	EXT			= $(EXT_STATIC)
+endif
+
+JAVA_BIN		= $(JAVA_HOME)/bin
+
+LIB_NAME		= cf++
+
+INCLUDES		= -I../include -I../src
+LIBRARIES		= -L$(BUILD_PATH) -l$(LIB_NAME) $(LIBS)
+LIBRARY_PATH	= .
+
+LIBCF			= $(BUILD_PATH)/lib$(LIB_NAME).$(EXT)
+
+JAVA_LIB_PATH	= -Djava.library.path=.
+CLASSPATH		= -classpath $(BUILD_PATH)
+
+JAVA_OPT		= -Xms10m -Xmx11m
+
+ifeq ($(OS_FAMILY),$(filter $(OS_FAMILY),hp-ux))
+	JAVA_OPT	+= -V2
+endif
+
+ifeq ($(OS_FAMILY),$(filter $(OS_FAMILY),hp-ux solaris linux))
+	ifeq ($(VER),64)
+		JAVA_OPT	+= -d64
+
+		ifeq ($(OS_FAMILY),solaris)
+			LIBRARY_PATH := $(LIBRARY_PATH):/usr/local/lib/sparcv9
+		endif
+	endif
+endif
+
+ifeq ($(memcheck),yes)
+	VALGRIND	= valgrind --leak-check=full --trace-children=yes --show-reachable=yes --track-origins=yes
+endif
+
+ifeq ($(profiling),yes)
+	VALGRIND	= valgrind --tool=callgrind
+	CDEFS		+= -D_PROFILING
+endif
+
+#----------------------------------------------------------
+# label
+#----------------------------------------------------------
+all:
+	make $(shell ls *.c *.cpp *.java | awk -F"." '{ print $$1 }')
+	@echo ========== Complete test ==========
+
+dep: $(BUILD_PATH) $(LIBCF)
+
+$(BUILD_PATH): dummy
+	@if [ ! -d $@ ] ; then mkdir $@ ; fi
+$(LIBCF): dummy
+	cd ../src; make all;
+
+%: %.c
+	make dep
+	$(CC) $(CFLAGS) $(LDFLAGS) $(CDEFS) $(INCLUDES) -o $(BUILD_PATH)/$@.$(EXT_EXECUTE) $? $(LIBRARIES)
+ifeq ($(execute),yes)
+	cd $(BUILD_PATH); $(LIBENV)=$(LIBRARY_PATH) $(VALGRIND) ./$@.$(EXT_EXECUTE)
+endif
+ifeq ($(profiling),yes)
+	kcachegrind ../_build/callgrind.out.*
+endif
+
+%: %.cpp
+	make dep
+	$(CXX) $(CFLAGS) $(LDFLAGS) $(CDEFS) $(INCLUDES) -o $(BUILD_PATH)/$@.$(EXT_EXECUTE) $? $(LIBRARIES)
+ifeq ($(execute),yes)
+	cd $(BUILD_PATH); $(LIBENV)=$(LIBRARY_PATH) $(VALGRIND) ./$@.$(EXT_EXECUTE)
+endif
+ifeq ($(profiling),yes)
+	kcachegrind ../_build/callgrind.out.*
+endif
+
+%: %.java
+	make dep
+	$(JAVA_BIN)/javac -d $(BUILD_PATH) $(CLASSPATH) $?
+ifeq ($(execute),yes)
+	cd $(BUILD_PATH); $(LIBENV)=$(LIBRARY_PATH) $(VALGRIND) $(JAVA_BIN)/java $(JAVA_OPT) $(CLASSPATH) $(JAVA_LIB_PATH) $@
+endif
+
+clean: dummy
+	rm -rf $(BUILD_PATH)/*.o
+	rm -rf *.txt
+	rm -rf $(BUILD_PATH)
+
+dummy:
Index: trunk/test/test.cpp
===================================================================
--- trunk/test/test.cpp	(revision 4)
+++ trunk/test/test.cpp	(revision 4)
@@ -0,0 +1,262 @@
+#include "cf/test.hpp"
+#include "cf/bin.h"
+#include "cf/codec.h"
+#include "cf/file.h"
+#include "cf/logger.h"
+#include "cf/task.h"
+#include "cf/util.h"
+#include "cf/network.h"
+
+#include <string>
+
+/*--------------------------------------------------------------*/
+
+// test string
+#define STRING	"test string"
+#define LOGFILE	"lol"
+// for networking
+#define HOST	"localhost"
+#define PORT	1234
+#define TIMEOUT	3
+
+/*--------------------------------------------------------------*/
+
+static void throwEx2() throw (cf::exception);
+static void throwEx1() throw (cf::exception);
+static int serverWorker(void * arg);
+static int clientWorker(void * arg);
+
+/*--------------------------------------------------------------*/
+
+cf::task::mutex gMutex;
+cf::task::thread gServerWorker(serverWorker);
+
+/*--------------------------------------------------------------*/
+
+TEST(Exception, main)
+{
+	try
+	{
+		throwEx1();
+	}
+	catch (cf::exception & e)
+	{
+		std::cerr << e.stackTrace();
+	}
+}
+
+TEST(Bin, main)
+{
+	cf::bin a, b(STRING);
+
+	a = b;
+
+	cf::bin c = b;
+
+	b.print("bin-value");
+}
+
+TEST(Codec, main)
+{
+	std::string e;
+	cf::bin d;
+	cf::codec::ICodec * codec = NULL;
+
+	codec = cf::codec::base64::getInstance();;
+	e = codec->encode(STRING);
+	d = codec->decode(e);
+	std::cout << "input   : " << STRING << "\n"
+			  << "encoded : " << e      << "\n";
+	d.print("decoded");
+
+	codec = cf::codec::hex::getInstance();;
+	e = codec->encode(STRING);
+	d = codec->decode(e);
+	std::cout << "input   : " << STRING << "\n"
+			  << "encoded : " << e      << "\n";
+	d.print("decoded");
+}
+
+TEST(File, main)
+{
+	cf::file f(STRING);
+
+	f.open(cf::file::CREATE | cf::file::RW | cf::file::LOCK);
+	f.write(cf::bin(STRING));
+	f.close();
+	f.remove();
+}
+
+TEST(Logger, main)
+{
+	enum LOG_LEVEL
+	{
+		ERR = 1,
+		WARN,
+		INFO,
+		DEBUG
+	};
+	cf::logger * log = cf::logger::getInstance();
+
+	log->init(".");
+	log->setLevel(10);
+
+	log->add(LOGFILE, ERR  , "ERROR"   , cf::logger::DAILY);
+	log->add(LOGFILE, WARN , "WARNNING", cf::logger::DAILY);
+	log->add(LOGFILE, INFO , "INFO"    , cf::logger::DAILY);
+	log->add(LOGFILE, DEBUG, "DEBUG"   , cf::logger::DAILY);
+
+	log->write(ERR, "this is log message");
+}
+
+TEST(Util, main)
+{
+	cf::util::datetime dt = cf::util::getInstance()->getDateTime();
+
+	std::cout << "date : "
+			  << dt.mYear << ":" << dt.mMonth << ":" << dt.mDay
+			  << "(" << dt.mWeek << ":" << dt.mWeekName << ")"
+			  << std::endl;
+	std::cout << "time : "
+			  << dt.mHour << ":" << dt.mMin << ":" << dt.mSec << "." << dt.mUsec
+			  << std::endl;
+}
+
+TEST(ThreadNetworking, Server)
+{
+	std::cout << "opening " << PORT << " ..." << std::endl;
+
+	gServerWorker.start(NULL);
+
+	// wait for server-binding
+	cf::task::thread::sleep(10);
+
+	std::cout << "server worker was started" << std::endl;
+}
+
+TEST(ThreadNetworking, Client)
+{
+	const int max = 5;
+	int i = 0;
+
+	cf::task::thread worker[max] = {
+		cf::task::thread(clientWorker),
+		cf::task::thread(clientWorker),
+		cf::task::thread(clientWorker),
+		cf::task::thread(clientWorker),
+		cf::task::thread(clientWorker),
+	};
+
+	for (i = 0 ; i < max ; i++)
+		worker[i].start(NULL);
+
+	for (i = 0 ; i < max ; i++)
+		worker[i].join();
+}
+
+TEST(Networking, NIC)
+{
+	std::cout << "H/W Address : "
+			  << cf::network::nic::getMACAddress()
+			  << std::endl;
+}
+
+int main(int argc, char ** argv)
+{
+	TEST_INIT(argc, argv);
+
+	TEST_RUN(Exception       , main);
+	TEST_RUN(Bin             , main);
+	TEST_RUN(Codec           , main);
+	TEST_RUN(File            , main);
+	TEST_RUN(Logger          , main);
+	TEST_RUN(Util            , main);
+	TEST_RUN(ThreadNetworking, Server);
+	TEST_RUN(ThreadNetworking, Client);
+	TEST_RUN(Networking      , NIC);
+
+	TEST_RESULT();
+
+	return 0;
+}
+
+/*--------------------------------------------------------------*/
+
+void throwEx2() throw (cf::exception)
+{
+	THROW_EXCEPTION("exception test");
+}
+
+void throwEx1() throw (cf::exception)
+{
+	try
+	{
+		throwEx2();
+	}
+	catch (cf::exception & e)
+	{
+		FORWARD_EXCEPTION(e);
+	}
+}
+
+int serverWorker(void * arg)
+{
+	try
+	{
+		cf::network::tcp server;
+		cf::network::tcp client;
+		cf::bin msg;
+
+		server.listen(PORT);
+
+		while (true)
+		{
+			client.attach(server.accept().detach());
+			msg = client.receive();
+			client.send(msg);
+			client.close();
+		}
+
+		server.close();
+	}
+	catch (cf::exception & e)
+	{
+		std::cerr << e.stackTrace();
+	}
+
+	return 0;
+}
+
+int clientWorker(void * arg)
+{
+	std::cout << "connecting to "
+			  << HOST << ":" << PORT << " ..."
+			  << std::endl;
+
+	try
+	{
+		cf::network::tcp client;
+		cf::ulong_t tid = cf::task::thread::id();
+		cf::bin msg(STR(STRING << " " << tid).c_str());
+		cf::bin response;
+
+		client.connect(HOST, PORT, TIMEOUT);
+		client.send(msg);
+		response = client.receive();
+		client.close();
+
+		SYNCHRONIZED(gMutex)
+		{
+			response.print("print response in synchronized-scope : ");
+		}
+	}
+	catch (cf::exception & e)
+	{
+		SYNCHRONIZED(gMutex)
+		{
+			std::cerr << e.stackTrace() << cf::exception::systemMessage();
+		}
+	}
+
+	return 0;
+}
Index: trunk/windows/libcf++.sln
===================================================================
--- trunk/windows/libcf++.sln	(revision 4)
+++ trunk/windows/libcf++.sln	(revision 4)
@@ -0,0 +1,37 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcf++", "libcf++.vcproj", "{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{A5567A0F-56C8-404E-AB02-5E95C8EE6BC0}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE} = {F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}.Debug|Win32.Build.0 = Debug|Win32
+		{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}.Debug|x64.ActiveCfg = Debug|x64
+		{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}.Debug|x64.Build.0 = Debug|x64
+		{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}.Release|Win32.ActiveCfg = Release|Win32
+		{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}.Release|Win32.Build.0 = Release|Win32
+		{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}.Release|x64.ActiveCfg = Release|x64
+		{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}.Release|x64.Build.0 = Release|x64
+		{A5567A0F-56C8-404E-AB02-5E95C8EE6BC0}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A5567A0F-56C8-404E-AB02-5E95C8EE6BC0}.Debug|Win32.Build.0 = Debug|Win32
+		{A5567A0F-56C8-404E-AB02-5E95C8EE6BC0}.Debug|x64.ActiveCfg = Debug|Win32
+		{A5567A0F-56C8-404E-AB02-5E95C8EE6BC0}.Release|Win32.ActiveCfg = Release|Win32
+		{A5567A0F-56C8-404E-AB02-5E95C8EE6BC0}.Release|Win32.Build.0 = Release|Win32
+		{A5567A0F-56C8-404E-AB02-5E95C8EE6BC0}.Release|x64.ActiveCfg = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: trunk/windows/libcf++.vcproj
===================================================================
--- trunk/windows/libcf++.vcproj	(revision 4)
+++ trunk/windows/libcf++.vcproj	(revision 4)
@@ -0,0 +1,403 @@
+<?xml version="1.0" encoding="ks_c_5601-1987"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="libcf++"
+	ProjectGUID="{F6D565DE-91B5-46E1-AD17-2C7067C1DDCE}"
+	RootNamespace="libcf"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\libcf++.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\libcf++.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\libcf++.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\libcf++.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="src"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\src\bin.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\codec.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\dirent.win32.hpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\exception.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\file.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\jni.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\logger.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\macaddr.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\memory.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\network.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\task.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\util.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="include"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<Filter
+				Name="cf"
+				>
+				<File
+					RelativePath="..\include\cf\bin.h"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\codec.h"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\exception.h"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\file.h"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\formatter.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\jni.h"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\logger.h"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\memory.h"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\network.h"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\task.h"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\test.hpp"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\types.h"
+					>
+				</File>
+				<File
+					RelativePath="..\include\cf\util.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="resources"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: trunk/windows/libcf++.vsprops
===================================================================
--- trunk/windows/libcf++.vsprops	(revision 4)
+++ trunk/windows/libcf++.vsprops	(revision 4)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="ks_c_5601-1987"?>
+<VisualStudioPropertySheet
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="libcf++"
+	>
+	<Tool
+		Name="VCCLCompilerTool"
+		AdditionalIncludeDirectories="../include"
+		DisableSpecificWarnings="4290;4996"
+	/>
+</VisualStudioPropertySheet>
Index: trunk/windows/test.vcproj
===================================================================
--- trunk/windows/test.vcproj	(revision 4)
+++ trunk/windows/test.vcproj	(revision 4)
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="ks_c_5601-1987"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="test"
+	ProjectGUID="{A5567A0F-56C8-404E-AB02-5E95C8EE6BC0}"
+	RootNamespace="test"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\libcf++.vsprops"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\libcf++.vsprops"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="src"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\test\test.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="include"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</Filter>
+		<Filter
+			Name="resources"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
