Set svn:eol-style for all files

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@66 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjlib/include/pj/config.h b/pjlib/include/pj/config.h
index deb602b..2a8d5c0 100644
--- a/pjlib/include/pj/config.h
+++ b/pjlib/include/pj/config.h
@@ -1,465 +1,465 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_CONFIG_H__

-#define __PJ_CONFIG_H__

-

-/**

- * @file config.h

- * @brief PJLIB Main configuration settings.

- */

-

-/********************************************************************

- * Include compiler specific configuration.

- */

-#if defined(_MSC_VER)

-#  include <pj/compat/cc_msvc.h>

-#elif defined(__GNUC__)

-#  include <pj/compat/cc_gcc.h>

-#else

-#  error "Unknown compiler."

-#endif

-

-

-/********************************************************************

- * Include target OS specific configuration.

- */

-#if defined(PJ_WIN32) && PJ_WIN32!=0

-#  include <pj/compat/os_win32.h>

-#elif defined(PJ_LINUX) && PJ_LINUX!=0

-#  include <pj/compat/os_linux.h>

-#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL!=0

-#  include <pj/compat/os_linux_kernel.h>

-#elif defined(PJ_PALMOS) && PJ_PALMOS!=0

-#  include <pj/compat/os_palmos.h>

-#elif defined(PJ_SUNOS) && PJ_SUNOS!=0

-#  include <pj/compat/os_sunos.h>

-#else

-#  error "Please specify target os."

-#endif

-

-

-/********************************************************************

- * Target machine specific configuration.

- */

-#if defined (PJ_M_I386) && PJ_M_I386 != 0

-#   include <pj/compat/m_i386.h>

-#elif defined (PJ_M_M68K) && PJ_M_M68K != 0

-#   include <pj/compat/m_m68k.h>

-#elif defined (PJ_M_ALPHA) && PJ_M_ALPHA != 0

-#   include <pj/compat/m_alpha.h>

-#elif defined (PJ_M_SPARC) && PJ_M_SPARC != 0

-#   include <pj/compat/m_sparc.h>

-#else

-#  error "Please specify target machine."

-#endif

-

-/* Include size_t definition. */

-#include <pj/compat/size_t.h>

-

-/* Include site/user specific configuration to control PJLIB features.

- * YOU MUST CREATE THIS FILE YOURSELF!!

- */

-#include <pj/config_site.h>

-

-/********************************************************************

- * PJLIB Features.

- */

-

-/* Overrides for DOXYGEN */

-#ifdef DOXYGEN

-#   undef PJ_FUNCTIONS_ARE_INLINED

-#   undef PJ_HAS_FLOATING_POINT

-#   undef PJ_LOG_MAX_LEVEL

-#   undef PJ_LOG_MAX_SIZE

-#   undef PJ_LOG_USE_STACK_BUFFER

-#   undef PJ_TERM_HAS_COLOR

-#   undef PJ_POOL_DEBUG

-#   undef PJ_HAS_TCP

-#   undef PJ_MAX_HOSTNAME

-#   undef PJ_IOQUEUE_MAX_HANDLES

-#   undef FD_SETSIZE

-#   undef PJ_HAS_SEMAPHORE

-#   undef PJ_HAS_EVENT_OBJ

-#   undef PJ_ENABLE_EXTRA_CHECK

-#endif

-

-/**

- * @defgroup pj_config Build Configuration

- * @ingroup PJ

- * @{

- *

- * This section contains macros that can set during PJLIB build process

- * to controll various aspects of the library.

- *

- * <b>Note</b>: the values in this page does NOT necessarily reflect to the

- * macro values during the build process.

- */

-

-/**

- * If this macro is set to 1, it will enable some debugging checking

- * in the library.

- *

- * Default: equal to (NOT NDEBUG).

- */

-#ifndef PJ_DEBUG

-#  ifndef NDEBUG

-#    define PJ_DEBUG		    1

-#  else

-#    define PJ_DEBUG		    0

-#  endif

-#endif

-

-/**

- * Expand functions in *_i.h header files as inline.

- *

- * Default: 0.

- */

-#ifndef PJ_FUNCTIONS_ARE_INLINED

-#  define PJ_FUNCTIONS_ARE_INLINED  0

-#endif

-

-/**

- * Use floating point computations in the library.

- *

- * Default: 1.

- */

-#ifndef PJ_HAS_FLOATING_POINT

-#  define PJ_HAS_FLOATING_POINT	    1

-#endif

-

-/**

- * Declare maximum logging level/verbosity. Lower number indicates higher

- * importance, with the highest importance has level zero. The least

- * important level is five in this implementation, but this can be extended

- * by supplying the appropriate implementation.

- *

- * The level conventions:

- *  - 0: fatal error

- *  - 1: error

- *  - 2: warning

- *  - 3: info

- *  - 4: debug

- *  - 5: trace

- *  - 6: more detailed trace

- *

- * Default: 4

- */

-#ifndef PJ_LOG_MAX_LEVEL

-#  define PJ_LOG_MAX_LEVEL   5

-#endif

-

-/**

- * Maximum message size that can be sent to output device for each call

- * to PJ_LOG(). If the message size is longer than this value, it will be cut.

- * This may affect the stack usage, depending whether PJ_LOG_USE_STACK_BUFFER

- * flag is set.

- *

- * Default: 800

- */

-#ifndef PJ_LOG_MAX_SIZE

-#  define PJ_LOG_MAX_SIZE	    800

-#endif

-

-/**

- * Log buffer.

- * Does the log get the buffer from the stack? (default is yes).

- * If the value is set to NO, then the buffer will be taken from static

- * buffer, which in this case will make the log function non-reentrant.

- *

- * Default: 1

- */

-#ifndef PJ_LOG_USE_STACK_BUFFER

-#  define PJ_LOG_USE_STACK_BUFFER   1

-#endif

-

-

-/**

- * Colorfull terminal (for logging etc).

- *

- * Default: 1

- */

-#ifndef PJ_TERM_HAS_COLOR

-#  define PJ_TERM_HAS_COLOR	    1

-#endif

-

-/**

- * Pool debugging.

- *

- * Default: 0

- */

-#ifndef PJ_POOL_DEBUG

-#  define PJ_POOL_DEBUG		    0

-#endif

-

-/**

- * \def PJ_HAS_TCP

- * Support TCP in the library.

- * Disabling TCP will reduce the footprint slightly (about 6KB).

- *

- * Default: 1

- */

-#ifndef PJ_HAS_TCP

-#  define PJ_HAS_TCP		    1

-#endif

-

-/**

- * Maximum hostname length.

- * Libraries sometimes needs to make copy of an address to stack buffer;

- * the value here affects the stack usage.

- *

- * Default: 128

- */

-#ifndef PJ_MAX_HOSTNAME

-#  define PJ_MAX_HOSTNAME	    (128)

-#endif

-

-/**

- * Constants for declaring the maximum handles that can be supported by

- * a single IOQ framework. This constant might not be relevant to the 

- * underlying I/O queue impelementation, but still, developers should be 

- * aware of this constant, to make sure that the program will not break when

- * the underlying implementation changes.

- *

- * For implementation based on select(), the value here will be used as the

- * maximum number of socket handles passed to select() (i.e. FD_SETSIZE will 

- * be set to this value).

- *

- * Default: 256

- */

-#ifndef PJ_IOQUEUE_MAX_HANDLES

-#  define PJ_IOQUEUE_MAX_HANDLES    (256)

-#endif

-

-/**

- * Overrides FD_SETSIZE so it is consistent throughout the library.

- * OS specific configuration header (compat/os_*) might have declared

- * FD_SETSIZE, thus we only set if it hasn't been declared.

- *

- * Default: #PJ_IOQUEUE_MAX_HANDLES

- */

-#ifndef FD_SETSIZE

-#  define FD_SETSIZE		    PJ_IOQUEUE_MAX_HANDLES

-#endif

-

-/**

- * Has semaphore functionality?

- *

- * Default: 1

- */

-#ifndef PJ_HAS_SEMAPHORE

-#  define PJ_HAS_SEMAPHORE	    1

-#endif

-

-

-/**

- * Event object (for synchronization, e.g. in Win32)

- *

- * Default: 1

- */

-#ifndef PJ_HAS_EVENT_OBJ

-#  define PJ_HAS_EVENT_OBJ	    1

-#endif

-

-

-/**

- * Enable library's extra check.

- * If this macro is enabled, #PJ_ASSERT_RETURN macro will expand to

- * run-time checking. If this macro is disabled, #PJ_ASSERT_RETURN

- * will simply evaluate to #pj_assert().

- *

- * You can disable this macro to reduce size, at the risk of crashes

- * if invalid value (e.g. NULL) is passed to the library.

- *

- * Default: 1

- */

-#ifndef PJ_ENABLE_EXTRA_CHECK

-#   define PJ_ENABLE_EXTRA_CHECK    1

-#endif

-

-

-/**

- * Enable name registration for exceptions with #pj_exception_id_alloc().

- * If this feature is enabled, then the library will keep track of

- * names associated with each exception ID requested by application via

- * #pj_exception_id_alloc().

- *

- * Disabling this macro will reduce the code and .bss size by a tad bit.

- * See also #PJ_MAX_EXCEPTION_ID.

- *

- * Default: 1

- */

-#ifndef PJ_HAS_EXCEPTION_NAMES

-#   define PJ_HAS_EXCEPTION_NAMES   1

-#endif

-

-/**

- * Maximum number of unique exception IDs that can be requested

- * with #pj_exception_id_alloc(). For each entry, a small record will

- * be allocated in the .bss segment.

- *

- * Default: 16

- */

-#ifndef PJ_MAX_EXCEPTION_ID

-#   define PJ_MAX_EXCEPTION_ID      16

-#endif

-

-/** @} */

-

-/********************************************************************

- * General macros.

- */

-

-/**

- * @def PJ_INLINE(type)

- * @param type The return type of the function.

- * Expand the function as inline.

- */

-#define PJ_INLINE(type)	  PJ_INLINE_SPECIFIER type

-

-/**

- * @def PJ_DECL(type)

- * @param type The return type of the function.

- * Declare a function.

- */

-/**

- * @def PJ_DECL_NO_RETURN(type)

- * @param type The return type of the function.

- * Declare a function that will not return.

- */

-/**

- * @def PJ_BEGIN_DECL

- * Mark beginning of declaration section in a header file.

- */

-/**

- * @def PJ_END_DECL

- * Mark end of declaration section in a header file.

- */

-#ifdef __cplusplus

-#  define PJ_DECL(type)		    type

-#  define PJ_DECL_NO_RETURN(type)   type PJ_NORETURN

-#  define PJ_BEGIN_DECL		    extern "C" {

-#  define PJ_END_DECL		    }

-#else

-#  define PJ_DECL(type)		    extern type

-#  define PJ_DECL_NO_RETURN(type)   PJ_NORETURN type

-#  define PJ_BEGIN_DECL

-#  define PJ_END_DECL

-#endif

-

-/**

- * @def PJ_DEF(type)

- * @param type The return type of the function.

- * Define a function.

- */

-#define PJ_DEF(type)	  type

-

-/**

- * @def PJ_EXPORT_SYMBOL(sym)

- * @param sym The symbol to export.

- * Export the specified symbol in compilation type that requires export

- * (e.g. Linux kernel).

- */

-#ifdef __PJ_EXPORT_SYMBOL

-#  define PJ_EXPORT_SYMBOL(sym)	    __PJ_EXPORT_SYMBOL(sym)

-#else

-#  define PJ_EXPORT_SYMBOL(sym)

-#endif

-

-/**

- * @def PJ_IDECL(type)

- * @param type  The function's return type.

- * Declare a function that may be expanded as inline.

- */

-/**

- * @def PJ_IDEF(type)

- * @param type  The function's return type.

- * Define a function that may be expanded as inline.

- */

-

-#if PJ_FUNCTIONS_ARE_INLINED

-#  define PJ_IDECL(type)  PJ_INLINE(type)

-#  define PJ_IDEF(type)   PJ_INLINE(type)

-#else

-#  define PJ_IDECL(type)  PJ_DECL(type)

-#  define PJ_IDEF(type)   PJ_DEF(type)

-#endif

-

-/**

- * @def PJ_UNUSED_ARG(arg)

- * @param arg   The argument name.

- * PJ_UNUSED_ARG prevents warning about unused argument in a function.

- */

-#define PJ_UNUSED_ARG(arg)  (void)arg

-

-/**

- * @def PJ_TODO(id)

- * @param id    Any identifier that will be printed as TODO message.

- * PJ_TODO macro will display TODO message as warning during compilation.

- * Example: PJ_TODO(CLEAN_UP_ERROR);

- */

-#ifndef PJ_TODO

-#  define PJ_TODO(id)	    TODO___##id:

-#endif

-

-/**

- * Function attributes to inform that the function may throw exception.

- *

- * @param x     The exception list, enclosed in parenthesis.

- */

-#define __pj_throw__(x)

-

-

-/********************************************************************

- * Sanity Checks

- */

-#ifndef PJ_HAS_HIGH_RES_TIMER

-#  error "PJ_HAS_HIGH_RES_TIMER is not defined!"

-#endif

-

-#if !defined(PJ_HAS_PENTIUM)

-#  error "PJ_HAS_PENTIUM is not defined!"

-#endif

-

-#if !defined(PJ_IS_LITTLE_ENDIAN)

-#  error "PJ_IS_LITTLE_ENDIAN is not defined!"

-#endif

-

-#if !defined(PJ_IS_BIG_ENDIAN)

-#  error "PJ_IS_BIG_ENDIAN is not defined!"

-#endif

-

-

-

-PJ_BEGIN_DECL

-

-/**

- * PJLIB version string.

- */

-extern const char *PJ_VERSION;

-

-/**

- * Dump configuration to log with verbosity equal to info(3).

- */

-PJ_DECL(void) pj_dump_config(void);

-

-PJ_END_DECL

-

-

-#endif	/* __PJ_CONFIG_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_CONFIG_H__
+#define __PJ_CONFIG_H__
+
+/**
+ * @file config.h
+ * @brief PJLIB Main configuration settings.
+ */
+
+/********************************************************************
+ * Include compiler specific configuration.
+ */
+#if defined(_MSC_VER)
+#  include <pj/compat/cc_msvc.h>
+#elif defined(__GNUC__)
+#  include <pj/compat/cc_gcc.h>
+#else
+#  error "Unknown compiler."
+#endif
+
+
+/********************************************************************
+ * Include target OS specific configuration.
+ */
+#if defined(PJ_WIN32) && PJ_WIN32!=0
+#  include <pj/compat/os_win32.h>
+#elif defined(PJ_LINUX) && PJ_LINUX!=0
+#  include <pj/compat/os_linux.h>
+#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL!=0
+#  include <pj/compat/os_linux_kernel.h>
+#elif defined(PJ_PALMOS) && PJ_PALMOS!=0
+#  include <pj/compat/os_palmos.h>
+#elif defined(PJ_SUNOS) && PJ_SUNOS!=0
+#  include <pj/compat/os_sunos.h>
+#else
+#  error "Please specify target os."
+#endif
+
+
+/********************************************************************
+ * Target machine specific configuration.
+ */
+#if defined (PJ_M_I386) && PJ_M_I386 != 0
+#   include <pj/compat/m_i386.h>
+#elif defined (PJ_M_M68K) && PJ_M_M68K != 0
+#   include <pj/compat/m_m68k.h>
+#elif defined (PJ_M_ALPHA) && PJ_M_ALPHA != 0
+#   include <pj/compat/m_alpha.h>
+#elif defined (PJ_M_SPARC) && PJ_M_SPARC != 0
+#   include <pj/compat/m_sparc.h>
+#else
+#  error "Please specify target machine."
+#endif
+
+/* Include size_t definition. */
+#include <pj/compat/size_t.h>
+
+/* Include site/user specific configuration to control PJLIB features.
+ * YOU MUST CREATE THIS FILE YOURSELF!!
+ */
+#include <pj/config_site.h>
+
+/********************************************************************
+ * PJLIB Features.
+ */
+
+/* Overrides for DOXYGEN */
+#ifdef DOXYGEN
+#   undef PJ_FUNCTIONS_ARE_INLINED
+#   undef PJ_HAS_FLOATING_POINT
+#   undef PJ_LOG_MAX_LEVEL
+#   undef PJ_LOG_MAX_SIZE
+#   undef PJ_LOG_USE_STACK_BUFFER
+#   undef PJ_TERM_HAS_COLOR
+#   undef PJ_POOL_DEBUG
+#   undef PJ_HAS_TCP
+#   undef PJ_MAX_HOSTNAME
+#   undef PJ_IOQUEUE_MAX_HANDLES
+#   undef FD_SETSIZE
+#   undef PJ_HAS_SEMAPHORE
+#   undef PJ_HAS_EVENT_OBJ
+#   undef PJ_ENABLE_EXTRA_CHECK
+#endif
+
+/**
+ * @defgroup pj_config Build Configuration
+ * @ingroup PJ
+ * @{
+ *
+ * This section contains macros that can set during PJLIB build process
+ * to controll various aspects of the library.
+ *
+ * <b>Note</b>: the values in this page does NOT necessarily reflect to the
+ * macro values during the build process.
+ */
+
+/**
+ * If this macro is set to 1, it will enable some debugging checking
+ * in the library.
+ *
+ * Default: equal to (NOT NDEBUG).
+ */
+#ifndef PJ_DEBUG
+#  ifndef NDEBUG
+#    define PJ_DEBUG		    1
+#  else
+#    define PJ_DEBUG		    0
+#  endif
+#endif
+
+/**
+ * Expand functions in *_i.h header files as inline.
+ *
+ * Default: 0.
+ */
+#ifndef PJ_FUNCTIONS_ARE_INLINED
+#  define PJ_FUNCTIONS_ARE_INLINED  0
+#endif
+
+/**
+ * Use floating point computations in the library.
+ *
+ * Default: 1.
+ */
+#ifndef PJ_HAS_FLOATING_POINT
+#  define PJ_HAS_FLOATING_POINT	    1
+#endif
+
+/**
+ * Declare maximum logging level/verbosity. Lower number indicates higher
+ * importance, with the highest importance has level zero. The least
+ * important level is five in this implementation, but this can be extended
+ * by supplying the appropriate implementation.
+ *
+ * The level conventions:
+ *  - 0: fatal error
+ *  - 1: error
+ *  - 2: warning
+ *  - 3: info
+ *  - 4: debug
+ *  - 5: trace
+ *  - 6: more detailed trace
+ *
+ * Default: 4
+ */
+#ifndef PJ_LOG_MAX_LEVEL
+#  define PJ_LOG_MAX_LEVEL   5
+#endif
+
+/**
+ * Maximum message size that can be sent to output device for each call
+ * to PJ_LOG(). If the message size is longer than this value, it will be cut.
+ * This may affect the stack usage, depending whether PJ_LOG_USE_STACK_BUFFER
+ * flag is set.
+ *
+ * Default: 800
+ */
+#ifndef PJ_LOG_MAX_SIZE
+#  define PJ_LOG_MAX_SIZE	    800
+#endif
+
+/**
+ * Log buffer.
+ * Does the log get the buffer from the stack? (default is yes).
+ * If the value is set to NO, then the buffer will be taken from static
+ * buffer, which in this case will make the log function non-reentrant.
+ *
+ * Default: 1
+ */
+#ifndef PJ_LOG_USE_STACK_BUFFER
+#  define PJ_LOG_USE_STACK_BUFFER   1
+#endif
+
+
+/**
+ * Colorfull terminal (for logging etc).
+ *
+ * Default: 1
+ */
+#ifndef PJ_TERM_HAS_COLOR
+#  define PJ_TERM_HAS_COLOR	    1
+#endif
+
+/**
+ * Pool debugging.
+ *
+ * Default: 0
+ */
+#ifndef PJ_POOL_DEBUG
+#  define PJ_POOL_DEBUG		    0
+#endif
+
+/**
+ * \def PJ_HAS_TCP
+ * Support TCP in the library.
+ * Disabling TCP will reduce the footprint slightly (about 6KB).
+ *
+ * Default: 1
+ */
+#ifndef PJ_HAS_TCP
+#  define PJ_HAS_TCP		    1
+#endif
+
+/**
+ * Maximum hostname length.
+ * Libraries sometimes needs to make copy of an address to stack buffer;
+ * the value here affects the stack usage.
+ *
+ * Default: 128
+ */
+#ifndef PJ_MAX_HOSTNAME
+#  define PJ_MAX_HOSTNAME	    (128)
+#endif
+
+/**
+ * Constants for declaring the maximum handles that can be supported by
+ * a single IOQ framework. This constant might not be relevant to the 
+ * underlying I/O queue impelementation, but still, developers should be 
+ * aware of this constant, to make sure that the program will not break when
+ * the underlying implementation changes.
+ *
+ * For implementation based on select(), the value here will be used as the
+ * maximum number of socket handles passed to select() (i.e. FD_SETSIZE will 
+ * be set to this value).
+ *
+ * Default: 256
+ */
+#ifndef PJ_IOQUEUE_MAX_HANDLES
+#  define PJ_IOQUEUE_MAX_HANDLES    (256)
+#endif
+
+/**
+ * Overrides FD_SETSIZE so it is consistent throughout the library.
+ * OS specific configuration header (compat/os_*) might have declared
+ * FD_SETSIZE, thus we only set if it hasn't been declared.
+ *
+ * Default: #PJ_IOQUEUE_MAX_HANDLES
+ */
+#ifndef FD_SETSIZE
+#  define FD_SETSIZE		    PJ_IOQUEUE_MAX_HANDLES
+#endif
+
+/**
+ * Has semaphore functionality?
+ *
+ * Default: 1
+ */
+#ifndef PJ_HAS_SEMAPHORE
+#  define PJ_HAS_SEMAPHORE	    1
+#endif
+
+
+/**
+ * Event object (for synchronization, e.g. in Win32)
+ *
+ * Default: 1
+ */
+#ifndef PJ_HAS_EVENT_OBJ
+#  define PJ_HAS_EVENT_OBJ	    1
+#endif
+
+
+/**
+ * Enable library's extra check.
+ * If this macro is enabled, #PJ_ASSERT_RETURN macro will expand to
+ * run-time checking. If this macro is disabled, #PJ_ASSERT_RETURN
+ * will simply evaluate to #pj_assert().
+ *
+ * You can disable this macro to reduce size, at the risk of crashes
+ * if invalid value (e.g. NULL) is passed to the library.
+ *
+ * Default: 1
+ */
+#ifndef PJ_ENABLE_EXTRA_CHECK
+#   define PJ_ENABLE_EXTRA_CHECK    1
+#endif
+
+
+/**
+ * Enable name registration for exceptions with #pj_exception_id_alloc().
+ * If this feature is enabled, then the library will keep track of
+ * names associated with each exception ID requested by application via
+ * #pj_exception_id_alloc().
+ *
+ * Disabling this macro will reduce the code and .bss size by a tad bit.
+ * See also #PJ_MAX_EXCEPTION_ID.
+ *
+ * Default: 1
+ */
+#ifndef PJ_HAS_EXCEPTION_NAMES
+#   define PJ_HAS_EXCEPTION_NAMES   1
+#endif
+
+/**
+ * Maximum number of unique exception IDs that can be requested
+ * with #pj_exception_id_alloc(). For each entry, a small record will
+ * be allocated in the .bss segment.
+ *
+ * Default: 16
+ */
+#ifndef PJ_MAX_EXCEPTION_ID
+#   define PJ_MAX_EXCEPTION_ID      16
+#endif
+
+/** @} */
+
+/********************************************************************
+ * General macros.
+ */
+
+/**
+ * @def PJ_INLINE(type)
+ * @param type The return type of the function.
+ * Expand the function as inline.
+ */
+#define PJ_INLINE(type)	  PJ_INLINE_SPECIFIER type
+
+/**
+ * @def PJ_DECL(type)
+ * @param type The return type of the function.
+ * Declare a function.
+ */
+/**
+ * @def PJ_DECL_NO_RETURN(type)
+ * @param type The return type of the function.
+ * Declare a function that will not return.
+ */
+/**
+ * @def PJ_BEGIN_DECL
+ * Mark beginning of declaration section in a header file.
+ */
+/**
+ * @def PJ_END_DECL
+ * Mark end of declaration section in a header file.
+ */
+#ifdef __cplusplus
+#  define PJ_DECL(type)		    type
+#  define PJ_DECL_NO_RETURN(type)   type PJ_NORETURN
+#  define PJ_BEGIN_DECL		    extern "C" {
+#  define PJ_END_DECL		    }
+#else
+#  define PJ_DECL(type)		    extern type
+#  define PJ_DECL_NO_RETURN(type)   PJ_NORETURN type
+#  define PJ_BEGIN_DECL
+#  define PJ_END_DECL
+#endif
+
+/**
+ * @def PJ_DEF(type)
+ * @param type The return type of the function.
+ * Define a function.
+ */
+#define PJ_DEF(type)	  type
+
+/**
+ * @def PJ_EXPORT_SYMBOL(sym)
+ * @param sym The symbol to export.
+ * Export the specified symbol in compilation type that requires export
+ * (e.g. Linux kernel).
+ */
+#ifdef __PJ_EXPORT_SYMBOL
+#  define PJ_EXPORT_SYMBOL(sym)	    __PJ_EXPORT_SYMBOL(sym)
+#else
+#  define PJ_EXPORT_SYMBOL(sym)
+#endif
+
+/**
+ * @def PJ_IDECL(type)
+ * @param type  The function's return type.
+ * Declare a function that may be expanded as inline.
+ */
+/**
+ * @def PJ_IDEF(type)
+ * @param type  The function's return type.
+ * Define a function that may be expanded as inline.
+ */
+
+#if PJ_FUNCTIONS_ARE_INLINED
+#  define PJ_IDECL(type)  PJ_INLINE(type)
+#  define PJ_IDEF(type)   PJ_INLINE(type)
+#else
+#  define PJ_IDECL(type)  PJ_DECL(type)
+#  define PJ_IDEF(type)   PJ_DEF(type)
+#endif
+
+/**
+ * @def PJ_UNUSED_ARG(arg)
+ * @param arg   The argument name.
+ * PJ_UNUSED_ARG prevents warning about unused argument in a function.
+ */
+#define PJ_UNUSED_ARG(arg)  (void)arg
+
+/**
+ * @def PJ_TODO(id)
+ * @param id    Any identifier that will be printed as TODO message.
+ * PJ_TODO macro will display TODO message as warning during compilation.
+ * Example: PJ_TODO(CLEAN_UP_ERROR);
+ */
+#ifndef PJ_TODO
+#  define PJ_TODO(id)	    TODO___##id:
+#endif
+
+/**
+ * Function attributes to inform that the function may throw exception.
+ *
+ * @param x     The exception list, enclosed in parenthesis.
+ */
+#define __pj_throw__(x)
+
+
+/********************************************************************
+ * Sanity Checks
+ */
+#ifndef PJ_HAS_HIGH_RES_TIMER
+#  error "PJ_HAS_HIGH_RES_TIMER is not defined!"
+#endif
+
+#if !defined(PJ_HAS_PENTIUM)
+#  error "PJ_HAS_PENTIUM is not defined!"
+#endif
+
+#if !defined(PJ_IS_LITTLE_ENDIAN)
+#  error "PJ_IS_LITTLE_ENDIAN is not defined!"
+#endif
+
+#if !defined(PJ_IS_BIG_ENDIAN)
+#  error "PJ_IS_BIG_ENDIAN is not defined!"
+#endif
+
+
+
+PJ_BEGIN_DECL
+
+/**
+ * PJLIB version string.
+ */
+extern const char *PJ_VERSION;
+
+/**
+ * Dump configuration to log with verbosity equal to info(3).
+ */
+PJ_DECL(void) pj_dump_config(void);
+
+PJ_END_DECL
+
+
+#endif	/* __PJ_CONFIG_H__ */
+
diff --git a/pjlib/include/pj/ctype.h b/pjlib/include/pj/ctype.h
index e2ab103..0319cfd 100644
--- a/pjlib/include/pj/ctype.h
+++ b/pjlib/include/pj/ctype.h
@@ -1,173 +1,173 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_CTYPE_H__

-#define __PJ_CTYPE_H__

-

-/**

- * @file ctype.h

- * @brief C type helper macros.

- */

-

-#include <pj/types.h>

-#include <pj/compat/ctype.h>

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup pj_ctype ctype - Character Type

- * @ingroup PJ_MISC

- * @{

- *

- * This module contains several inline functions/macros for testing or

- * manipulating character types. It is provided in PJLIB because PJLIB

- * must not depend to LIBC.

- */

-

-/** 

- * Returns a non-zero value if either isalpha or isdigit is true for c.

- * @param c     The integer character to test.

- * @return      Non-zero value if either isalpha or isdigit is true for c.

- */

-PJ_INLINE(int) pj_isalnum(int c) { return isalnum(c); }

-

-/** 

- * Returns a non-zero value if c is a particular representation of an 

- * alphabetic character.

- * @param c     The integer character to test.

- * @return      Non-zero value if c is a particular representation of an 

- *              alphabetic character.

- */

-PJ_INLINE(int) pj_isalpha(int c) { return isalpha(c); }

-

-/** 

- * Returns a non-zero value if c is a particular representation of an 

- * ASCII character.

- * @param c     The integer character to test.

- * @return      Non-zero value if c is a particular representation of 

- *              an ASCII character.

- */

-PJ_INLINE(int) pj_isascii(int c) { return isascii(c); }

-

-/** 

- * Returns a non-zero value if c is a particular representation of 

- * a decimal-digit character.

- * @param c     The integer character to test.

- * @return      Non-zero value if c is a particular representation of 

- *              a decimal-digit character.

- */

-PJ_INLINE(int) pj_isdigit(int c) { return isdigit(c); }

-

-/** 

- * Returns a non-zero value if c is a particular representation of 

- * a space character (0x09 - 0x0D or 0x20).

- * @param c     The integer character to test.

- * @return      Non-zero value if c is a particular representation of 

- *              a space character (0x09 - 0x0D or 0x20).

- */

-PJ_INLINE(int) pj_isspace(int c) { return isspace(c); }

-

-/** 

- * Returns a non-zero value if c is a particular representation of 

- * a lowercase character.

- * @param c     The integer character to test.

- * @return      Non-zero value if c is a particular representation of 

- *              a lowercase character.

- */

-PJ_INLINE(int) pj_islower(int c) { return islower(c); }

-

-

-/** 

- * Returns a non-zero value if c is a particular representation of 

- * a uppercase character.

- * @param c     The integer character to test.

- * @return      Non-zero value if c is a particular representation of 

- *              a uppercase character.

- */

-PJ_INLINE(int) pj_isupper(int c) { return isupper(c); }

-

-/**

- * Returns a non-zero value if c is a either a space (' ') or horizontal

- * tab ('\\t') character.

- * @param c     The integer character to test.

- * @return      Non-zero value if c is a either a space (' ') or horizontal

- *              tab ('\\t') character.

- */

-PJ_INLINE(int) pj_isblank(int c) { return isblank(c); }

-

-/**

- * Converts character to lowercase.

- * @param c     The integer character to convert.

- * @return      Lowercase character of c.

- */

-PJ_INLINE(int) pj_tolower(int c) { return tolower(c); }

-

-/**

- * Converts character to uppercase.

- * @param c     The integer character to convert.

- * @return      Uppercase character of c.

- */

-PJ_INLINE(int) pj_toupper(int c) { return toupper(c); }

-

-/**

- * Returns a non-zero value if c is a particular representation of 

- * an hexadecimal digit character.

- * @param c     The integer character to test.

- * @return      Non-zero value if c is a particular representation of 

- *              an hexadecimal digit character.

- */

-PJ_INLINE(int) pj_isxdigit(int c){ return isxdigit(c); }

-

-/**

- * Array of hex digits, in lowerspace.

- */

-extern char pj_hex_digits[];

-

-/**

- * Convert a value to hex representation.

- * @param value	    Integral value to convert.

- * @param p	    Buffer to hold the hex representation, which must be

- *		    at least two bytes length.

- */

-PJ_INLINE(void) pj_val_to_hex_digit(unsigned value, char *p)

-{

-    *p++ = pj_hex_digits[ (value & 0xF0) >> 4 ];

-    *p   = pj_hex_digits[ (value & 0x0F) ];

-}

-

-/**

- * Convert hex digit c to integral value.

- * @param c	The hex digit character.

- * @return	The integral value between 0 and 15.

- */

-PJ_INLINE(unsigned) pj_hex_digit_to_val(unsigned c)

-{

-    if (c <= '9')

-	return (c-'0') & 0x0F;

-    else if (c <= 'F')

-	return  (c-'A'+10) & 0x0F;

-    else

-	return (c-'a'+10) & 0x0F;

-}

-

-/** @} */

-

-PJ_END_DECL

-

-#endif	/* __PJ_CTYPE_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_CTYPE_H__
+#define __PJ_CTYPE_H__
+
+/**
+ * @file ctype.h
+ * @brief C type helper macros.
+ */
+
+#include <pj/types.h>
+#include <pj/compat/ctype.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup pj_ctype ctype - Character Type
+ * @ingroup PJ_MISC
+ * @{
+ *
+ * This module contains several inline functions/macros for testing or
+ * manipulating character types. It is provided in PJLIB because PJLIB
+ * must not depend to LIBC.
+ */
+
+/** 
+ * Returns a non-zero value if either isalpha or isdigit is true for c.
+ * @param c     The integer character to test.
+ * @return      Non-zero value if either isalpha or isdigit is true for c.
+ */
+PJ_INLINE(int) pj_isalnum(int c) { return isalnum(c); }
+
+/** 
+ * Returns a non-zero value if c is a particular representation of an 
+ * alphabetic character.
+ * @param c     The integer character to test.
+ * @return      Non-zero value if c is a particular representation of an 
+ *              alphabetic character.
+ */
+PJ_INLINE(int) pj_isalpha(int c) { return isalpha(c); }
+
+/** 
+ * Returns a non-zero value if c is a particular representation of an 
+ * ASCII character.
+ * @param c     The integer character to test.
+ * @return      Non-zero value if c is a particular representation of 
+ *              an ASCII character.
+ */
+PJ_INLINE(int) pj_isascii(int c) { return isascii(c); }
+
+/** 
+ * Returns a non-zero value if c is a particular representation of 
+ * a decimal-digit character.
+ * @param c     The integer character to test.
+ * @return      Non-zero value if c is a particular representation of 
+ *              a decimal-digit character.
+ */
+PJ_INLINE(int) pj_isdigit(int c) { return isdigit(c); }
+
+/** 
+ * Returns a non-zero value if c is a particular representation of 
+ * a space character (0x09 - 0x0D or 0x20).
+ * @param c     The integer character to test.
+ * @return      Non-zero value if c is a particular representation of 
+ *              a space character (0x09 - 0x0D or 0x20).
+ */
+PJ_INLINE(int) pj_isspace(int c) { return isspace(c); }
+
+/** 
+ * Returns a non-zero value if c is a particular representation of 
+ * a lowercase character.
+ * @param c     The integer character to test.
+ * @return      Non-zero value if c is a particular representation of 
+ *              a lowercase character.
+ */
+PJ_INLINE(int) pj_islower(int c) { return islower(c); }
+
+
+/** 
+ * Returns a non-zero value if c is a particular representation of 
+ * a uppercase character.
+ * @param c     The integer character to test.
+ * @return      Non-zero value if c is a particular representation of 
+ *              a uppercase character.
+ */
+PJ_INLINE(int) pj_isupper(int c) { return isupper(c); }
+
+/**
+ * Returns a non-zero value if c is a either a space (' ') or horizontal
+ * tab ('\\t') character.
+ * @param c     The integer character to test.
+ * @return      Non-zero value if c is a either a space (' ') or horizontal
+ *              tab ('\\t') character.
+ */
+PJ_INLINE(int) pj_isblank(int c) { return isblank(c); }
+
+/**
+ * Converts character to lowercase.
+ * @param c     The integer character to convert.
+ * @return      Lowercase character of c.
+ */
+PJ_INLINE(int) pj_tolower(int c) { return tolower(c); }
+
+/**
+ * Converts character to uppercase.
+ * @param c     The integer character to convert.
+ * @return      Uppercase character of c.
+ */
+PJ_INLINE(int) pj_toupper(int c) { return toupper(c); }
+
+/**
+ * Returns a non-zero value if c is a particular representation of 
+ * an hexadecimal digit character.
+ * @param c     The integer character to test.
+ * @return      Non-zero value if c is a particular representation of 
+ *              an hexadecimal digit character.
+ */
+PJ_INLINE(int) pj_isxdigit(int c){ return isxdigit(c); }
+
+/**
+ * Array of hex digits, in lowerspace.
+ */
+extern char pj_hex_digits[];
+
+/**
+ * Convert a value to hex representation.
+ * @param value	    Integral value to convert.
+ * @param p	    Buffer to hold the hex representation, which must be
+ *		    at least two bytes length.
+ */
+PJ_INLINE(void) pj_val_to_hex_digit(unsigned value, char *p)
+{
+    *p++ = pj_hex_digits[ (value & 0xF0) >> 4 ];
+    *p   = pj_hex_digits[ (value & 0x0F) ];
+}
+
+/**
+ * Convert hex digit c to integral value.
+ * @param c	The hex digit character.
+ * @return	The integral value between 0 and 15.
+ */
+PJ_INLINE(unsigned) pj_hex_digit_to_val(unsigned c)
+{
+    if (c <= '9')
+	return (c-'0') & 0x0F;
+    else if (c <= 'F')
+	return  (c-'A'+10) & 0x0F;
+    else
+	return (c-'a'+10) & 0x0F;
+}
+
+/** @} */
+
+PJ_END_DECL
+
+#endif	/* __PJ_CTYPE_H__ */
+
diff --git a/pjlib/include/pj/doxygen.h b/pjlib/include/pj/doxygen.h
index 1b5f479..f4bf8db 100644
--- a/pjlib/include/pj/doxygen.h
+++ b/pjlib/include/pj/doxygen.h
@@ -1,1019 +1,1019 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_DOXYGEN_H__

-#define __PJ_DOXYGEN_H__

-

-/**

- * @file doxygen.h

- * @brief Doxygen's mainpage.

- */

-

-/*////////////////////////////////////////////////////////////////////////// */

-/*

-	INTRODUCTION PAGE

- */

-

-/**

- * @mainpage Welcome to PJLIB!

- *

- * @section intro_sec What is PJLIB

- *

- * PJLIB is a small foundation library written in C for making scalable 

- * applications. Because of its small footprint, it can be used in embedded 

- * applications (we hope so!), but yet the library is also aimed for 

- * facilitating high performance protocol stacks.

- *

- * PJLIB is released under LGPL terms.

- *

- * @section download_sec Download

- *

- * PJLIB and all documentation can be downloaded from 

- * http://www.pjproject.net.

- *

- *

- * @section how_to_use_sec About This Documentation

- *

- * This document is generated directly from PJLIB source file using

- * \a doxygen (http://www.doxygen.org). Doxygen is a great (and free!) 

- * tools for generating such documentation.

- *

- * @subsection doc_ver_subsec Version

- *

- * This document corresponds to PJLIB version 0.3-pre2.

- *

- *

- * @subsection find_samples_subsec How to Read This Document

- *

- * This documentation is laid out more to be a reference guide instead

- * of tutorial, therefore first time users may find it difficult to

- * grasp PJLIB by reading this document alone.

- *

- * However, we've tried our best to make this document easy to follow.

- * For first time users, we would suggest that you follow these steps

- * when reading this documentation:

- *

- *  - continue reading this introduction chapter. At the end of this

- *    chapter, you'll find section called \ref pjlib_fundamentals_sec

- *    which should guide you to understand basic things about PJLIB.

- *

- *  - find information about specific features that you want to use

- *    in PJLIB. Use the <b>Module Index</b> to find out about all 

- *    features in PJLIB (if you're browsing the HTML documentation,

- *    click on the \a Module link on top of the page, or if you're

- *    reading the PDF documentation, click on \a Module \a Documentation

- *    on the navigation pane on the left).

- *

- * @subsection doc_organize_sec How To's

- *

- * Please find below links to specific tasks that you probably

- * want to do:

- *

- *  - <b>How to Build PJLIB</b>

- *\n

- * Please refer to \ref pjlib_build_sys_pg page for more information.

- *

- *  - <b>How to Use PJLIB in My Application</b>

- *\n

- * Please refer to \ref configure_app_sec for more information.

- *

- *  - <b>How to Port PJLIB</b>

- *\n

- * Please refer to \ref porting_pjlib_pg page.

- *

- *  - <b>Where to Read Samples Documentation</b>

- *\n

- * Most of the modules provide link to the corresponding sample file.

- * Alternatively, to get the list of all examples, you can click on 

- * <b>Related Pages</b> on the top of HTML document or on 

- * <b>PJLIB Page Documentation</b> on navigation pane of your PDF reader.

- *

- *  - <b>How to Submit Code to PJLIB Project</b>

- *\n

- * Please read \ref pjlib_coding_convention_page before submitting

- * your code. Send your code as patch against current Subversion tree

- * to the appropriate mailing list.

- *

- *

- * @section features_sec Features

- *

- * @subsection open_source_feat It's Open Source!

- *

- * PJLIB is currently released on LGPL license. We may release PJLIB under

- * additional schemes in the future (such as GPL or MPL) to incorporate

- * linking with specific application, however, one thing for sure is

- * we will NEVER be able to make PJLIB a proprietary software.

- *

- * @subsection extreme_portable_feat Extreme Portability

- *

- * PJLIB is designed to be extremely portable. It can run on any kind

- * of processors (16-bit, 32-bit, or 64-bit, big or little endian, single

- * or multi-processors) and operating systems. Floating point or no

- * floating point. Multi-threading or not.

- * It can even run in environment where no ANSI LIBC is available. 

- *

- * Currently PJLIB is being ported to:

- *  - x86, Win32 (Win95/98/ME, NT/2000/XP/2003, mingw).

- *  - x86, Linux (user mode and as <b>kernel module</b>(!)).

- *  - alpha, Linux

- * And coming up:

- *  - x86, eCos

- *  - ultra-II, Solaris.

- *  - powerpc, MacOS

- *  - m68k, PalmOS.

- *  - arm, PocketPC

- *

- * No other library is known to have this extreme portability!

- *

- * @subsection small_size_feat Small in Size

- *

- * One of the primary objectives is to have library that is small in size for

- * typical embedded applications. As a rough guidance, we aim to keep the 

- * library size below 100KB for it to be considered as small.

- * As the result, most of the functionalities in the library can be tailored

- * to meet the requirements; user can enable/disable specific functionalities

- * to get the desired size/performance/functionality balance.

- *

- * For more info, please see @ref pj_config.

- *

- * @subsection no_dyn_mem No Dynamic Memory Allocations

- *

- * The central idea of PJLIB is that for applications to run as fast as it can,

- * it should not use \a malloc() at all, but instead should get the memory 

- * from a preallocated storage pool. There are few things that can be 

- * optimized with this approach:

- *

- *  - \a alloc() is a O(1) operation.

- *  - no mutex is used inside alloc(). It is assumed that synchronization 

- *    will be used in higher abstraction by application anyway.

- *  - no \a free() is required. All chunks will be deleted when the pool is 

- *    destroyed.

- *

- * The performance gained on some systems can be as high as 10x speed up

- * against \a malloc() and \a free().

- *

- * For more information, see \ref PJ_POOL_GROUP

- *

- * 

- * @subsection os_abstract_feat Operating System Abstraction

- *

- * PJLIB has abstractions for features that are normally not portable 

- * across operating systems: 

- *  - @ref PJ_THREAD

- *\n

- *    Portable thread manipulation.

- *  - @ref PJ_TLS

- *\n

- *    Storing data in thread's private data.

- *  - @ref PJ_MUTEX

- *\n

- *    Mutual exclusion protection.

- *  - @ref PJ_SEM

- *\n

- *    Semaphores.

- *  - @ref PJ_ATOMIC

- *\n

- *    Atomic variables and their operations.

- *  - @ref PJ_CRIT_SEC

- *\n

- *    Fast locking of critical sections.

- *  - @ref PJ_LOCK

- *\n

- *    High level abstraction for lock objects.

- *  - @ref PJ_EVENT

- *\n

- *    Event object.

- *  - @ref PJ_TIME

- *\n

- *    Portable time manipulation.

- *  - @ref PJ_TIMESTAMP

- *\n

- *    High resolution time value.

- *  - etc.

- *

- *

- * @subsection ll_network_io_sec Low-Level Network I/O

- *

- * PJLIB has very portable abstraction and fairly complete set of API for

- * doing network I/O communications. At the lowest level, PJLIB provides:

- *

- *  - @ref PJ_SOCK

- *\n

- *    A highly portable socket abstraction, runs on all kind of

- *    network APIs such as standard BSD socket, Windows socket, Linux

- *    \b kernel socket, PalmOS networking API, etc.

- *

- *  - @ref pj_addr_resolve

- *\n

- *    Portable address resolution, which implements #pj_gethostbyname().

- *

- *  - @ref PJ_SOCK_SELECT

- *\n

- *    A portable \a select() like API (#pj_sock_select()) which can be

- *    implemented with various back-end.

- *

- *

- * @subsection hl_network_io_sec High-Level Network I/O

- *

- * At higher abstraction, PJLIB provides @ref PJ_IOQUEUE, 

- * which promotes creating high performance network

- * applications by managing asynchronous I/O. This is a passive framework

- * that utilizes the most effective way to manage asynchronous I/O

- * on a given platform, such as:

- *  - IoCompletionPort on WinNT,

- *  - on Linux it can use either /dev/epoll or aio.

- *  - or to fall back to use @a select()

- *

- * At even a higher abstraction, PJLIB provides @ref PJ_EQUEUE, which

- * combines asynchronous I/O with timer management and thread management 

- * to fasilitate creating trully high performance, event driven

- * application.

- * 

- *

- * @subsection timer_mgmt_sec Timer Management

- *

- * A passive framework for managing timer, see @ref PJ_TIMER for more info.

- * There is also function to retrieve high resolution timestamp

- * from the system (see @ref PJ_TIMESTAMP).

- *

- *

- * @subsection data_struct_sec Various Data Structures

- *

- * Various data structures are provided in the library:

- *

- *  - @ref PJ_PSTR

- *  - @ref PJ_ARRAY

- *  - @ref PJ_HASH

- *  - @ref PJ_LIST

- *  - @ref PJ_RBTREE

- *

- *

- * @subsection exception_sec Exception Construct

- *

- * A convenient TRY/CATCH like construct to propagate errors, which by

- * default are used by the @ref PJ_POOL_GROUP "memory pool" and 

- * the lexical scanner in pjlib-util. The exception

- * construct can be used to write programs like below:

- *

- * <pre>

- *    #define SYNTAX_ERROR  1

- *

- *    PJ_TRY {

- *       msg = NULL;

- *       msg = parse_msg(buf, len);

- *    }

- *    PJ_CATCH ( SYNTAX_ERROR ) {

- *       .. handle error ..

- *    }

- *    PJ_END;

- * </pre>

- *

- * Please see @ref PJ_EXCEPT for more information.

- *

- *

- * @subsection logging_sec Logging Facility

- *

- * PJLIB @ref PJ_LOG consists of macros to write logging information to

- * some output device. Some of the features of the logging facility:

- *

- *  - the verbosity can be fine-tuned both at compile time (to control

- *    the library size) or run-time (to control the verbosity of the

- *    information).

- *  - output device is configurable (e.g. stdout, printk, file, etc.)

- *  - log decoration is configurable.

- *

- * See @ref PJ_LOG for more information.

- *

- *

- * @subsection guid_gen_sec Random and GUID Generation

- *

- * PJLIB provides facility to create random string 

- * (#pj_create_random_string()) or globally unique identifier

- * (see @ref PJ_GUID).

- *

- *

- *

- * @section configure_app_sec Configuring Application to use PJLIB

- *

- * @subsection pjlib_compil_sec Building PJLIB

- *

- * Follow the instructions in \ref pjlib_build_sys_pg to build

- * PJLIB.

- *

- * @subsection pjlib_compil_app_sec Building Applications with PJLIB

- *

- * Use the following settings when building applications with PJLIB.

- *

- * @subsubsection compil_inc_dir_sec Include Search Path

- *

- * Add this to your include search path ($PJLIB is PJLIB root directory):

- * <pre>

- *   $PJLIB/include

- * </pre>

- *

- * @subsubsection compil_inc_file_sec Include PJLIB Header

- *

- * To include all PJLIB headers:

- * \verbatim

-    #include <pjlib.h>

-   \endverbatim

- *

- * Alternatively, you can include individual PJLIB headers like this:

- * \verbatim

-     #include <pj/log.h>

-     #include <pj/os.h>

-  \endverbatim

- *

- *

- * @subsubsection compil_lib_dir_sec Library Path

- *

- * Add this to your library search path:

- * <pre>

- *   $PJLIB/lib

- * </pre>

- *

- * Then add the appropriate PJLIB library to your link specification. For

- * example, you would add \c libpj-i386-linux-gcc.a when you're building

- * applications in Linux.

- *

- *

- * @subsection pjlib_fundamentals_sec Principles in Using PJLIB

- *

- * Few things that you \b MUST do when using PJLIB, to make sure that

- * you create trully portable applications.

- *

- * @subsubsection call_pjlib_init_sec Call pj_init()

- *

- * Before you do anything else, call \c pj_init(). This would make sure that

- * PJLIB system is properly set up.

- *

- * @subsubsection no_ansi_subsec Do NOT Use ANSI C

- *

- * Contrary to popular teaching, ANSI C (and LIBC) is not the most portable

- * library in the world, nor it's the most ubiquitous. For example, LIBC

- * is not available in Linux kernel. Also normally LIBC will be excluded

- * from compilation of RTOSes to reduce size.

- *

- * So for maximum portability, do NOT use ANSI C. Do not even try to include

- * any other header files outside <include/pj>. Stick with the functionalities

- * provided by PJLIB. 

- *

- *

- * @subsubsection string_rep_subsubsec Use pj_str_t instead of C Strings

- *

- * PJLIB uses pj_str_t instead of normal C strings. You SHOULD follow this

- * convention too. Remember, ANSI string-h is not always available. And

- * PJLIB string is faster!

- *

- * @subsubsection mem_alloc_subsubsec Use Pool for Memory Allocations

- *

- * You MUST NOT use \a malloc() or any other memory allocation functions.

- * Use PJLIB pool instead! It's faster and most portable.

- *

- * @subsection logging_subsubsec Use Logging for Text Display

- *

- * DO NOT use <stdio.h> for text output. Use PJLIB logging instead.

- *

- *

- * @section porting_pjlib_sec0 Porting PJLIB

- *

- * Please see \ref porting_pjlib_pg page on more information to port

- * PJLIB to new target.

- *

- * @section enjoy_sec Enjoy Using PJLIB!

- *

- * We hope that you find PJLIB usefull for your application. If you

- * have any questions, suggestions, critics, bug fixes, or anything

- * else, we would be happy to hear it.

- *

- * Enjoy using PJLIB!

- *

- * Benny Prijono < bennylp at pjproject dot net >

- */

-

-

-

-/*////////////////////////////////////////////////////////////////////////// */

-/*

-         CODING CONVENTION

- */

-

-/**

- * @page pjlib_coding_convention_page Coding Convention

- *

- * Before you submit your code/patches to be included with PJLIB, you must

- * make sure that your code is compliant with PJLIB coding convention.

- * <b>This is very important!</b> Otherwise we would not accept your code.

- *

- * @section coding_conv_editor_sec Editor Settings

- *

- * The single most important thing in the whole coding convention is editor 

- * settings. It's more important than the correctness of your code (bugs will

- * only crash the system, but incorrect tab size is mental!).

- *

- * Kindly set your editor as follows:

- *  - tab size to \b 8.

- *  - indentation to \b 4.

- *

- * With \c vi, you can do it with:

- * <pre>

- *  :se ts=8

- *  :se sts=4

- * </pre>

- *

- * You should replace tab with eight spaces.

- *

- * @section coding_conv_detail_sec Coding Style

- *

- * Coding style MUST strictly follow K&R style. The rest of coding style

- * must follow current style. You SHOULD be able to observe the style

- * currently used by PJLIB from PJLIB sources, and apply the style to your 

- * code. If you're not able to do simple thing like to observe PJLIB

- * coding style from the sources, then logic dictates that your ability to

- * observe more difficult area in PJLIB such as memory allocation strategy, 

- * concurrency, etc is questionable.

- *

- * @section coding_conv_comment_sec Commenting Your Code

- *

- * Public API (e.g. in header files) MUST have doxygen compliant comments.

- *

- */

-

-

-/*////////////////////////////////////////////////////////////////////////// */

-/*

-	BUILDING AND INSTALLING PJLIB

- */

-

-

-

-/**

- * @page pjlib_build_sys_pg Building, and Installing PJLIB

- *

- * @section build_sys_install_sec Build and Installation

- *

- * @subsection build_sys_install_win32_sec Visual Studio

- *

- * The PJLIB Visual Studio workspace supports the building of PJLIB

- * for Win32 target. Although currently only the Visual Studio 6 Workspace is

- * actively maintained, developers with later version of Visual Studio

- * can easily imports VS6 workspace into their IDE.

- *

- * To start building PJLIB projects with Visual Studio 6 or later, open

- * the \a workspace file in the corresponding \b \c build directory. You have

- * several choices on which \a dsw file to open:

- \verbatim

- $PJPROJECT/build/pjproject.dsw

- $PJPROJECT/pjlib/build/pjlib.dsw

- $PJPROJECT/pjsip/build/pjsip.dsw

- ..etc

- \endverbatim

- *

- * The easiest way is to open <tt>pjproject.dsw</tt> file in \b \c $PJPROJECT/build

- * directory. However this will only build the required projects, not

- * the complete projects. For example, the PJLIB test and samples projects 

- * are not included in this workspace. To build the complete projects, you must

- * open and build each \a dsw file in \c build directory in each

- * subprojects. For example, to open the complete PJLIB workspace, open

- * <tt>pjlib.dsw</tt> in <tt>$PJPROJECT/pjlib/build</tt> directory.

- *

- *

- * @subsubsection config_site_create_vc_sec Create config_site.h

- *

- * The file <tt><b>$PJPROJECT/pjlib/include/pj/config_site.h</b></tt>

- * is supposed to contain configuration that is specific to your site/target.

- * This file is not part of PJLIB, so you must create it yourself. Normally

- * you just need to create a blank file.

- *

- * The reason why it's not included in PJLIB is so that you would not accidently

- * overwrite your site configuration.

- *

- * If you fail to do this, Visual C will complain with error like: 

- *

- * <b>"fatal error C1083: Cannot open include file: 'pj/config_site.h': No such file 

- * or directory"</b>.

- *

- * @subsubsection build_vc_subsubsec Build the Projects

- *

- * Just hit the build button!

- *

- *

- * @subsection build_sys_install_unix_sec Make System

- *

- * For other targets, PJLIB provides a rather comprehensive build system

- * that uses GNU \a make (and only GNU \a make will work). 

- * Currently, the build system supports building * PJLIB for these targets:

- *  - i386/Win32/mingw

- *  - i386/Linux

- *  - i386/Linux (kernel)

- *  - alpha/linux

- *  - sparc/SunOS

- *  - etc..

- *

- *

- * @subsubsection build_req_sec Requirements

- *

- * In order to use the \c make based build system, you MUST have:

- *

- *  - <b>GNU make</b>

- *\n

- *    The Makefiles heavily utilize GNU make commands which most likely

- *    are not available in other \c make system.

- *  - <b>bash</b> shell is recommended.

- *\n

- *    Specificly, there is a command <tt>"echo -n"</tt> which may not work

- *    in other shells. This command is used when generating dependencies

- *    (<tt>make dep</tt>) and it's located in 

- *    <tt>$PJPROJECT/build/rules.mak</tt>.

- *  - <b>ar</b>, <b>ranlib</b> from GNU binutils

- *\n

- *    In your system has different <tt>ar</tt> or <tt>ranlib</tt> (e.g. they

- *    may have been installed as <tt>gar</tt> and <tt>granlib</tt>), then

- *    either you create the relevant symbolic links, <b>or</b> modify

- *    <tt>$PJPROJECT/build/cc-gcc.mak</tt> and rename <tt>ar</tt> and

- *    <tt>ranlib</tt> to the appropriate names.

- *  - <b>gcc</b> to generate dependency.

- *\n

- *    Currently the build system uses <tt>"gcc -MM"</tt> to generate build

- *    dependencies. If <tt>gcc</tt> is not desired to generate dependency,

- *    then either you don't run <tt>make dep</tt>, <b>or</b> edit

- *    <tt>$PJPROJECT/build/rules.mak</tt> to calculate dependency using

- *    your prefered method. (And let me know when you do so so that I can

- *    update the file. :) )

- *

- * @subsubsection build_overview_sec Building the Project

- *

- * Generally, steps required to build the PJLIB are:

- *

- \verbatim

-   $ cd /home/user/pjproject         # <-- go to $PJPROJECT

-   $ vi build.mak                    # <-- set build target etc

-   $ touch pjlib/include/pj/config_site.h

-   $ cd pjlib/build                  # <-- go to projet's build dir

-   $ make                            # <-- build the project

- \endverbatim

- *

- * For other project, \a cd to <tt>build</tt> directory in the project

- * and execute \a make from there.

- *

- * \note For Linux kernel target, there are additional steps required, which

- * will be explained in section \ref linux_kern_target_subsec.

- *

- * @subsubsection build_mak_sec Editing build.mak

- * 

- * The \c build.mak file in \c $PJPROJECT root directory is used to

- * specify the build configuration. This file is expected to export

- * the following \a make variables:

- *

- *  - <tt><b>MACHINE_NAME</b></tt>

- *\n

- *    Target machine/processor, one of: <b>{ i386 | alpha | sparc }</b>.

- *

- *  - <tt><b>OS_NAME</b></tt>

- *\n

- *    Target operating system, one of: <b>{ win32 | linux | 

- *      linux-kernel | sunos }</b>.

- *

- *  - <tt><b>CC_NAME</b></tt>

- *\n

- *    Compiler name: <b>{ gcc | vc }</b>\n

- *    (Note that support for Visual C (vc) compiler with the \c make system is

- *    experimental, and it will only work when run inside a DOS shell

- *    (i.e. <tt>"HOST_NAME=win32"</tt>)).

- *

- *  - <tt><b>HOST_NAME</b></tt>

- *\n

- *    Build host: <b>{ unix | mingw | win32 }</b>\n

- *    (Note: win32 host means a DOS command prompt. Support for this type

- *    of development host is experimental).

- *

- * These variables will cause the correct configuration file in 

- * \c $PJPROJECT/build directory to be executed by \a make. For 

- * example, specifying \c OS_NAME=linux will cause file \c os-linux.mak

- * in \c build directory to be executed. These files contain specific

- * configuration for the option that is selected.

- *

- * For Linux kernel target, you are also required to declare the following

- * variables in this file:

- *	- \c KERNEL_DIR: full path of kernel source tree.

- *	- \c KERNEL_ARCH: kernel ARCH options (e.g. "ARCH=um"), or leave blank

- * 	     for default.

- *	- \c PJPROJECT_DIR: full path of PJPROJECT source tree.

- *

- * Apart from these, there are also additional steps required to build

- * Linux kernel target, which will be explained in \ref linux_kern_target_subsec.

- *

- * @subsubsection build_dir_sec Files in "build" Directory

- *

- * The <tt>*.mak</tt> files in \c $PJPROJECT/build directory are used to specify

- * the configuration for the specified compiler, target machine target 

- * operating system, and host options. These files will be executed

- * (included) by \a make during building process, depending on the values

- * specified in <b>$PJPROJECT/build.mak</b> file.

- *

- * Normally you don't need to edit these files, except when you're porting

- * PJLIB to new target.

- *

- * Below are the description of some files in this directory:

- *

- *  - <tt>rules.mak</tt>: contains generic rules always included during make.

- *  - <tt>cc-gcc.mak</tt>: rules when gcc is used for compiler.

- *  - <tt>cc-vc.mak</tt>: rules when MSVC compiler is used.

- *  - <tt>host-mingw.mak</tt>: rules for building in mingw host.

- *  - <tt>host-unix.mak</tt>: rules for building in Unix/Posix host.

- *  - <tt>host-win32.mak</tt>: rules for building in Win32 command console

- *    (only valid when VC is used).

- *  - <tt>m-i386.mak</tt>: rules when target machine is an i386 processor.

- *  - <tt>m-m68k.mak</tt>: rules when target machine is an m68k processor.

- *  - <tt>os-linux.mak</tt>: rules when target OS is Linux.

- *  - <tt>os-linux-kernel.mak</tt>: rules when PJLIB is to be build as

- *    part of Linux kernel.

- *  - <tt>os-win32.mak</tt>: rules when target OS is Win32.

- *

- *

- * @subsubsection config_site_create_sec Create config_site.h

- *

- * The file <tt><b>$PJPROJECT/pjlib/include/pj/config_site.h</b></tt>

- * is supposed to contain configuration that is specific to your site/target.

- * This file is not part of PJLIB, so you must create it yourself.

- *

- * The reason why it's not included in PJLIB is so that you would not accidently

- * overwrite your site configuration.

- *

- *

- * @subsubsection invoking_make_sec Invoking make

- *

- * Normally, \a make is invoked in \c build directory under each project.

- * For example, to build PJLIB, you would invoke \a make in

- * \c $PJPROJECT/pjlib/build directory like below:

- *

- \verbatim

-   $ cd pjlib/build

-   $ make

- \endverbatim

- *

- * Alternatively you may invoke <tt>make</tt> in <tt>$PJPROJECT</tt> 

- * directory, to build all projects under that directory (e.g. 

- * PJLIB, PJSIP, etc.).

- *

- *

- * @subsubsection linux_kern_target_subsec Linux Kernel Target

- *

- * \note

- * <b>BUILDING APPLICATIONS IN LINUX KERNEL MODE IS A VERY DANGEROUS BUSINESS.

- * YOU MAY CRASH THE WHOLE OF YOUR SYSTEM, CORRUPT YOUR HARDISK, ETC. PJLIB

- * KERNEL MODULES ARE STILL IN EXPERIMENTAL PHASE. DO NOT RUN IT IN PRODUCTION

- * SYSTEMS OR OTHER SYSTEMS WHERE RISK OF LOSS OF DATA IS NOT ACCEPTABLE.

- * YOU HAVE BEEN WARNED.</b>

- *

- * \note

- * <b>User Mode Linux (UML)</b> provides excellent way to experiment with Linux

- * kernel without risking the stability of the host system. See

- * http://user-mode-linux.sourceforge.net for details.

- *

- * \note

- * I only use <b>UML</b> to experiment with PJLIB kernel modules.

- * <b>I wouldn't be so foolish to use my host Linux machine to experiment

- * with this.</b> 

- *

- * \note

- * You have been warned.

- *

- * For building PJLIB for Linux kernel target, there are additional steps required.

- * In general, the additional tasks are:

- *	- Declare some more variables in <b><tt>build.mak</tt></b> file (this

- *        has been explained in \ref build_mak_sec above).

- *      - Perform these two small modifications in kernel source tree.

- *

- * There are two small modification need to be applied to the kernel tree.

- *

- * <b>1. Edit <tt>Makefile</tt> in kernel root source tree.</b>

- *

- * Add the following lines at the end of the <tt>Makefile</tt> in your 

- * <tt>$KERNEL_SRC</tt> dir:

- \verbatim

-script:

-       $(SCRIPT)

- \endverbatim

- *

- * \note Remember to replace spaces with <b>tab</b> in the Makefile.

- *

- * The modification above is needed to capture kernel's \c $CFLAGS and 

- * \c $CFLAGS_MODULE which will be used for PJLIB's compilation.

- *

- * <b>2. Add Additional Exports.</b>

- *

- * We need the kernel to export some more symbols for our use. So we declare

- * the additional symbols to be exported in <tt>extra-exports.c</tt> file, and add

- * a this file to be compiled into the kernel:

- *

- *	- Copy the file <tt>extra-exports.c</tt> from <tt>pjlib/src/pj</tt> 

- *	  directory to <tt>$KERNEL_SRC/kernel/</tt> directory.

- *	- Edit <tt>Makefile</tt> in that directory, and add this line

- *        somewhere after the declaration of that variable:

- \verbatim

-obj-y   += extra-exports.o

- \endverbatim

- *

- * To illustrate what have been done in your kernel source tree, below

- * is screenshot of my kernel source tree _after_ the modification.

- *

- \verbatim

-[root@vpc-linux linux-2.6.7]# pwd

-/usr/src/linux-2.6.7

-[root@vpc-linux linux-2.6.7]# 

-[root@vpc-linux linux-2.6.7]# 

-[root@vpc-linux linux-2.6.7]# tail Makefile 

-

-endif   # skip-makefile

-

-FORCE:

-

-.PHONY: script

-

-script:

-        $(SCRIPT)

-

-[root@vpc-linux linux-2.6.7]# 

-[root@vpc-linux linux-2.6.7]# 

-[root@vpc-linux linux-2.6.7]# head kernel/extra-exports.c 

-#include <linux/module.h>

-#include <linux/syscalls.h>

-

-EXPORT_SYMBOL(sys_select);

-

-EXPORT_SYMBOL(sys_epoll_create);

-EXPORT_SYMBOL(sys_epoll_ctl);

-EXPORT_SYMBOL(sys_epoll_wait);

-

-EXPORT_SYMBOL(sys_socket);

-[root@vpc-linux linux-2.6.7]# 

-[root@vpc-linux linux-2.6.7]# 

-[root@vpc-linux linux-2.6.7]# head -15 kernel/Makefile 

-#

-# Makefile for the linux kernel.

-#

-

-obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \

-            exit.o itimer.o time.o softirq.o resource.o \

-            sysctl.o capability.o ptrace.o timer.o user.o \

-            signal.o sys.o kmod.o workqueue.o pid.o \

-            rcupdate.o intermodule.o extable.o params.o posix-timers.o \

-            kthread.o

-

-obj-y   +=  extra-exports.o

-

-obj-$(CONFIG_FUTEX) += futex.o

-obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o

-[root@vpc-linux linux-2.6.7]# 

-

- \endverbatim

- *

- * Then you must rebuild the kernel.

- * If you fail to do this, you won't be able to <b>insmod</b> pjlib.

- *

- * \note You will see a lots of warning messages during pjlib-test compilation.

- * The warning messages complain about unresolved symbols which are defined

- * in pjlib module. You can safely ignore these warnings. However, you can not

- * ignore warnings about non-pjlib unresolved symbols.

- *

- * 

- * @subsection makefile_explained_sec Makefile Explained

- *

- * The \a Makefile for each project (e.g. PJLIB, PJSIP, etc) should be

- * very similar in the contents. The Makefile is located under \c build

- * directory in each project subdir.

- *

- * @subsubsection pjlib_makefile_subsec PJLIB Makefile.

- *

- * Below is PJLIB's Makefile:

- *

- * \include build/Makefile

- *

- * @subsubsection pjlib_os_makefile_subsec PJLIB os-linux.mak.

- *

- * Below is file <tt><b>os-linux.mak</b></tt> file in 

- * <tt>$PJPROJECT/pjlib/build</tt> directory,

- * which is OS specific configuration file for Linux target that is specific 

- * for PJLIB project. For \b global OS specific configuration, please see

- * <tt>$PJPROJECT/build/os-*.mak</tt>.

- *

- * \include build/os-linux.mak

- *

- */

-

-

-/*////////////////////////////////////////////////////////////////////////// */

-/*

-         PORTING PJLIB

- */

-

-

-

-/**

- * @page porting_pjlib_pg Porting PJLIB

- *

- *

- * @section new_arch_sec Porting to New CPU Architecture

- *

- * Below is step-by-step guide to add support for new CPU architecture.

- * This sample is based on porting to Alpha architecture; however steps for 

- * porting to other CPU architectures should be pretty similar. 

- *

- * Also note that in this example, the operating system used is <b>Linux</b>.

- * Should you wish to add support for new operating system, then follow

- * the next section \ref porting_os_sec.

- *

- * Step-by-step guide to port to new CPU architecture:

- *  - decide the name for the new architecture. In this case, we choose

- *    <tt><b>alpha</b></tt>.

- *  - edit file <tt>$PJPROJECT/build.mak</tt>, and add new section for

- *    the new target:

- *    <pre>

- *      #

- *      # Linux alpha, gcc

- *      #

- *      export MACHINE_NAME := <b>alpha</b>

- *      export OS_NAME := linux

- *      export CC_NAME := gcc

- *      export HOST_NAME := unix

- *    </pre>

- *

- *  - create a new file <tt>$PJPROJECT/build/<b>m-alpha</b>.mak</tt>.

- *    Alternatively create a copy from other file in this directory.

- *    The contents of this file will look something like:

- *    <pre>

- *      export M_CFLAGS := $(CC_DEF)<b>PJ_M_ALPHA=1</b>

- *      export M_CXXFLAGS :=

- *      export M_LDFLAGS :=

- *      export M_SOURCES :=

- *    </pre>

- *  - create a new file <tt>$PJPROJECT/pjlib/include/pj/compat/<b>m_alpha.h</b></tt>.

- *    Alternatively create a copy from other header file in this directory.

- *    The contents of this file will look something like:

- *    <pre>

- *      #define PJ_HAS_PENTIUM          0

- *      #define PJ_IS_LITTLE_ENDIAN     1

- *      #define PJ_IS_BIG_ENDIAN        0

- *    </pre>

- *  - edit <tt>pjlib/include/pj/<b>config.h</b></tt>. Add new processor

- *    configuration in this header file, like follows:

- *    <pre>

- *      ...

- *      #elif defined (PJ_M_ALPHA) && PJ_M_ALPHA != 0

- *      #   include <pj/compat/m_alpha.h>

- *      ...

- *    </pre>

- *  - done. Build PJLIB with:

- *    <pre>

- *      $ cd $PJPROJECT/pjlib/build

- *      $ make dep

- *      $ make clean

- *      $ make

- *    </pre>

- *

- * @section porting_os_sec Porting to New Operating System Target

- *

- * This section will try to give you rough guideline on how to

- * port PJLIB to a new target. As a sample, we give the target a name tag, 

- * for example <tt><b>xos</b></tt> (for X OS). 

- *

- * @subsection new_compat_os_h_file_sec Create New Compat Header File

- *

- * You'll need to create a new header file 

- * <b><tt>include/pj/compat/os_xos.h</tt></b>. You can copy as a 

- * template other header file and edit it accordingly.

- *

- * @subsection modify_config_h_file_sec Modify config.h

- *

- * Then modify file <b><tt>include/pj/config.h</tt></b> to include

- * this file accordingly (e.g. when macro <tt><b>PJ_XOS</b></tt> is

- * defined):

- *

- \verbatim

- ...

- #elif defined(PJ_XOS)

- #  include <pj/compat/os_xos.h>

- #else

- #...

- \endverbatim

- * 

- * @subsection new_target_mak_file_sec Create New Global Make Config File

- *

- * Then you'll need to create global configuration file that

- * is specific for this OS, i.e. <tt><b>os-xos.mak</b></tt> in 

- * <tt><b>$PJPROJECT/build</b></tt> directory.

- *

- * At very minimum, the file will normally need to define

- * <tt><b>PJ_XOS=1</b></tt> in the \c CFLAGS section:

- *

- \verbatim

-#

-# $PJPROJECT/build/os-xos.mak:

-#

-export OS_CFLAGS   := $(CC_DEF)PJ_XOS=1

-export OS_CXXFLAGS := 

-export OS_LDFLAGS  :=

-export OS_SOURCES  := 

- \endverbatim

- *

- *

- * @subsection new_target_prj_mak_file_sec Create New Project's Make Config File

- *

- * Then you'll need to create xos-specific configuration file

- * for PJLIB. This file is also named <tt><b>os-xos.mak</b></tt>,

- * but its located in <tt><b>pjlib/build</b></tt> directory.

- * This file will specify source files that are specific to

- * this OS to be included in the build process.

- *

- * Below is a sample:

- \verbatim

-#

-# pjlib/build/os-xos.mak:

-#  XOS specific configuration for PJLIB.

-#

-export PJLIB_OBJS += 	os_core_xos.o \

-                        os_error_unix.o \

-                        os_time_ansi.o

-export TEST_OBJS +=	main.o

-export TARGETS	    =	pjlib pjlib-test

- \endverbatim

- *

- * @subsection new_target_src_sec Create and Edit Source Files

- *

- * You'll normally need to create at least these files:

- *  - <tt><b>os_core_xos.c</b></tt>: core OS specific

- *    functionality.

- *  - <tt><b>os_timestamp_xos.c</b></tt>: how to get timestamp

- *    in this OS.

- *

- * Depending on how things are done in your OS, you may need

- * to create these files:

- *  - <tt><b>os_error_*.c</b></tt>: how to manipulate

- *    OS error codes. Alternatively you may use existing

- *    <tt>os_error_unix.c</tt> if the OS has \c errno and

- *    \c strerror() function.

- *  - <tt><b>ioqueue_*.c</b></tt>: if the OS has specific method

- *    to perform asynchronous I/O. Alternatively you may

- *    use existing <tt>ioqueue_select.c</tt> if the OS supports

- *    \c select() function call.

- *  - <tt><b>sock_*.c</b></tt>: if the OS has specific method

- *    to perform socket communication. Alternatively you may

- *    use existing <tt>sock_bsd.c</tt> if the OS supports

- *    BSD socket API, and edit <tt>include/pj/compat/socket.h</tt>

- *    file accordingly.

- *

- * You will also need to check various files in 

- * <tt><b>include/pj/compat/*.h</b></tt>, to see if they're 

- * compatible with your OS.

- *

- * @subsection new_target_build_file_sec Build The Project

- *

- * After basic building blocks have been created for the OS, then

- * the easiest way to see which parts need to be fixed is by building

- * the project and see the error messages.

- *

- * @subsection new_target_edit_vs_new_file_sec Editing Existing Files vs Creating New File

- *

- * When you encounter compatibility errors in PJLIB during porting,

- * you have three options on how to fix the error:

- *  - edit the existing <tt>*.c</tt> file, and give it <tt>#ifdef</tt>

- *    switch for the new OS, or

- *  - edit <tt>include/pj/compat/*.h</tt> instead, or

- *  - create a totally new file.

- *

- * Basicly there is no strict rule on which approach is the best

- * to use, however the following guidelines may be used:

- *  - if the file is expected to be completely different than

- *    any existing file, then perhaps you should create a completely

- *    new file. For example, file <tt>os_core_xxx.c</tt> will 

- *    normally be different for each OS flavour.

- *  - if the difference can be localized in <tt>include/compat</tt>

- *    header file, and existing <tt>#ifdef</tt> switch is there,

- *    then preferably you should edit this <tt>include/compat</tt>

- *    header file.

- *  - if the existing <tt>*.c</tt> file has <tt>#ifdef</tt> switch,

- *    then you may add another <tt>#elif</tt> switch there. This

- *    normally is used for behaviors that are not totally

- *    different on each platform.

- *  - other than that above, use your own judgement on whether

- *    to edit the file or create new file etc.

- */

-

-#endif	/* __PJ_DOXYGEN_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_DOXYGEN_H__
+#define __PJ_DOXYGEN_H__
+
+/**
+ * @file doxygen.h
+ * @brief Doxygen's mainpage.
+ */
+
+/*////////////////////////////////////////////////////////////////////////// */
+/*
+	INTRODUCTION PAGE
+ */
+
+/**
+ * @mainpage Welcome to PJLIB!
+ *
+ * @section intro_sec What is PJLIB
+ *
+ * PJLIB is a small foundation library written in C for making scalable 
+ * applications. Because of its small footprint, it can be used in embedded 
+ * applications (we hope so!), but yet the library is also aimed for 
+ * facilitating high performance protocol stacks.
+ *
+ * PJLIB is released under LGPL terms.
+ *
+ * @section download_sec Download
+ *
+ * PJLIB and all documentation can be downloaded from 
+ * http://www.pjproject.net.
+ *
+ *
+ * @section how_to_use_sec About This Documentation
+ *
+ * This document is generated directly from PJLIB source file using
+ * \a doxygen (http://www.doxygen.org). Doxygen is a great (and free!) 
+ * tools for generating such documentation.
+ *
+ * @subsection doc_ver_subsec Version
+ *
+ * This document corresponds to PJLIB version 0.3-pre2.
+ *
+ *
+ * @subsection find_samples_subsec How to Read This Document
+ *
+ * This documentation is laid out more to be a reference guide instead
+ * of tutorial, therefore first time users may find it difficult to
+ * grasp PJLIB by reading this document alone.
+ *
+ * However, we've tried our best to make this document easy to follow.
+ * For first time users, we would suggest that you follow these steps
+ * when reading this documentation:
+ *
+ *  - continue reading this introduction chapter. At the end of this
+ *    chapter, you'll find section called \ref pjlib_fundamentals_sec
+ *    which should guide you to understand basic things about PJLIB.
+ *
+ *  - find information about specific features that you want to use
+ *    in PJLIB. Use the <b>Module Index</b> to find out about all 
+ *    features in PJLIB (if you're browsing the HTML documentation,
+ *    click on the \a Module link on top of the page, or if you're
+ *    reading the PDF documentation, click on \a Module \a Documentation
+ *    on the navigation pane on the left).
+ *
+ * @subsection doc_organize_sec How To's
+ *
+ * Please find below links to specific tasks that you probably
+ * want to do:
+ *
+ *  - <b>How to Build PJLIB</b>
+ *\n
+ * Please refer to \ref pjlib_build_sys_pg page for more information.
+ *
+ *  - <b>How to Use PJLIB in My Application</b>
+ *\n
+ * Please refer to \ref configure_app_sec for more information.
+ *
+ *  - <b>How to Port PJLIB</b>
+ *\n
+ * Please refer to \ref porting_pjlib_pg page.
+ *
+ *  - <b>Where to Read Samples Documentation</b>
+ *\n
+ * Most of the modules provide link to the corresponding sample file.
+ * Alternatively, to get the list of all examples, you can click on 
+ * <b>Related Pages</b> on the top of HTML document or on 
+ * <b>PJLIB Page Documentation</b> on navigation pane of your PDF reader.
+ *
+ *  - <b>How to Submit Code to PJLIB Project</b>
+ *\n
+ * Please read \ref pjlib_coding_convention_page before submitting
+ * your code. Send your code as patch against current Subversion tree
+ * to the appropriate mailing list.
+ *
+ *
+ * @section features_sec Features
+ *
+ * @subsection open_source_feat It's Open Source!
+ *
+ * PJLIB is currently released on LGPL license. We may release PJLIB under
+ * additional schemes in the future (such as GPL or MPL) to incorporate
+ * linking with specific application, however, one thing for sure is
+ * we will NEVER be able to make PJLIB a proprietary software.
+ *
+ * @subsection extreme_portable_feat Extreme Portability
+ *
+ * PJLIB is designed to be extremely portable. It can run on any kind
+ * of processors (16-bit, 32-bit, or 64-bit, big or little endian, single
+ * or multi-processors) and operating systems. Floating point or no
+ * floating point. Multi-threading or not.
+ * It can even run in environment where no ANSI LIBC is available. 
+ *
+ * Currently PJLIB is being ported to:
+ *  - x86, Win32 (Win95/98/ME, NT/2000/XP/2003, mingw).
+ *  - x86, Linux (user mode and as <b>kernel module</b>(!)).
+ *  - alpha, Linux
+ * And coming up:
+ *  - x86, eCos
+ *  - ultra-II, Solaris.
+ *  - powerpc, MacOS
+ *  - m68k, PalmOS.
+ *  - arm, PocketPC
+ *
+ * No other library is known to have this extreme portability!
+ *
+ * @subsection small_size_feat Small in Size
+ *
+ * One of the primary objectives is to have library that is small in size for
+ * typical embedded applications. As a rough guidance, we aim to keep the 
+ * library size below 100KB for it to be considered as small.
+ * As the result, most of the functionalities in the library can be tailored
+ * to meet the requirements; user can enable/disable specific functionalities
+ * to get the desired size/performance/functionality balance.
+ *
+ * For more info, please see @ref pj_config.
+ *
+ * @subsection no_dyn_mem No Dynamic Memory Allocations
+ *
+ * The central idea of PJLIB is that for applications to run as fast as it can,
+ * it should not use \a malloc() at all, but instead should get the memory 
+ * from a preallocated storage pool. There are few things that can be 
+ * optimized with this approach:
+ *
+ *  - \a alloc() is a O(1) operation.
+ *  - no mutex is used inside alloc(). It is assumed that synchronization 
+ *    will be used in higher abstraction by application anyway.
+ *  - no \a free() is required. All chunks will be deleted when the pool is 
+ *    destroyed.
+ *
+ * The performance gained on some systems can be as high as 10x speed up
+ * against \a malloc() and \a free().
+ *
+ * For more information, see \ref PJ_POOL_GROUP
+ *
+ * 
+ * @subsection os_abstract_feat Operating System Abstraction
+ *
+ * PJLIB has abstractions for features that are normally not portable 
+ * across operating systems: 
+ *  - @ref PJ_THREAD
+ *\n
+ *    Portable thread manipulation.
+ *  - @ref PJ_TLS
+ *\n
+ *    Storing data in thread's private data.
+ *  - @ref PJ_MUTEX
+ *\n
+ *    Mutual exclusion protection.
+ *  - @ref PJ_SEM
+ *\n
+ *    Semaphores.
+ *  - @ref PJ_ATOMIC
+ *\n
+ *    Atomic variables and their operations.
+ *  - @ref PJ_CRIT_SEC
+ *\n
+ *    Fast locking of critical sections.
+ *  - @ref PJ_LOCK
+ *\n
+ *    High level abstraction for lock objects.
+ *  - @ref PJ_EVENT
+ *\n
+ *    Event object.
+ *  - @ref PJ_TIME
+ *\n
+ *    Portable time manipulation.
+ *  - @ref PJ_TIMESTAMP
+ *\n
+ *    High resolution time value.
+ *  - etc.
+ *
+ *
+ * @subsection ll_network_io_sec Low-Level Network I/O
+ *
+ * PJLIB has very portable abstraction and fairly complete set of API for
+ * doing network I/O communications. At the lowest level, PJLIB provides:
+ *
+ *  - @ref PJ_SOCK
+ *\n
+ *    A highly portable socket abstraction, runs on all kind of
+ *    network APIs such as standard BSD socket, Windows socket, Linux
+ *    \b kernel socket, PalmOS networking API, etc.
+ *
+ *  - @ref pj_addr_resolve
+ *\n
+ *    Portable address resolution, which implements #pj_gethostbyname().
+ *
+ *  - @ref PJ_SOCK_SELECT
+ *\n
+ *    A portable \a select() like API (#pj_sock_select()) which can be
+ *    implemented with various back-end.
+ *
+ *
+ * @subsection hl_network_io_sec High-Level Network I/O
+ *
+ * At higher abstraction, PJLIB provides @ref PJ_IOQUEUE, 
+ * which promotes creating high performance network
+ * applications by managing asynchronous I/O. This is a passive framework
+ * that utilizes the most effective way to manage asynchronous I/O
+ * on a given platform, such as:
+ *  - IoCompletionPort on WinNT,
+ *  - on Linux it can use either /dev/epoll or aio.
+ *  - or to fall back to use @a select()
+ *
+ * At even a higher abstraction, PJLIB provides @ref PJ_EQUEUE, which
+ * combines asynchronous I/O with timer management and thread management 
+ * to fasilitate creating trully high performance, event driven
+ * application.
+ * 
+ *
+ * @subsection timer_mgmt_sec Timer Management
+ *
+ * A passive framework for managing timer, see @ref PJ_TIMER for more info.
+ * There is also function to retrieve high resolution timestamp
+ * from the system (see @ref PJ_TIMESTAMP).
+ *
+ *
+ * @subsection data_struct_sec Various Data Structures
+ *
+ * Various data structures are provided in the library:
+ *
+ *  - @ref PJ_PSTR
+ *  - @ref PJ_ARRAY
+ *  - @ref PJ_HASH
+ *  - @ref PJ_LIST
+ *  - @ref PJ_RBTREE
+ *
+ *
+ * @subsection exception_sec Exception Construct
+ *
+ * A convenient TRY/CATCH like construct to propagate errors, which by
+ * default are used by the @ref PJ_POOL_GROUP "memory pool" and 
+ * the lexical scanner in pjlib-util. The exception
+ * construct can be used to write programs like below:
+ *
+ * <pre>
+ *    #define SYNTAX_ERROR  1
+ *
+ *    PJ_TRY {
+ *       msg = NULL;
+ *       msg = parse_msg(buf, len);
+ *    }
+ *    PJ_CATCH ( SYNTAX_ERROR ) {
+ *       .. handle error ..
+ *    }
+ *    PJ_END;
+ * </pre>
+ *
+ * Please see @ref PJ_EXCEPT for more information.
+ *
+ *
+ * @subsection logging_sec Logging Facility
+ *
+ * PJLIB @ref PJ_LOG consists of macros to write logging information to
+ * some output device. Some of the features of the logging facility:
+ *
+ *  - the verbosity can be fine-tuned both at compile time (to control
+ *    the library size) or run-time (to control the verbosity of the
+ *    information).
+ *  - output device is configurable (e.g. stdout, printk, file, etc.)
+ *  - log decoration is configurable.
+ *
+ * See @ref PJ_LOG for more information.
+ *
+ *
+ * @subsection guid_gen_sec Random and GUID Generation
+ *
+ * PJLIB provides facility to create random string 
+ * (#pj_create_random_string()) or globally unique identifier
+ * (see @ref PJ_GUID).
+ *
+ *
+ *
+ * @section configure_app_sec Configuring Application to use PJLIB
+ *
+ * @subsection pjlib_compil_sec Building PJLIB
+ *
+ * Follow the instructions in \ref pjlib_build_sys_pg to build
+ * PJLIB.
+ *
+ * @subsection pjlib_compil_app_sec Building Applications with PJLIB
+ *
+ * Use the following settings when building applications with PJLIB.
+ *
+ * @subsubsection compil_inc_dir_sec Include Search Path
+ *
+ * Add this to your include search path ($PJLIB is PJLIB root directory):
+ * <pre>
+ *   $PJLIB/include
+ * </pre>
+ *
+ * @subsubsection compil_inc_file_sec Include PJLIB Header
+ *
+ * To include all PJLIB headers:
+ * \verbatim
+    #include <pjlib.h>
+   \endverbatim
+ *
+ * Alternatively, you can include individual PJLIB headers like this:
+ * \verbatim
+     #include <pj/log.h>
+     #include <pj/os.h>
+  \endverbatim
+ *
+ *
+ * @subsubsection compil_lib_dir_sec Library Path
+ *
+ * Add this to your library search path:
+ * <pre>
+ *   $PJLIB/lib
+ * </pre>
+ *
+ * Then add the appropriate PJLIB library to your link specification. For
+ * example, you would add \c libpj-i386-linux-gcc.a when you're building
+ * applications in Linux.
+ *
+ *
+ * @subsection pjlib_fundamentals_sec Principles in Using PJLIB
+ *
+ * Few things that you \b MUST do when using PJLIB, to make sure that
+ * you create trully portable applications.
+ *
+ * @subsubsection call_pjlib_init_sec Call pj_init()
+ *
+ * Before you do anything else, call \c pj_init(). This would make sure that
+ * PJLIB system is properly set up.
+ *
+ * @subsubsection no_ansi_subsec Do NOT Use ANSI C
+ *
+ * Contrary to popular teaching, ANSI C (and LIBC) is not the most portable
+ * library in the world, nor it's the most ubiquitous. For example, LIBC
+ * is not available in Linux kernel. Also normally LIBC will be excluded
+ * from compilation of RTOSes to reduce size.
+ *
+ * So for maximum portability, do NOT use ANSI C. Do not even try to include
+ * any other header files outside <include/pj>. Stick with the functionalities
+ * provided by PJLIB. 
+ *
+ *
+ * @subsubsection string_rep_subsubsec Use pj_str_t instead of C Strings
+ *
+ * PJLIB uses pj_str_t instead of normal C strings. You SHOULD follow this
+ * convention too. Remember, ANSI string-h is not always available. And
+ * PJLIB string is faster!
+ *
+ * @subsubsection mem_alloc_subsubsec Use Pool for Memory Allocations
+ *
+ * You MUST NOT use \a malloc() or any other memory allocation functions.
+ * Use PJLIB pool instead! It's faster and most portable.
+ *
+ * @subsection logging_subsubsec Use Logging for Text Display
+ *
+ * DO NOT use <stdio.h> for text output. Use PJLIB logging instead.
+ *
+ *
+ * @section porting_pjlib_sec0 Porting PJLIB
+ *
+ * Please see \ref porting_pjlib_pg page on more information to port
+ * PJLIB to new target.
+ *
+ * @section enjoy_sec Enjoy Using PJLIB!
+ *
+ * We hope that you find PJLIB usefull for your application. If you
+ * have any questions, suggestions, critics, bug fixes, or anything
+ * else, we would be happy to hear it.
+ *
+ * Enjoy using PJLIB!
+ *
+ * Benny Prijono < bennylp at pjproject dot net >
+ */
+
+
+
+/*////////////////////////////////////////////////////////////////////////// */
+/*
+         CODING CONVENTION
+ */
+
+/**
+ * @page pjlib_coding_convention_page Coding Convention
+ *
+ * Before you submit your code/patches to be included with PJLIB, you must
+ * make sure that your code is compliant with PJLIB coding convention.
+ * <b>This is very important!</b> Otherwise we would not accept your code.
+ *
+ * @section coding_conv_editor_sec Editor Settings
+ *
+ * The single most important thing in the whole coding convention is editor 
+ * settings. It's more important than the correctness of your code (bugs will
+ * only crash the system, but incorrect tab size is mental!).
+ *
+ * Kindly set your editor as follows:
+ *  - tab size to \b 8.
+ *  - indentation to \b 4.
+ *
+ * With \c vi, you can do it with:
+ * <pre>
+ *  :se ts=8
+ *  :se sts=4
+ * </pre>
+ *
+ * You should replace tab with eight spaces.
+ *
+ * @section coding_conv_detail_sec Coding Style
+ *
+ * Coding style MUST strictly follow K&R style. The rest of coding style
+ * must follow current style. You SHOULD be able to observe the style
+ * currently used by PJLIB from PJLIB sources, and apply the style to your 
+ * code. If you're not able to do simple thing like to observe PJLIB
+ * coding style from the sources, then logic dictates that your ability to
+ * observe more difficult area in PJLIB such as memory allocation strategy, 
+ * concurrency, etc is questionable.
+ *
+ * @section coding_conv_comment_sec Commenting Your Code
+ *
+ * Public API (e.g. in header files) MUST have doxygen compliant comments.
+ *
+ */
+
+
+/*////////////////////////////////////////////////////////////////////////// */
+/*
+	BUILDING AND INSTALLING PJLIB
+ */
+
+
+
+/**
+ * @page pjlib_build_sys_pg Building, and Installing PJLIB
+ *
+ * @section build_sys_install_sec Build and Installation
+ *
+ * @subsection build_sys_install_win32_sec Visual Studio
+ *
+ * The PJLIB Visual Studio workspace supports the building of PJLIB
+ * for Win32 target. Although currently only the Visual Studio 6 Workspace is
+ * actively maintained, developers with later version of Visual Studio
+ * can easily imports VS6 workspace into their IDE.
+ *
+ * To start building PJLIB projects with Visual Studio 6 or later, open
+ * the \a workspace file in the corresponding \b \c build directory. You have
+ * several choices on which \a dsw file to open:
+ \verbatim
+ $PJPROJECT/build/pjproject.dsw
+ $PJPROJECT/pjlib/build/pjlib.dsw
+ $PJPROJECT/pjsip/build/pjsip.dsw
+ ..etc
+ \endverbatim
+ *
+ * The easiest way is to open <tt>pjproject.dsw</tt> file in \b \c $PJPROJECT/build
+ * directory. However this will only build the required projects, not
+ * the complete projects. For example, the PJLIB test and samples projects 
+ * are not included in this workspace. To build the complete projects, you must
+ * open and build each \a dsw file in \c build directory in each
+ * subprojects. For example, to open the complete PJLIB workspace, open
+ * <tt>pjlib.dsw</tt> in <tt>$PJPROJECT/pjlib/build</tt> directory.
+ *
+ *
+ * @subsubsection config_site_create_vc_sec Create config_site.h
+ *
+ * The file <tt><b>$PJPROJECT/pjlib/include/pj/config_site.h</b></tt>
+ * is supposed to contain configuration that is specific to your site/target.
+ * This file is not part of PJLIB, so you must create it yourself. Normally
+ * you just need to create a blank file.
+ *
+ * The reason why it's not included in PJLIB is so that you would not accidently
+ * overwrite your site configuration.
+ *
+ * If you fail to do this, Visual C will complain with error like: 
+ *
+ * <b>"fatal error C1083: Cannot open include file: 'pj/config_site.h': No such file 
+ * or directory"</b>.
+ *
+ * @subsubsection build_vc_subsubsec Build the Projects
+ *
+ * Just hit the build button!
+ *
+ *
+ * @subsection build_sys_install_unix_sec Make System
+ *
+ * For other targets, PJLIB provides a rather comprehensive build system
+ * that uses GNU \a make (and only GNU \a make will work). 
+ * Currently, the build system supports building * PJLIB for these targets:
+ *  - i386/Win32/mingw
+ *  - i386/Linux
+ *  - i386/Linux (kernel)
+ *  - alpha/linux
+ *  - sparc/SunOS
+ *  - etc..
+ *
+ *
+ * @subsubsection build_req_sec Requirements
+ *
+ * In order to use the \c make based build system, you MUST have:
+ *
+ *  - <b>GNU make</b>
+ *\n
+ *    The Makefiles heavily utilize GNU make commands which most likely
+ *    are not available in other \c make system.
+ *  - <b>bash</b> shell is recommended.
+ *\n
+ *    Specificly, there is a command <tt>"echo -n"</tt> which may not work
+ *    in other shells. This command is used when generating dependencies
+ *    (<tt>make dep</tt>) and it's located in 
+ *    <tt>$PJPROJECT/build/rules.mak</tt>.
+ *  - <b>ar</b>, <b>ranlib</b> from GNU binutils
+ *\n
+ *    In your system has different <tt>ar</tt> or <tt>ranlib</tt> (e.g. they
+ *    may have been installed as <tt>gar</tt> and <tt>granlib</tt>), then
+ *    either you create the relevant symbolic links, <b>or</b> modify
+ *    <tt>$PJPROJECT/build/cc-gcc.mak</tt> and rename <tt>ar</tt> and
+ *    <tt>ranlib</tt> to the appropriate names.
+ *  - <b>gcc</b> to generate dependency.
+ *\n
+ *    Currently the build system uses <tt>"gcc -MM"</tt> to generate build
+ *    dependencies. If <tt>gcc</tt> is not desired to generate dependency,
+ *    then either you don't run <tt>make dep</tt>, <b>or</b> edit
+ *    <tt>$PJPROJECT/build/rules.mak</tt> to calculate dependency using
+ *    your prefered method. (And let me know when you do so so that I can
+ *    update the file. :) )
+ *
+ * @subsubsection build_overview_sec Building the Project
+ *
+ * Generally, steps required to build the PJLIB are:
+ *
+ \verbatim
+   $ cd /home/user/pjproject         # <-- go to $PJPROJECT
+   $ vi build.mak                    # <-- set build target etc
+   $ touch pjlib/include/pj/config_site.h
+   $ cd pjlib/build                  # <-- go to projet's build dir
+   $ make                            # <-- build the project
+ \endverbatim
+ *
+ * For other project, \a cd to <tt>build</tt> directory in the project
+ * and execute \a make from there.
+ *
+ * \note For Linux kernel target, there are additional steps required, which
+ * will be explained in section \ref linux_kern_target_subsec.
+ *
+ * @subsubsection build_mak_sec Editing build.mak
+ * 
+ * The \c build.mak file in \c $PJPROJECT root directory is used to
+ * specify the build configuration. This file is expected to export
+ * the following \a make variables:
+ *
+ *  - <tt><b>MACHINE_NAME</b></tt>
+ *\n
+ *    Target machine/processor, one of: <b>{ i386 | alpha | sparc }</b>.
+ *
+ *  - <tt><b>OS_NAME</b></tt>
+ *\n
+ *    Target operating system, one of: <b>{ win32 | linux | 
+ *      linux-kernel | sunos }</b>.
+ *
+ *  - <tt><b>CC_NAME</b></tt>
+ *\n
+ *    Compiler name: <b>{ gcc | vc }</b>\n
+ *    (Note that support for Visual C (vc) compiler with the \c make system is
+ *    experimental, and it will only work when run inside a DOS shell
+ *    (i.e. <tt>"HOST_NAME=win32"</tt>)).
+ *
+ *  - <tt><b>HOST_NAME</b></tt>
+ *\n
+ *    Build host: <b>{ unix | mingw | win32 }</b>\n
+ *    (Note: win32 host means a DOS command prompt. Support for this type
+ *    of development host is experimental).
+ *
+ * These variables will cause the correct configuration file in 
+ * \c $PJPROJECT/build directory to be executed by \a make. For 
+ * example, specifying \c OS_NAME=linux will cause file \c os-linux.mak
+ * in \c build directory to be executed. These files contain specific
+ * configuration for the option that is selected.
+ *
+ * For Linux kernel target, you are also required to declare the following
+ * variables in this file:
+ *	- \c KERNEL_DIR: full path of kernel source tree.
+ *	- \c KERNEL_ARCH: kernel ARCH options (e.g. "ARCH=um"), or leave blank
+ * 	     for default.
+ *	- \c PJPROJECT_DIR: full path of PJPROJECT source tree.
+ *
+ * Apart from these, there are also additional steps required to build
+ * Linux kernel target, which will be explained in \ref linux_kern_target_subsec.
+ *
+ * @subsubsection build_dir_sec Files in "build" Directory
+ *
+ * The <tt>*.mak</tt> files in \c $PJPROJECT/build directory are used to specify
+ * the configuration for the specified compiler, target machine target 
+ * operating system, and host options. These files will be executed
+ * (included) by \a make during building process, depending on the values
+ * specified in <b>$PJPROJECT/build.mak</b> file.
+ *
+ * Normally you don't need to edit these files, except when you're porting
+ * PJLIB to new target.
+ *
+ * Below are the description of some files in this directory:
+ *
+ *  - <tt>rules.mak</tt>: contains generic rules always included during make.
+ *  - <tt>cc-gcc.mak</tt>: rules when gcc is used for compiler.
+ *  - <tt>cc-vc.mak</tt>: rules when MSVC compiler is used.
+ *  - <tt>host-mingw.mak</tt>: rules for building in mingw host.
+ *  - <tt>host-unix.mak</tt>: rules for building in Unix/Posix host.
+ *  - <tt>host-win32.mak</tt>: rules for building in Win32 command console
+ *    (only valid when VC is used).
+ *  - <tt>m-i386.mak</tt>: rules when target machine is an i386 processor.
+ *  - <tt>m-m68k.mak</tt>: rules when target machine is an m68k processor.
+ *  - <tt>os-linux.mak</tt>: rules when target OS is Linux.
+ *  - <tt>os-linux-kernel.mak</tt>: rules when PJLIB is to be build as
+ *    part of Linux kernel.
+ *  - <tt>os-win32.mak</tt>: rules when target OS is Win32.
+ *
+ *
+ * @subsubsection config_site_create_sec Create config_site.h
+ *
+ * The file <tt><b>$PJPROJECT/pjlib/include/pj/config_site.h</b></tt>
+ * is supposed to contain configuration that is specific to your site/target.
+ * This file is not part of PJLIB, so you must create it yourself.
+ *
+ * The reason why it's not included in PJLIB is so that you would not accidently
+ * overwrite your site configuration.
+ *
+ *
+ * @subsubsection invoking_make_sec Invoking make
+ *
+ * Normally, \a make is invoked in \c build directory under each project.
+ * For example, to build PJLIB, you would invoke \a make in
+ * \c $PJPROJECT/pjlib/build directory like below:
+ *
+ \verbatim
+   $ cd pjlib/build
+   $ make
+ \endverbatim
+ *
+ * Alternatively you may invoke <tt>make</tt> in <tt>$PJPROJECT</tt> 
+ * directory, to build all projects under that directory (e.g. 
+ * PJLIB, PJSIP, etc.).
+ *
+ *
+ * @subsubsection linux_kern_target_subsec Linux Kernel Target
+ *
+ * \note
+ * <b>BUILDING APPLICATIONS IN LINUX KERNEL MODE IS A VERY DANGEROUS BUSINESS.
+ * YOU MAY CRASH THE WHOLE OF YOUR SYSTEM, CORRUPT YOUR HARDISK, ETC. PJLIB
+ * KERNEL MODULES ARE STILL IN EXPERIMENTAL PHASE. DO NOT RUN IT IN PRODUCTION
+ * SYSTEMS OR OTHER SYSTEMS WHERE RISK OF LOSS OF DATA IS NOT ACCEPTABLE.
+ * YOU HAVE BEEN WARNED.</b>
+ *
+ * \note
+ * <b>User Mode Linux (UML)</b> provides excellent way to experiment with Linux
+ * kernel without risking the stability of the host system. See
+ * http://user-mode-linux.sourceforge.net for details.
+ *
+ * \note
+ * I only use <b>UML</b> to experiment with PJLIB kernel modules.
+ * <b>I wouldn't be so foolish to use my host Linux machine to experiment
+ * with this.</b> 
+ *
+ * \note
+ * You have been warned.
+ *
+ * For building PJLIB for Linux kernel target, there are additional steps required.
+ * In general, the additional tasks are:
+ *	- Declare some more variables in <b><tt>build.mak</tt></b> file (this
+ *        has been explained in \ref build_mak_sec above).
+ *      - Perform these two small modifications in kernel source tree.
+ *
+ * There are two small modification need to be applied to the kernel tree.
+ *
+ * <b>1. Edit <tt>Makefile</tt> in kernel root source tree.</b>
+ *
+ * Add the following lines at the end of the <tt>Makefile</tt> in your 
+ * <tt>$KERNEL_SRC</tt> dir:
+ \verbatim
+script:
+       $(SCRIPT)
+ \endverbatim
+ *
+ * \note Remember to replace spaces with <b>tab</b> in the Makefile.
+ *
+ * The modification above is needed to capture kernel's \c $CFLAGS and 
+ * \c $CFLAGS_MODULE which will be used for PJLIB's compilation.
+ *
+ * <b>2. Add Additional Exports.</b>
+ *
+ * We need the kernel to export some more symbols for our use. So we declare
+ * the additional symbols to be exported in <tt>extra-exports.c</tt> file, and add
+ * a this file to be compiled into the kernel:
+ *
+ *	- Copy the file <tt>extra-exports.c</tt> from <tt>pjlib/src/pj</tt> 
+ *	  directory to <tt>$KERNEL_SRC/kernel/</tt> directory.
+ *	- Edit <tt>Makefile</tt> in that directory, and add this line
+ *        somewhere after the declaration of that variable:
+ \verbatim
+obj-y   += extra-exports.o
+ \endverbatim
+ *
+ * To illustrate what have been done in your kernel source tree, below
+ * is screenshot of my kernel source tree _after_ the modification.
+ *
+ \verbatim
+[root@vpc-linux linux-2.6.7]# pwd
+/usr/src/linux-2.6.7
+[root@vpc-linux linux-2.6.7]# 
+[root@vpc-linux linux-2.6.7]# 
+[root@vpc-linux linux-2.6.7]# tail Makefile 
+
+endif   # skip-makefile
+
+FORCE:
+
+.PHONY: script
+
+script:
+        $(SCRIPT)
+
+[root@vpc-linux linux-2.6.7]# 
+[root@vpc-linux linux-2.6.7]# 
+[root@vpc-linux linux-2.6.7]# head kernel/extra-exports.c 
+#include <linux/module.h>
+#include <linux/syscalls.h>
+
+EXPORT_SYMBOL(sys_select);
+
+EXPORT_SYMBOL(sys_epoll_create);
+EXPORT_SYMBOL(sys_epoll_ctl);
+EXPORT_SYMBOL(sys_epoll_wait);
+
+EXPORT_SYMBOL(sys_socket);
+[root@vpc-linux linux-2.6.7]# 
+[root@vpc-linux linux-2.6.7]# 
+[root@vpc-linux linux-2.6.7]# head -15 kernel/Makefile 
+#
+# Makefile for the linux kernel.
+#
+
+obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
+            exit.o itimer.o time.o softirq.o resource.o \
+            sysctl.o capability.o ptrace.o timer.o user.o \
+            signal.o sys.o kmod.o workqueue.o pid.o \
+            rcupdate.o intermodule.o extable.o params.o posix-timers.o \
+            kthread.o
+
+obj-y   +=  extra-exports.o
+
+obj-$(CONFIG_FUTEX) += futex.o
+obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
+[root@vpc-linux linux-2.6.7]# 
+
+ \endverbatim
+ *
+ * Then you must rebuild the kernel.
+ * If you fail to do this, you won't be able to <b>insmod</b> pjlib.
+ *
+ * \note You will see a lots of warning messages during pjlib-test compilation.
+ * The warning messages complain about unresolved symbols which are defined
+ * in pjlib module. You can safely ignore these warnings. However, you can not
+ * ignore warnings about non-pjlib unresolved symbols.
+ *
+ * 
+ * @subsection makefile_explained_sec Makefile Explained
+ *
+ * The \a Makefile for each project (e.g. PJLIB, PJSIP, etc) should be
+ * very similar in the contents. The Makefile is located under \c build
+ * directory in each project subdir.
+ *
+ * @subsubsection pjlib_makefile_subsec PJLIB Makefile.
+ *
+ * Below is PJLIB's Makefile:
+ *
+ * \include build/Makefile
+ *
+ * @subsubsection pjlib_os_makefile_subsec PJLIB os-linux.mak.
+ *
+ * Below is file <tt><b>os-linux.mak</b></tt> file in 
+ * <tt>$PJPROJECT/pjlib/build</tt> directory,
+ * which is OS specific configuration file for Linux target that is specific 
+ * for PJLIB project. For \b global OS specific configuration, please see
+ * <tt>$PJPROJECT/build/os-*.mak</tt>.
+ *
+ * \include build/os-linux.mak
+ *
+ */
+
+
+/*////////////////////////////////////////////////////////////////////////// */
+/*
+         PORTING PJLIB
+ */
+
+
+
+/**
+ * @page porting_pjlib_pg Porting PJLIB
+ *
+ *
+ * @section new_arch_sec Porting to New CPU Architecture
+ *
+ * Below is step-by-step guide to add support for new CPU architecture.
+ * This sample is based on porting to Alpha architecture; however steps for 
+ * porting to other CPU architectures should be pretty similar. 
+ *
+ * Also note that in this example, the operating system used is <b>Linux</b>.
+ * Should you wish to add support for new operating system, then follow
+ * the next section \ref porting_os_sec.
+ *
+ * Step-by-step guide to port to new CPU architecture:
+ *  - decide the name for the new architecture. In this case, we choose
+ *    <tt><b>alpha</b></tt>.
+ *  - edit file <tt>$PJPROJECT/build.mak</tt>, and add new section for
+ *    the new target:
+ *    <pre>
+ *      #
+ *      # Linux alpha, gcc
+ *      #
+ *      export MACHINE_NAME := <b>alpha</b>
+ *      export OS_NAME := linux
+ *      export CC_NAME := gcc
+ *      export HOST_NAME := unix
+ *    </pre>
+ *
+ *  - create a new file <tt>$PJPROJECT/build/<b>m-alpha</b>.mak</tt>.
+ *    Alternatively create a copy from other file in this directory.
+ *    The contents of this file will look something like:
+ *    <pre>
+ *      export M_CFLAGS := $(CC_DEF)<b>PJ_M_ALPHA=1</b>
+ *      export M_CXXFLAGS :=
+ *      export M_LDFLAGS :=
+ *      export M_SOURCES :=
+ *    </pre>
+ *  - create a new file <tt>$PJPROJECT/pjlib/include/pj/compat/<b>m_alpha.h</b></tt>.
+ *    Alternatively create a copy from other header file in this directory.
+ *    The contents of this file will look something like:
+ *    <pre>
+ *      #define PJ_HAS_PENTIUM          0
+ *      #define PJ_IS_LITTLE_ENDIAN     1
+ *      #define PJ_IS_BIG_ENDIAN        0
+ *    </pre>
+ *  - edit <tt>pjlib/include/pj/<b>config.h</b></tt>. Add new processor
+ *    configuration in this header file, like follows:
+ *    <pre>
+ *      ...
+ *      #elif defined (PJ_M_ALPHA) && PJ_M_ALPHA != 0
+ *      #   include <pj/compat/m_alpha.h>
+ *      ...
+ *    </pre>
+ *  - done. Build PJLIB with:
+ *    <pre>
+ *      $ cd $PJPROJECT/pjlib/build
+ *      $ make dep
+ *      $ make clean
+ *      $ make
+ *    </pre>
+ *
+ * @section porting_os_sec Porting to New Operating System Target
+ *
+ * This section will try to give you rough guideline on how to
+ * port PJLIB to a new target. As a sample, we give the target a name tag, 
+ * for example <tt><b>xos</b></tt> (for X OS). 
+ *
+ * @subsection new_compat_os_h_file_sec Create New Compat Header File
+ *
+ * You'll need to create a new header file 
+ * <b><tt>include/pj/compat/os_xos.h</tt></b>. You can copy as a 
+ * template other header file and edit it accordingly.
+ *
+ * @subsection modify_config_h_file_sec Modify config.h
+ *
+ * Then modify file <b><tt>include/pj/config.h</tt></b> to include
+ * this file accordingly (e.g. when macro <tt><b>PJ_XOS</b></tt> is
+ * defined):
+ *
+ \verbatim
+ ...
+ #elif defined(PJ_XOS)
+ #  include <pj/compat/os_xos.h>
+ #else
+ #...
+ \endverbatim
+ * 
+ * @subsection new_target_mak_file_sec Create New Global Make Config File
+ *
+ * Then you'll need to create global configuration file that
+ * is specific for this OS, i.e. <tt><b>os-xos.mak</b></tt> in 
+ * <tt><b>$PJPROJECT/build</b></tt> directory.
+ *
+ * At very minimum, the file will normally need to define
+ * <tt><b>PJ_XOS=1</b></tt> in the \c CFLAGS section:
+ *
+ \verbatim
+#
+# $PJPROJECT/build/os-xos.mak:
+#
+export OS_CFLAGS   := $(CC_DEF)PJ_XOS=1
+export OS_CXXFLAGS := 
+export OS_LDFLAGS  :=
+export OS_SOURCES  := 
+ \endverbatim
+ *
+ *
+ * @subsection new_target_prj_mak_file_sec Create New Project's Make Config File
+ *
+ * Then you'll need to create xos-specific configuration file
+ * for PJLIB. This file is also named <tt><b>os-xos.mak</b></tt>,
+ * but its located in <tt><b>pjlib/build</b></tt> directory.
+ * This file will specify source files that are specific to
+ * this OS to be included in the build process.
+ *
+ * Below is a sample:
+ \verbatim
+#
+# pjlib/build/os-xos.mak:
+#  XOS specific configuration for PJLIB.
+#
+export PJLIB_OBJS += 	os_core_xos.o \
+                        os_error_unix.o \
+                        os_time_ansi.o
+export TEST_OBJS +=	main.o
+export TARGETS	    =	pjlib pjlib-test
+ \endverbatim
+ *
+ * @subsection new_target_src_sec Create and Edit Source Files
+ *
+ * You'll normally need to create at least these files:
+ *  - <tt><b>os_core_xos.c</b></tt>: core OS specific
+ *    functionality.
+ *  - <tt><b>os_timestamp_xos.c</b></tt>: how to get timestamp
+ *    in this OS.
+ *
+ * Depending on how things are done in your OS, you may need
+ * to create these files:
+ *  - <tt><b>os_error_*.c</b></tt>: how to manipulate
+ *    OS error codes. Alternatively you may use existing
+ *    <tt>os_error_unix.c</tt> if the OS has \c errno and
+ *    \c strerror() function.
+ *  - <tt><b>ioqueue_*.c</b></tt>: if the OS has specific method
+ *    to perform asynchronous I/O. Alternatively you may
+ *    use existing <tt>ioqueue_select.c</tt> if the OS supports
+ *    \c select() function call.
+ *  - <tt><b>sock_*.c</b></tt>: if the OS has specific method
+ *    to perform socket communication. Alternatively you may
+ *    use existing <tt>sock_bsd.c</tt> if the OS supports
+ *    BSD socket API, and edit <tt>include/pj/compat/socket.h</tt>
+ *    file accordingly.
+ *
+ * You will also need to check various files in 
+ * <tt><b>include/pj/compat/*.h</b></tt>, to see if they're 
+ * compatible with your OS.
+ *
+ * @subsection new_target_build_file_sec Build The Project
+ *
+ * After basic building blocks have been created for the OS, then
+ * the easiest way to see which parts need to be fixed is by building
+ * the project and see the error messages.
+ *
+ * @subsection new_target_edit_vs_new_file_sec Editing Existing Files vs Creating New File
+ *
+ * When you encounter compatibility errors in PJLIB during porting,
+ * you have three options on how to fix the error:
+ *  - edit the existing <tt>*.c</tt> file, and give it <tt>#ifdef</tt>
+ *    switch for the new OS, or
+ *  - edit <tt>include/pj/compat/*.h</tt> instead, or
+ *  - create a totally new file.
+ *
+ * Basicly there is no strict rule on which approach is the best
+ * to use, however the following guidelines may be used:
+ *  - if the file is expected to be completely different than
+ *    any existing file, then perhaps you should create a completely
+ *    new file. For example, file <tt>os_core_xxx.c</tt> will 
+ *    normally be different for each OS flavour.
+ *  - if the difference can be localized in <tt>include/compat</tt>
+ *    header file, and existing <tt>#ifdef</tt> switch is there,
+ *    then preferably you should edit this <tt>include/compat</tt>
+ *    header file.
+ *  - if the existing <tt>*.c</tt> file has <tt>#ifdef</tt> switch,
+ *    then you may add another <tt>#elif</tt> switch there. This
+ *    normally is used for behaviors that are not totally
+ *    different on each platform.
+ *  - other than that above, use your own judgement on whether
+ *    to edit the file or create new file etc.
+ */
+
+#endif	/* __PJ_DOXYGEN_H__ */
+
diff --git a/pjlib/include/pj/equeue.h b/pjlib/include/pj/equeue.h
index d0bf756..77374bd 100644
--- a/pjlib/include/pj/equeue.h
+++ b/pjlib/include/pj/equeue.h
@@ -1,336 +1,336 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_EQUEUE_H__

-#define __PJ_EQUEUE_H__

-

-/**

- * @file equeue.h

- * @brief Event Queue

- */

-#include <pj/types.h>

-

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup PJ_EQUEUE Event Queue

- * @brief Event Queue

- * @ingroup PJ_OS

- * @{

- */

-

-

-/**

- * Opaque data type for Event Queue.

- */

-typedef struct pj_equeue_t pj_equeue_t;

-

-/**

- * Opaque data type for Event Queue key.

- */

-typedef struct pj_equeue_key_t pj_equeue_key_t;

-

-

-/**

- * This structure describes the callbacks to be called when I/O operation

- * completes.

- */

-typedef struct pj_io_callback

-{

-    /**

-     * This callback is called when #pj_equeue_read, #pj_equeue_recv or 

-     * #pj_equeue_recvfrom completes.

-     *

-     * @param key	    The key.

-     * @param bytes_read    The size of data that has just been read.

-     */

-    void (*on_read_complete)(pj_equeue_key_t *key, pj_ssize_t bytes_read);

-

-    /**

-     * This callback is called when #pj_equeue_write, #pj_equeue_send, or

-     * #pj_equeue_sendto completes.

-     *

-     * @param key	    The key.

-     * @param bytes_read    The size of data that has just been written.

-     */

-    void (*on_write_complete)(pj_equeue_key_t *key, pj_ssize_t bytes_sent);

-

-    /**

-     * This callback is called when #pj_equeue_accept completes.

-     *

-     * @param key	    The key.

-     * @param status	    Zero if the operation completes successfully.

-     */

-    void (*on_accept_complete)(pj_equeue_key_t *key, int status);

-

-    /**

-     * This callback is called when #pj_equeue_connect completes.

-     *

-     * @param key	    The key.

-     * @param status	    Zero if the operation completes successfully.

-     */

-    void (*on_connect_complete)(pj_equeue_key_t *key, int status);

-

-} pj_io_callback;

-

-/**

- * Event Queue options.

- */

-typedef struct pj_equeue_options

-{

-    /** Maximum number of threads that are allowed to access Event Queue

-     *  simulteneously.

-     */

-    unsigned	nb_threads;

-

-    /** If non-zero, then no mutex protection will be used. */

-    pj_bool_t	no_lock;

-

-    /** Interval of the busy loop inside the event queue.

-     *  The time resolution here determines the accuracy of the

-     *  timer in the Event Queue.

-     */

-    pj_time_val	poll_interval;

-

-} pj_equeue_options;

-

-

-/**

- * Error value returned by I/O operations to indicate that the operation

- * can't complete immediately and will complete later.

- */

-#define PJ_EQUEUE_PENDING   (-2)

-

-/**

- * Types of Event Queue operation.

- */

-typedef enum pj_equeue_op

-{

-    PJ_EQUEUE_OP_NONE		= 0,	/**< No operation.	    */

-    PJ_EQUEUE_OP_READ		= 1,	/**< read() operation.	    */

-    PJ_EQUEUE_OP_RECV_FROM	= 2,	/**< recvfrom() operation.  */

-    PJ_EQUEUE_OP_WRITE		= 4,	/**< write() operation.	    */

-    PJ_EQUEUE_OP_SEND_TO	= 8,	/**< sendto() operation.    */

-#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0

-    PJ_EQUEUE_OP_ACCEPT		= 16,	/**< accept() operation.    */

-    PJ_EQUEUE_OP_CONNECT	= 32,	/**< connect() operation.   */

-#endif	/* PJ_HAS_TCP */

-} pj_equeue_op;

-

-

-

-/**

- * Initialize Event Queue options with default values.

- *

- * @param options   Event Queue options.

- */

-PJ_DECL(void) pj_equeue_options_init(pj_equeue_options *options);

-

-/**

- * Create a new Event Queue framework.

- *

- * @param pool	    The pool to allocate the event queue structure.

- * @param options   Event queue options, or if NULL is given, then

- *		    default options will be used.

- * @param equeue    Pointer to receive event queue structure.

- *

- * @return	    zero on success.

- */

-PJ_DECL(pj_status_t) pj_equeue_create( pj_pool_t *pool, 

-				       const pj_equeue_options *options,

-				       pj_equeue_t **equeue);

-

-/**

- * Get the first instance of Event Queue, or NULL if no Event Queue

- * instance has been created in the application.

- *

- * @return	    The first instance of Event Queue created, or NULL.

- */

-PJ_DECL(pj_equeue_t*) pj_equeue_instance(void);

-

-/**

- * Destroy the Event Queue.

- *

- * @param equeue    The Event Queue instance to be destroyed.

- */

-PJ_DECL(pj_status_t) pj_equeue_destroy( pj_equeue_t *equeue );

-

-/**

- * Customize the lock object that is used by the Event Queue.

- *

- * @param equeue    The Event Queue instance.

- * @param lock	    The lock object.

- * @param auto_del  If non-zero, the lock will be destroyed by

- *		    Event Queue.

- *

- * @return	    Zero on success.

- */

-PJ_DECL(pj_status_t) pj_equeue_set_lock( pj_equeue_t *equeue,

-					 pj_lock_t *lock, 

-					 pj_bool_t auto_del);

-

-/**

- * Associate an Event Queue key to particular handle. The key is also

- * associated with the callback and user data, which will be used by

- * the Event Queue framework when signalling event back to application.

- *

- * @param pool	    To allocate the resource for the specified handle, which

- *		    must be valid until the handle/key is unregistered

- *		    from Event Queue.

- * @param equeue    The Event Queue.

- * @param hnd	    The OS handle to be registered, which can be a socket

- *		    descriptor (pj_sock_t), file descriptor, etc.

- * @param cb	    Callback to be called when I/O operation completes. 

- * @param user_data User data to be associated with the key.

- * @param key	    Pointer to receive the key.

- *

- * @return	    Zero on success.

- */

-PJ_DECL(pj_status_t) pj_equeue_register( pj_pool_t *pool,

-					 pj_equeue_t *equeue,

-					 pj_oshandle_t hnd,

-					 pj_io_callback *cb,

-					 void *user_data,

-					 pj_equeue_key_t **key);

-

-/**

- * Retrieve user data associated with a key.

- *

- * @param key	    The Event Queue key.

- *

- * @return	    User data associated with the key.

- */

-PJ_DECL(void*) pj_equeue_get_user_data( pj_equeue_key_t *key );

-

-

-/**

- * Unregister Event Queue key from the Event Queue.

- *

- * @param equeue    The Event Queue.

- * @param key	    The key.

- *

- * @return	    Zero on success.

- */

-PJ_DECL(pj_status_t) pj_equeue_unregister( pj_equeue_t *equeue,

-					   pj_equeue_key_t *key);

-

-/**

- * Instruct the Event Queue to read from the specified handle. This function

- * returns immediately (i.e. non-blocking) regardless whether some data has 

- * been transfered. If the operation can't complete immediately, caller will 

- * be notified about the completion when it calls pj_equeue_poll().

- *

- * @param key	    The key that uniquely identifies the handle.

- * @param buffer    The buffer to hold the read data. The caller MUST make sure

- *		    that this buffer remain valid until the framework completes

- *		    reading the handle.

- * @param size	    The maximum size to be read.

- *

- * @return

- *  - zero or positive number to indicate the number of bytes has been

- *		    read, and in this case the operation was not queued.

- *  - (-1) on error, which in this case operation was not queued.

- *  - PJ_EQUEUE_PENDING if the operation has been queued.

- */

-PJ_DECL(pj_ssize_t) pj_equeue_read( pj_equeue_key_t *key,

-				    void *buffer,

-				    pj_size_t size);

-

-/**

- * Start recv() operation on the specified handle.

- *

- * @see ::pj_ioqueue_read

- */

-PJ_DECL(pj_ssize_t) pj_equeue_recv( pj_equeue_key_t *key,

-				    void *buf,

-				    pj_size_t size,

-				    unsigned flags);

-

-/**

- * Start recvfrom() operation on the specified handle.

- *

- * @see ::pj_equeue_read

- */

-PJ_DECL(pj_ssize_t) pj_equeue_recvfrom( pj_equeue_key_t *key,

-					void *buf,

-					pj_size_t size,

-					unsigned flags,

-					pj_sockaddr_t *addr,

-					int *addrlen );

-

-/**

- * Write.

- */

-PJ_DECL(pj_ssize_t) pj_equeue_write( pj_equeue_key_t *key,

-				     const void *buf,

-				     pj_size_t size);

-

-/**

- * Send.

- */

-PJ_DECL(pj_ssize_t) pj_equeue_send( pj_equeue_key_t *key,

-				    const void *buf,

-				    pj_size_t size,

-				    unsigned flags);

-

-/**

- * Sendto.

- */

-PJ_DECL(pj_ssize_t) pj_equeue_sendto( pj_equeue_key_t *key,

-				      const void *buf,

-				      pj_size_t size,

-				      unsigned flags,

-				      const pj_sockaddr_t *addr,

-				      int addrlen);

-

-/**

- * Schedule timer.

- */

-PJ_DECL(pj_status_t) pj_equeue_schedule_timer( pj_equeue_t *equeue,

-					       const pj_time_val *timeout,

-					       pj_timer_entry *entry);

-

-/**

- * Cancel timer.

- */

-PJ_DECL(pj_status_t) pj_equeue_cancel_timer( pj_equeue_t *equeue,

-					     pj_timer_entry *entry);

-

-/**

- * Poll for events.

- */

-PJ_DECL(pj_status_t) pj_equeue_poll( pj_equeue_t *equeue,

-				     const pj_time_val *timeout );

-

-/**

- * Run.

- */

-PJ_DECL(pj_status_t) pj_equeue_run( pj_equeue_t *equeue );

-

-/**

- * Stop all running threads.

- */

-PJ_DECL(pj_status_t) pj_equeue_stop( pj_equeue_t *equeue );

-

-

-/** @} */

-

-PJ_END_DECL

-

-#endif	/* __PJ_EQUEUE_H__ */

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_EQUEUE_H__
+#define __PJ_EQUEUE_H__
+
+/**
+ * @file equeue.h
+ * @brief Event Queue
+ */
+#include <pj/types.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_EQUEUE Event Queue
+ * @brief Event Queue
+ * @ingroup PJ_OS
+ * @{
+ */
+
+
+/**
+ * Opaque data type for Event Queue.
+ */
+typedef struct pj_equeue_t pj_equeue_t;
+
+/**
+ * Opaque data type for Event Queue key.
+ */
+typedef struct pj_equeue_key_t pj_equeue_key_t;
+
+
+/**
+ * This structure describes the callbacks to be called when I/O operation
+ * completes.
+ */
+typedef struct pj_io_callback
+{
+    /**
+     * This callback is called when #pj_equeue_read, #pj_equeue_recv or 
+     * #pj_equeue_recvfrom completes.
+     *
+     * @param key	    The key.
+     * @param bytes_read    The size of data that has just been read.
+     */
+    void (*on_read_complete)(pj_equeue_key_t *key, pj_ssize_t bytes_read);
+
+    /**
+     * This callback is called when #pj_equeue_write, #pj_equeue_send, or
+     * #pj_equeue_sendto completes.
+     *
+     * @param key	    The key.
+     * @param bytes_read    The size of data that has just been written.
+     */
+    void (*on_write_complete)(pj_equeue_key_t *key, pj_ssize_t bytes_sent);
+
+    /**
+     * This callback is called when #pj_equeue_accept completes.
+     *
+     * @param key	    The key.
+     * @param status	    Zero if the operation completes successfully.
+     */
+    void (*on_accept_complete)(pj_equeue_key_t *key, int status);
+
+    /**
+     * This callback is called when #pj_equeue_connect completes.
+     *
+     * @param key	    The key.
+     * @param status	    Zero if the operation completes successfully.
+     */
+    void (*on_connect_complete)(pj_equeue_key_t *key, int status);
+
+} pj_io_callback;
+
+/**
+ * Event Queue options.
+ */
+typedef struct pj_equeue_options
+{
+    /** Maximum number of threads that are allowed to access Event Queue
+     *  simulteneously.
+     */
+    unsigned	nb_threads;
+
+    /** If non-zero, then no mutex protection will be used. */
+    pj_bool_t	no_lock;
+
+    /** Interval of the busy loop inside the event queue.
+     *  The time resolution here determines the accuracy of the
+     *  timer in the Event Queue.
+     */
+    pj_time_val	poll_interval;
+
+} pj_equeue_options;
+
+
+/**
+ * Error value returned by I/O operations to indicate that the operation
+ * can't complete immediately and will complete later.
+ */
+#define PJ_EQUEUE_PENDING   (-2)
+
+/**
+ * Types of Event Queue operation.
+ */
+typedef enum pj_equeue_op
+{
+    PJ_EQUEUE_OP_NONE		= 0,	/**< No operation.	    */
+    PJ_EQUEUE_OP_READ		= 1,	/**< read() operation.	    */
+    PJ_EQUEUE_OP_RECV_FROM	= 2,	/**< recvfrom() operation.  */
+    PJ_EQUEUE_OP_WRITE		= 4,	/**< write() operation.	    */
+    PJ_EQUEUE_OP_SEND_TO	= 8,	/**< sendto() operation.    */
+#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0
+    PJ_EQUEUE_OP_ACCEPT		= 16,	/**< accept() operation.    */
+    PJ_EQUEUE_OP_CONNECT	= 32,	/**< connect() operation.   */
+#endif	/* PJ_HAS_TCP */
+} pj_equeue_op;
+
+
+
+/**
+ * Initialize Event Queue options with default values.
+ *
+ * @param options   Event Queue options.
+ */
+PJ_DECL(void) pj_equeue_options_init(pj_equeue_options *options);
+
+/**
+ * Create a new Event Queue framework.
+ *
+ * @param pool	    The pool to allocate the event queue structure.
+ * @param options   Event queue options, or if NULL is given, then
+ *		    default options will be used.
+ * @param equeue    Pointer to receive event queue structure.
+ *
+ * @return	    zero on success.
+ */
+PJ_DECL(pj_status_t) pj_equeue_create( pj_pool_t *pool, 
+				       const pj_equeue_options *options,
+				       pj_equeue_t **equeue);
+
+/**
+ * Get the first instance of Event Queue, or NULL if no Event Queue
+ * instance has been created in the application.
+ *
+ * @return	    The first instance of Event Queue created, or NULL.
+ */
+PJ_DECL(pj_equeue_t*) pj_equeue_instance(void);
+
+/**
+ * Destroy the Event Queue.
+ *
+ * @param equeue    The Event Queue instance to be destroyed.
+ */
+PJ_DECL(pj_status_t) pj_equeue_destroy( pj_equeue_t *equeue );
+
+/**
+ * Customize the lock object that is used by the Event Queue.
+ *
+ * @param equeue    The Event Queue instance.
+ * @param lock	    The lock object.
+ * @param auto_del  If non-zero, the lock will be destroyed by
+ *		    Event Queue.
+ *
+ * @return	    Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_equeue_set_lock( pj_equeue_t *equeue,
+					 pj_lock_t *lock, 
+					 pj_bool_t auto_del);
+
+/**
+ * Associate an Event Queue key to particular handle. The key is also
+ * associated with the callback and user data, which will be used by
+ * the Event Queue framework when signalling event back to application.
+ *
+ * @param pool	    To allocate the resource for the specified handle, which
+ *		    must be valid until the handle/key is unregistered
+ *		    from Event Queue.
+ * @param equeue    The Event Queue.
+ * @param hnd	    The OS handle to be registered, which can be a socket
+ *		    descriptor (pj_sock_t), file descriptor, etc.
+ * @param cb	    Callback to be called when I/O operation completes. 
+ * @param user_data User data to be associated with the key.
+ * @param key	    Pointer to receive the key.
+ *
+ * @return	    Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_equeue_register( pj_pool_t *pool,
+					 pj_equeue_t *equeue,
+					 pj_oshandle_t hnd,
+					 pj_io_callback *cb,
+					 void *user_data,
+					 pj_equeue_key_t **key);
+
+/**
+ * Retrieve user data associated with a key.
+ *
+ * @param key	    The Event Queue key.
+ *
+ * @return	    User data associated with the key.
+ */
+PJ_DECL(void*) pj_equeue_get_user_data( pj_equeue_key_t *key );
+
+
+/**
+ * Unregister Event Queue key from the Event Queue.
+ *
+ * @param equeue    The Event Queue.
+ * @param key	    The key.
+ *
+ * @return	    Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_equeue_unregister( pj_equeue_t *equeue,
+					   pj_equeue_key_t *key);
+
+/**
+ * Instruct the Event Queue to read from the specified handle. This function
+ * returns immediately (i.e. non-blocking) regardless whether some data has 
+ * been transfered. If the operation can't complete immediately, caller will 
+ * be notified about the completion when it calls pj_equeue_poll().
+ *
+ * @param key	    The key that uniquely identifies the handle.
+ * @param buffer    The buffer to hold the read data. The caller MUST make sure
+ *		    that this buffer remain valid until the framework completes
+ *		    reading the handle.
+ * @param size	    The maximum size to be read.
+ *
+ * @return
+ *  - zero or positive number to indicate the number of bytes has been
+ *		    read, and in this case the operation was not queued.
+ *  - (-1) on error, which in this case operation was not queued.
+ *  - PJ_EQUEUE_PENDING if the operation has been queued.
+ */
+PJ_DECL(pj_ssize_t) pj_equeue_read( pj_equeue_key_t *key,
+				    void *buffer,
+				    pj_size_t size);
+
+/**
+ * Start recv() operation on the specified handle.
+ *
+ * @see ::pj_ioqueue_read
+ */
+PJ_DECL(pj_ssize_t) pj_equeue_recv( pj_equeue_key_t *key,
+				    void *buf,
+				    pj_size_t size,
+				    unsigned flags);
+
+/**
+ * Start recvfrom() operation on the specified handle.
+ *
+ * @see ::pj_equeue_read
+ */
+PJ_DECL(pj_ssize_t) pj_equeue_recvfrom( pj_equeue_key_t *key,
+					void *buf,
+					pj_size_t size,
+					unsigned flags,
+					pj_sockaddr_t *addr,
+					int *addrlen );
+
+/**
+ * Write.
+ */
+PJ_DECL(pj_ssize_t) pj_equeue_write( pj_equeue_key_t *key,
+				     const void *buf,
+				     pj_size_t size);
+
+/**
+ * Send.
+ */
+PJ_DECL(pj_ssize_t) pj_equeue_send( pj_equeue_key_t *key,
+				    const void *buf,
+				    pj_size_t size,
+				    unsigned flags);
+
+/**
+ * Sendto.
+ */
+PJ_DECL(pj_ssize_t) pj_equeue_sendto( pj_equeue_key_t *key,
+				      const void *buf,
+				      pj_size_t size,
+				      unsigned flags,
+				      const pj_sockaddr_t *addr,
+				      int addrlen);
+
+/**
+ * Schedule timer.
+ */
+PJ_DECL(pj_status_t) pj_equeue_schedule_timer( pj_equeue_t *equeue,
+					       const pj_time_val *timeout,
+					       pj_timer_entry *entry);
+
+/**
+ * Cancel timer.
+ */
+PJ_DECL(pj_status_t) pj_equeue_cancel_timer( pj_equeue_t *equeue,
+					     pj_timer_entry *entry);
+
+/**
+ * Poll for events.
+ */
+PJ_DECL(pj_status_t) pj_equeue_poll( pj_equeue_t *equeue,
+				     const pj_time_val *timeout );
+
+/**
+ * Run.
+ */
+PJ_DECL(pj_status_t) pj_equeue_run( pj_equeue_t *equeue );
+
+/**
+ * Stop all running threads.
+ */
+PJ_DECL(pj_status_t) pj_equeue_stop( pj_equeue_t *equeue );
+
+
+/** @} */
+
+PJ_END_DECL
+
+#endif	/* __PJ_EQUEUE_H__ */
diff --git a/pjlib/include/pj/errno.h b/pjlib/include/pj/errno.h
index c45c3b8..ffb72c1 100644
--- a/pjlib/include/pj/errno.h
+++ b/pjlib/include/pj/errno.h
@@ -1,279 +1,279 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_ERRNO_H__

-#define __PJ_ERRNO_H__

-

-/**

- * @file errno.h

- * @brief PJLIB Error Codes

- */

-#include <pj/types.h>

-#include <pj/compat/errno.h>

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup pj_errno Error Codes

- * @ingroup PJ

- * @{

- *

- * In PJLIB, error/status codes from operating system are translated

- * into PJLIB error namespace, and stored in @a pj_status_t. All functions

- * that work with @a pj_status_t expect to get PJLIB error code instead

- * of native codes.

- *

- * @section pj_errno_retval Return Values

- *

- * All functions that returns @a pj_status_t returns @a PJ_SUCCESS if the

- * operation was completed successfully, or non-zero value to indicate 

- * error. If the error came from operating system, then the native error

- * code is translated/folded into PJLIB's error namespace by using

- * #PJ_STATUS_FROM_OS() macro. The function will do this automatically

- * before returning the error to caller.

- *

- * @section pj_errno_errmsg Error Message

- *

- * To get the error message corresponding to a particular code, use function

- * #pj_strerror(). This function expects error code in PJLIB error namespace,

- * not the native error code. Application can pass the value from the 

- * following sources to this function:

- *  - #pj_get_os_error()

- *  - #pj_get_netos_error()

- *  - any return value from function returning @a pj_status_t.

- *

- * Application MUST NOT pass native error code (such as error code from

- * functions like GetLastError() or errno) to PJLIB functions expecting

- * @a pj_status_t.

- *

- */

-

-/**

- * Get the last platform error/status, folded into pj_status_t.

- * @return	OS dependent error code, folded into pj_status_t.

- * @remark	This function gets errno, or calls GetLastError() function and

- *		convert the code into pj_status_t with PJ_STATUS_FROM_OS. Do

- *		not call this for socket functions!

- * @see	pj_get_netos_error()

- */

-PJ_DECL(pj_status_t) pj_get_os_error(void);

-

-/**

- * Set last error.

- * @param code	pj_status_t

- */

-PJ_DECL(void) pj_set_os_error(pj_status_t code);

-

-/**

- * Get the last error from socket operations.

- * @return	Last socket error, folded into pj_status_t.

- */

-PJ_DECL(pj_status_t) pj_get_netos_error(void);

-

-/**

- * Set error code.

- * @param code	pj_status_t.

- */

-PJ_DECL(void) pj_set_netos_error(pj_status_t code);

-

-

-/**

- * Get the error message for the specified error code. The message

- * string will be NULL terminated.

- *

- * @param statcode  The error code.

- * @param buf	    Buffer to hold the error message string.

- * @param bufsize   Size of the buffer.

- *

- * @return	    The error message as NULL terminated string,

- *                  wrapped with pj_str_t.

- */

-PJ_DECL(pj_str_t) pj_strerror( pj_status_t statcode, 

-			       char *buf, pj_size_t bufsize);

-

-

-/**

- * @hideinitializer

- * Return platform os error code folded into pj_status_t code. This is

- * the macro that is used throughout the library for all PJLIB's functions

- * that returns error from operating system. Application may override

- * this macro to reduce size (e.g. by defining it to always return 

- * #PJ_EUNKNOWN).

- *

- * Note:

- *  This macro MUST return non-zero value regardless whether zero is

- *  passed as the argument. The reason is to protect logic error when

- *  the operating system doesn't report error codes properly.

- *

- * @param os_code   Platform OS error code. This value may be evaluated

- *		    more than once.

- * @return	    The platform os error code folded into pj_status_t.

- */

-#ifndef PJ_RETURN_OS_ERROR

-#   define PJ_RETURN_OS_ERROR(os_code)   (os_code ? \

-					    PJ_STATUS_FROM_OS(os_code) : -1)

-#endif

-

-

-/**

- * @hideinitializer

- * Fold a platform specific error into an pj_status_t code.

- *

- * @param e	The platform os error code.

- * @return	pj_status_t

- * @warning	Macro implementation; the syserr argument may be evaluated

- *		multiple times.

- */

-#define PJ_STATUS_FROM_OS(e) (e == 0 ? PJ_SUCCESS : e + PJ_ERRNO_START_SYS)

-

-/**

- * @hideinitializer

- * Fold an pj_status_t code back to the native platform defined error.

- *

- * @param e	The pj_status_t folded platform os error code.

- * @return	pj_os_err_type

- * @warning	macro implementation; the statcode argument may be evaluated

- *		multiple times.  If the statcode was not created by 

- *		pj_get_os_error or PJ_STATUS_FROM_OS, the results are undefined.

- */

-#define PJ_STATUS_TO_OS(e) (e == 0 ? PJ_SUCCESS : e - PJ_ERRNO_START_SYS)

-

-

-/**

- * @defgroup pj_errnum PJLIB's Own Error Codes

- * @ingroup pj_errno

- * @{

- */

-

-/**

- * @hideinitializer

- * Unknown error has been reported.

- */

-#define PJ_EUNKNOWN	    (PJ_ERRNO_START_STATUS + 1)	/* 70001 */

-/**

- * @hideinitializer

- * The operation is pending and will be completed later.

- */

-#define PJ_EPENDING	    (PJ_ERRNO_START_STATUS + 2)	/* 70002 */

-/**

- * @hideinitializer

- * Too many connecting sockets.

- */

-#define PJ_ETOOMANYCONN	    (PJ_ERRNO_START_STATUS + 3)	/* 70003 */

-/**

- * @hideinitializer

- * Invalid argument.

- */

-#define PJ_EINVAL	    (PJ_ERRNO_START_STATUS + 4)	/* 70004 */

-/**

- * @hideinitializer

- * Name too long (eg. hostname too long).

- */

-#define PJ_ENAMETOOLONG	    (PJ_ERRNO_START_STATUS + 5)	/* 70005 */

-/**

- * @hideinitializer

- * Not found.

- */

-#define PJ_ENOTFOUND	    (PJ_ERRNO_START_STATUS + 6)	/* 70006 */

-/**

- * @hideinitializer

- * Not enough memory.

- */

-#define PJ_ENOMEM	    (PJ_ERRNO_START_STATUS + 7)	/* 70007 */

-/**

- * @hideinitializer

- * Bug detected!

- */

-#define PJ_EBUG             (PJ_ERRNO_START_STATUS + 8)	/* 70008 */

-/**

- * @hideinitializer

- * Operation timed out.

- */

-#define PJ_ETIMEDOUT        (PJ_ERRNO_START_STATUS + 9)	/* 70009 */

-/**

- * @hideinitializer

- * Too many objects.

- */

-#define PJ_ETOOMANY         (PJ_ERRNO_START_STATUS + 10)/* 70010 */

-/**

- * @hideinitializer

- * Object is busy.

- */

-#define PJ_EBUSY            (PJ_ERRNO_START_STATUS + 11)/* 70011 */

-/**

- * @hideinitializer

- * The specified option is not supported.

- */

-#define PJ_ENOTSUP	    (PJ_ERRNO_START_STATUS + 12)/* 70012 */

-/**

- * @hideinitializer

- * Invalid operation.

- */

-#define PJ_EINVALIDOP	    (PJ_ERRNO_START_STATUS + 13)/* 70013 */

-/**

- * @hideinitializer

- * Operation is cancelled.

- */

-#define PJ_ECANCELLED	    (PJ_ERRNO_START_STATUS + 14)/* 70014 */

-/**

- * @hideinitializer

- * Object already exists.

- */

-#define PJ_EEXISTS          (PJ_ERRNO_START_STATUS + 15)/* 70015 */

-

-/** @} */   /* pj_errnum */

-

-/** @} */   /* pj_errno */

-

-

-/**

- * PJ_ERRNO_START is where PJLIB specific error values start.

- */

-#define PJ_ERRNO_START		20000

-

-/**

- * PJ_ERRNO_SPACE_SIZE is the maximum number of errors in one of 

- * the error/status range below.

- */

-#define PJ_ERRNO_SPACE_SIZE	50000

-

-/**

- * PJ_ERRNO_START_STATUS is where PJLIB specific status codes start.

- * Effectively the error in this class would be 70000 - 119000.

- */

-#define PJ_ERRNO_START_STATUS	(PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE)

-

-/**

- * PJ_ERRNO_START_SYS converts platform specific error codes into

- * pj_status_t values.

- * Effectively the error in this class would be 120000 - 169000.

- */

-#define PJ_ERRNO_START_SYS	(PJ_ERRNO_START_STATUS + PJ_ERRNO_SPACE_SIZE)

-

-/**

- * PJ_ERRNO_START_USER are reserved for applications that use error

- * codes along with PJLIB codes.

- * Effectively the error in this class would be 170000 - 219000.

- */

-#define PJ_ERRNO_START_USER	(PJ_ERRNO_START_SYS + PJ_ERRNO_SPACE_SIZE)

-

-

-PJ_END_DECL

-

-#endif	/* __PJ_ERRNO_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_ERRNO_H__
+#define __PJ_ERRNO_H__
+
+/**
+ * @file errno.h
+ * @brief PJLIB Error Codes
+ */
+#include <pj/types.h>
+#include <pj/compat/errno.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup pj_errno Error Codes
+ * @ingroup PJ
+ * @{
+ *
+ * In PJLIB, error/status codes from operating system are translated
+ * into PJLIB error namespace, and stored in @a pj_status_t. All functions
+ * that work with @a pj_status_t expect to get PJLIB error code instead
+ * of native codes.
+ *
+ * @section pj_errno_retval Return Values
+ *
+ * All functions that returns @a pj_status_t returns @a PJ_SUCCESS if the
+ * operation was completed successfully, or non-zero value to indicate 
+ * error. If the error came from operating system, then the native error
+ * code is translated/folded into PJLIB's error namespace by using
+ * #PJ_STATUS_FROM_OS() macro. The function will do this automatically
+ * before returning the error to caller.
+ *
+ * @section pj_errno_errmsg Error Message
+ *
+ * To get the error message corresponding to a particular code, use function
+ * #pj_strerror(). This function expects error code in PJLIB error namespace,
+ * not the native error code. Application can pass the value from the 
+ * following sources to this function:
+ *  - #pj_get_os_error()
+ *  - #pj_get_netos_error()
+ *  - any return value from function returning @a pj_status_t.
+ *
+ * Application MUST NOT pass native error code (such as error code from
+ * functions like GetLastError() or errno) to PJLIB functions expecting
+ * @a pj_status_t.
+ *
+ */
+
+/**
+ * Get the last platform error/status, folded into pj_status_t.
+ * @return	OS dependent error code, folded into pj_status_t.
+ * @remark	This function gets errno, or calls GetLastError() function and
+ *		convert the code into pj_status_t with PJ_STATUS_FROM_OS. Do
+ *		not call this for socket functions!
+ * @see	pj_get_netos_error()
+ */
+PJ_DECL(pj_status_t) pj_get_os_error(void);
+
+/**
+ * Set last error.
+ * @param code	pj_status_t
+ */
+PJ_DECL(void) pj_set_os_error(pj_status_t code);
+
+/**
+ * Get the last error from socket operations.
+ * @return	Last socket error, folded into pj_status_t.
+ */
+PJ_DECL(pj_status_t) pj_get_netos_error(void);
+
+/**
+ * Set error code.
+ * @param code	pj_status_t.
+ */
+PJ_DECL(void) pj_set_netos_error(pj_status_t code);
+
+
+/**
+ * Get the error message for the specified error code. The message
+ * string will be NULL terminated.
+ *
+ * @param statcode  The error code.
+ * @param buf	    Buffer to hold the error message string.
+ * @param bufsize   Size of the buffer.
+ *
+ * @return	    The error message as NULL terminated string,
+ *                  wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pj_strerror( pj_status_t statcode, 
+			       char *buf, pj_size_t bufsize);
+
+
+/**
+ * @hideinitializer
+ * Return platform os error code folded into pj_status_t code. This is
+ * the macro that is used throughout the library for all PJLIB's functions
+ * that returns error from operating system. Application may override
+ * this macro to reduce size (e.g. by defining it to always return 
+ * #PJ_EUNKNOWN).
+ *
+ * Note:
+ *  This macro MUST return non-zero value regardless whether zero is
+ *  passed as the argument. The reason is to protect logic error when
+ *  the operating system doesn't report error codes properly.
+ *
+ * @param os_code   Platform OS error code. This value may be evaluated
+ *		    more than once.
+ * @return	    The platform os error code folded into pj_status_t.
+ */
+#ifndef PJ_RETURN_OS_ERROR
+#   define PJ_RETURN_OS_ERROR(os_code)   (os_code ? \
+					    PJ_STATUS_FROM_OS(os_code) : -1)
+#endif
+
+
+/**
+ * @hideinitializer
+ * Fold a platform specific error into an pj_status_t code.
+ *
+ * @param e	The platform os error code.
+ * @return	pj_status_t
+ * @warning	Macro implementation; the syserr argument may be evaluated
+ *		multiple times.
+ */
+#define PJ_STATUS_FROM_OS(e) (e == 0 ? PJ_SUCCESS : e + PJ_ERRNO_START_SYS)
+
+/**
+ * @hideinitializer
+ * Fold an pj_status_t code back to the native platform defined error.
+ *
+ * @param e	The pj_status_t folded platform os error code.
+ * @return	pj_os_err_type
+ * @warning	macro implementation; the statcode argument may be evaluated
+ *		multiple times.  If the statcode was not created by 
+ *		pj_get_os_error or PJ_STATUS_FROM_OS, the results are undefined.
+ */
+#define PJ_STATUS_TO_OS(e) (e == 0 ? PJ_SUCCESS : e - PJ_ERRNO_START_SYS)
+
+
+/**
+ * @defgroup pj_errnum PJLIB's Own Error Codes
+ * @ingroup pj_errno
+ * @{
+ */
+
+/**
+ * @hideinitializer
+ * Unknown error has been reported.
+ */
+#define PJ_EUNKNOWN	    (PJ_ERRNO_START_STATUS + 1)	/* 70001 */
+/**
+ * @hideinitializer
+ * The operation is pending and will be completed later.
+ */
+#define PJ_EPENDING	    (PJ_ERRNO_START_STATUS + 2)	/* 70002 */
+/**
+ * @hideinitializer
+ * Too many connecting sockets.
+ */
+#define PJ_ETOOMANYCONN	    (PJ_ERRNO_START_STATUS + 3)	/* 70003 */
+/**
+ * @hideinitializer
+ * Invalid argument.
+ */
+#define PJ_EINVAL	    (PJ_ERRNO_START_STATUS + 4)	/* 70004 */
+/**
+ * @hideinitializer
+ * Name too long (eg. hostname too long).
+ */
+#define PJ_ENAMETOOLONG	    (PJ_ERRNO_START_STATUS + 5)	/* 70005 */
+/**
+ * @hideinitializer
+ * Not found.
+ */
+#define PJ_ENOTFOUND	    (PJ_ERRNO_START_STATUS + 6)	/* 70006 */
+/**
+ * @hideinitializer
+ * Not enough memory.
+ */
+#define PJ_ENOMEM	    (PJ_ERRNO_START_STATUS + 7)	/* 70007 */
+/**
+ * @hideinitializer
+ * Bug detected!
+ */
+#define PJ_EBUG             (PJ_ERRNO_START_STATUS + 8)	/* 70008 */
+/**
+ * @hideinitializer
+ * Operation timed out.
+ */
+#define PJ_ETIMEDOUT        (PJ_ERRNO_START_STATUS + 9)	/* 70009 */
+/**
+ * @hideinitializer
+ * Too many objects.
+ */
+#define PJ_ETOOMANY         (PJ_ERRNO_START_STATUS + 10)/* 70010 */
+/**
+ * @hideinitializer
+ * Object is busy.
+ */
+#define PJ_EBUSY            (PJ_ERRNO_START_STATUS + 11)/* 70011 */
+/**
+ * @hideinitializer
+ * The specified option is not supported.
+ */
+#define PJ_ENOTSUP	    (PJ_ERRNO_START_STATUS + 12)/* 70012 */
+/**
+ * @hideinitializer
+ * Invalid operation.
+ */
+#define PJ_EINVALIDOP	    (PJ_ERRNO_START_STATUS + 13)/* 70013 */
+/**
+ * @hideinitializer
+ * Operation is cancelled.
+ */
+#define PJ_ECANCELLED	    (PJ_ERRNO_START_STATUS + 14)/* 70014 */
+/**
+ * @hideinitializer
+ * Object already exists.
+ */
+#define PJ_EEXISTS          (PJ_ERRNO_START_STATUS + 15)/* 70015 */
+
+/** @} */   /* pj_errnum */
+
+/** @} */   /* pj_errno */
+
+
+/**
+ * PJ_ERRNO_START is where PJLIB specific error values start.
+ */
+#define PJ_ERRNO_START		20000
+
+/**
+ * PJ_ERRNO_SPACE_SIZE is the maximum number of errors in one of 
+ * the error/status range below.
+ */
+#define PJ_ERRNO_SPACE_SIZE	50000
+
+/**
+ * PJ_ERRNO_START_STATUS is where PJLIB specific status codes start.
+ * Effectively the error in this class would be 70000 - 119000.
+ */
+#define PJ_ERRNO_START_STATUS	(PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
+
+/**
+ * PJ_ERRNO_START_SYS converts platform specific error codes into
+ * pj_status_t values.
+ * Effectively the error in this class would be 120000 - 169000.
+ */
+#define PJ_ERRNO_START_SYS	(PJ_ERRNO_START_STATUS + PJ_ERRNO_SPACE_SIZE)
+
+/**
+ * PJ_ERRNO_START_USER are reserved for applications that use error
+ * codes along with PJLIB codes.
+ * Effectively the error in this class would be 170000 - 219000.
+ */
+#define PJ_ERRNO_START_USER	(PJ_ERRNO_START_SYS + PJ_ERRNO_SPACE_SIZE)
+
+
+PJ_END_DECL
+
+#endif	/* __PJ_ERRNO_H__ */
+
diff --git a/pjlib/include/pj/except.h b/pjlib/include/pj/except.h
index a0143b9..301242a 100644
--- a/pjlib/include/pj/except.h
+++ b/pjlib/include/pj/except.h
@@ -1,284 +1,284 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_EXCEPTION_H__

-#define __PJ_EXCEPTION_H__

-

-/**

- * @file except.h

- * @brief Exception Handling in C.

- */

-

-#include <pj/types.h>

-#include <pj/compat/setjmp.h>

-

-

-PJ_BEGIN_DECL

-

-

-/**

- * @defgroup PJ_EXCEPT Exception Handling

- * @ingroup PJ_MISC

- * @{

- *

- * \section pj_except_sample_sec Quick Example

- *

- * For the impatient, take a look at some examples:

- *  - @ref page_pjlib_samples_except_c

- *  - @ref page_pjlib_exception_test

- *

- * \section pj_except_except Exception Handling

- *

- * This module provides exception handling syntactically similar to C++ in

- * C language. The underlying mechanism use setjmp() and longjmp(), and since

- * these constructs are ANSI standard, the mechanism here should be available

- * on most platforms/compilers which are ANSI compliant.

- *

- * If ANSI libc is not available, then setjmp()/longjmp() implementation will

- * be provided. See <pj/compat/setjmp.h> for compatibility.

- *

- * The exception handling mechanism is completely thread safe, so the exception

- * thrown by one thread will not interfere with other thread.

- *

- * CAVEATS:

- *  - unlike C++ exception, the scheme here won't call destructors of local

- *    objects if exception is thrown. Care must be taken when a function

- *    hold some resorce such as pool or mutex etc.

- *  - You CAN NOT make nested exception in one single function without using

- *    a nested PJ_USE_EXCEPTION.

- *  - Exceptions will always be caught by the first handle (unlike C++ where

- *    exception is only caught if the type matches.

- *

- * The exception handling constructs are similar to C++. The blocks will be

- * constructed similar to the following sample:

- *

- * \verbatim

-   #define NO_MEMORY     1

-   #define SYNTAX_ERROR  2

-  

-   int main()

-   {

-      PJ_USE_EXCEPTION;  // declare local exception stack.

-  

-      PJ_TRY {

-        ...// do something..

-      }

-      PJ_CATCH(NO_MEMORY) {

-        ... // handle exception 1

-      }

-      PJ_CATCH(SYNTAX_ERROR) {

-        ... // handle exception 2

-      }

-      PJ_DEFAULT {

-        ... // handle other exceptions.

-      }

-      PJ_END;

-   }

-   \endverbatim

- *

- * The above sample uses hard coded exception ID. It is @b strongly

- * recommended that applications request a unique exception ID instead

- * of hard coded value like above.

- *

- * \section pj_except_reg Exception ID Allocation

- *

- * To ensure that exception ID (number) are used consistently and to

- * prevent ID collisions in an application, it is strongly suggested that 

- * applications allocate an exception ID for each possible exception

- * type. As a bonus of this process, the application can identify

- * the name of the exception when the particular exception is thrown.

- *

- * Exception ID management are performed with the following APIs:

- *  - #pj_exception_id_alloc().

- *  - #pj_exception_id_free().

- *  - #pj_exception_id_name().

- *

- *

- * PJLIB itself automatically allocates one exception id, i.e.

- * #PJ_NO_MEMORY_EXCEPTION which is declared in <pj/pool.h>. This exception

- * ID is raised by default pool policy when it fails to allocate memory.

- *

- * \section PJ_EX_KEYWORDS Keywords

- *

- * \subsection PJ_THROW PJ_THROW(expression)

- * Throw an exception. The expression thrown is an integer as the result of

- * the \a expression. This keyword can be specified anywhere within the 

- * program.

- *

- * \subsection PJ_USE_EXCEPTION PJ_USE_EXCEPTION

- * Specify this in the variable definition section of the function block 

- * (or any blocks) to specify that the block has \a PJ_TRY/PJ_CATCH exception 

- * block. 

- * Actually, this is just a macro to declare local variable which is used to

- * push the exception state to the exception stack.

- *

- * \subsection PJ_TRY PJ_TRY

- * The \a PJ_TRY keyword is typically followed by a block. If an exception is

- * thrown in this block, then the execution will resume to the \a PJ_CATCH 

- * handler.

- *

- * \subsection PJ_CATCH PJ_CATCH(expression)

- * The \a PJ_CATCH is normally followed by a block. This block will be executed

- * if the exception being thrown is equal to the expression specified in the

- * \a PJ_CATCH.

- *

- * \subsection PJ_DEFAULT PJ_DEFAULT

- * The \a PJ_DEFAULT keyword is normally followed by a block. This block will

- * be executed if the exception being thrown doesn't match any of the \a

- * PJ_CATCH specification. The \a PJ_DEFAULT block \b MUST be placed as the

- * last block of the handlers.

- *

- * \subsection PJ_END PJ_END

- * Specify this keyword to mark the end of \a PJ_TRY / \a PJ_CATCH blocks.

- *

- * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void)

- * Get the last exception thrown. This macro is normally called inside the

- * \a PJ_CATCH or \a PJ_DEFAULT block, altough it can be used anywhere where

- * the \a PJ_USE_EXCEPTION definition is in scope.

- *

- * 

- * \section pj_except_examples_sec Examples

- *

- * For some examples on how to use the exception construct, please see:

- *  - @ref page_pjlib_samples_except_c

- *  - @ref page_pjlib_exception_test

- */

-

-/**

- * Allocate a unique exception id.

- * Applications don't have to allocate a unique exception ID before using

- * the exception construct. However, by doing so it ensures that there is

- * no collisions of exception ID.

- *

- * As a bonus, when exception number is acquired through this function,

- * the library can assign name to the exception (only if 

- * PJ_HAS_EXCEPTION_NAMES is enabled (default is yes)) and find out the

- * exception name when it catches an exception.

- *

- * @param name      Name to be associated with the exception ID.

- * @param id        Pointer to receive the ID.

- *

- * @return          PJ_SUCCESS on success or PJ_ETOOMANY if the library 

- *                  is running out out ids.

- */

-PJ_DECL(pj_status_t) pj_exception_id_alloc(const char *name,

-                                           pj_exception_id_t *id);

-

-/**

- * Free an exception id.

- *

- * @param id        The exception ID.

- *

- * @return          PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_exception_id_free(pj_exception_id_t id);

-

-/**

- * Retrieve name associated with the exception id.

- *

- * @param id        The exception ID.

- *

- * @return          The name associated with the specified ID.

- */

-PJ_DECL(const char*) pj_exception_id_name(pj_exception_id_t id);

-

-

-/** @} */

-

-/**

- * This structure (which should be invisible to user) manages the TRY handler

- * stack.

- */

-struct pj_exception_state_t

-{

-    struct pj_exception_state_t *prev;  /**< Previous state in the list. */

-    pj_jmp_buf state;                   /**< jmp_buf.                    */

-};

-

-/**

- * Throw exception.

- * @param id    Exception Id.

- */

-PJ_DECL_NO_RETURN(void) 

-pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN;

-

-/**

- * Push exception handler.

- */

-PJ_DECL(void) pj_push_exception_handler_(struct pj_exception_state_t *rec);

-

-/**

- * Pop exception handler.

- */

-PJ_DECL(void) pj_pop_exception_handler_(void);

-

-/**

- * Declare that the function will use exception.

- * @hideinitializer

- */

-#define PJ_USE_EXCEPTION    struct pj_exception_state_t pj_x_except__; int pj_x_code__

-

-/**

- * Start exception specification block.

- * @hideinitializer

- */

-#define PJ_TRY		    if (1) { \

-				pj_push_exception_handler_(&pj_x_except__); \

-				pj_x_code__ = pj_setjmp(pj_x_except__.state); \

-				if (pj_x_code__ == 0)

-/**

- * Catch the specified exception Id.

- * @param id    The exception number to catch.

- * @hideinitializer

- */

-#define PJ_CATCH(id)	    else if (pj_x_code__ == (id))

-

-/**

- * Catch any exception number.

- * @hideinitializer

- */

-#define PJ_DEFAULT	    else

-

-/**

- * End of exception specification block.

- * @hideinitializer

- */

-#define PJ_END			pj_pop_exception_handler_(); \

-			    } else {}

-

-/**

- * Throw exception.

- * @param exception_id  The exception number.

- * @hideinitializer

- */

-#define PJ_THROW(exception_id)	pj_throw_exception_(exception_id)

-

-/**

- * Get current exception.

- * @return      Current exception code.

- * @hideinitializer

- */

-#define PJ_GET_EXCEPTION()	(pj_x_code__)

-

-PJ_END_DECL

-

-

-

-#endif	/* __PJ_EXCEPTION_H__ */

-

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_EXCEPTION_H__
+#define __PJ_EXCEPTION_H__
+
+/**
+ * @file except.h
+ * @brief Exception Handling in C.
+ */
+
+#include <pj/types.h>
+#include <pj/compat/setjmp.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJ_EXCEPT Exception Handling
+ * @ingroup PJ_MISC
+ * @{
+ *
+ * \section pj_except_sample_sec Quick Example
+ *
+ * For the impatient, take a look at some examples:
+ *  - @ref page_pjlib_samples_except_c
+ *  - @ref page_pjlib_exception_test
+ *
+ * \section pj_except_except Exception Handling
+ *
+ * This module provides exception handling syntactically similar to C++ in
+ * C language. The underlying mechanism use setjmp() and longjmp(), and since
+ * these constructs are ANSI standard, the mechanism here should be available
+ * on most platforms/compilers which are ANSI compliant.
+ *
+ * If ANSI libc is not available, then setjmp()/longjmp() implementation will
+ * be provided. See <pj/compat/setjmp.h> for compatibility.
+ *
+ * The exception handling mechanism is completely thread safe, so the exception
+ * thrown by one thread will not interfere with other thread.
+ *
+ * CAVEATS:
+ *  - unlike C++ exception, the scheme here won't call destructors of local
+ *    objects if exception is thrown. Care must be taken when a function
+ *    hold some resorce such as pool or mutex etc.
+ *  - You CAN NOT make nested exception in one single function without using
+ *    a nested PJ_USE_EXCEPTION.
+ *  - Exceptions will always be caught by the first handle (unlike C++ where
+ *    exception is only caught if the type matches.
+ *
+ * The exception handling constructs are similar to C++. The blocks will be
+ * constructed similar to the following sample:
+ *
+ * \verbatim
+   #define NO_MEMORY     1
+   #define SYNTAX_ERROR  2
+  
+   int main()
+   {
+      PJ_USE_EXCEPTION;  // declare local exception stack.
+  
+      PJ_TRY {
+        ...// do something..
+      }
+      PJ_CATCH(NO_MEMORY) {
+        ... // handle exception 1
+      }
+      PJ_CATCH(SYNTAX_ERROR) {
+        ... // handle exception 2
+      }
+      PJ_DEFAULT {
+        ... // handle other exceptions.
+      }
+      PJ_END;
+   }
+   \endverbatim
+ *
+ * The above sample uses hard coded exception ID. It is @b strongly
+ * recommended that applications request a unique exception ID instead
+ * of hard coded value like above.
+ *
+ * \section pj_except_reg Exception ID Allocation
+ *
+ * To ensure that exception ID (number) are used consistently and to
+ * prevent ID collisions in an application, it is strongly suggested that 
+ * applications allocate an exception ID for each possible exception
+ * type. As a bonus of this process, the application can identify
+ * the name of the exception when the particular exception is thrown.
+ *
+ * Exception ID management are performed with the following APIs:
+ *  - #pj_exception_id_alloc().
+ *  - #pj_exception_id_free().
+ *  - #pj_exception_id_name().
+ *
+ *
+ * PJLIB itself automatically allocates one exception id, i.e.
+ * #PJ_NO_MEMORY_EXCEPTION which is declared in <pj/pool.h>. This exception
+ * ID is raised by default pool policy when it fails to allocate memory.
+ *
+ * \section PJ_EX_KEYWORDS Keywords
+ *
+ * \subsection PJ_THROW PJ_THROW(expression)
+ * Throw an exception. The expression thrown is an integer as the result of
+ * the \a expression. This keyword can be specified anywhere within the 
+ * program.
+ *
+ * \subsection PJ_USE_EXCEPTION PJ_USE_EXCEPTION
+ * Specify this in the variable definition section of the function block 
+ * (or any blocks) to specify that the block has \a PJ_TRY/PJ_CATCH exception 
+ * block. 
+ * Actually, this is just a macro to declare local variable which is used to
+ * push the exception state to the exception stack.
+ *
+ * \subsection PJ_TRY PJ_TRY
+ * The \a PJ_TRY keyword is typically followed by a block. If an exception is
+ * thrown in this block, then the execution will resume to the \a PJ_CATCH 
+ * handler.
+ *
+ * \subsection PJ_CATCH PJ_CATCH(expression)
+ * The \a PJ_CATCH is normally followed by a block. This block will be executed
+ * if the exception being thrown is equal to the expression specified in the
+ * \a PJ_CATCH.
+ *
+ * \subsection PJ_DEFAULT PJ_DEFAULT
+ * The \a PJ_DEFAULT keyword is normally followed by a block. This block will
+ * be executed if the exception being thrown doesn't match any of the \a
+ * PJ_CATCH specification. The \a PJ_DEFAULT block \b MUST be placed as the
+ * last block of the handlers.
+ *
+ * \subsection PJ_END PJ_END
+ * Specify this keyword to mark the end of \a PJ_TRY / \a PJ_CATCH blocks.
+ *
+ * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void)
+ * Get the last exception thrown. This macro is normally called inside the
+ * \a PJ_CATCH or \a PJ_DEFAULT block, altough it can be used anywhere where
+ * the \a PJ_USE_EXCEPTION definition is in scope.
+ *
+ * 
+ * \section pj_except_examples_sec Examples
+ *
+ * For some examples on how to use the exception construct, please see:
+ *  - @ref page_pjlib_samples_except_c
+ *  - @ref page_pjlib_exception_test
+ */
+
+/**
+ * Allocate a unique exception id.
+ * Applications don't have to allocate a unique exception ID before using
+ * the exception construct. However, by doing so it ensures that there is
+ * no collisions of exception ID.
+ *
+ * As a bonus, when exception number is acquired through this function,
+ * the library can assign name to the exception (only if 
+ * PJ_HAS_EXCEPTION_NAMES is enabled (default is yes)) and find out the
+ * exception name when it catches an exception.
+ *
+ * @param name      Name to be associated with the exception ID.
+ * @param id        Pointer to receive the ID.
+ *
+ * @return          PJ_SUCCESS on success or PJ_ETOOMANY if the library 
+ *                  is running out out ids.
+ */
+PJ_DECL(pj_status_t) pj_exception_id_alloc(const char *name,
+                                           pj_exception_id_t *id);
+
+/**
+ * Free an exception id.
+ *
+ * @param id        The exception ID.
+ *
+ * @return          PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_exception_id_free(pj_exception_id_t id);
+
+/**
+ * Retrieve name associated with the exception id.
+ *
+ * @param id        The exception ID.
+ *
+ * @return          The name associated with the specified ID.
+ */
+PJ_DECL(const char*) pj_exception_id_name(pj_exception_id_t id);
+
+
+/** @} */
+
+/**
+ * This structure (which should be invisible to user) manages the TRY handler
+ * stack.
+ */
+struct pj_exception_state_t
+{
+    struct pj_exception_state_t *prev;  /**< Previous state in the list. */
+    pj_jmp_buf state;                   /**< jmp_buf.                    */
+};
+
+/**
+ * Throw exception.
+ * @param id    Exception Id.
+ */
+PJ_DECL_NO_RETURN(void) 
+pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN;
+
+/**
+ * Push exception handler.
+ */
+PJ_DECL(void) pj_push_exception_handler_(struct pj_exception_state_t *rec);
+
+/**
+ * Pop exception handler.
+ */
+PJ_DECL(void) pj_pop_exception_handler_(void);
+
+/**
+ * Declare that the function will use exception.
+ * @hideinitializer
+ */
+#define PJ_USE_EXCEPTION    struct pj_exception_state_t pj_x_except__; int pj_x_code__
+
+/**
+ * Start exception specification block.
+ * @hideinitializer
+ */
+#define PJ_TRY		    if (1) { \
+				pj_push_exception_handler_(&pj_x_except__); \
+				pj_x_code__ = pj_setjmp(pj_x_except__.state); \
+				if (pj_x_code__ == 0)
+/**
+ * Catch the specified exception Id.
+ * @param id    The exception number to catch.
+ * @hideinitializer
+ */
+#define PJ_CATCH(id)	    else if (pj_x_code__ == (id))
+
+/**
+ * Catch any exception number.
+ * @hideinitializer
+ */
+#define PJ_DEFAULT	    else
+
+/**
+ * End of exception specification block.
+ * @hideinitializer
+ */
+#define PJ_END			pj_pop_exception_handler_(); \
+			    } else {}
+
+/**
+ * Throw exception.
+ * @param exception_id  The exception number.
+ * @hideinitializer
+ */
+#define PJ_THROW(exception_id)	pj_throw_exception_(exception_id)
+
+/**
+ * Get current exception.
+ * @return      Current exception code.
+ * @hideinitializer
+ */
+#define PJ_GET_EXCEPTION()	(pj_x_code__)
+
+PJ_END_DECL
+
+
+
+#endif	/* __PJ_EXCEPTION_H__ */
+
+
diff --git a/pjlib/include/pj/fifobuf.h b/pjlib/include/pj/fifobuf.h
index ee3a19a..59af013 100644
--- a/pjlib/include/pj/fifobuf.h
+++ b/pjlib/include/pj/fifobuf.h
@@ -1,43 +1,43 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_FIFOBUF_H__

-#define __PJ_FIFOBUF_H__

-

-#include <pj/types.h>

-

-PJ_BEGIN_DECL

-

-typedef struct pj_fifobuf_t pj_fifobuf_t;

-struct pj_fifobuf_t

-{

-    char *first, *last;

-    char *ubegin, *uend;

-    int full;

-};

-

-PJ_DECL(void)	     pj_fifobuf_init (pj_fifobuf_t *fb, void *buffer, unsigned size);

-PJ_DECL(unsigned)    pj_fifobuf_max_size (pj_fifobuf_t *fb);

-PJ_DECL(void*)	     pj_fifobuf_alloc (pj_fifobuf_t *fb, unsigned size);

-PJ_DECL(pj_status_t) pj_fifobuf_unalloc (pj_fifobuf_t *fb, void *buf);

-PJ_DECL(pj_status_t) pj_fifobuf_free (pj_fifobuf_t *fb, void *buf);

-

-PJ_END_DECL

-

-#endif	/* __PJ_FIFOBUF_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_FIFOBUF_H__
+#define __PJ_FIFOBUF_H__
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+typedef struct pj_fifobuf_t pj_fifobuf_t;
+struct pj_fifobuf_t
+{
+    char *first, *last;
+    char *ubegin, *uend;
+    int full;
+};
+
+PJ_DECL(void)	     pj_fifobuf_init (pj_fifobuf_t *fb, void *buffer, unsigned size);
+PJ_DECL(unsigned)    pj_fifobuf_max_size (pj_fifobuf_t *fb);
+PJ_DECL(void*)	     pj_fifobuf_alloc (pj_fifobuf_t *fb, unsigned size);
+PJ_DECL(pj_status_t) pj_fifobuf_unalloc (pj_fifobuf_t *fb, void *buf);
+PJ_DECL(pj_status_t) pj_fifobuf_free (pj_fifobuf_t *fb, void *buf);
+
+PJ_END_DECL
+
+#endif	/* __PJ_FIFOBUF_H__ */
+
diff --git a/pjlib/include/pj/file_access.h b/pjlib/include/pj/file_access.h
index efa7121..5eed23d 100644
--- a/pjlib/include/pj/file_access.h
+++ b/pjlib/include/pj/file_access.h
@@ -1,108 +1,108 @@
-/* $Id */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_FILE_ACCESS_H__

-#define __PJ_FILE_ACCESS_H__

-

-/**

- * @file file_access.h

- * @brief File manipulation and access.

- */

-#include <pj/types.h>

-

-PJ_BEGIN_DECL 

-

-/**

- * @defgroup PJ_FILE_ACCESS File Access

- * @ingroup PJ_IO

- * @{

- *

- */

-

-/**

- * This structure describes file information, to be obtained by

- * calling #pj_file_getstat(). The time information in this structure

- * is in local time.

- */

-typedef struct pj_file_stat

-{

-    pj_off_t        size;   /**< Total file size.               */

-    pj_time_val     atime;  /**< Time of last access.           */

-    pj_time_val     mtime;  /**< Time of last modification.     */

-    pj_time_val     ctime;  /**< Time of last creation.         */

-} pj_file_stat;

-

-

-/**

- * Returns non-zero if the specified file exists.

- *

- * @param filename      The file name.

- *

- * @return              Non-zero if the file exists.

- */

-PJ_DECL(pj_bool_t) pj_file_exists(const char *filename);

-

-/**

- * Returns the size of the file.

- *

- * @param filename      The file name.

- *

- * @return              The file size in bytes or -1 on error.

- */

-PJ_DECL(pj_off_t) pj_file_size(const char *filename);

-

-/**

- * Delete a file.

- *

- * @param filename      The filename.

- *

- * @return              PJ_SUCCESS on success or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_file_delete(const char *filename);

-

-/**

- * Move a \c oldname to \c newname. If \c newname already exists,

- * it will be overwritten.

- *

- * @param oldname       The file to rename.

- * @param newname       New filename to assign.

- *

- * @return              PJ_SUCCESS on success or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_file_move( const char *oldname, 

-                                   const char *newname);

-

-

-/**

- * Return information about the specified file. The time information in

- * the \c stat structure will be in local time.

- *

- * @param filename      The filename.

- * @param stat          Pointer to variable to receive file information.

- *

- * @return              PJ_SUCCESS on success or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat);

-

-

-/** @} */

-

-PJ_END_DECL

-

-

-#endif	/* __PJ_FILE_ACCESS_H__ */

+/* $Id */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_FILE_ACCESS_H__
+#define __PJ_FILE_ACCESS_H__
+
+/**
+ * @file file_access.h
+ * @brief File manipulation and access.
+ */
+#include <pj/types.h>
+
+PJ_BEGIN_DECL 
+
+/**
+ * @defgroup PJ_FILE_ACCESS File Access
+ * @ingroup PJ_IO
+ * @{
+ *
+ */
+
+/**
+ * This structure describes file information, to be obtained by
+ * calling #pj_file_getstat(). The time information in this structure
+ * is in local time.
+ */
+typedef struct pj_file_stat
+{
+    pj_off_t        size;   /**< Total file size.               */
+    pj_time_val     atime;  /**< Time of last access.           */
+    pj_time_val     mtime;  /**< Time of last modification.     */
+    pj_time_val     ctime;  /**< Time of last creation.         */
+} pj_file_stat;
+
+
+/**
+ * Returns non-zero if the specified file exists.
+ *
+ * @param filename      The file name.
+ *
+ * @return              Non-zero if the file exists.
+ */
+PJ_DECL(pj_bool_t) pj_file_exists(const char *filename);
+
+/**
+ * Returns the size of the file.
+ *
+ * @param filename      The file name.
+ *
+ * @return              The file size in bytes or -1 on error.
+ */
+PJ_DECL(pj_off_t) pj_file_size(const char *filename);
+
+/**
+ * Delete a file.
+ *
+ * @param filename      The filename.
+ *
+ * @return              PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_file_delete(const char *filename);
+
+/**
+ * Move a \c oldname to \c newname. If \c newname already exists,
+ * it will be overwritten.
+ *
+ * @param oldname       The file to rename.
+ * @param newname       New filename to assign.
+ *
+ * @return              PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_file_move( const char *oldname, 
+                                   const char *newname);
+
+
+/**
+ * Return information about the specified file. The time information in
+ * the \c stat structure will be in local time.
+ *
+ * @param filename      The filename.
+ * @param stat          Pointer to variable to receive file information.
+ *
+ * @return              PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat);
+
+
+/** @} */
+
+PJ_END_DECL
+
+
+#endif	/* __PJ_FILE_ACCESS_H__ */
diff --git a/pjlib/include/pj/file_io.h b/pjlib/include/pj/file_io.h
index e66c2cc..ea0e207 100644
--- a/pjlib/include/pj/file_io.h
+++ b/pjlib/include/pj/file_io.h
@@ -1,172 +1,172 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_FILE_IO_H__

-#define __PJ_FILE_IO_H__

-

-/**

- * @file file_io.h

- * @brief Simple file I/O abstraction.

- */

-#include <pj/types.h>

-

-PJ_BEGIN_DECL 

-

-/**

- * @defgroup PJ_FILE_IO File I/O

- * @ingroup PJ_IO

- * @{

- *

- * This file contains functionalities to perform file I/O. The file

- * I/O can be implemented with various back-end, either using native

- * file API or ANSI stream. 

- *

- * @section pj_file_size_limit_sec Size Limits

- *

- * There may be limitation on the size that can be handled by the

- * #pj_file_setpos() or #pj_file_getpos() functions. The API itself

- * uses 64-bit integer for the file offset/position (where available); 

- * however some backends (such as ANSI) may only support signed 32-bit 

- * offset resolution.

- *

- * Reading and writing operation uses signed 32-bit integer to indicate

- * the size.

- *

- *

- */

-

-/**

- * These enumerations are used when opening file. Values PJ_O_RDONLY,

- * PJ_O_WRONLY, and PJ_O_RDWR are mutually exclusive. Value PJ_O_APPEND

- * can only be used when the file is opened for writing. 

- */

-enum pj_file_access

-{

-    PJ_O_RDONLY     = 0x1101,   /**< Open file for reading.             */

-    PJ_O_WRONLY     = 0x1102,   /**< Open file for writing.             */

-    PJ_O_RDWR       = 0x1103,   /**< Open file for reading and writing. 

-                                     File will be truncated.            */

-    PJ_O_APPEND     = 0x1108,   /**< Append to existing file.           */

-};

-

-/**

- * The seek directive when setting the file position with #pj_file_setpos.

- */

-enum pj_file_seek_type

-{

-    PJ_SEEK_SET     = 0x1201,   /**< Offset from beginning of the file. */

-    PJ_SEEK_CUR     = 0x1202,   /**< Offset from current position.      */

-    PJ_SEEK_END     = 0x1203,   /**< Size of the file plus offset.      */

-};

-

-/**

- * Open the file as specified in \c pathname with the specified

- * mode, and return the handle in \c fd. All files will be opened

- * as binary.

- *

- * @param pool          Pool to allocate memory for the new file descriptor.

- * @param pathname      The file name to open.

- * @param flags         Open flags, which is bitmask combination of

- *                      #pj_file_access enum. The flag must be either

- *                      PJ_O_RDONLY, PJ_O_WRONLY, or PJ_O_RDWR. When file

- *                      writing is specified, existing file will be 

- *                      truncated unless PJ_O_APPEND is specified.

- * @param fd            The returned descriptor.

- *

- * @return              PJ_SUCCESS or the appropriate error code on error.

- */

-PJ_DECL(pj_status_t) pj_file_open(pj_pool_t *pool,

-                                  const char *pathname, 

-                                  unsigned flags,

-                                  pj_oshandle_t *fd);

-

-/**

- * Close an opened file descriptor.

- *

- * @param fd            The file descriptor.

- *

- * @return              PJ_SUCCESS or the appropriate error code on error.

- */

-PJ_DECL(pj_status_t) pj_file_close(pj_oshandle_t fd);

-

-/**

- * Write data with the specified size to an opened file.

- *

- * @param fd            The file descriptor.

- * @param data          Data to be written to the file.

- * @param size          On input, specifies the size of data to be written.

- *                      On return, it contains the number of data actually

- *                      written to the file.

- *

- * @return              PJ_SUCCESS or the appropriate error code on error.

- */

-PJ_DECL(pj_status_t) pj_file_write(pj_oshandle_t fd,

-                                   const void *data,

-                                   pj_ssize_t *size);

-

-/**

- * Read data from the specified file. When end-of-file condition is set,

- * this function will return PJ_SUCCESS but the size will contain zero.

- *

- * @param fd            The file descriptor.

- * @param data          Pointer to buffer to receive the data.

- * @param size          On input, specifies the maximum number of data to

- *                      read from the file. On output, it contains the size

- *                      of data actually read from the file. It will contain

- *                      zero when EOF occurs.

- *

- * @return              PJ_SUCCESS or the appropriate error code on error.

- *                      When EOF occurs, the return is PJ_SUCCESS but size

- *                      will report zero.

- */

-PJ_DECL(pj_status_t) pj_file_read(pj_oshandle_t fd,

-                                  void *data,

-                                  pj_ssize_t *size);

-

-/**

- * Set file position to new offset according to directive \c whence.

- *

- * @param fd            The file descriptor.

- * @param offset        The new file position to set.

- * @param whence        The directive.

- *

- * @return              PJ_SUCCESS or the appropriate error code on error.

- */

-PJ_DECL(pj_status_t) pj_file_setpos(pj_oshandle_t fd,

-                                    pj_off_t offset,

-                                    enum pj_file_seek_type whence);

-

-/**

- * Get current file position.

- *

- * @param fd            The file descriptor.

- * @param pos           On return contains the file position as measured

- *                      from the beginning of the file.

- *

- * @return              PJ_SUCCESS or the appropriate error code on error.

- */

-PJ_DECL(pj_status_t) pj_file_getpos(pj_oshandle_t fd,

-                                    pj_off_t *pos);

-

-/** @} */

-

-

-PJ_END_DECL

-

-#endif  /* __PJ_FILE_IO_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_FILE_IO_H__
+#define __PJ_FILE_IO_H__
+
+/**
+ * @file file_io.h
+ * @brief Simple file I/O abstraction.
+ */
+#include <pj/types.h>
+
+PJ_BEGIN_DECL 
+
+/**
+ * @defgroup PJ_FILE_IO File I/O
+ * @ingroup PJ_IO
+ * @{
+ *
+ * This file contains functionalities to perform file I/O. The file
+ * I/O can be implemented with various back-end, either using native
+ * file API or ANSI stream. 
+ *
+ * @section pj_file_size_limit_sec Size Limits
+ *
+ * There may be limitation on the size that can be handled by the
+ * #pj_file_setpos() or #pj_file_getpos() functions. The API itself
+ * uses 64-bit integer for the file offset/position (where available); 
+ * however some backends (such as ANSI) may only support signed 32-bit 
+ * offset resolution.
+ *
+ * Reading and writing operation uses signed 32-bit integer to indicate
+ * the size.
+ *
+ *
+ */
+
+/**
+ * These enumerations are used when opening file. Values PJ_O_RDONLY,
+ * PJ_O_WRONLY, and PJ_O_RDWR are mutually exclusive. Value PJ_O_APPEND
+ * can only be used when the file is opened for writing. 
+ */
+enum pj_file_access
+{
+    PJ_O_RDONLY     = 0x1101,   /**< Open file for reading.             */
+    PJ_O_WRONLY     = 0x1102,   /**< Open file for writing.             */
+    PJ_O_RDWR       = 0x1103,   /**< Open file for reading and writing. 
+                                     File will be truncated.            */
+    PJ_O_APPEND     = 0x1108,   /**< Append to existing file.           */
+};
+
+/**
+ * The seek directive when setting the file position with #pj_file_setpos.
+ */
+enum pj_file_seek_type
+{
+    PJ_SEEK_SET     = 0x1201,   /**< Offset from beginning of the file. */
+    PJ_SEEK_CUR     = 0x1202,   /**< Offset from current position.      */
+    PJ_SEEK_END     = 0x1203,   /**< Size of the file plus offset.      */
+};
+
+/**
+ * Open the file as specified in \c pathname with the specified
+ * mode, and return the handle in \c fd. All files will be opened
+ * as binary.
+ *
+ * @param pool          Pool to allocate memory for the new file descriptor.
+ * @param pathname      The file name to open.
+ * @param flags         Open flags, which is bitmask combination of
+ *                      #pj_file_access enum. The flag must be either
+ *                      PJ_O_RDONLY, PJ_O_WRONLY, or PJ_O_RDWR. When file
+ *                      writing is specified, existing file will be 
+ *                      truncated unless PJ_O_APPEND is specified.
+ * @param fd            The returned descriptor.
+ *
+ * @return              PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_open(pj_pool_t *pool,
+                                  const char *pathname, 
+                                  unsigned flags,
+                                  pj_oshandle_t *fd);
+
+/**
+ * Close an opened file descriptor.
+ *
+ * @param fd            The file descriptor.
+ *
+ * @return              PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_close(pj_oshandle_t fd);
+
+/**
+ * Write data with the specified size to an opened file.
+ *
+ * @param fd            The file descriptor.
+ * @param data          Data to be written to the file.
+ * @param size          On input, specifies the size of data to be written.
+ *                      On return, it contains the number of data actually
+ *                      written to the file.
+ *
+ * @return              PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_write(pj_oshandle_t fd,
+                                   const void *data,
+                                   pj_ssize_t *size);
+
+/**
+ * Read data from the specified file. When end-of-file condition is set,
+ * this function will return PJ_SUCCESS but the size will contain zero.
+ *
+ * @param fd            The file descriptor.
+ * @param data          Pointer to buffer to receive the data.
+ * @param size          On input, specifies the maximum number of data to
+ *                      read from the file. On output, it contains the size
+ *                      of data actually read from the file. It will contain
+ *                      zero when EOF occurs.
+ *
+ * @return              PJ_SUCCESS or the appropriate error code on error.
+ *                      When EOF occurs, the return is PJ_SUCCESS but size
+ *                      will report zero.
+ */
+PJ_DECL(pj_status_t) pj_file_read(pj_oshandle_t fd,
+                                  void *data,
+                                  pj_ssize_t *size);
+
+/**
+ * Set file position to new offset according to directive \c whence.
+ *
+ * @param fd            The file descriptor.
+ * @param offset        The new file position to set.
+ * @param whence        The directive.
+ *
+ * @return              PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_setpos(pj_oshandle_t fd,
+                                    pj_off_t offset,
+                                    enum pj_file_seek_type whence);
+
+/**
+ * Get current file position.
+ *
+ * @param fd            The file descriptor.
+ * @param pos           On return contains the file position as measured
+ *                      from the beginning of the file.
+ *
+ * @return              PJ_SUCCESS or the appropriate error code on error.
+ */
+PJ_DECL(pj_status_t) pj_file_getpos(pj_oshandle_t fd,
+                                    pj_off_t *pos);
+
+/** @} */
+
+
+PJ_END_DECL
+
+#endif  /* __PJ_FILE_IO_H__ */
+
diff --git a/pjlib/include/pj/guid.h b/pjlib/include/pj/guid.h
index 2fc9656..9c6d30b 100644
--- a/pjlib/include/pj/guid.h
+++ b/pjlib/include/pj/guid.h
@@ -1,91 +1,91 @@
-/* $Id */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_GUID_H__

-#define __PJ_GUID_H__

-

-

-/**

- * @file guid.h

- * @brief GUID Globally Unique Identifier.

- */

-#include <pj/types.h>

-

-

-PJ_BEGIN_DECL

-

-

-/**

- * @defgroup PJ_DS Data Structure.

- * @ingroup PJ

- */

-/**

- * @defgroup PJ_GUID Globally Unique Identifier

- * @ingroup PJ_DS

- * @{

- *

- * This module provides API to create string that is globally unique.

- * If application doesn't require that strong requirement, it can just

- * use #pj_create_random_string() instead.

- */

-

-

-/**

- * PJ_GUID_STRING_LENGTH specifies length of GUID string. The value is

- * dependent on the algorithm used internally to generate the GUID string.

- * If real GUID generator is used, then the length will be 128bit or 

- * 32 bytes. If shadow GUID generator is used, then the length

- * will be 20 bytes. Application should not assume which algorithm will

- * be used by GUID generator.

- */

-extern const unsigned PJ_GUID_STRING_LENGTH;

-

-/**

- * PJ_GUID_MAX_LENGTH specifies the maximum length of GUID string,

- * regardless of which algorithm to use.

- */

-#define PJ_GUID_MAX_LENGTH  32

-

-/**

- * Create a globally unique string, which length is PJ_GUID_STRING_LENGTH

- * characters. Caller is responsible for preallocating the storage used

- * in the string.

- *

- * @param str       The string to store the result.

- *

- * @return          The string.

- */

-PJ_DECL(pj_str_t*) pj_generate_unique_string(pj_str_t *str);

-

-/**

- * Generate a unique string.

- *

- * @param pool	    Pool to allocate memory from.

- * @param str	    The string.

- */

-PJ_DECL(void) pj_create_unique_string(pj_pool_t *pool, pj_str_t *str);

-

-

-/**

- * @}

- */

-

-PJ_END_DECL

-

-#endif/* __PJ_GUID_H__ */

-

+/* $Id */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_GUID_H__
+#define __PJ_GUID_H__
+
+
+/**
+ * @file guid.h
+ * @brief GUID Globally Unique Identifier.
+ */
+#include <pj/types.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJ_DS Data Structure.
+ * @ingroup PJ
+ */
+/**
+ * @defgroup PJ_GUID Globally Unique Identifier
+ * @ingroup PJ_DS
+ * @{
+ *
+ * This module provides API to create string that is globally unique.
+ * If application doesn't require that strong requirement, it can just
+ * use #pj_create_random_string() instead.
+ */
+
+
+/**
+ * PJ_GUID_STRING_LENGTH specifies length of GUID string. The value is
+ * dependent on the algorithm used internally to generate the GUID string.
+ * If real GUID generator is used, then the length will be 128bit or 
+ * 32 bytes. If shadow GUID generator is used, then the length
+ * will be 20 bytes. Application should not assume which algorithm will
+ * be used by GUID generator.
+ */
+extern const unsigned PJ_GUID_STRING_LENGTH;
+
+/**
+ * PJ_GUID_MAX_LENGTH specifies the maximum length of GUID string,
+ * regardless of which algorithm to use.
+ */
+#define PJ_GUID_MAX_LENGTH  32
+
+/**
+ * Create a globally unique string, which length is PJ_GUID_STRING_LENGTH
+ * characters. Caller is responsible for preallocating the storage used
+ * in the string.
+ *
+ * @param str       The string to store the result.
+ *
+ * @return          The string.
+ */
+PJ_DECL(pj_str_t*) pj_generate_unique_string(pj_str_t *str);
+
+/**
+ * Generate a unique string.
+ *
+ * @param pool	    Pool to allocate memory from.
+ * @param str	    The string.
+ */
+PJ_DECL(void) pj_create_unique_string(pj_pool_t *pool, pj_str_t *str);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif/* __PJ_GUID_H__ */
+
diff --git a/pjlib/include/pj/hash.h b/pjlib/include/pj/hash.h
index cee8e71..41c89bc 100644
--- a/pjlib/include/pj/hash.h
+++ b/pjlib/include/pj/hash.h
@@ -1,171 +1,171 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_HASH_H__

-#define __PJ_HASH_H__

-

-/**

- * @file hash.h

- * @brief Hash Table.

- */

-

-#include <pj/types.h>

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup PJ_HASH Hash Table

- * @ingroup PJ_DS

- * @{

- * A hash table is a dictionary in which keys are mapped to array positions by

- * hash functions. Having the keys of more than one item map to the same 

- * position is called a collision. In this library, we will chain the nodes

- * that have the same key in a list.

- */

-

-/**

- * If this constant is used as keylen, then the key is interpreted as

- * NULL terminated string.

- */

-#define PJ_HASH_KEY_STRING	((unsigned)-1)

-

-/**

- * This is the function that is used by the hash table to calculate hash value

- * of the specified key.

- *

- * @param hval	    the initial hash value, or zero.

- * @param key	    the key to calculate.

- * @param keylen    the length of the key, or PJ_HASH_KEY_STRING to treat 

- *		    the key as null terminated string.

- *

- * @return          the hash value.

- */

-PJ_DECL(pj_uint32_t) pj_hash_calc(pj_uint32_t hval, 

-				  const void *key, unsigned keylen);

-

-

-/**

- * Convert the key to lowercase and calculate the hash value. The resulting

- * string is stored in \c result.

- *

- * @param hval      The initial hash value, normally zero.

- * @param result    Buffer to store the result, which must be enough to hold

- *                  the string.

- * @param key       The input key to be converted and calculated.

- *

- * @return          The hash value.

- */

-PJ_DECL(pj_uint32_t) pj_hash_calc_tolower(pj_uint32_t hval,

-                                          char *result,

-                                          const pj_str_t *key);

-

-/**

- * Create a hash table with the specified 'bucket' size.

- *

- * @param pool	the pool from which the hash table will be allocated from.

- * @param size	the bucket size, which will be round-up to the nearest 2^n+1

- *

- * @return the hash table.

- */

-PJ_DECL(pj_hash_table_t*) pj_hash_create(pj_pool_t *pool, unsigned size);

-

-

-/**

- * Get the value associated with the specified key.

- *

- * @param ht	    the hash table.

- * @param key	    the key to look for.

- * @param keylen    the length of the key, or PJ_HASH_KEY_STRING to use the

- *		    string length of the key.

- *

- * @return the value associated with the key, or NULL if the key is not found.

- */

-PJ_DECL(void *) pj_hash_get( pj_hash_table_t *ht,

-			     const void *key, unsigned keylen );

-

-

-/**

- * Associate/disassociate a value with the specified key.

- *

- * @param pool	    the pool to allocate the new entry if a new entry has to be

- *		    created.

- * @param ht	    the hash table.

- * @param key	    the key.

- * @param keylen    the length of the key, or PJ_HASH_KEY_STRING to use the 

- *		    string length of the key.

- * @param value	    value to be associated, or NULL to delete the entry with

- *		    the specified key.

- */

-PJ_DECL(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht,

-			   const void *key, unsigned keylen,

-			   void *value );

-

-/**

- * Get the total number of entries in the hash table.

- *

- * @param ht	the hash table.

- *

- * @return the number of entries in the hash table.

- */

-PJ_DECL(unsigned) pj_hash_count( pj_hash_table_t *ht );

-

-

-/**

- * Get the iterator to the first element in the hash table. 

- *

- * @param ht	the hash table.

- * @param it	the iterator for iterating hash elements.

- *

- * @return the iterator to the hash element, or NULL if no element presents.

- */

-PJ_DECL(pj_hash_iterator_t*) pj_hash_first( pj_hash_table_t *ht,

-					    pj_hash_iterator_t *it );

-

-

-/**

- * Get the next element from the iterator.

- *

- * @param ht	the hash table.

- * @param it	the hash iterator.

- *

- * @return the next iterator, or NULL if there's no more element.

- */

-PJ_DECL(pj_hash_iterator_t*) pj_hash_next( pj_hash_table_t *ht, 

-					   pj_hash_iterator_t *it );

-

-/**

- * Get the value associated with a hash iterator.

- *

- * @param ht	the hash table.

- * @param it	the hash iterator.

- *

- * @return the value associated with the current element in iterator.

- */

-PJ_DECL(void*) pj_hash_this( pj_hash_table_t *ht,

-			     pj_hash_iterator_t *it );

-

-

-/**

- * @}

- */

-

-PJ_END_DECL

-

-#endif

-

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_HASH_H__
+#define __PJ_HASH_H__
+
+/**
+ * @file hash.h
+ * @brief Hash Table.
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_HASH Hash Table
+ * @ingroup PJ_DS
+ * @{
+ * A hash table is a dictionary in which keys are mapped to array positions by
+ * hash functions. Having the keys of more than one item map to the same 
+ * position is called a collision. In this library, we will chain the nodes
+ * that have the same key in a list.
+ */
+
+/**
+ * If this constant is used as keylen, then the key is interpreted as
+ * NULL terminated string.
+ */
+#define PJ_HASH_KEY_STRING	((unsigned)-1)
+
+/**
+ * This is the function that is used by the hash table to calculate hash value
+ * of the specified key.
+ *
+ * @param hval	    the initial hash value, or zero.
+ * @param key	    the key to calculate.
+ * @param keylen    the length of the key, or PJ_HASH_KEY_STRING to treat 
+ *		    the key as null terminated string.
+ *
+ * @return          the hash value.
+ */
+PJ_DECL(pj_uint32_t) pj_hash_calc(pj_uint32_t hval, 
+				  const void *key, unsigned keylen);
+
+
+/**
+ * Convert the key to lowercase and calculate the hash value. The resulting
+ * string is stored in \c result.
+ *
+ * @param hval      The initial hash value, normally zero.
+ * @param result    Buffer to store the result, which must be enough to hold
+ *                  the string.
+ * @param key       The input key to be converted and calculated.
+ *
+ * @return          The hash value.
+ */
+PJ_DECL(pj_uint32_t) pj_hash_calc_tolower(pj_uint32_t hval,
+                                          char *result,
+                                          const pj_str_t *key);
+
+/**
+ * Create a hash table with the specified 'bucket' size.
+ *
+ * @param pool	the pool from which the hash table will be allocated from.
+ * @param size	the bucket size, which will be round-up to the nearest 2^n+1
+ *
+ * @return the hash table.
+ */
+PJ_DECL(pj_hash_table_t*) pj_hash_create(pj_pool_t *pool, unsigned size);
+
+
+/**
+ * Get the value associated with the specified key.
+ *
+ * @param ht	    the hash table.
+ * @param key	    the key to look for.
+ * @param keylen    the length of the key, or PJ_HASH_KEY_STRING to use the
+ *		    string length of the key.
+ *
+ * @return the value associated with the key, or NULL if the key is not found.
+ */
+PJ_DECL(void *) pj_hash_get( pj_hash_table_t *ht,
+			     const void *key, unsigned keylen );
+
+
+/**
+ * Associate/disassociate a value with the specified key.
+ *
+ * @param pool	    the pool to allocate the new entry if a new entry has to be
+ *		    created.
+ * @param ht	    the hash table.
+ * @param key	    the key.
+ * @param keylen    the length of the key, or PJ_HASH_KEY_STRING to use the 
+ *		    string length of the key.
+ * @param value	    value to be associated, or NULL to delete the entry with
+ *		    the specified key.
+ */
+PJ_DECL(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht,
+			   const void *key, unsigned keylen,
+			   void *value );
+
+/**
+ * Get the total number of entries in the hash table.
+ *
+ * @param ht	the hash table.
+ *
+ * @return the number of entries in the hash table.
+ */
+PJ_DECL(unsigned) pj_hash_count( pj_hash_table_t *ht );
+
+
+/**
+ * Get the iterator to the first element in the hash table. 
+ *
+ * @param ht	the hash table.
+ * @param it	the iterator for iterating hash elements.
+ *
+ * @return the iterator to the hash element, or NULL if no element presents.
+ */
+PJ_DECL(pj_hash_iterator_t*) pj_hash_first( pj_hash_table_t *ht,
+					    pj_hash_iterator_t *it );
+
+
+/**
+ * Get the next element from the iterator.
+ *
+ * @param ht	the hash table.
+ * @param it	the hash iterator.
+ *
+ * @return the next iterator, or NULL if there's no more element.
+ */
+PJ_DECL(pj_hash_iterator_t*) pj_hash_next( pj_hash_table_t *ht, 
+					   pj_hash_iterator_t *it );
+
+/**
+ * Get the value associated with a hash iterator.
+ *
+ * @param ht	the hash table.
+ * @param it	the hash iterator.
+ *
+ * @return the value associated with the current element in iterator.
+ */
+PJ_DECL(void*) pj_hash_this( pj_hash_table_t *ht,
+			     pj_hash_iterator_t *it );
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif
+
+
diff --git a/pjlib/include/pj/ioqueue.h b/pjlib/include/pj/ioqueue.h
index 26484ca..86a5309 100644
--- a/pjlib/include/pj/ioqueue.h
+++ b/pjlib/include/pj/ioqueue.h
@@ -1,665 +1,665 @@
-/* $Id$

- */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_IOQUEUE_H__

-#define __PJ_IOQUEUE_H__

-

-/**

- * @file ioqueue.h

- * @brief I/O Dispatching Mechanism

- */

-

-#include <pj/types.h>

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup PJ_IO Input/Output

- * @brief Input/Output

- * @ingroup PJ_OS

- *

- * This section contains API building blocks to perform network I/O and 

- * communications. If provides:

- *  - @ref PJ_SOCK

- *\n

- *    A highly portable socket abstraction, runs on all kind of

- *    network APIs such as standard BSD socket, Windows socket, Linux

- *    \b kernel socket, PalmOS networking API, etc.

- *

- *  - @ref pj_addr_resolve

- *\n

- *    Portable address resolution, which implements #pj_gethostbyname().

- *

- *  - @ref PJ_SOCK_SELECT

- *\n

- *    A portable \a select() like API (#pj_sock_select()) which can be

- *    implemented with various back-ends.

- *

- *  - @ref PJ_IOQUEUE

- *\n

- *    Framework for dispatching network events.

- *

- * For more information see the modules below.

- */

-

-/**

- * @defgroup PJ_IOQUEUE I/O Event Dispatching Queue

- * @ingroup PJ_IO

- * @{

- *

- * I/O Queue provides API for performing asynchronous I/O operations. It

- * conforms to proactor pattern, which allows application to submit an

- * asynchronous operation and to be notified later when the operation has

- * completed.

- *

- * The I/O Queue can work on both socket and file descriptors. For 

- * asynchronous file operations however, one must make sure that the correct

- * file I/O back-end is used, because not all file I/O back-end can be

- * used with the ioqueue. Please see \ref PJ_FILE_IO for more details.

- *

- * The framework works natively in platforms where asynchronous operation API

- * exists, such as in Windows NT with IoCompletionPort/IOCP. In other 

- * platforms, the I/O queue abstracts the operating system's event poll API

- * to provide semantics similar to IoCompletionPort with minimal penalties

- * (i.e. per ioqueue and per handle mutex protection).

- *

- * The I/O queue provides more than just unified abstraction. It also:

- *  - makes sure that the operation uses the most effective way to utilize

- *    the underlying mechanism, to achieve the maximum theoritical

- *    throughput possible on a given platform.

- *  - choose the most efficient mechanism for event polling on a given

- *    platform.

- *

- * Currently, the I/O Queue is implemented using:

- *  - <tt><b>select()</b></tt>, as the common denominator, but the least 

- *    efficient. Also the number of descriptor is limited to 

- *    \c PJ_IOQUEUE_MAX_HANDLES (which by default is 64).

- *  - <tt><b>/dev/epoll</b></tt> on Linux (user mode and kernel mode), 

- *    a much faster replacement for select() on Linux (and more importantly

- *    doesn't have limitation on number of descriptors).

- *  - <b>I/O Completion ports</b> on Windows NT/2000/XP, which is the most 

- *    efficient way to dispatch events in Windows NT based OSes, and most 

- *    importantly, it doesn't have the limit on how many handles to monitor.

- *    And it works with files (not only sockets) as well.

- *

- *

- * \section pj_ioqueue_concurrency_sec Concurrency Rules

- *

- * The items below describe rules that must be obeyed when using the I/O 

- * queue, with regard to concurrency:

- *  - simultaneous operations (by different threads) to different key is safe.

- *  - simultaneous operations to the same key is also safe, except

- *    <b>unregistration</b>, which is described below.

- *  - <b>care must be taken when unregistering a key</b> from the

- *    ioqueue. Application must take care that when one thread is issuing

- *    an unregistration, other thread is not simultaneously invoking an

- *    operation <b>to the same key</b>.

- *\n

- *    This happens because the ioqueue functions are working with a pointer

- *    to the key, and there is a possible race condition where the pointer

- *    has been rendered invalid by other threads before the ioqueue has a

- *    chance to acquire mutex on it.

- *

- * \section pj_ioqeuue_examples_sec Examples

- *

- * For some examples on how to use the I/O Queue, please see:

- *

- *  - \ref page_pjlib_ioqueue_tcp_test

- *  - \ref page_pjlib_ioqueue_udp_test

- *  - \ref page_pjlib_ioqueue_perf_test

- */

-

-

-/**

- * This structure describes operation specific key to be submitted to

- * I/O Queue when performing the asynchronous operation. This key will

- * be returned to the application when completion callback is called.

- *

- * Application normally wants to attach it's specific data in the

- * \c user_data field so that it can keep track of which operation has

- * completed when the callback is called. Alternatively, application can

- * also extend this struct to include its data, because the pointer that

- * is returned in the completion callback will be exactly the same as

- * the pointer supplied when the asynchronous function is called.

- */

-typedef struct pj_ioqueue_op_key_t

-{ 

-    void *internal__[32];           /**< Internal I/O Queue data.   */

-    void *user_data;                /**< Application data.          */

-} pj_ioqueue_op_key_t;

-

-/**

- * This structure describes the callbacks to be called when I/O operation

- * completes.

- */

-typedef struct pj_ioqueue_callback

-{

-    /**

-     * This callback is called when #pj_ioqueue_recv or #pj_ioqueue_recvfrom

-     * completes.

-     *

-     * @param key	    The key.

-     * @param op_key        Operation key.

-     * @param bytes_read    >= 0 to indicate the amount of data read, 

-     *                      otherwise negative value containing the error

-     *                      code. To obtain the pj_status_t error code, use

-     *                      (pj_status_t code = -bytes_read).

-     */

-    void (*on_read_complete)(pj_ioqueue_key_t *key, 

-                             pj_ioqueue_op_key_t *op_key, 

-                             pj_ssize_t bytes_read);

-

-    /**

-     * This callback is called when #pj_ioqueue_write or #pj_ioqueue_sendto

-     * completes.

-     *

-     * @param key	    The key.

-     * @param op_key        Operation key.

-     * @param bytes_sent    >= 0 to indicate the amount of data written, 

-     *                      otherwise negative value containing the error

-     *                      code. To obtain the pj_status_t error code, use

-     *                      (pj_status_t code = -bytes_sent).

-     */

-    void (*on_write_complete)(pj_ioqueue_key_t *key, 

-                              pj_ioqueue_op_key_t *op_key, 

-                              pj_ssize_t bytes_sent);

-

-    /**

-     * This callback is called when #pj_ioqueue_accept completes.

-     *

-     * @param key	    The key.

-     * @param op_key        Operation key.

-     * @param sock          Newly connected socket.

-     * @param status	    Zero if the operation completes successfully.

-     */

-    void (*on_accept_complete)(pj_ioqueue_key_t *key, 

-                               pj_ioqueue_op_key_t *op_key, 

-                               pj_sock_t sock, 

-                               pj_status_t status);

-

-    /**

-     * This callback is called when #pj_ioqueue_connect completes.

-     *

-     * @param key	    The key.

-     * @param status	    PJ_SUCCESS if the operation completes successfully.

-     */

-    void (*on_connect_complete)(pj_ioqueue_key_t *key, 

-                                pj_status_t status);

-} pj_ioqueue_callback;

-

-

-/**

- * Types of pending I/O Queue operation. This enumeration is only used

- * internally within the ioqueue.

- */

-typedef enum pj_ioqueue_operation_e

-{

-    PJ_IOQUEUE_OP_NONE		= 0,	/**< No operation.          */

-    PJ_IOQUEUE_OP_READ		= 1,	/**< read() operation.      */

-    PJ_IOQUEUE_OP_RECV          = 2,    /**< recv() operation.      */

-    PJ_IOQUEUE_OP_RECV_FROM	= 4,	/**< recvfrom() operation.  */

-    PJ_IOQUEUE_OP_WRITE		= 8,	/**< write() operation.     */

-    PJ_IOQUEUE_OP_SEND          = 16,   /**< send() operation.      */

-    PJ_IOQUEUE_OP_SEND_TO	= 32,	/**< sendto() operation.    */

-#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0

-    PJ_IOQUEUE_OP_ACCEPT	= 64,	/**< accept() operation.    */

-    PJ_IOQUEUE_OP_CONNECT	= 128,	/**< connect() operation.   */

-#endif	/* PJ_HAS_TCP */

-} pj_ioqueue_operation_e;

-

-

-/**

- * This macro specifies the maximum number of events that can be

- * processed by the ioqueue on a single poll cycle, on implementation

- * that supports it. The value is only meaningfull when specified

- * during PJLIB build.

- */

-#ifndef PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL

-#   define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL     (16)

-#endif

-

-/**

- * When this flag is specified in ioqueue's recv() or send() operations,

- * the ioqueue will always mark the operation as asynchronous.

- */

-#define PJ_IOQUEUE_ALWAYS_ASYNC	    ((pj_uint32_t)1 << (pj_uint32_t)31)

-

-/**

- * Return the name of the ioqueue implementation.

- *

- * @return		Implementation name.

- */

-PJ_DECL(const char*) pj_ioqueue_name(void);

-

-

-/**

- * Create a new I/O Queue framework.

- *

- * @param pool		The pool to allocate the I/O queue structure. 

- * @param max_fd	The maximum number of handles to be supported, which 

- *			should not exceed PJ_IOQUEUE_MAX_HANDLES.

- * @param ioqueue	Pointer to hold the newly created I/O Queue.

- *

- * @return		PJ_SUCCESS on success.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_create( pj_pool_t *pool, 

-					pj_size_t max_fd,

-					pj_ioqueue_t **ioqueue);

-

-/**

- * Destroy the I/O queue.

- *

- * @param ioque	        The I/O Queue to be destroyed.

- *

- * @return              PJ_SUCCESS if success.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioque );

-

-/**

- * Set the lock object to be used by the I/O Queue. This function can only

- * be called right after the I/O queue is created, before any handle is

- * registered to the I/O queue.

- *

- * Initially the I/O queue is created with non-recursive mutex protection. 

- * Applications can supply alternative lock to be used by calling this 

- * function.

- *

- * @param ioque         The ioqueue instance.

- * @param lock          The lock to be used by the ioqueue.

- * @param auto_delete   In non-zero, the lock will be deleted by the ioqueue.

- *

- * @return              PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioque, 

-					  pj_lock_t *lock,

-					  pj_bool_t auto_delete );

-

-/**

- * Register a socket to the I/O queue framework. 

- * When a socket is registered to the IOQueue, it may be modified to use

- * non-blocking IO. If it is modified, there is no guarantee that this 

- * modification will be restored after the socket is unregistered.

- *

- * @param pool	    To allocate the resource for the specified handle, 

- *		    which must be valid until the handle/key is unregistered 

- *		    from I/O Queue.

- * @param ioque	    The I/O Queue.

- * @param sock	    The socket.

- * @param user_data User data to be associated with the key, which can be

- *		    retrieved later.

- * @param cb	    Callback to be called when I/O operation completes. 

- * @param key       Pointer to receive the key to be associated with this

- *                  socket. Subsequent I/O queue operation will need this

- *                  key.

- *

- * @return	    PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,

-					       pj_ioqueue_t *ioque,

-					       pj_sock_t sock,

-					       void *user_data,

-					       const pj_ioqueue_callback *cb,

-                                               pj_ioqueue_key_t **key );

-

-/**

- * Unregister from the I/O Queue framework. Caller must make sure that

- * the key doesn't have any pending operations before calling this function,

- * by calling #pj_ioqueue_is_pending() for all previously submitted

- * operations except asynchronous connect, and if necessary call

- * #pj_ioqueue_post_completion() to cancel the pending operations.

- *

- * Note that asynchronous connect operation will automatically be 

- * cancelled during the unregistration.

- *

- * @param key	    The key that was previously obtained from registration.

- *

- * @return          PJ_SUCCESS on success or the error code.

- *

- * @see pj_ioqueue_is_pending

- */

-PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key );

-

-

-/**

- * Get user data associated with an ioqueue key.

- *

- * @param key	    The key that was previously obtained from registration.

- *

- * @return          The user data associated with the descriptor, or NULL 

- *                  on error or if no data is associated with the key during

- *                  registration.

- */

-PJ_DECL(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key );

-

-/**

- * Set or change the user data to be associated with the file descriptor or

- * handle or socket descriptor.

- *

- * @param key	    The key that was previously obtained from registration.

- * @param user_data User data to be associated with the descriptor.

- * @param old_data  Optional parameter to retrieve the old user data.

- *

- * @return          PJ_SUCCESS on success or the error code.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,

-                                               void *user_data,

-                                               void **old_data);

-

-

-/**

- * Initialize operation key.

- *

- * @param op_key    The operation key to be initialied.

- * @param size	    The size of the operation key.

- */

-PJ_DECL(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,

-				      pj_size_t size );

-

-/**

- * Check if operation is pending on the specified operation key.

- * The \c op_key must have been initialized with #pj_ioqueue_op_key_init() 

- * or submitted as pending operation before, or otherwise the result 

- * is undefined.

- *

- * @param key       The key.

- * @param op_key    The operation key, previously submitted to any of

- *                  the I/O functions and has returned PJ_EPENDING.

- *

- * @return          Non-zero if operation is still pending.

- */

-PJ_DECL(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key,

-                                          pj_ioqueue_op_key_t *op_key );

-

-

-/**

- * Post completion status to the specified operation key and call the

- * appropriate callback. When the callback is called, the number of bytes 

- * received in read/write callback or the status in accept/connect callback

- * will be set from the \c bytes_status parameter.

- *

- * @param key           The key.

- * @param op_key        Pending operation key.

- * @param bytes_status  Number of bytes or status to be set. A good value

- *                      to put here is -PJ_ECANCELLED.

- *

- * @return              PJ_SUCCESS if completion status has been successfully

- *                      sent.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key,

-                                                 pj_ioqueue_op_key_t *op_key,

-                                                 pj_ssize_t bytes_status );

-

-

-

-#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0

-/**

- * Instruct I/O Queue to accept incoming connection on the specified 

- * listening socket. This function will return immediately (i.e. non-blocking)

- * regardless whether a connection is immediately available. If the function

- * can't complete immediately, the caller will be notified about the incoming

- * connection when it calls pj_ioqueue_poll(). If a new connection is

- * immediately available, the function returns PJ_SUCCESS with the new

- * connection; in this case, the callback WILL NOT be called.

- *

- * @param key	    The key which registered to the server socket.

- * @param op_key    An operation specific key to be associated with the

- *                  pending operation, so that application can keep track of

- *                  which operation has been completed when the callback is

- *                  called.

- * @param new_sock  Argument which contain pointer to receive the new socket

- *                  for the incoming connection.

- * @param local	    Optional argument which contain pointer to variable to 

- *                  receive local address.

- * @param remote    Optional argument which contain pointer to variable to 

- *                  receive the remote address.

- * @param addrlen   On input, contains the length of the buffer for the

- *		    address, and on output, contains the actual length of the

- *		    address. This argument is optional.

- * @return

- *  - PJ_SUCCESS    When connection is available immediately, and the 

- *                  parameters will be updated to contain information about 

- *                  the new connection. In this case, a completion callback

- *                  WILL NOT be called.

- *  - PJ_EPENDING   If no connection is available immediately. When a new

- *                  connection arrives, the callback will be called.

- *  - non-zero      which indicates the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key,

-                                        pj_ioqueue_op_key_t *op_key,

-					pj_sock_t *sock,

-					pj_sockaddr_t *local,

-					pj_sockaddr_t *remote,

-					int *addrlen );

-

-/**

- * Initiate non-blocking socket connect. If the socket can NOT be connected

- * immediately, asynchronous connect() will be scheduled and caller will be

- * notified via completion callback when it calls pj_ioqueue_poll(). If

- * socket is connected immediately, the function returns PJ_SUCCESS and

- * completion callback WILL NOT be called.

- *

- * @param key	    The key associated with TCP socket

- * @param addr	    The remote address.

- * @param addrlen   The remote address length.

- *

- * @return

- *  - PJ_SUCCESS    If socket is connected immediately. In this case, the

- *                  completion callback WILL NOT be called.

- *  - PJ_EPENDING   If operation is queued, or 

- *  - non-zero      Indicates the error code.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,

-					 const pj_sockaddr_t *addr,

-					 int addrlen );

-

-#endif	/* PJ_HAS_TCP */

-

-/**

- * Poll the I/O Queue for completed events.

- *

- * @param ioque		the I/O Queue.

- * @param timeout	polling timeout, or NULL if the thread wishes to wait

- *			indefinetely for the event.

- *

- * @return 

- *  - zero if timed out (no event).

- *  - (<0) if error occured during polling. Callback will NOT be called.

- *  - (>1) to indicate numbers of events. Callbacks have been called.

- */

-PJ_DECL(int) pj_ioqueue_poll( pj_ioqueue_t *ioque,

-			      const pj_time_val *timeout);

-

-

-/**

- * Instruct the I/O Queue to read from the specified handle. This function

- * returns immediately (i.e. non-blocking) regardless whether some data has 

- * been transfered. If the operation can't complete immediately, caller will 

- * be notified about the completion when it calls pj_ioqueue_poll(). If data

- * is immediately available, the function will return PJ_SUCCESS and the

- * callback WILL NOT be called.

- *

- * @param key	    The key that uniquely identifies the handle.

- * @param op_key    An operation specific key to be associated with the

- *                  pending operation, so that application can keep track of

- *                  which operation has been completed when the callback is

- *                  called. Caller must make sure that this key remains 

- *                  valid until the function completes.

- * @param buffer    The buffer to hold the read data. The caller MUST make sure

- *		    that this buffer remain valid until the framework completes

- *		    reading the handle.

- * @param length    On input, it specifies the size of the buffer. If data is

- *                  available to be read immediately, the function returns

- *                  PJ_SUCCESS and this argument will be filled with the

- *                  amount of data read. If the function is pending, caller

- *                  will be notified about the amount of data read in the

- *                  callback. This parameter can point to local variable in

- *                  caller's stack and doesn't have to remain valid for the

- *                  duration of pending operation.

- * @param flags     Recv flag. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then

- *		    the function will never return PJ_SUCCESS.

- *

- * @return

- *  - PJ_SUCCESS    If immediate data has been received in the buffer. In this

- *                  case, the callback WILL NOT be called.

- *  - PJ_EPENDING   If the operation has been queued, and the callback will be

- *                  called when data has been received.

- *  - non-zero      The return value indicates the error code.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key,

-                                      pj_ioqueue_op_key_t *op_key,

-				      void *buffer,

-				      pj_ssize_t *length,

-				      pj_uint32_t flags );

-

-/**

- * This function behaves similarly as #pj_ioqueue_recv(), except that it is

- * normally called for socket, and the remote address will also be returned

- * along with the data. Caller MUST make sure that both buffer and addr

- * remain valid until the framework completes reading the data.

- *

- * @param key	    The key that uniquely identifies the handle.

- * @param op_key    An operation specific key to be associated with the

- *                  pending operation, so that application can keep track of

- *                  which operation has been completed when the callback is

- *                  called.

- * @param buffer    The buffer to hold the read data. The caller MUST make sure

- *		    that this buffer remain valid until the framework completes

- *		    reading the handle.

- * @param length    On input, it specifies the size of the buffer. If data is

- *                  available to be read immediately, the function returns

- *                  PJ_SUCCESS and this argument will be filled with the

- *                  amount of data read. If the function is pending, caller

- *                  will be notified about the amount of data read in the

- *                  callback. This parameter can point to local variable in

- *                  caller's stack and doesn't have to remain valid for the

- *                  duration of pending operation.

- * @param flags     Recv flag. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then

- *		    the function will never return PJ_SUCCESS.

- * @param addr      Optional Pointer to buffer to receive the address.

- * @param addrlen   On input, specifies the length of the address buffer.

- *                  On output, it will be filled with the actual length of

- *                  the address. This argument can be NULL if \c addr is not

- *                  specified.

- *

- * @return

- *  - PJ_SUCCESS    If immediate data has been received. In this case, the 

- *		    callback must have been called before this function 

- *		    returns, and no pending operation is scheduled.

- *  - PJ_EPENDING   If the operation has been queued.

- *  - non-zero      The return value indicates the error code.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key,

-                                          pj_ioqueue_op_key_t *op_key,

-					  void *buffer,

-					  pj_ssize_t *length,

-                                          pj_uint32_t flags,

-					  pj_sockaddr_t *addr,

-					  int *addrlen);

-

-/**

- * Instruct the I/O Queue to write to the handle. This function will return

- * immediately (i.e. non-blocking) regardless whether some data has been 

- * transfered. If the function can't complete immediately, the caller will

- * be notified about the completion when it calls pj_ioqueue_poll(). If 

- * operation completes immediately and data has been transfered, the function

- * returns PJ_SUCCESS and the callback will NOT be called.

- *

- * @param key	    The key that identifies the handle.

- * @param op_key    An operation specific key to be associated with the

- *                  pending operation, so that application can keep track of

- *                  which operation has been completed when the callback is

- *                  called.

- * @param data	    The data to send. Caller MUST make sure that this buffer 

- *		    remains valid until the write operation completes.

- * @param length    On input, it specifies the length of data to send. When

- *                  data was sent immediately, this function returns PJ_SUCCESS

- *                  and this parameter contains the length of data sent. If

- *                  data can not be sent immediately, an asynchronous operation

- *                  is scheduled and caller will be notified via callback the

- *                  number of bytes sent. This parameter can point to local 

- *                  variable on caller's stack and doesn't have to remain 

- *                  valid until the operation has completed.

- * @param flags     Send flags. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then

- *		    the function will never return PJ_SUCCESS.

- *

- * @return

- *  - PJ_SUCCESS    If data was immediately transfered. In this case, no

- *                  pending operation has been scheduled and the callback

- *                  WILL NOT be called.

- *  - PJ_EPENDING   If the operation has been queued. Once data base been

- *                  transfered, the callback will be called.

- *  - non-zero      The return value indicates the error code.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key,

-                                      pj_ioqueue_op_key_t *op_key,

-				      const void *data,

-				      pj_ssize_t *length,

-				      pj_uint32_t flags );

-

-

-/**

- * Instruct the I/O Queue to write to the handle. This function will return

- * immediately (i.e. non-blocking) regardless whether some data has been 

- * transfered. If the function can't complete immediately, the caller will

- * be notified about the completion when it calls pj_ioqueue_poll(). If 

- * operation completes immediately and data has been transfered, the function

- * returns PJ_SUCCESS and the callback will NOT be called.

- *

- * @param key	    the key that identifies the handle.

- * @param op_key    An operation specific key to be associated with the

- *                  pending operation, so that application can keep track of

- *                  which operation has been completed when the callback is

- *                  called.

- * @param data	    the data to send. Caller MUST make sure that this buffer 

- *		    remains valid until the write operation completes.

- * @param length    On input, it specifies the length of data to send. When

- *                  data was sent immediately, this function returns PJ_SUCCESS

- *                  and this parameter contains the length of data sent. If

- *                  data can not be sent immediately, an asynchronous operation

- *                  is scheduled and caller will be notified via callback the

- *                  number of bytes sent. This parameter can point to local 

- *                  variable on caller's stack and doesn't have to remain 

- *                  valid until the operation has completed.

- * @param flags     send flags. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then

- *		    the function will never return PJ_SUCCESS.

- * @param addr      Optional remote address.

- * @param addrlen   Remote address length, \c addr is specified.

- *

- * @return

- *  - PJ_SUCCESS    If data was immediately written.

- *  - PJ_EPENDING   If the operation has been queued.

- *  - non-zero      The return value indicates the error code.

- */

-PJ_DECL(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,

-                                        pj_ioqueue_op_key_t *op_key,

-					const void *data,

-					pj_ssize_t *length,

-                                        pj_uint32_t flags,

-					const pj_sockaddr_t *addr,

-					int addrlen);

-

-

-/**

- * !}

- */

-

-PJ_END_DECL

-

-#endif	/* __PJ_IOQUEUE_H__ */

-

+/* $Id$
+ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_IOQUEUE_H__
+#define __PJ_IOQUEUE_H__
+
+/**
+ * @file ioqueue.h
+ * @brief I/O Dispatching Mechanism
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_IO Input/Output
+ * @brief Input/Output
+ * @ingroup PJ_OS
+ *
+ * This section contains API building blocks to perform network I/O and 
+ * communications. If provides:
+ *  - @ref PJ_SOCK
+ *\n
+ *    A highly portable socket abstraction, runs on all kind of
+ *    network APIs such as standard BSD socket, Windows socket, Linux
+ *    \b kernel socket, PalmOS networking API, etc.
+ *
+ *  - @ref pj_addr_resolve
+ *\n
+ *    Portable address resolution, which implements #pj_gethostbyname().
+ *
+ *  - @ref PJ_SOCK_SELECT
+ *\n
+ *    A portable \a select() like API (#pj_sock_select()) which can be
+ *    implemented with various back-ends.
+ *
+ *  - @ref PJ_IOQUEUE
+ *\n
+ *    Framework for dispatching network events.
+ *
+ * For more information see the modules below.
+ */
+
+/**
+ * @defgroup PJ_IOQUEUE I/O Event Dispatching Queue
+ * @ingroup PJ_IO
+ * @{
+ *
+ * I/O Queue provides API for performing asynchronous I/O operations. It
+ * conforms to proactor pattern, which allows application to submit an
+ * asynchronous operation and to be notified later when the operation has
+ * completed.
+ *
+ * The I/O Queue can work on both socket and file descriptors. For 
+ * asynchronous file operations however, one must make sure that the correct
+ * file I/O back-end is used, because not all file I/O back-end can be
+ * used with the ioqueue. Please see \ref PJ_FILE_IO for more details.
+ *
+ * The framework works natively in platforms where asynchronous operation API
+ * exists, such as in Windows NT with IoCompletionPort/IOCP. In other 
+ * platforms, the I/O queue abstracts the operating system's event poll API
+ * to provide semantics similar to IoCompletionPort with minimal penalties
+ * (i.e. per ioqueue and per handle mutex protection).
+ *
+ * The I/O queue provides more than just unified abstraction. It also:
+ *  - makes sure that the operation uses the most effective way to utilize
+ *    the underlying mechanism, to achieve the maximum theoritical
+ *    throughput possible on a given platform.
+ *  - choose the most efficient mechanism for event polling on a given
+ *    platform.
+ *
+ * Currently, the I/O Queue is implemented using:
+ *  - <tt><b>select()</b></tt>, as the common denominator, but the least 
+ *    efficient. Also the number of descriptor is limited to 
+ *    \c PJ_IOQUEUE_MAX_HANDLES (which by default is 64).
+ *  - <tt><b>/dev/epoll</b></tt> on Linux (user mode and kernel mode), 
+ *    a much faster replacement for select() on Linux (and more importantly
+ *    doesn't have limitation on number of descriptors).
+ *  - <b>I/O Completion ports</b> on Windows NT/2000/XP, which is the most 
+ *    efficient way to dispatch events in Windows NT based OSes, and most 
+ *    importantly, it doesn't have the limit on how many handles to monitor.
+ *    And it works with files (not only sockets) as well.
+ *
+ *
+ * \section pj_ioqueue_concurrency_sec Concurrency Rules
+ *
+ * The items below describe rules that must be obeyed when using the I/O 
+ * queue, with regard to concurrency:
+ *  - simultaneous operations (by different threads) to different key is safe.
+ *  - simultaneous operations to the same key is also safe, except
+ *    <b>unregistration</b>, which is described below.
+ *  - <b>care must be taken when unregistering a key</b> from the
+ *    ioqueue. Application must take care that when one thread is issuing
+ *    an unregistration, other thread is not simultaneously invoking an
+ *    operation <b>to the same key</b>.
+ *\n
+ *    This happens because the ioqueue functions are working with a pointer
+ *    to the key, and there is a possible race condition where the pointer
+ *    has been rendered invalid by other threads before the ioqueue has a
+ *    chance to acquire mutex on it.
+ *
+ * \section pj_ioqeuue_examples_sec Examples
+ *
+ * For some examples on how to use the I/O Queue, please see:
+ *
+ *  - \ref page_pjlib_ioqueue_tcp_test
+ *  - \ref page_pjlib_ioqueue_udp_test
+ *  - \ref page_pjlib_ioqueue_perf_test
+ */
+
+
+/**
+ * This structure describes operation specific key to be submitted to
+ * I/O Queue when performing the asynchronous operation. This key will
+ * be returned to the application when completion callback is called.
+ *
+ * Application normally wants to attach it's specific data in the
+ * \c user_data field so that it can keep track of which operation has
+ * completed when the callback is called. Alternatively, application can
+ * also extend this struct to include its data, because the pointer that
+ * is returned in the completion callback will be exactly the same as
+ * the pointer supplied when the asynchronous function is called.
+ */
+typedef struct pj_ioqueue_op_key_t
+{ 
+    void *internal__[32];           /**< Internal I/O Queue data.   */
+    void *user_data;                /**< Application data.          */
+} pj_ioqueue_op_key_t;
+
+/**
+ * This structure describes the callbacks to be called when I/O operation
+ * completes.
+ */
+typedef struct pj_ioqueue_callback
+{
+    /**
+     * This callback is called when #pj_ioqueue_recv or #pj_ioqueue_recvfrom
+     * completes.
+     *
+     * @param key	    The key.
+     * @param op_key        Operation key.
+     * @param bytes_read    >= 0 to indicate the amount of data read, 
+     *                      otherwise negative value containing the error
+     *                      code. To obtain the pj_status_t error code, use
+     *                      (pj_status_t code = -bytes_read).
+     */
+    void (*on_read_complete)(pj_ioqueue_key_t *key, 
+                             pj_ioqueue_op_key_t *op_key, 
+                             pj_ssize_t bytes_read);
+
+    /**
+     * This callback is called when #pj_ioqueue_write or #pj_ioqueue_sendto
+     * completes.
+     *
+     * @param key	    The key.
+     * @param op_key        Operation key.
+     * @param bytes_sent    >= 0 to indicate the amount of data written, 
+     *                      otherwise negative value containing the error
+     *                      code. To obtain the pj_status_t error code, use
+     *                      (pj_status_t code = -bytes_sent).
+     */
+    void (*on_write_complete)(pj_ioqueue_key_t *key, 
+                              pj_ioqueue_op_key_t *op_key, 
+                              pj_ssize_t bytes_sent);
+
+    /**
+     * This callback is called when #pj_ioqueue_accept completes.
+     *
+     * @param key	    The key.
+     * @param op_key        Operation key.
+     * @param sock          Newly connected socket.
+     * @param status	    Zero if the operation completes successfully.
+     */
+    void (*on_accept_complete)(pj_ioqueue_key_t *key, 
+                               pj_ioqueue_op_key_t *op_key, 
+                               pj_sock_t sock, 
+                               pj_status_t status);
+
+    /**
+     * This callback is called when #pj_ioqueue_connect completes.
+     *
+     * @param key	    The key.
+     * @param status	    PJ_SUCCESS if the operation completes successfully.
+     */
+    void (*on_connect_complete)(pj_ioqueue_key_t *key, 
+                                pj_status_t status);
+} pj_ioqueue_callback;
+
+
+/**
+ * Types of pending I/O Queue operation. This enumeration is only used
+ * internally within the ioqueue.
+ */
+typedef enum pj_ioqueue_operation_e
+{
+    PJ_IOQUEUE_OP_NONE		= 0,	/**< No operation.          */
+    PJ_IOQUEUE_OP_READ		= 1,	/**< read() operation.      */
+    PJ_IOQUEUE_OP_RECV          = 2,    /**< recv() operation.      */
+    PJ_IOQUEUE_OP_RECV_FROM	= 4,	/**< recvfrom() operation.  */
+    PJ_IOQUEUE_OP_WRITE		= 8,	/**< write() operation.     */
+    PJ_IOQUEUE_OP_SEND          = 16,   /**< send() operation.      */
+    PJ_IOQUEUE_OP_SEND_TO	= 32,	/**< sendto() operation.    */
+#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0
+    PJ_IOQUEUE_OP_ACCEPT	= 64,	/**< accept() operation.    */
+    PJ_IOQUEUE_OP_CONNECT	= 128,	/**< connect() operation.   */
+#endif	/* PJ_HAS_TCP */
+} pj_ioqueue_operation_e;
+
+
+/**
+ * This macro specifies the maximum number of events that can be
+ * processed by the ioqueue on a single poll cycle, on implementation
+ * that supports it. The value is only meaningfull when specified
+ * during PJLIB build.
+ */
+#ifndef PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL
+#   define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL     (16)
+#endif
+
+/**
+ * When this flag is specified in ioqueue's recv() or send() operations,
+ * the ioqueue will always mark the operation as asynchronous.
+ */
+#define PJ_IOQUEUE_ALWAYS_ASYNC	    ((pj_uint32_t)1 << (pj_uint32_t)31)
+
+/**
+ * Return the name of the ioqueue implementation.
+ *
+ * @return		Implementation name.
+ */
+PJ_DECL(const char*) pj_ioqueue_name(void);
+
+
+/**
+ * Create a new I/O Queue framework.
+ *
+ * @param pool		The pool to allocate the I/O queue structure. 
+ * @param max_fd	The maximum number of handles to be supported, which 
+ *			should not exceed PJ_IOQUEUE_MAX_HANDLES.
+ * @param ioqueue	Pointer to hold the newly created I/O Queue.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_create( pj_pool_t *pool, 
+					pj_size_t max_fd,
+					pj_ioqueue_t **ioqueue);
+
+/**
+ * Destroy the I/O queue.
+ *
+ * @param ioque	        The I/O Queue to be destroyed.
+ *
+ * @return              PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioque );
+
+/**
+ * Set the lock object to be used by the I/O Queue. This function can only
+ * be called right after the I/O queue is created, before any handle is
+ * registered to the I/O queue.
+ *
+ * Initially the I/O queue is created with non-recursive mutex protection. 
+ * Applications can supply alternative lock to be used by calling this 
+ * function.
+ *
+ * @param ioque         The ioqueue instance.
+ * @param lock          The lock to be used by the ioqueue.
+ * @param auto_delete   In non-zero, the lock will be deleted by the ioqueue.
+ *
+ * @return              PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioque, 
+					  pj_lock_t *lock,
+					  pj_bool_t auto_delete );
+
+/**
+ * Register a socket to the I/O queue framework. 
+ * When a socket is registered to the IOQueue, it may be modified to use
+ * non-blocking IO. If it is modified, there is no guarantee that this 
+ * modification will be restored after the socket is unregistered.
+ *
+ * @param pool	    To allocate the resource for the specified handle, 
+ *		    which must be valid until the handle/key is unregistered 
+ *		    from I/O Queue.
+ * @param ioque	    The I/O Queue.
+ * @param sock	    The socket.
+ * @param user_data User data to be associated with the key, which can be
+ *		    retrieved later.
+ * @param cb	    Callback to be called when I/O operation completes. 
+ * @param key       Pointer to receive the key to be associated with this
+ *                  socket. Subsequent I/O queue operation will need this
+ *                  key.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,
+					       pj_ioqueue_t *ioque,
+					       pj_sock_t sock,
+					       void *user_data,
+					       const pj_ioqueue_callback *cb,
+                                               pj_ioqueue_key_t **key );
+
+/**
+ * Unregister from the I/O Queue framework. Caller must make sure that
+ * the key doesn't have any pending operations before calling this function,
+ * by calling #pj_ioqueue_is_pending() for all previously submitted
+ * operations except asynchronous connect, and if necessary call
+ * #pj_ioqueue_post_completion() to cancel the pending operations.
+ *
+ * Note that asynchronous connect operation will automatically be 
+ * cancelled during the unregistration.
+ *
+ * @param key	    The key that was previously obtained from registration.
+ *
+ * @return          PJ_SUCCESS on success or the error code.
+ *
+ * @see pj_ioqueue_is_pending
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key );
+
+
+/**
+ * Get user data associated with an ioqueue key.
+ *
+ * @param key	    The key that was previously obtained from registration.
+ *
+ * @return          The user data associated with the descriptor, or NULL 
+ *                  on error or if no data is associated with the key during
+ *                  registration.
+ */
+PJ_DECL(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key );
+
+/**
+ * Set or change the user data to be associated with the file descriptor or
+ * handle or socket descriptor.
+ *
+ * @param key	    The key that was previously obtained from registration.
+ * @param user_data User data to be associated with the descriptor.
+ * @param old_data  Optional parameter to retrieve the old user data.
+ *
+ * @return          PJ_SUCCESS on success or the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,
+                                               void *user_data,
+                                               void **old_data);
+
+
+/**
+ * Initialize operation key.
+ *
+ * @param op_key    The operation key to be initialied.
+ * @param size	    The size of the operation key.
+ */
+PJ_DECL(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,
+				      pj_size_t size );
+
+/**
+ * Check if operation is pending on the specified operation key.
+ * The \c op_key must have been initialized with #pj_ioqueue_op_key_init() 
+ * or submitted as pending operation before, or otherwise the result 
+ * is undefined.
+ *
+ * @param key       The key.
+ * @param op_key    The operation key, previously submitted to any of
+ *                  the I/O functions and has returned PJ_EPENDING.
+ *
+ * @return          Non-zero if operation is still pending.
+ */
+PJ_DECL(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key,
+                                          pj_ioqueue_op_key_t *op_key );
+
+
+/**
+ * Post completion status to the specified operation key and call the
+ * appropriate callback. When the callback is called, the number of bytes 
+ * received in read/write callback or the status in accept/connect callback
+ * will be set from the \c bytes_status parameter.
+ *
+ * @param key           The key.
+ * @param op_key        Pending operation key.
+ * @param bytes_status  Number of bytes or status to be set. A good value
+ *                      to put here is -PJ_ECANCELLED.
+ *
+ * @return              PJ_SUCCESS if completion status has been successfully
+ *                      sent.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key,
+                                                 pj_ioqueue_op_key_t *op_key,
+                                                 pj_ssize_t bytes_status );
+
+
+
+#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0
+/**
+ * Instruct I/O Queue to accept incoming connection on the specified 
+ * listening socket. This function will return immediately (i.e. non-blocking)
+ * regardless whether a connection is immediately available. If the function
+ * can't complete immediately, the caller will be notified about the incoming
+ * connection when it calls pj_ioqueue_poll(). If a new connection is
+ * immediately available, the function returns PJ_SUCCESS with the new
+ * connection; in this case, the callback WILL NOT be called.
+ *
+ * @param key	    The key which registered to the server socket.
+ * @param op_key    An operation specific key to be associated with the
+ *                  pending operation, so that application can keep track of
+ *                  which operation has been completed when the callback is
+ *                  called.
+ * @param new_sock  Argument which contain pointer to receive the new socket
+ *                  for the incoming connection.
+ * @param local	    Optional argument which contain pointer to variable to 
+ *                  receive local address.
+ * @param remote    Optional argument which contain pointer to variable to 
+ *                  receive the remote address.
+ * @param addrlen   On input, contains the length of the buffer for the
+ *		    address, and on output, contains the actual length of the
+ *		    address. This argument is optional.
+ * @return
+ *  - PJ_SUCCESS    When connection is available immediately, and the 
+ *                  parameters will be updated to contain information about 
+ *                  the new connection. In this case, a completion callback
+ *                  WILL NOT be called.
+ *  - PJ_EPENDING   If no connection is available immediately. When a new
+ *                  connection arrives, the callback will be called.
+ *  - non-zero      which indicates the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key,
+                                        pj_ioqueue_op_key_t *op_key,
+					pj_sock_t *sock,
+					pj_sockaddr_t *local,
+					pj_sockaddr_t *remote,
+					int *addrlen );
+
+/**
+ * Initiate non-blocking socket connect. If the socket can NOT be connected
+ * immediately, asynchronous connect() will be scheduled and caller will be
+ * notified via completion callback when it calls pj_ioqueue_poll(). If
+ * socket is connected immediately, the function returns PJ_SUCCESS and
+ * completion callback WILL NOT be called.
+ *
+ * @param key	    The key associated with TCP socket
+ * @param addr	    The remote address.
+ * @param addrlen   The remote address length.
+ *
+ * @return
+ *  - PJ_SUCCESS    If socket is connected immediately. In this case, the
+ *                  completion callback WILL NOT be called.
+ *  - PJ_EPENDING   If operation is queued, or 
+ *  - non-zero      Indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,
+					 const pj_sockaddr_t *addr,
+					 int addrlen );
+
+#endif	/* PJ_HAS_TCP */
+
+/**
+ * Poll the I/O Queue for completed events.
+ *
+ * @param ioque		the I/O Queue.
+ * @param timeout	polling timeout, or NULL if the thread wishes to wait
+ *			indefinetely for the event.
+ *
+ * @return 
+ *  - zero if timed out (no event).
+ *  - (<0) if error occured during polling. Callback will NOT be called.
+ *  - (>1) to indicate numbers of events. Callbacks have been called.
+ */
+PJ_DECL(int) pj_ioqueue_poll( pj_ioqueue_t *ioque,
+			      const pj_time_val *timeout);
+
+
+/**
+ * Instruct the I/O Queue to read from the specified handle. This function
+ * returns immediately (i.e. non-blocking) regardless whether some data has 
+ * been transfered. If the operation can't complete immediately, caller will 
+ * be notified about the completion when it calls pj_ioqueue_poll(). If data
+ * is immediately available, the function will return PJ_SUCCESS and the
+ * callback WILL NOT be called.
+ *
+ * @param key	    The key that uniquely identifies the handle.
+ * @param op_key    An operation specific key to be associated with the
+ *                  pending operation, so that application can keep track of
+ *                  which operation has been completed when the callback is
+ *                  called. Caller must make sure that this key remains 
+ *                  valid until the function completes.
+ * @param buffer    The buffer to hold the read data. The caller MUST make sure
+ *		    that this buffer remain valid until the framework completes
+ *		    reading the handle.
+ * @param length    On input, it specifies the size of the buffer. If data is
+ *                  available to be read immediately, the function returns
+ *                  PJ_SUCCESS and this argument will be filled with the
+ *                  amount of data read. If the function is pending, caller
+ *                  will be notified about the amount of data read in the
+ *                  callback. This parameter can point to local variable in
+ *                  caller's stack and doesn't have to remain valid for the
+ *                  duration of pending operation.
+ * @param flags     Recv flag. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then
+ *		    the function will never return PJ_SUCCESS.
+ *
+ * @return
+ *  - PJ_SUCCESS    If immediate data has been received in the buffer. In this
+ *                  case, the callback WILL NOT be called.
+ *  - PJ_EPENDING   If the operation has been queued, and the callback will be
+ *                  called when data has been received.
+ *  - non-zero      The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key,
+                                      pj_ioqueue_op_key_t *op_key,
+				      void *buffer,
+				      pj_ssize_t *length,
+				      pj_uint32_t flags );
+
+/**
+ * This function behaves similarly as #pj_ioqueue_recv(), except that it is
+ * normally called for socket, and the remote address will also be returned
+ * along with the data. Caller MUST make sure that both buffer and addr
+ * remain valid until the framework completes reading the data.
+ *
+ * @param key	    The key that uniquely identifies the handle.
+ * @param op_key    An operation specific key to be associated with the
+ *                  pending operation, so that application can keep track of
+ *                  which operation has been completed when the callback is
+ *                  called.
+ * @param buffer    The buffer to hold the read data. The caller MUST make sure
+ *		    that this buffer remain valid until the framework completes
+ *		    reading the handle.
+ * @param length    On input, it specifies the size of the buffer. If data is
+ *                  available to be read immediately, the function returns
+ *                  PJ_SUCCESS and this argument will be filled with the
+ *                  amount of data read. If the function is pending, caller
+ *                  will be notified about the amount of data read in the
+ *                  callback. This parameter can point to local variable in
+ *                  caller's stack and doesn't have to remain valid for the
+ *                  duration of pending operation.
+ * @param flags     Recv flag. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then
+ *		    the function will never return PJ_SUCCESS.
+ * @param addr      Optional Pointer to buffer to receive the address.
+ * @param addrlen   On input, specifies the length of the address buffer.
+ *                  On output, it will be filled with the actual length of
+ *                  the address. This argument can be NULL if \c addr is not
+ *                  specified.
+ *
+ * @return
+ *  - PJ_SUCCESS    If immediate data has been received. In this case, the 
+ *		    callback must have been called before this function 
+ *		    returns, and no pending operation is scheduled.
+ *  - PJ_EPENDING   If the operation has been queued.
+ *  - non-zero      The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key,
+                                          pj_ioqueue_op_key_t *op_key,
+					  void *buffer,
+					  pj_ssize_t *length,
+                                          pj_uint32_t flags,
+					  pj_sockaddr_t *addr,
+					  int *addrlen);
+
+/**
+ * Instruct the I/O Queue to write to the handle. This function will return
+ * immediately (i.e. non-blocking) regardless whether some data has been 
+ * transfered. If the function can't complete immediately, the caller will
+ * be notified about the completion when it calls pj_ioqueue_poll(). If 
+ * operation completes immediately and data has been transfered, the function
+ * returns PJ_SUCCESS and the callback will NOT be called.
+ *
+ * @param key	    The key that identifies the handle.
+ * @param op_key    An operation specific key to be associated with the
+ *                  pending operation, so that application can keep track of
+ *                  which operation has been completed when the callback is
+ *                  called.
+ * @param data	    The data to send. Caller MUST make sure that this buffer 
+ *		    remains valid until the write operation completes.
+ * @param length    On input, it specifies the length of data to send. When
+ *                  data was sent immediately, this function returns PJ_SUCCESS
+ *                  and this parameter contains the length of data sent. If
+ *                  data can not be sent immediately, an asynchronous operation
+ *                  is scheduled and caller will be notified via callback the
+ *                  number of bytes sent. This parameter can point to local 
+ *                  variable on caller's stack and doesn't have to remain 
+ *                  valid until the operation has completed.
+ * @param flags     Send flags. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then
+ *		    the function will never return PJ_SUCCESS.
+ *
+ * @return
+ *  - PJ_SUCCESS    If data was immediately transfered. In this case, no
+ *                  pending operation has been scheduled and the callback
+ *                  WILL NOT be called.
+ *  - PJ_EPENDING   If the operation has been queued. Once data base been
+ *                  transfered, the callback will be called.
+ *  - non-zero      The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key,
+                                      pj_ioqueue_op_key_t *op_key,
+				      const void *data,
+				      pj_ssize_t *length,
+				      pj_uint32_t flags );
+
+
+/**
+ * Instruct the I/O Queue to write to the handle. This function will return
+ * immediately (i.e. non-blocking) regardless whether some data has been 
+ * transfered. If the function can't complete immediately, the caller will
+ * be notified about the completion when it calls pj_ioqueue_poll(). If 
+ * operation completes immediately and data has been transfered, the function
+ * returns PJ_SUCCESS and the callback will NOT be called.
+ *
+ * @param key	    the key that identifies the handle.
+ * @param op_key    An operation specific key to be associated with the
+ *                  pending operation, so that application can keep track of
+ *                  which operation has been completed when the callback is
+ *                  called.
+ * @param data	    the data to send. Caller MUST make sure that this buffer 
+ *		    remains valid until the write operation completes.
+ * @param length    On input, it specifies the length of data to send. When
+ *                  data was sent immediately, this function returns PJ_SUCCESS
+ *                  and this parameter contains the length of data sent. If
+ *                  data can not be sent immediately, an asynchronous operation
+ *                  is scheduled and caller will be notified via callback the
+ *                  number of bytes sent. This parameter can point to local 
+ *                  variable on caller's stack and doesn't have to remain 
+ *                  valid until the operation has completed.
+ * @param flags     send flags. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then
+ *		    the function will never return PJ_SUCCESS.
+ * @param addr      Optional remote address.
+ * @param addrlen   Remote address length, \c addr is specified.
+ *
+ * @return
+ *  - PJ_SUCCESS    If data was immediately written.
+ *  - PJ_EPENDING   If the operation has been queued.
+ *  - non-zero      The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,
+                                        pj_ioqueue_op_key_t *op_key,
+					const void *data,
+					pj_ssize_t *length,
+                                        pj_uint32_t flags,
+					const pj_sockaddr_t *addr,
+					int addrlen);
+
+
+/**
+ * !}
+ */
+
+PJ_END_DECL
+
+#endif	/* __PJ_IOQUEUE_H__ */
+
diff --git a/pjlib/include/pj/list.h b/pjlib/include/pj/list.h
index 5aca688..fc0223c 100644
--- a/pjlib/include/pj/list.h
+++ b/pjlib/include/pj/list.h
@@ -1,236 +1,236 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_LIST_H__

-#define __PJ_LIST_H__

-

-/**

- * @file list.h

- * @brief Linked List data structure.

- */

-

-#include <pj/types.h>

-

-PJ_BEGIN_DECL

-

-/*

- * @defgroup PJ_DS Data Structure.

- * @ingroup PJ

- */

-

-/**

- * @defgroup PJ_LIST Linked List

- * @ingroup PJ_DS

- * @{

- *

- * List in PJLIB is implemented as doubly-linked list, and it won't require

- * dynamic memory allocation (just as all PJLIB data structures). The list here

- * should be viewed more like a low level C list instead of high level C++ list

- * (which normally are easier to use but require dynamic memory allocations),

- * therefore all caveats with C list apply here too (such as you can NOT put

- * a node in more than one lists).

- *

- * \section pj_list_example_sec Examples

- *

- * See below for examples on how to manipulate linked list:

- *  - @ref page_pjlib_samples_list_c

- *  - @ref page_pjlib_list_test

- */

-

-

-/**

- * Use this macro in the start of the structure declaration to declare that

- * the structure can be used in the linked list operation. This macro simply

- * declares additional member @a prev and @a next to the structure.

- * @hideinitializer

- */

-#define PJ_DECL_LIST_MEMBER(type)                       \

-                                   /** List @a prev. */ \

-                                   type *prev;          \

-                                   /** List @a next. */ \

-                                   type *next 

-

-

-/**

- * This structure describes generic list node and list. The owner of this list

- * must initialize the 'value' member to an appropriate value (typically the

- * owner itself).

- */

-struct pj_list

-{

-    PJ_DECL_LIST_MEMBER(void);

-};

-

-

-/**

- * Initialize the list.

- * Initially, the list will have no member, and function pj_list_empty() will

- * always return nonzero (which indicates TRUE) for the newly initialized 

- * list.

- *

- * @param node The list head.

- */

-PJ_INLINE(void) pj_list_init(pj_list_type * node)

-{

-    ((pj_list*)node)->next = ((pj_list*)node)->prev = node;

-}

-

-

-/**

- * Check that the list is empty.

- *

- * @param node	The list head.

- *

- * @return Non-zero if the list is not-empty, or zero if it is empty.

- *

- */

-PJ_INLINE(int) pj_list_empty(const pj_list_type * node)

-{

-    return ((pj_list*)node)->next == node;

-}

-

-

-/**

- * Insert the node to the list before the specified element position.

- *

- * @param pos	The element to which the node will be inserted before. 

- * @param node	The element to be inserted.

- *

- * @return void.

- */

-PJ_IDECL(void)	pj_list_insert_before(pj_list_type *pos, pj_list_type *node);

-

-

-/**

- * Inserts all nodes in \a nodes to the target list.

- *

- * @param lst	    The target list.

- * @param nodes	    Nodes list.

- */

-PJ_IDECL(void) pj_list_insert_nodes_before(pj_list_type *lst,

-					   pj_list_type *nodes);

-

-/**

- * Insert a node to the list after the specified element position.

- *

- * @param pos	    The element in the list which will precede the inserted 

- *		    element.

- * @param node	    The element to be inserted after the position element.

- *

- * @return void.

- */

-PJ_IDECL(void) pj_list_insert_after(pj_list_type *pos, pj_list_type *node);

-

-/**

- * Insert all nodes in \a nodes to the target list.

- *

- * @param lst	    The target list.

- * @param nodes	    Nodes list.

- */

-PJ_IDECL(void) pj_list_insert_nodes_after(pj_list_type *lst,

-					  pj_list_type *nodes);

-

-

-/**

- * Remove elements from the source list, and insert them to the destination

- * list. The elements of the source list will occupy the

- * front elements of the target list. Note that the node pointed by \a list2

- * itself is not considered as a node, but rather as the list descriptor, so

- * it will not be inserted to the \a list1. The elements to be inserted starts

- * at \a list2->next. If \a list2 is to be included in the operation, use

- * \a pj_list_insert_nodes_before.

- *

- * @param list1	The destination list.

- * @param list2	The source list.

- *

- * @return void.

- */

-PJ_IDECL(void) pj_list_merge_first(pj_list_type *list1, pj_list_type *list2);

-

-

-/**

- * Remove elements from the second list argument, and insert them to the list 

- * in the first argument. The elements from the second list will be appended

- * to the first list. Note that the node pointed by \a list2

- * itself is not considered as a node, but rather as the list descriptor, so

- * it will not be inserted to the \a list1. The elements to be inserted starts

- * at \a list2->next. If \a list2 is to be included in the operation, use

- * \a pj_list_insert_nodes_before.

- *

- * @param list1	    The element in the list which will precede the inserted 

- *		    element.

- * @param list2	    The element in the list to be inserted.

- *

- * @return void.

- */

-PJ_IDECL(void) pj_list_merge_last( pj_list_type *list1, pj_list_type *list2);

-

-

-/**

- * Erase the node from the list it currently belongs.

- *

- * @param node	    The element to be erased.

- */

-PJ_IDECL(void) pj_list_erase(pj_list_type *node);

-

-

-/**

- * Find node in the list.

- *

- * @param list	    The list head.

- * @param node	    The node element to be searched.

- *

- * @return The node itself if it is found in the list, or NULL if it is not 

- *         found in the list.

- */

-PJ_IDECL(pj_list_type*) pj_list_find_node(pj_list_type *list, 

-					  pj_list_type *node);

-

-

-/**

- * Search the list for the specified value, using the specified comparison

- * function. This function iterates on nodes in the list, started with the

- * first node, and call the user supplied comparison function until the

- * comparison function returns ZERO.

- *

- * @param list	    The list head.

- * @param value	    The user defined value to be passed in the comparison 

- *		    function

- * @param comp	    The comparison function, which should return ZERO to 

- *		    indicate that the searched value is found.

- *

- * @return The first node that matched, or NULL if it is not found.

- */

-PJ_IDECL(pj_list_type*) pj_list_search(pj_list_type *list, void *value,

-				       int (*comp)(void *value, 

-						   const pj_list_type *node)

-				       );

-

-

-/**

- * @}

- */

-

-#if PJ_FUNCTIONS_ARE_INLINED

-#  include "list_i.h"

-#endif

-

-PJ_END_DECL

-

-#endif	/* __PJ_LIST_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_LIST_H__
+#define __PJ_LIST_H__
+
+/**
+ * @file list.h
+ * @brief Linked List data structure.
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/*
+ * @defgroup PJ_DS Data Structure.
+ * @ingroup PJ
+ */
+
+/**
+ * @defgroup PJ_LIST Linked List
+ * @ingroup PJ_DS
+ * @{
+ *
+ * List in PJLIB is implemented as doubly-linked list, and it won't require
+ * dynamic memory allocation (just as all PJLIB data structures). The list here
+ * should be viewed more like a low level C list instead of high level C++ list
+ * (which normally are easier to use but require dynamic memory allocations),
+ * therefore all caveats with C list apply here too (such as you can NOT put
+ * a node in more than one lists).
+ *
+ * \section pj_list_example_sec Examples
+ *
+ * See below for examples on how to manipulate linked list:
+ *  - @ref page_pjlib_samples_list_c
+ *  - @ref page_pjlib_list_test
+ */
+
+
+/**
+ * Use this macro in the start of the structure declaration to declare that
+ * the structure can be used in the linked list operation. This macro simply
+ * declares additional member @a prev and @a next to the structure.
+ * @hideinitializer
+ */
+#define PJ_DECL_LIST_MEMBER(type)                       \
+                                   /** List @a prev. */ \
+                                   type *prev;          \
+                                   /** List @a next. */ \
+                                   type *next 
+
+
+/**
+ * This structure describes generic list node and list. The owner of this list
+ * must initialize the 'value' member to an appropriate value (typically the
+ * owner itself).
+ */
+struct pj_list
+{
+    PJ_DECL_LIST_MEMBER(void);
+};
+
+
+/**
+ * Initialize the list.
+ * Initially, the list will have no member, and function pj_list_empty() will
+ * always return nonzero (which indicates TRUE) for the newly initialized 
+ * list.
+ *
+ * @param node The list head.
+ */
+PJ_INLINE(void) pj_list_init(pj_list_type * node)
+{
+    ((pj_list*)node)->next = ((pj_list*)node)->prev = node;
+}
+
+
+/**
+ * Check that the list is empty.
+ *
+ * @param node	The list head.
+ *
+ * @return Non-zero if the list is not-empty, or zero if it is empty.
+ *
+ */
+PJ_INLINE(int) pj_list_empty(const pj_list_type * node)
+{
+    return ((pj_list*)node)->next == node;
+}
+
+
+/**
+ * Insert the node to the list before the specified element position.
+ *
+ * @param pos	The element to which the node will be inserted before. 
+ * @param node	The element to be inserted.
+ *
+ * @return void.
+ */
+PJ_IDECL(void)	pj_list_insert_before(pj_list_type *pos, pj_list_type *node);
+
+
+/**
+ * Inserts all nodes in \a nodes to the target list.
+ *
+ * @param lst	    The target list.
+ * @param nodes	    Nodes list.
+ */
+PJ_IDECL(void) pj_list_insert_nodes_before(pj_list_type *lst,
+					   pj_list_type *nodes);
+
+/**
+ * Insert a node to the list after the specified element position.
+ *
+ * @param pos	    The element in the list which will precede the inserted 
+ *		    element.
+ * @param node	    The element to be inserted after the position element.
+ *
+ * @return void.
+ */
+PJ_IDECL(void) pj_list_insert_after(pj_list_type *pos, pj_list_type *node);
+
+/**
+ * Insert all nodes in \a nodes to the target list.
+ *
+ * @param lst	    The target list.
+ * @param nodes	    Nodes list.
+ */
+PJ_IDECL(void) pj_list_insert_nodes_after(pj_list_type *lst,
+					  pj_list_type *nodes);
+
+
+/**
+ * Remove elements from the source list, and insert them to the destination
+ * list. The elements of the source list will occupy the
+ * front elements of the target list. Note that the node pointed by \a list2
+ * itself is not considered as a node, but rather as the list descriptor, so
+ * it will not be inserted to the \a list1. The elements to be inserted starts
+ * at \a list2->next. If \a list2 is to be included in the operation, use
+ * \a pj_list_insert_nodes_before.
+ *
+ * @param list1	The destination list.
+ * @param list2	The source list.
+ *
+ * @return void.
+ */
+PJ_IDECL(void) pj_list_merge_first(pj_list_type *list1, pj_list_type *list2);
+
+
+/**
+ * Remove elements from the second list argument, and insert them to the list 
+ * in the first argument. The elements from the second list will be appended
+ * to the first list. Note that the node pointed by \a list2
+ * itself is not considered as a node, but rather as the list descriptor, so
+ * it will not be inserted to the \a list1. The elements to be inserted starts
+ * at \a list2->next. If \a list2 is to be included in the operation, use
+ * \a pj_list_insert_nodes_before.
+ *
+ * @param list1	    The element in the list which will precede the inserted 
+ *		    element.
+ * @param list2	    The element in the list to be inserted.
+ *
+ * @return void.
+ */
+PJ_IDECL(void) pj_list_merge_last( pj_list_type *list1, pj_list_type *list2);
+
+
+/**
+ * Erase the node from the list it currently belongs.
+ *
+ * @param node	    The element to be erased.
+ */
+PJ_IDECL(void) pj_list_erase(pj_list_type *node);
+
+
+/**
+ * Find node in the list.
+ *
+ * @param list	    The list head.
+ * @param node	    The node element to be searched.
+ *
+ * @return The node itself if it is found in the list, or NULL if it is not 
+ *         found in the list.
+ */
+PJ_IDECL(pj_list_type*) pj_list_find_node(pj_list_type *list, 
+					  pj_list_type *node);
+
+
+/**
+ * Search the list for the specified value, using the specified comparison
+ * function. This function iterates on nodes in the list, started with the
+ * first node, and call the user supplied comparison function until the
+ * comparison function returns ZERO.
+ *
+ * @param list	    The list head.
+ * @param value	    The user defined value to be passed in the comparison 
+ *		    function
+ * @param comp	    The comparison function, which should return ZERO to 
+ *		    indicate that the searched value is found.
+ *
+ * @return The first node that matched, or NULL if it is not found.
+ */
+PJ_IDECL(pj_list_type*) pj_list_search(pj_list_type *list, void *value,
+				       int (*comp)(void *value, 
+						   const pj_list_type *node)
+				       );
+
+
+/**
+ * @}
+ */
+
+#if PJ_FUNCTIONS_ARE_INLINED
+#  include "list_i.h"
+#endif
+
+PJ_END_DECL
+
+#endif	/* __PJ_LIST_H__ */
+
diff --git a/pjlib/include/pj/list_i.h b/pjlib/include/pj/list_i.h
index 1ad0c08..c6d95c8 100644
--- a/pjlib/include/pj/list_i.h
+++ b/pjlib/include/pj/list_i.h
@@ -1,118 +1,118 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-

-

-/* Internal */

-PJ_IDEF(void) pj_link_node(pj_list_type *prev, pj_list_type *next)

-{

-    ((pj_list*)prev)->next = next;

-    ((pj_list*)next)->prev = prev;

-}

-

-/*

-PJ_IDEF(void) 

-pj_list_init(pj_list_type * node)

-{

-    ((pj_list*)node)->next = ((pj_list*)node)->prev = node;

-}

-

-PJ_IDEF(int) pj_list_empty(const pj_list_type * node)

-{

-    return ((pj_list*)node)->next == node;

-}

-*/

-

-PJ_IDEF(void) 

-pj_list_insert_after(pj_list_type *pos, pj_list_type *node)

-{

-    ((pj_list*)node)->prev = pos;

-    ((pj_list*)node)->next = ((pj_list*)pos)->next;

-    ((pj_list*) ((pj_list*)pos)->next) ->prev = node;

-    ((pj_list*)pos)->next = node;

-}

-

-

-PJ_IDEF(void) 

-pj_list_insert_before(pj_list_type *pos, pj_list_type *node)

-{

-    pj_list_insert_after(((pj_list*)pos)->prev, node);

-}

-

-

-PJ_IDEF(void)	    

-pj_list_insert_nodes_after(pj_list_type *pos, pj_list_type *lst)

-{

-    pj_list *lst_last = (pj_list *) ((pj_list*)lst)->prev;

-    pj_list *pos_next = (pj_list *) ((pj_list*)pos)->next;

-

-    pj_link_node(pos, lst);

-    pj_link_node(lst_last, pos_next);

-}

-

-PJ_IDEF(void) 

-pj_list_insert_nodes_before(pj_list_type *pos, pj_list_type *lst)

-{

-    pj_list_insert_nodes_after(((pj_list*)pos)->prev, lst);

-}

-

-PJ_IDEF(void)

-pj_list_merge_last(pj_list_type *lst1, pj_list_type *lst2)

-{

-    pj_link_node(((pj_list*)lst1)->prev, ((pj_list*)lst2)->next);

-    pj_link_node(((pj_list*)lst2)->prev, lst1);

-    pj_list_init(lst2);

-}

-

-PJ_IDEF(void)

-pj_list_merge_first(pj_list_type *lst1, pj_list_type *lst2)

-{

-    pj_link_node(((pj_list*)lst2)->prev, ((pj_list*)lst1)->next);

-    pj_link_node(((pj_list*)lst1), ((pj_list*)lst2)->next);

-    pj_list_init(lst2);

-}

-

-PJ_IDEF(void) 

-pj_list_erase(pj_list_type *node)

-{

-    pj_link_node( ((pj_list*)node)->prev, ((pj_list*)node)->next);

-}

-

-

-PJ_IDEF(pj_list_type*) 

-pj_list_find_node(pj_list_type *list, pj_list_type *node)

-{

-    pj_list *p = (pj_list *) ((pj_list*)list)->next;

-    while (p != list && p != node)

-	p = (pj_list *) p->next;

-

-    return p==node ? p : NULL;

-}

-

-

-PJ_IDEF(pj_list_type*) 

-pj_list_search(pj_list_type *list, void *value,

-	       int (*comp)(void *value, const pj_list_type *node))

-{

-    pj_list *p = (pj_list *) ((pj_list*)list)->next;

-    while (p != list && (*comp)(value, p) != 0)

-	p = (pj_list *) p->next;

-

-    return p==list ? NULL : p;

-}

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+
+
+/* Internal */
+PJ_IDEF(void) pj_link_node(pj_list_type *prev, pj_list_type *next)
+{
+    ((pj_list*)prev)->next = next;
+    ((pj_list*)next)->prev = prev;
+}
+
+/*
+PJ_IDEF(void) 
+pj_list_init(pj_list_type * node)
+{
+    ((pj_list*)node)->next = ((pj_list*)node)->prev = node;
+}
+
+PJ_IDEF(int) pj_list_empty(const pj_list_type * node)
+{
+    return ((pj_list*)node)->next == node;
+}
+*/
+
+PJ_IDEF(void) 
+pj_list_insert_after(pj_list_type *pos, pj_list_type *node)
+{
+    ((pj_list*)node)->prev = pos;
+    ((pj_list*)node)->next = ((pj_list*)pos)->next;
+    ((pj_list*) ((pj_list*)pos)->next) ->prev = node;
+    ((pj_list*)pos)->next = node;
+}
+
+
+PJ_IDEF(void) 
+pj_list_insert_before(pj_list_type *pos, pj_list_type *node)
+{
+    pj_list_insert_after(((pj_list*)pos)->prev, node);
+}
+
+
+PJ_IDEF(void)	    
+pj_list_insert_nodes_after(pj_list_type *pos, pj_list_type *lst)
+{
+    pj_list *lst_last = (pj_list *) ((pj_list*)lst)->prev;
+    pj_list *pos_next = (pj_list *) ((pj_list*)pos)->next;
+
+    pj_link_node(pos, lst);
+    pj_link_node(lst_last, pos_next);
+}
+
+PJ_IDEF(void) 
+pj_list_insert_nodes_before(pj_list_type *pos, pj_list_type *lst)
+{
+    pj_list_insert_nodes_after(((pj_list*)pos)->prev, lst);
+}
+
+PJ_IDEF(void)
+pj_list_merge_last(pj_list_type *lst1, pj_list_type *lst2)
+{
+    pj_link_node(((pj_list*)lst1)->prev, ((pj_list*)lst2)->next);
+    pj_link_node(((pj_list*)lst2)->prev, lst1);
+    pj_list_init(lst2);
+}
+
+PJ_IDEF(void)
+pj_list_merge_first(pj_list_type *lst1, pj_list_type *lst2)
+{
+    pj_link_node(((pj_list*)lst2)->prev, ((pj_list*)lst1)->next);
+    pj_link_node(((pj_list*)lst1), ((pj_list*)lst2)->next);
+    pj_list_init(lst2);
+}
+
+PJ_IDEF(void) 
+pj_list_erase(pj_list_type *node)
+{
+    pj_link_node( ((pj_list*)node)->prev, ((pj_list*)node)->next);
+}
+
+
+PJ_IDEF(pj_list_type*) 
+pj_list_find_node(pj_list_type *list, pj_list_type *node)
+{
+    pj_list *p = (pj_list *) ((pj_list*)list)->next;
+    while (p != list && p != node)
+	p = (pj_list *) p->next;
+
+    return p==node ? p : NULL;
+}
+
+
+PJ_IDEF(pj_list_type*) 
+pj_list_search(pj_list_type *list, void *value,
+	       int (*comp)(void *value, const pj_list_type *node))
+{
+    pj_list *p = (pj_list *) ((pj_list*)list)->next;
+    while (p != list && (*comp)(value, p) != 0)
+	p = (pj_list *) p->next;
+
+    return p==list ? NULL : p;
+}
+
diff --git a/pjlib/include/pj/lock.h b/pjlib/include/pj/lock.h
index 4eb50af..96c9e11 100644
--- a/pjlib/include/pj/lock.h
+++ b/pjlib/include/pj/lock.h
@@ -1,153 +1,153 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_LOCK_H__

-#define __PJ_LOCK_H__

-

-/**

- * @file lock.h

- * @brief Higher abstraction for locking objects.

- */

-#include <pj/types.h>

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup PJ_LOCK Lock Objects

- * @ingroup PJ_OS

- * @{

- *

- * <b>Lock Objects</b> are higher abstraction for different lock mechanisms.

- * It offers the same API for manipulating different lock types (e.g.

- * @ref PJ_MUTEX "mutex", @ref PJ_SEM "semaphores", or null locks).

- * Because Lock Objects have the same API for different types of lock

- * implementation, it can be passed around in function arguments. As the

- * result, it can be used to control locking policy for  a particular

- * feature.

- */

-

-

-/**

- * Create simple, non recursive mutex lock object.

- *

- * @param pool	    Memory pool.

- * @param name	    Lock object's name.

- * @param lock	    Pointer to store the returned handle.

- *

- * @return	    PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_lock_create_simple_mutex( pj_pool_t *pool,

-						  const char *name,

-						  pj_lock_t **lock );

-

-/**

- * Create recursive mutex lock object.

- *

- * @param pool	    Memory pool.

- * @param name	    Lock object's name.

- * @param lock	    Pointer to store the returned handle.

- *

- * @return	    PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_lock_create_recursive_mutex( pj_pool_t *pool,

-						     const char *name,

-						     pj_lock_t **lock );

-

-

-/**

- * Create NULL mutex. A NULL mutex doesn't actually have any synchronization

- * object attached to it.

- *

- * @param pool	    Memory pool.

- * @param name	    Lock object's name.

- * @param lock	    Pointer to store the returned handle.

- *

- * @return	    PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_lock_create_null_mutex( pj_pool_t *pool,

-						const char *name,

-						pj_lock_t **lock );

-

-

-#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0

-/**

- * Create semaphore lock object.

- *

- * @param pool	    Memory pool.

- * @param name	    Lock object's name.

- * @param initial   Initial value of the semaphore.

- * @param max	    Maximum value of the semaphore.

- * @param lock	    Pointer to store the returned handle.

- *

- * @return	    PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_lock_create_semaphore( pj_pool_t *pool,

-					       const char *name,

-					       unsigned initial,

-					       unsigned max,

-					       pj_lock_t **lock );

-

-#endif	/* PJ_HAS_SEMAPHORE */

-

-/**

- * Acquire lock on the specified lock object.

- *

- * @param lock	    The lock object.

- *

- * @return	    PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_lock_acquire( pj_lock_t *lock );

-

-

-/**

- * Try to acquire lock on the specified lock object.

- *

- * @param lock	    The lock object.

- *

- * @return	    PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_lock_tryacquire( pj_lock_t *lock );

-

-

-/**

- * Release lock on the specified lock object.

- *

- * @param lock	    The lock object.

- *

- * @return	    PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_lock_release( pj_lock_t *lock );

-

-

-/**

- * Destroy the lock object.

- *

- * @param lock	    The lock object.

- *

- * @return	    PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_lock_destroy( pj_lock_t *lock );

-

-

-/** @} */

-

-PJ_END_DECL

-

-

-#endif	/* __PJ_LOCK_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_LOCK_H__
+#define __PJ_LOCK_H__
+
+/**
+ * @file lock.h
+ * @brief Higher abstraction for locking objects.
+ */
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_LOCK Lock Objects
+ * @ingroup PJ_OS
+ * @{
+ *
+ * <b>Lock Objects</b> are higher abstraction for different lock mechanisms.
+ * It offers the same API for manipulating different lock types (e.g.
+ * @ref PJ_MUTEX "mutex", @ref PJ_SEM "semaphores", or null locks).
+ * Because Lock Objects have the same API for different types of lock
+ * implementation, it can be passed around in function arguments. As the
+ * result, it can be used to control locking policy for  a particular
+ * feature.
+ */
+
+
+/**
+ * Create simple, non recursive mutex lock object.
+ *
+ * @param pool	    Memory pool.
+ * @param name	    Lock object's name.
+ * @param lock	    Pointer to store the returned handle.
+ *
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_create_simple_mutex( pj_pool_t *pool,
+						  const char *name,
+						  pj_lock_t **lock );
+
+/**
+ * Create recursive mutex lock object.
+ *
+ * @param pool	    Memory pool.
+ * @param name	    Lock object's name.
+ * @param lock	    Pointer to store the returned handle.
+ *
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_create_recursive_mutex( pj_pool_t *pool,
+						     const char *name,
+						     pj_lock_t **lock );
+
+
+/**
+ * Create NULL mutex. A NULL mutex doesn't actually have any synchronization
+ * object attached to it.
+ *
+ * @param pool	    Memory pool.
+ * @param name	    Lock object's name.
+ * @param lock	    Pointer to store the returned handle.
+ *
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_create_null_mutex( pj_pool_t *pool,
+						const char *name,
+						pj_lock_t **lock );
+
+
+#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
+/**
+ * Create semaphore lock object.
+ *
+ * @param pool	    Memory pool.
+ * @param name	    Lock object's name.
+ * @param initial   Initial value of the semaphore.
+ * @param max	    Maximum value of the semaphore.
+ * @param lock	    Pointer to store the returned handle.
+ *
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_create_semaphore( pj_pool_t *pool,
+					       const char *name,
+					       unsigned initial,
+					       unsigned max,
+					       pj_lock_t **lock );
+
+#endif	/* PJ_HAS_SEMAPHORE */
+
+/**
+ * Acquire lock on the specified lock object.
+ *
+ * @param lock	    The lock object.
+ *
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_acquire( pj_lock_t *lock );
+
+
+/**
+ * Try to acquire lock on the specified lock object.
+ *
+ * @param lock	    The lock object.
+ *
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_tryacquire( pj_lock_t *lock );
+
+
+/**
+ * Release lock on the specified lock object.
+ *
+ * @param lock	    The lock object.
+ *
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_release( pj_lock_t *lock );
+
+
+/**
+ * Destroy the lock object.
+ *
+ * @param lock	    The lock object.
+ *
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_lock_destroy( pj_lock_t *lock );
+
+
+/** @} */
+
+PJ_END_DECL
+
+
+#endif	/* __PJ_LOCK_H__ */
+
diff --git a/pjlib/include/pj/log.h b/pjlib/include/pj/log.h
index 3f192da..4d8dc14 100644
--- a/pjlib/include/pj/log.h
+++ b/pjlib/include/pj/log.h
@@ -1,331 +1,331 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_LOG_H__

-#define __PJ_LOG_H__

-

-/**

- * @file log.h

- * @brief Logging Utility.

- */

-

-#include <pj/types.h>

-#include <stdarg.h>

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup PJ_MISC Miscelaneous

- * @ingroup PJ

- */

-

-/**

- * @defgroup PJ_LOG Logging Facility

- * @ingroup PJ_MISC

- * @{

- *

- * The PJLIB logging facility is a configurable, flexible, and convenient

- * way to write logging or trace information.

- *

- * To write to the log, one uses construct like below:

- *

- * <pre>

- *   ...

- *   PJ_LOG(3, ("main.c", "Starting hello..."));

- *   ...

- *   PJ_LOG(3, ("main.c", "Hello world from process %d", pj_getpid()));

- *   ...

- * </pre>

- *

- * In the above example, the number @b 3 controls the verbosity level of

- * the information (which means "information", by convention). The string

- * "main.c" specifies the source or sender of the message.

- *

- *

- * \section pj_log_quick_sample_sec Examples

- *

- * For examples, see:

- *  - @ref page_pjlib_samples_log_c.

- *

- */

-

-/**

- * Log decoration flag, to be specified with #pj_log_set_decor().

- */

-enum pj_log_decoration

-{

-    PJ_LOG_HAS_DAY_NAME   =   1, /**< Include day name [default: no].	     */

-    PJ_LOG_HAS_YEAR       =   2, /**< Include year digit [default: no]	     */

-    PJ_LOG_HAS_MONTH	  =   4, /**< Include month [default: no]	     */

-    PJ_LOG_HAS_DAY_OF_MON =   8, /**< Include day of month [default: no]     */

-    PJ_LOG_HAS_TIME	  =  16, /**< Include time [default: yes].	     */

-    PJ_LOG_HAS_MICRO_SEC  =  32, /**< Include microseconds [yes]             */

-    PJ_LOG_HAS_SENDER	  =  64, /**< Include sender in the log [yes].	     */

-    PJ_LOG_HAS_NEWLINE	  = 128, /**< Terminate each call with newline [yes].*/

-};

-

-/**

- * Write log message.

- * This is the main macro used to write text to the logging backend. 

- *

- * @param level	    The logging verbosity level. Lower number indicates higher

- *		    importance, with level zero indicates fatal error. Only

- *		    numeral argument is permitted (e.g. not variable).

- * @param arg	    Enclosed 'printf' like arguments, with the first 

- *		    argument is the sender, the second argument is format 

- *		    string and the following arguments are variable number of 

- *		    arguments suitable for the format string.

- *

- * Sample:

- * \verbatim

-   PJ_LOG(2, (__FILE__, "current value is %d", value));

-   \endverbatim

- * @hideinitializer

- */

-#define PJ_LOG(level,arg)	pj_log_wrapper_##level(arg)

-

-/**

- * Signature for function to be registered to the logging subsystem to

- * write the actual log message to some output device.

- *

- * @param level	    Log level.

- * @param data	    Log message.

- * @param len	    Message length.

- */

-typedef void pj_log_func(int level, const char *data, int len);

-

-/**

- * Default logging writer function used by front end logger function.

- * Application normally should NOT need to call this function, but

- * rather use the PJ_LOG macro.

- *

- * @param level	    Log level.

- * @param buffer    Log message.

- * @param len	    Message length.

- */

-PJ_DECL(void) pj_log_write(int level, const char *buffer, int len);

-

-

-#if PJ_LOG_MAX_LEVEL >= 1

-

-/**

- * Write to log.

- *

- * @param sender    Source of the message.

- * @param level	    Verbosity level.

- * @param format    Format.

- * @param marker    Marker.

- */

-PJ_DECL(void) pj_log(const char *sender, int level, 

-		     const char *format, va_list marker);

-

-/**

- * Change log output function. The front-end logging functions will call

- * this function to write the actual message to the desired device. 

- * By default, the front-end functions use pj_log_write() to write

- * the messages, unless it's changed by calling this function.

- *

- * @param func	    The function that will be called to write the log

- *		    messages to the desired device.

- */

-PJ_DECL(void) pj_log_set_log_func( pj_log_func *func );

-

-/**

- * Get the current log output function that is used to write log messages.

- *

- * @return	    Current log output function.

- */

-PJ_DECL(pj_log_func*) pj_log_get_log_func(void);

-

-/**

- * Set maximum log level. Application can call this function to set 

- * the desired level of verbosity of the logging messages. The bigger the

- * value, the more verbose the logging messages will be printed. However,

- * the maximum level of verbosity can not exceed compile time value of

- * PJ_LOG_MAX_LEVEL.

- *

- * @param level	    The maximum level of verbosity of the logging

- *		    messages (6=very detailed..1=error only, 0=disabled)

- */

-PJ_DECL(void) pj_log_set_level(int level);

-

-/**

- * Get current maximum log verbositylevel.

- *

- * @return	    Current log maximum level.

- */

-PJ_DECL(int) pj_log_get_level(void);

-

-/**

- * Set log decoration. The log decoration flag controls what are printed

- * to output device alongside the actual message. For example, application

- * can specify that date/time information should be displayed with each

- * log message.

- *

- * @param decor	    Bitmask combination of #pj_log_decoration to control

- *		    the layout of the log message.

- */

-PJ_DECL(void) pj_log_set_decor(unsigned decor);

-

-/**

- * Get current log decoration flag.

- *

- * @return	    Log decoration flag.

- */

-PJ_DECL(unsigned) pj_log_get_decor(void);

-

-

-#else	/* #if PJ_LOG_MAX_LEVEL >= 1 */

-

-/**

- * Change log output function. The front-end logging functions will call

- * this function to write the actual message to the desired device. 

- * By default, the front-end functions use pj_log_write() to write

- * the messages, unless it's changed by calling this function.

- *

- * @param func	    The function that will be called to write the log

- *		    messages to the desired device.

- */

-#  define pj_log_set_log_func(func)

-

-/**

- * Set maximum log level. Application can call this function to set 

- * the desired level of verbosity of the logging messages. The bigger the

- * value, the more verbose the logging messages will be printed. However,

- * the maximum level of verbosity can not exceed compile time value of

- * PJ_LOG_MAX_LEVEL.

- *

- * @param level	    The maximum level of verbosity of the logging

- *		    messages (6=very detailed..1=error only, 0=disabled)

- */

-#  define pj_log_set_level(level)

-

-/**

- * Set log decoration. The log decoration flag controls what are printed

- * to output device alongside the actual message. For example, application

- * can specify that date/time information should be displayed with each

- * log message.

- *

- * @param decor	    Bitmask combination of #pj_log_decoration to control

- *		    the layout of the log message.

- */

-#  define pj_log_set_decor(decor)

-

-#endif	/* #if PJ_LOG_MAX_LEVEL >= 1 */

-

-/** 

- * @}

- */

-

-///////////////////////////////////////////////////////////////////////////////

-/*

- * Log functions implementation prototypes.

- * These functions are called by PJ_LOG macros according to verbosity

- * level specified when calling the macro. Applications should not normally

- * need to call these functions directly.

- */

-

-/**

- * @def pj_log_wrapper_1(arg)

- * Internal function to write log with verbosity 1. Will evaluate to

- * empty expression if PJ_LOG_MAX_LEVEL is below 1.

- * @param arg       Log expression.

- */

-#if PJ_LOG_MAX_LEVEL >= 1

-    #define pj_log_wrapper_1(arg)	pj_log_1 arg

-    /** Internal function. */

-    PJ_DECL(void) pj_log_1(const char *src, const char *format, ...);

-#else

-    #define pj_log_wrapper_1(arg)

-#endif

-

-/**

- * @def pj_log_wrapper_2(arg)

- * Internal function to write log with verbosity 2. Will evaluate to

- * empty expression if PJ_LOG_MAX_LEVEL is below 2.

- * @param arg       Log expression.

- */

-#if PJ_LOG_MAX_LEVEL >= 2

-    #define pj_log_wrapper_2(arg)	pj_log_2 arg

-    /** Internal function. */

-    PJ_DECL(void) pj_log_2(const char *src, const char *format, ...);

-#else

-    #define pj_log_wrapper_2(arg)

-#endif

-

-/**

- * @def pj_log_wrapper_3(arg)

- * Internal function to write log with verbosity 3. Will evaluate to

- * empty expression if PJ_LOG_MAX_LEVEL is below 3.

- * @param arg       Log expression.

- */

-#if PJ_LOG_MAX_LEVEL >= 3

-    #define pj_log_wrapper_3(arg)	pj_log_3 arg

-    /** Internal function. */

-    PJ_DECL(void) pj_log_3(const char *src, const char *format, ...);

-#else

-    #define pj_log_wrapper_3(arg)

-#endif

-

-/**

- * @def pj_log_wrapper_4(arg)

- * Internal function to write log with verbosity 4. Will evaluate to

- * empty expression if PJ_LOG_MAX_LEVEL is below 4.

- * @param arg       Log expression.

- */

-#if PJ_LOG_MAX_LEVEL >= 4

-    #define pj_log_wrapper_4(arg)	pj_log_4 arg

-    /** Internal function. */

-    PJ_DECL(void) pj_log_4(const char *src, const char *format, ...);

-#else

-    #define pj_log_wrapper_4(arg)

-#endif

-

-/**

- * @def pj_log_wrapper_5(arg)

- * Internal function to write log with verbosity 5. Will evaluate to

- * empty expression if PJ_LOG_MAX_LEVEL is below 5.

- * @param arg       Log expression.

- */

-#if PJ_LOG_MAX_LEVEL >= 5

-    #define pj_log_wrapper_5(arg)	pj_log_5 arg

-    /** Internal function. */

-    PJ_DECL(void) pj_log_5(const char *src, const char *format, ...);

-#else

-    #define pj_log_wrapper_5(arg)

-#endif

-

-/**

- * @def pj_log_wrapper_6(arg)

- * Internal function to write log with verbosity 6. Will evaluate to

- * empty expression if PJ_LOG_MAX_LEVEL is below 6.

- * @param arg       Log expression.

- */

-#if PJ_LOG_MAX_LEVEL >= 6

-    #define pj_log_wrapper_6(arg)	pj_log_6 arg

-    /** Internal function. */

-    PJ_DECL(void) pj_log_6(const char *src, const char *format, ...);

-#else

-    #define pj_log_wrapper_6(arg)

-#endif

-

-

-PJ_END_DECL 

-

-#endif  /* __PJ_LOG_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_LOG_H__
+#define __PJ_LOG_H__
+
+/**
+ * @file log.h
+ * @brief Logging Utility.
+ */
+
+#include <pj/types.h>
+#include <stdarg.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_MISC Miscelaneous
+ * @ingroup PJ
+ */
+
+/**
+ * @defgroup PJ_LOG Logging Facility
+ * @ingroup PJ_MISC
+ * @{
+ *
+ * The PJLIB logging facility is a configurable, flexible, and convenient
+ * way to write logging or trace information.
+ *
+ * To write to the log, one uses construct like below:
+ *
+ * <pre>
+ *   ...
+ *   PJ_LOG(3, ("main.c", "Starting hello..."));
+ *   ...
+ *   PJ_LOG(3, ("main.c", "Hello world from process %d", pj_getpid()));
+ *   ...
+ * </pre>
+ *
+ * In the above example, the number @b 3 controls the verbosity level of
+ * the information (which means "information", by convention). The string
+ * "main.c" specifies the source or sender of the message.
+ *
+ *
+ * \section pj_log_quick_sample_sec Examples
+ *
+ * For examples, see:
+ *  - @ref page_pjlib_samples_log_c.
+ *
+ */
+
+/**
+ * Log decoration flag, to be specified with #pj_log_set_decor().
+ */
+enum pj_log_decoration
+{
+    PJ_LOG_HAS_DAY_NAME   =   1, /**< Include day name [default: no].	     */
+    PJ_LOG_HAS_YEAR       =   2, /**< Include year digit [default: no]	     */
+    PJ_LOG_HAS_MONTH	  =   4, /**< Include month [default: no]	     */
+    PJ_LOG_HAS_DAY_OF_MON =   8, /**< Include day of month [default: no]     */
+    PJ_LOG_HAS_TIME	  =  16, /**< Include time [default: yes].	     */
+    PJ_LOG_HAS_MICRO_SEC  =  32, /**< Include microseconds [yes]             */
+    PJ_LOG_HAS_SENDER	  =  64, /**< Include sender in the log [yes].	     */
+    PJ_LOG_HAS_NEWLINE	  = 128, /**< Terminate each call with newline [yes].*/
+};
+
+/**
+ * Write log message.
+ * This is the main macro used to write text to the logging backend. 
+ *
+ * @param level	    The logging verbosity level. Lower number indicates higher
+ *		    importance, with level zero indicates fatal error. Only
+ *		    numeral argument is permitted (e.g. not variable).
+ * @param arg	    Enclosed 'printf' like arguments, with the first 
+ *		    argument is the sender, the second argument is format 
+ *		    string and the following arguments are variable number of 
+ *		    arguments suitable for the format string.
+ *
+ * Sample:
+ * \verbatim
+   PJ_LOG(2, (__FILE__, "current value is %d", value));
+   \endverbatim
+ * @hideinitializer
+ */
+#define PJ_LOG(level,arg)	pj_log_wrapper_##level(arg)
+
+/**
+ * Signature for function to be registered to the logging subsystem to
+ * write the actual log message to some output device.
+ *
+ * @param level	    Log level.
+ * @param data	    Log message.
+ * @param len	    Message length.
+ */
+typedef void pj_log_func(int level, const char *data, int len);
+
+/**
+ * Default logging writer function used by front end logger function.
+ * Application normally should NOT need to call this function, but
+ * rather use the PJ_LOG macro.
+ *
+ * @param level	    Log level.
+ * @param buffer    Log message.
+ * @param len	    Message length.
+ */
+PJ_DECL(void) pj_log_write(int level, const char *buffer, int len);
+
+
+#if PJ_LOG_MAX_LEVEL >= 1
+
+/**
+ * Write to log.
+ *
+ * @param sender    Source of the message.
+ * @param level	    Verbosity level.
+ * @param format    Format.
+ * @param marker    Marker.
+ */
+PJ_DECL(void) pj_log(const char *sender, int level, 
+		     const char *format, va_list marker);
+
+/**
+ * Change log output function. The front-end logging functions will call
+ * this function to write the actual message to the desired device. 
+ * By default, the front-end functions use pj_log_write() to write
+ * the messages, unless it's changed by calling this function.
+ *
+ * @param func	    The function that will be called to write the log
+ *		    messages to the desired device.
+ */
+PJ_DECL(void) pj_log_set_log_func( pj_log_func *func );
+
+/**
+ * Get the current log output function that is used to write log messages.
+ *
+ * @return	    Current log output function.
+ */
+PJ_DECL(pj_log_func*) pj_log_get_log_func(void);
+
+/**
+ * Set maximum log level. Application can call this function to set 
+ * the desired level of verbosity of the logging messages. The bigger the
+ * value, the more verbose the logging messages will be printed. However,
+ * the maximum level of verbosity can not exceed compile time value of
+ * PJ_LOG_MAX_LEVEL.
+ *
+ * @param level	    The maximum level of verbosity of the logging
+ *		    messages (6=very detailed..1=error only, 0=disabled)
+ */
+PJ_DECL(void) pj_log_set_level(int level);
+
+/**
+ * Get current maximum log verbositylevel.
+ *
+ * @return	    Current log maximum level.
+ */
+PJ_DECL(int) pj_log_get_level(void);
+
+/**
+ * Set log decoration. The log decoration flag controls what are printed
+ * to output device alongside the actual message. For example, application
+ * can specify that date/time information should be displayed with each
+ * log message.
+ *
+ * @param decor	    Bitmask combination of #pj_log_decoration to control
+ *		    the layout of the log message.
+ */
+PJ_DECL(void) pj_log_set_decor(unsigned decor);
+
+/**
+ * Get current log decoration flag.
+ *
+ * @return	    Log decoration flag.
+ */
+PJ_DECL(unsigned) pj_log_get_decor(void);
+
+
+#else	/* #if PJ_LOG_MAX_LEVEL >= 1 */
+
+/**
+ * Change log output function. The front-end logging functions will call
+ * this function to write the actual message to the desired device. 
+ * By default, the front-end functions use pj_log_write() to write
+ * the messages, unless it's changed by calling this function.
+ *
+ * @param func	    The function that will be called to write the log
+ *		    messages to the desired device.
+ */
+#  define pj_log_set_log_func(func)
+
+/**
+ * Set maximum log level. Application can call this function to set 
+ * the desired level of verbosity of the logging messages. The bigger the
+ * value, the more verbose the logging messages will be printed. However,
+ * the maximum level of verbosity can not exceed compile time value of
+ * PJ_LOG_MAX_LEVEL.
+ *
+ * @param level	    The maximum level of verbosity of the logging
+ *		    messages (6=very detailed..1=error only, 0=disabled)
+ */
+#  define pj_log_set_level(level)
+
+/**
+ * Set log decoration. The log decoration flag controls what are printed
+ * to output device alongside the actual message. For example, application
+ * can specify that date/time information should be displayed with each
+ * log message.
+ *
+ * @param decor	    Bitmask combination of #pj_log_decoration to control
+ *		    the layout of the log message.
+ */
+#  define pj_log_set_decor(decor)
+
+#endif	/* #if PJ_LOG_MAX_LEVEL >= 1 */
+
+/** 
+ * @}
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Log functions implementation prototypes.
+ * These functions are called by PJ_LOG macros according to verbosity
+ * level specified when calling the macro. Applications should not normally
+ * need to call these functions directly.
+ */
+
+/**
+ * @def pj_log_wrapper_1(arg)
+ * Internal function to write log with verbosity 1. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 1.
+ * @param arg       Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 1
+    #define pj_log_wrapper_1(arg)	pj_log_1 arg
+    /** Internal function. */
+    PJ_DECL(void) pj_log_1(const char *src, const char *format, ...);
+#else
+    #define pj_log_wrapper_1(arg)
+#endif
+
+/**
+ * @def pj_log_wrapper_2(arg)
+ * Internal function to write log with verbosity 2. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 2.
+ * @param arg       Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 2
+    #define pj_log_wrapper_2(arg)	pj_log_2 arg
+    /** Internal function. */
+    PJ_DECL(void) pj_log_2(const char *src, const char *format, ...);
+#else
+    #define pj_log_wrapper_2(arg)
+#endif
+
+/**
+ * @def pj_log_wrapper_3(arg)
+ * Internal function to write log with verbosity 3. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 3.
+ * @param arg       Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 3
+    #define pj_log_wrapper_3(arg)	pj_log_3 arg
+    /** Internal function. */
+    PJ_DECL(void) pj_log_3(const char *src, const char *format, ...);
+#else
+    #define pj_log_wrapper_3(arg)
+#endif
+
+/**
+ * @def pj_log_wrapper_4(arg)
+ * Internal function to write log with verbosity 4. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 4.
+ * @param arg       Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 4
+    #define pj_log_wrapper_4(arg)	pj_log_4 arg
+    /** Internal function. */
+    PJ_DECL(void) pj_log_4(const char *src, const char *format, ...);
+#else
+    #define pj_log_wrapper_4(arg)
+#endif
+
+/**
+ * @def pj_log_wrapper_5(arg)
+ * Internal function to write log with verbosity 5. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 5.
+ * @param arg       Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 5
+    #define pj_log_wrapper_5(arg)	pj_log_5 arg
+    /** Internal function. */
+    PJ_DECL(void) pj_log_5(const char *src, const char *format, ...);
+#else
+    #define pj_log_wrapper_5(arg)
+#endif
+
+/**
+ * @def pj_log_wrapper_6(arg)
+ * Internal function to write log with verbosity 6. Will evaluate to
+ * empty expression if PJ_LOG_MAX_LEVEL is below 6.
+ * @param arg       Log expression.
+ */
+#if PJ_LOG_MAX_LEVEL >= 6
+    #define pj_log_wrapper_6(arg)	pj_log_6 arg
+    /** Internal function. */
+    PJ_DECL(void) pj_log_6(const char *src, const char *format, ...);
+#else
+    #define pj_log_wrapper_6(arg)
+#endif
+
+
+PJ_END_DECL 
+
+#endif  /* __PJ_LOG_H__ */
+
diff --git a/pjlib/include/pj/os.h b/pjlib/include/pj/os.h
index edd5d1d..7b03c96 100644
--- a/pjlib/include/pj/os.h
+++ b/pjlib/include/pj/os.h
@@ -1,995 +1,995 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_OS_H__

-#define __PJ_OS_H__

-

-/**

- * @file os.h

- * @brief OS dependent functions

- */

-#include <pj/types.h>

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup PJ_OS Operating System Dependent Functionality.

- * @ingroup PJ

- */

-

-

-///////////////////////////////////////////////////////////////////////////////

-/**

- * @defgroup PJ_THREAD Threads

- * @ingroup PJ_OS

- * @{

- * This module provides multithreading API.

- *

- * \section pj_thread_examples_sec Examples

- *

- * For examples, please see:

- *  - \ref page_pjlib_thread_test

- *  - \ref page_pjlib_sleep_test

- *

- */

-

-/**

- * Thread creation flags:

- * - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.

- */

-typedef enum pj_thread_create_flags

-{

-    PJ_THREAD_SUSPENDED = 1

-} pj_thread_create_flags;

-

-

-/**

- * Specify this as \a stack_size argument in #pj_thread_create() to specify

- * that thread should use default stack size for the current platform.

- */

-#define PJ_THREAD_DEFAULT_STACK_SIZE    0

-

-/**

- * Type of thread entry function.

- */

-typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);

-

-/**

- * Size of thread struct.

- */

-#if !defined(PJ_THREAD_DESC_SIZE)

-#   define PJ_THREAD_DESC_SIZE	    (16)

-#endif

-

-/**

- * Thread structure, to thread's state when the thread is created by external

- * or native API. 

- */

-typedef long pj_thread_desc[PJ_THREAD_DESC_SIZE];

-

-/**

- * Get process ID.

- * @return process ID.

- */

-PJ_DECL(pj_uint32_t) pj_getpid(void);

-

-/**

- * Create a new thread.

- *

- * @param pool          The memory pool from which the thread record 

- *                      will be allocated from.

- * @param thread_name   The optional name to be assigned to the thread.

- * @param proc          Thread entry function.

- * @param arg           Argument to be passed to the thread entry function.

- * @param stack_size    The size of the stack for the new thread, or ZERO or

- *                      PJ_THREAD_DEFAULT_STACK_SIZE to let the 

- *		        library choose the reasonable size for the stack. 

- *                      For some systems, the stack will be allocated from 

- *                      the pool, so the pool must have suitable capacity.

- * @param flags         Flags for thread creation, which is bitmask combination 

- *                      from enum pj_thread_create_flags.

- * @param thread        Pointer to hold the newly created thread.

- *

- * @return	        PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_thread_create(  pj_pool_t *pool, 

-                                        const char *thread_name,

-				        pj_thread_proc *proc, 

-                                        void *arg,

-				        pj_size_t stack_size, 

-                                        unsigned flags,

-					pj_thread_t **thread );

-

-/**

- * Register a thread that was created by external or native API to PJLIB.

- * This function must be called in the context of the thread being registered.

- * When the thread is created by external function or API call,

- * it must be 'registered' to PJLIB using pj_thread_register(), so that it can

- * cooperate with PJLIB's framework. During registration, some data needs to

- * be maintained, and this data must remain available during the thread's 

- * lifetime.

- *

- * @param thread_name   The optional name to be assigned to the thread.

- * @param desc          Thread descriptor, which must be available throughout 

- *                      the lifetime of the thread.

- * @param thread        Pointer to hold the created thread handle.

- *

- * @return              PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,

-					  pj_thread_desc desc,

-					  pj_thread_t **thread);

-

-/**

- * Get thread name.

- *

- * @param thread    The thread handle.

- *

- * @return Thread name as null terminated string.

- */

-PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);

-

-/**

- * Resume a suspended thread.

- *

- * @param thread    The thread handle.

- *

- * @return zero on success.

- */

-PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);

-

-/**

- * Get the current thread.

- *

- * @return Thread handle of current thread.

- */

-PJ_DECL(pj_thread_t*) pj_thread_this(void);

-

-/**

- * Join thread.

- * This function will block the caller thread until the specified thread exits.

- *

- * @param thread    The thread handle.

- *

- * @return zero on success.

- */

-PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);

-

-

-/**

- * Destroy thread and release resources allocated for the thread.

- * However, the memory allocated for the pj_thread_t itself will only be released

- * when the pool used to create the thread is destroyed.

- *

- * @param thread    The thread handle.

- *

- * @return zero on success.

- */

-PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);

-

-

-/**

- * Put the current thread to sleep for the specified miliseconds.

- *

- * @param msec Miliseconds delay.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);

-

-/**

- * @def PJ_CHECK_STACK()

- * PJ_CHECK_STACK() macro is used to check the sanity of the stack.

- * The OS implementation may check that no stack overflow occurs, and

- * it also may collect statistic about stack usage.

- */

-#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0

-

-#  define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)

-

-/** @internal

- * The implementation of stack checking. 

- */

-PJ_DECL(void) pj_thread_check_stack(const char *file, int line);

-

-/** @internal

- * Get maximum stack usage statistic. 

- */

-PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);

-

-/** @internal

- * Dump thread stack status. 

- */

-PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,

-					      const char **file,

-					      int *line);

-#else

-

-#  define PJ_CHECK_STACK()

-/** pj_thread_get_stack_max_usage() for the thread */

-#  define pj_thread_get_stack_max_usage(thread)	    0

-/** pj_thread_get_stack_info() for the thread */

-#  define pj_thread_get_stack_info(thread,f,l)	    (*(f)="",*(l)=0)

-#endif	/* PJ_OS_HAS_CHECK_STACK */

-

-/**

- * @}

- */

-

-///////////////////////////////////////////////////////////////////////////////

-/**

- * @defgroup PJ_TLS Thread Local Storage.

- * @ingroup PJ_OS

- * @{

- */

-

-/** 

- * Allocate thread local storage index. The initial value of the variable at

- * the index is zero.

- *

- * @param index	    Pointer to hold the return value.

- * @return	    PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);

-

-/**

- * Deallocate thread local variable.

- *

- * @param index	    The variable index.

- */

-PJ_DECL(void) pj_thread_local_free(long index);

-

-/**

- * Set the value of thread local variable.

- *

- * @param index	    The index of the variable.

- * @param value	    The value.

- */

-PJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value);

-

-/**

- * Get the value of thread local variable.

- *

- * @param index	    The index of the variable.

- * @return	    The value.

- */

-PJ_DECL(void*) pj_thread_local_get(long index);

-

-

-/**

- * @}

- */

-

-

-///////////////////////////////////////////////////////////////////////////////

-/**

- * @defgroup PJ_ATOMIC Atomic Variables

- * @ingroup PJ_OS

- * @{

- *

- * This module provides API to manipulate atomic variables.

- *

- * \section pj_atomic_examples_sec Examples

- *

- * For some example codes, please see:

- *  - @ref page_pjlib_atomic_test

- */

-

-

-/**

- * Create atomic variable.

- *

- * @param pool	    The pool.

- * @param initial   The initial value of the atomic variable.

- * @param atomic    Pointer to hold the atomic variable upon return.

- *

- * @return	    PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool, 

-				       pj_atomic_value_t initial,

-				       pj_atomic_t **atomic );

-

-/**

- * Destroy atomic variable.

- *

- * @param atomic_var	the atomic variable.

- *

- * @return PJ_SUCCESS if success.

- */

-PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );

-

-/**

- * Set the value of an atomic type, and return the previous value.

- *

- * @param atomic_var	the atomic variable.

- * @param value		value to be set to the variable.

- */

-PJ_DECL(void) pj_atomic_set( pj_atomic_t *atomic_var, 

-			     pj_atomic_value_t value);

-

-/**

- * Get the value of an atomic type.

- *

- * @param atomic_var	the atomic variable.

- *

- * @return the value of the atomic variable.

- */

-PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);

-

-/**

- * Increment the value of an atomic type.

- *

- * @param atomic_var	the atomic variable.

- */

-PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var);

-

-/**

- * Increment the value of an atomic type and get the result.

- *

- * @param atomic_var	the atomic variable.

- *

- * @return              The incremented value.

- */

-PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var);

-

-/**

- * Decrement the value of an atomic type.

- *

- * @param atomic_var	the atomic variable.

- */

-PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var);

-

-/**

- * Decrement the value of an atomic type and get the result.

- *

- * @param atomic_var	the atomic variable.

- *

- * @return              The decremented value.

- */

-PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var);

-

-/**

- * Add a value to an atomic type.

- *

- * @param atomic_var	The atomic variable.

- * @param value		Value to be added.

- */

-PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var,

-			     pj_atomic_value_t value);

-

-/**

- * Add a value to an atomic type and get the result.

- *

- * @param atomic_var	The atomic variable.

- * @param value		Value to be added.

- *

- * @return              The result after the addition.

- */

-PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,

-			                          pj_atomic_value_t value);

-

-/**

- * @}

- */

-

-///////////////////////////////////////////////////////////////////////////////

-/**

- * @defgroup PJ_MUTEX Mutexes.

- * @ingroup PJ_OS

- * @{

- *

- * Mutex manipulation. Alternatively, application can use higher abstraction

- * for lock objects, which provides uniform API for all kinds of lock 

- * mechanisms, including mutex. See @ref PJ_LOCK for more information.

- */

-

-/**

- * Mutex types:

- *  - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.

- *  - PJ_MUTEX_SIMPLE: non-recursive mutex.

- *  - PJ_MUTEX_RECURSIVE: recursive mutex.

- */

-typedef enum pj_mutex_type_e

-{

-    PJ_MUTEX_DEFAULT,

-    PJ_MUTEX_SIMPLE,

-    PJ_MUTEX_RECURSE,

-} pj_mutex_type_e;

-

-

-/**

- * Create mutex of the specified type.

- *

- * @param pool	    The pool.

- * @param name	    Name to be associated with the mutex (for debugging).

- * @param type	    The type of the mutex, of type #pj_mutex_type_e.

- * @param mutex	    Pointer to hold the returned mutex instance.

- *

- * @return	    PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool, 

-                                     const char *name,

-				     int type, 

-                                     pj_mutex_t **mutex);

-

-/**

- * Create simple, non-recursive mutex.

- * This function is a simple wrapper for #pj_mutex_create to create 

- * non-recursive mutex.

- *

- * @param pool	    The pool.

- * @param name	    Mutex name.

- * @param mutex	    Pointer to hold the returned mutex instance.

- *

- * @return	    PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,

-					     pj_mutex_t **mutex );

-

-/**

- * Create recursive mutex.

- * This function is a simple wrapper for #pj_mutex_create to create 

- * recursive mutex.

- *

- * @param pool	    The pool.

- * @param name	    Mutex name.

- * @param mutex	    Pointer to hold the returned mutex instance.

- *

- * @return	    PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,

-					        const char *name,

-						pj_mutex_t **mutex );

-

-/**

- * Acquire mutex lock.

- *

- * @param mutex	    The mutex.

- * @return	    PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);

-

-/**

- * Release mutex lock.

- *

- * @param mutex	    The mutex.

- * @return	    PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);

-

-/**

- * Try to acquire mutex lock.

- *

- * @param mutex	    The mutex.

- * @return	    PJ_SUCCESS on success, or the error code if the

- *		    lock couldn't be acquired.

- */

-PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);

-

-/**

- * Destroy mutex.

- *

- * @param mutex	    Te mutex.

- * @return	    PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);

-

-/**

- * Determine whether calling thread is owning the mutex (only available when

- * PJ_DEBUG is set).

- * @param mutex	    The mutex.

- * @return	    Non-zero if yes.

- */

-#if defined(PJ_DEBUG) && PJ_DEBUG != 0

-   PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);

-#else

-#  define pj_mutex_is_locked(mutex)	    1

-#endif

-

-/**

- * @}

- */

-

-///////////////////////////////////////////////////////////////////////////////

-/**

- * @defgroup PJ_CRIT_SEC Critical sections.

- * @ingroup PJ_OS

- * @{

- * Critical section protection can be used to protect regions where:

- *  - mutual exclusion protection is needed.

- *  - it's rather too expensive to create a mutex.

- *  - the time spent in the region is very very brief.

- *

- * Critical section is a global object, and it prevents any threads from

- * entering any regions that are protected by critical section once a thread

- * is already in the section.

- *

- * Critial section is \a not recursive!

- *

- * Application <b>MUST NOT</b> call any functions that may cause current

- * thread to block (such as allocating memory, performing I/O, locking mutex,

- * etc.) while holding the critical section.

- */

-/**

- * Enter critical section.

- */

-PJ_DECL(void) pj_enter_critical_section(void);

-

-/**

- * Leave critical section.

- */

-PJ_DECL(void) pj_leave_critical_section(void);

-

-/**

- * @}

- */

-

-///////////////////////////////////////////////////////////////////////////////

-#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0

-/**

- * @defgroup PJ_SEM Semaphores.

- * @ingroup PJ_OS

- * @{

- *

- * This module provides abstraction for semaphores, where available.

- */

-

-/**

- * Create semaphore.

- *

- * @param pool	    The pool.

- * @param name	    Name to be assigned to the semaphore (for logging purpose)

- * @param initial   The initial count of the semaphore.

- * @param max	    The maximum count of the semaphore.

- * @param sem	    Pointer to hold the semaphore created.

- *

- * @return	    PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool, 

-                                    const char *name,

-				    unsigned initial, 

-                                    unsigned max,

-				    pj_sem_t **sem);

-

-/**

- * Wait for semaphore.

- *

- * @param sem	The semaphore.

- *

- * @return	PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);

-

-/**

- * Try wait for semaphore.

- *

- * @param sem	The semaphore.

- *

- * @return	PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);

-

-/**

- * Release semaphore.

- *

- * @param sem	The semaphore.

- *

- * @return	PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);

-

-/**

- * Destroy semaphore.

- *

- * @param sem	The semaphore.

- *

- * @return	PJ_SUCCESS on success, or the error code.

- */

-PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);

-

-/**

- * @}

- */

-#endif	/* PJ_HAS_SEMAPHORE */

-

-

-///////////////////////////////////////////////////////////////////////////////

-#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0

-/**

- * @defgroup PJ_EVENT Event Object.

- * @ingroup PJ_OS

- * @{

- *

- * This module provides abstraction to event object (e.g. Win32 Event) where

- * available. Event objects can be used for synchronization among threads.

- */

-

-/**

- * Create event object.

- *

- * @param pool		The pool.

- * @param name		The name of the event object (for logging purpose).

- * @param manual_reset	Specify whether the event is manual-reset

- * @param initial	Specify the initial state of the event object.

- * @param event		Pointer to hold the returned event object.

- *

- * @return event handle, or NULL if failed.

- */

-PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,

-				     pj_bool_t manual_reset, pj_bool_t initial,

-				     pj_event_t **event);

-

-/**

- * Wait for event to be signaled.

- *

- * @param event	    The event object.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);

-

-/**

- * Try wait for event object to be signalled.

- *

- * @param event The event object.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);

-

-/**

- * Set the event object state to signaled. For auto-reset event, this 

- * will only release the first thread that are waiting on the event. For

- * manual reset event, the state remains signaled until the event is reset.

- * If there is no thread waiting on the event, the event object state 

- * remains signaled.

- *

- * @param event	    The event object.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);

-

-/**

- * Set the event object to signaled state to release appropriate number of

- * waiting threads and then reset the event object to non-signaled. For

- * manual-reset event, this function will release all waiting threads. For

- * auto-reset event, this function will only release one waiting thread.

- *

- * @param event	    The event object.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);

-

-/**

- * Set the event object state to non-signaled.

- *

- * @param event	    The event object.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);

-

-/**

- * Destroy the event object.

- *

- * @param event	    The event object.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);

-

-/**

- * @}

- */

-#endif	/* PJ_HAS_EVENT_OBJ */

-

-///////////////////////////////////////////////////////////////////////////////

-/**

- * @addtogroup PJ_TIME Time Data Type and Manipulation.

- * @ingroup PJ_OS

- * @{

- * This module provides API for manipulating time.

- *

- * \section pj_time_examples_sec Examples

- *

- * For examples, please see:

- *  - \ref page_pjlib_sleep_test

- */

-

-/**

- * Get current time of day in local representation.

- *

- * @param tv	Variable to store the result.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);

-

-

-/**

- * Parse time value into date/time representation.

- *

- * @param tv	The time.

- * @param pt	Variable to store the date time result.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);

-

-/**

- * Encode date/time to time value.

- *

- * @param pt	The date/time.

- * @param tv	Variable to store time value result.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);

-

-/**

- * Convert local time to GMT.

- *

- * @param tv	Time to convert.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);

-

-/**

- * Convert GMT to local time.

- *

- * @param tv	Time to convert.

- *

- * @return zero if successfull.

- */

-PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);

-

-/**

- * @}

- */

-

-///////////////////////////////////////////////////////////////////////////////

-#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0

-

-/**

- * @defgroup PJ_TERM Terminal

- * @ingroup PJ_OS

- * @{

- */

-

-/**

- * Set current terminal color.

- *

- * @param color	    The RGB color.

- *

- * @return zero on success.

- */

-PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);

-

-/**

- * Get current terminal foreground color.

- *

- * @return RGB color.

- */

-PJ_DECL(pj_color_t) pj_term_get_color(void);

-

-/**

- * @}

- */

-

-#endif	/* PJ_TERM_HAS_COLOR */

-

-///////////////////////////////////////////////////////////////////////////////

-/**

- * @defgroup PJ_TIMESTAMP High Resolution Timestamp

- * @ingroup PJ_OS

- * @{

- *

- * PJLIB provides <b>High Resolution Timestamp</b> API to access highest 

- * resolution timestamp value provided by the platform. The API is usefull

- * to measure precise elapsed time, and can be used in applications such

- * as profiling.

- *

- * The timestamp value is represented in cycles, and can be related to

- * normal time (in seconds or sub-seconds) using various functions provided.

- *

- * \section pj_timestamp_examples_sec Examples

- *

- * For examples, please see:

- *  - \ref page_pjlib_sleep_test

- *  - \ref page_pjlib_timestamp_test

- */

-

-/*

- * High resolution timer.

- */

-#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0

-

-/**

- * This structure represents high resolution (64bit) time value. The time

- * values represent time in cycles, which is retrieved by calling

- * #pj_get_timestamp().

- */

-typedef union pj_timestamp

-{

-    struct

-    {

-#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0

-	pj_uint32_t lo;     /**< Low 32-bit value of the 64-bit value. */

-	pj_uint32_t hi;     /**< high 32-bit value of the 64-bit value. */

-#else

-	pj_uint32_t hi;     /**< high 32-bit value of the 64-bit value. */

-	pj_uint32_t lo;     /**< Low 32-bit value of the 64-bit value. */

-#endif

-    } u32;                  /**< The 64-bit value as two 32-bit values. */

-

-#if PJ_HAS_INT64

-    pj_uint64_t u64;        /**< The whole 64-bit value, where available. */

-#endif

-} pj_timestamp;

-

-

-/**

- * Acquire high resolution timer value. The time value are stored

- * in cycles.

- *

- * @param ts	    High resolution timer value.

- * @return	    PJ_SUCCESS or the appropriate error code.

- *

- * @see pj_get_timestamp_freq().

- */

-PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);

-

-/**

- * Get high resolution timer frequency, in cycles per second.

- *

- * @param freq	    Timer frequency, in cycles per second.

- * @return	    PJ_SUCCESS or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);

-

-/**

- * Add timestamp t2 to t1.

- * @param t1	    t1.

- * @param t2	    t2.

- */

-PJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2)

-{

-#if PJ_HAS_INT64

-    t1->u64 += t2->u64;

-#else

-    pj_uint32_t old = t1->u32.lo;

-    t1->u32.hi += t2->u32.hi;

-    t1->u32.lo += t2->u32.lo;

-    if (t1->u32.lo < old)

-	++t1->u32.hi;

-#endif

-}

-

-/**

- * Substract timestamp t2 from t1.

- * @param t1	    t1.

- * @param t2	    t2.

- */

-PJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2)

-{

-#if PJ_HAS_INT64

-    t1->u64 -= t2->u64;

-#else

-    t1->u32.hi -= t2->u32.hi;

-    if (t1->u32.lo >= t2->u32.lo)

-	t1->u32.lo -= t2->u32.lo;

-    else {

-	t1->u32.lo -= t2->u32.lo;

-	--t1->u32.hi;

-    }

-#endif

-}

-

-/**

- * Calculate the elapsed time, and store it in pj_time_val.

- * This function calculates the elapsed time using highest precision

- * calculation that is available for current platform, considering

- * whether floating point or 64-bit precision arithmetic is available. 

- * For maximum portability, application should prefer to use this function

- * rather than calculating the elapsed time by itself.

- *

- * @param start     The starting timestamp.

- * @param stop      The end timestamp.

- *

- * @return	    Elapsed time as #pj_time_val.

- *

- * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()

- */

-PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,

-                                      const pj_timestamp *stop );

-

-/**

- * Calculate the elapsed time in 32-bit microseconds.

- * This function calculates the elapsed time using highest precision

- * calculation that is available for current platform, considering

- * whether floating point or 64-bit precision arithmetic is available. 

- * For maximum portability, application should prefer to use this function

- * rather than calculating the elapsed time by itself.

- *

- * @param start     The starting timestamp.

- * @param stop      The end timestamp.

- *

- * @return	    Elapsed time in microsecond.

- *

- * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()

- */

-PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,

-                                      const pj_timestamp *stop );

-

-/**

- * Calculate the elapsed time in 32-bit nanoseconds.

- * This function calculates the elapsed time using highest precision

- * calculation that is available for current platform, considering

- * whether floating point or 64-bit precision arithmetic is available. 

- * For maximum portability, application should prefer to use this function

- * rather than calculating the elapsed time by itself.

- *

- * @param start     The starting timestamp.

- * @param stop      The end timestamp.

- *

- * @return	    Elapsed time in nanoseconds.

- *

- * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()

- */

-PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,

-                                         const pj_timestamp *stop );

-

-/**

- * Calculate the elapsed time in 32-bit cycles.

- * This function calculates the elapsed time using highest precision

- * calculation that is available for current platform, considering

- * whether floating point or 64-bit precision arithmetic is available. 

- * For maximum portability, application should prefer to use this function

- * rather than calculating the elapsed time by itself.

- *

- * @param start     The starting timestamp.

- * @param stop      The end timestamp.

- *

- * @return	    Elapsed time in cycles.

- *

- * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()

- */

-PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,

-                                       const pj_timestamp *stop );

-

-

-#endif	/* PJ_HAS_HIGH_RES_TIMER */

-

-/** @} */

-

-

-///////////////////////////////////////////////////////////////////////////////

-/**

- * Internal PJLIB function to initialize the threading subsystem.

- * @return          PJ_SUCCESS or the appropriate error code.

- */

-pj_status_t pj_thread_init(void);

-

-

-PJ_END_DECL

-

-#endif  /* __PJ_OS_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_OS_H__
+#define __PJ_OS_H__
+
+/**
+ * @file os.h
+ * @brief OS dependent functions
+ */
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_OS Operating System Dependent Functionality.
+ * @ingroup PJ
+ */
+
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup PJ_THREAD Threads
+ * @ingroup PJ_OS
+ * @{
+ * This module provides multithreading API.
+ *
+ * \section pj_thread_examples_sec Examples
+ *
+ * For examples, please see:
+ *  - \ref page_pjlib_thread_test
+ *  - \ref page_pjlib_sleep_test
+ *
+ */
+
+/**
+ * Thread creation flags:
+ * - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.
+ */
+typedef enum pj_thread_create_flags
+{
+    PJ_THREAD_SUSPENDED = 1
+} pj_thread_create_flags;
+
+
+/**
+ * Specify this as \a stack_size argument in #pj_thread_create() to specify
+ * that thread should use default stack size for the current platform.
+ */
+#define PJ_THREAD_DEFAULT_STACK_SIZE    0
+
+/**
+ * Type of thread entry function.
+ */
+typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);
+
+/**
+ * Size of thread struct.
+ */
+#if !defined(PJ_THREAD_DESC_SIZE)
+#   define PJ_THREAD_DESC_SIZE	    (16)
+#endif
+
+/**
+ * Thread structure, to thread's state when the thread is created by external
+ * or native API. 
+ */
+typedef long pj_thread_desc[PJ_THREAD_DESC_SIZE];
+
+/**
+ * Get process ID.
+ * @return process ID.
+ */
+PJ_DECL(pj_uint32_t) pj_getpid(void);
+
+/**
+ * Create a new thread.
+ *
+ * @param pool          The memory pool from which the thread record 
+ *                      will be allocated from.
+ * @param thread_name   The optional name to be assigned to the thread.
+ * @param proc          Thread entry function.
+ * @param arg           Argument to be passed to the thread entry function.
+ * @param stack_size    The size of the stack for the new thread, or ZERO or
+ *                      PJ_THREAD_DEFAULT_STACK_SIZE to let the 
+ *		        library choose the reasonable size for the stack. 
+ *                      For some systems, the stack will be allocated from 
+ *                      the pool, so the pool must have suitable capacity.
+ * @param flags         Flags for thread creation, which is bitmask combination 
+ *                      from enum pj_thread_create_flags.
+ * @param thread        Pointer to hold the newly created thread.
+ *
+ * @return	        PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_create(  pj_pool_t *pool, 
+                                        const char *thread_name,
+				        pj_thread_proc *proc, 
+                                        void *arg,
+				        pj_size_t stack_size, 
+                                        unsigned flags,
+					pj_thread_t **thread );
+
+/**
+ * Register a thread that was created by external or native API to PJLIB.
+ * This function must be called in the context of the thread being registered.
+ * When the thread is created by external function or API call,
+ * it must be 'registered' to PJLIB using pj_thread_register(), so that it can
+ * cooperate with PJLIB's framework. During registration, some data needs to
+ * be maintained, and this data must remain available during the thread's 
+ * lifetime.
+ *
+ * @param thread_name   The optional name to be assigned to the thread.
+ * @param desc          Thread descriptor, which must be available throughout 
+ *                      the lifetime of the thread.
+ * @param thread        Pointer to hold the created thread handle.
+ *
+ * @return              PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,
+					  pj_thread_desc desc,
+					  pj_thread_t **thread);
+
+/**
+ * Get thread name.
+ *
+ * @param thread    The thread handle.
+ *
+ * @return Thread name as null terminated string.
+ */
+PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);
+
+/**
+ * Resume a suspended thread.
+ *
+ * @param thread    The thread handle.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
+
+/**
+ * Get the current thread.
+ *
+ * @return Thread handle of current thread.
+ */
+PJ_DECL(pj_thread_t*) pj_thread_this(void);
+
+/**
+ * Join thread.
+ * This function will block the caller thread until the specified thread exits.
+ *
+ * @param thread    The thread handle.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
+
+
+/**
+ * Destroy thread and release resources allocated for the thread.
+ * However, the memory allocated for the pj_thread_t itself will only be released
+ * when the pool used to create the thread is destroyed.
+ *
+ * @param thread    The thread handle.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);
+
+
+/**
+ * Put the current thread to sleep for the specified miliseconds.
+ *
+ * @param msec Miliseconds delay.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);
+
+/**
+ * @def PJ_CHECK_STACK()
+ * PJ_CHECK_STACK() macro is used to check the sanity of the stack.
+ * The OS implementation may check that no stack overflow occurs, and
+ * it also may collect statistic about stack usage.
+ */
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
+
+#  define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)
+
+/** @internal
+ * The implementation of stack checking. 
+ */
+PJ_DECL(void) pj_thread_check_stack(const char *file, int line);
+
+/** @internal
+ * Get maximum stack usage statistic. 
+ */
+PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);
+
+/** @internal
+ * Dump thread stack status. 
+ */
+PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
+					      const char **file,
+					      int *line);
+#else
+
+#  define PJ_CHECK_STACK()
+/** pj_thread_get_stack_max_usage() for the thread */
+#  define pj_thread_get_stack_max_usage(thread)	    0
+/** pj_thread_get_stack_info() for the thread */
+#  define pj_thread_get_stack_info(thread,f,l)	    (*(f)="",*(l)=0)
+#endif	/* PJ_OS_HAS_CHECK_STACK */
+
+/**
+ * @}
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup PJ_TLS Thread Local Storage.
+ * @ingroup PJ_OS
+ * @{
+ */
+
+/** 
+ * Allocate thread local storage index. The initial value of the variable at
+ * the index is zero.
+ *
+ * @param index	    Pointer to hold the return value.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);
+
+/**
+ * Deallocate thread local variable.
+ *
+ * @param index	    The variable index.
+ */
+PJ_DECL(void) pj_thread_local_free(long index);
+
+/**
+ * Set the value of thread local variable.
+ *
+ * @param index	    The index of the variable.
+ * @param value	    The value.
+ */
+PJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value);
+
+/**
+ * Get the value of thread local variable.
+ *
+ * @param index	    The index of the variable.
+ * @return	    The value.
+ */
+PJ_DECL(void*) pj_thread_local_get(long index);
+
+
+/**
+ * @}
+ */
+
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup PJ_ATOMIC Atomic Variables
+ * @ingroup PJ_OS
+ * @{
+ *
+ * This module provides API to manipulate atomic variables.
+ *
+ * \section pj_atomic_examples_sec Examples
+ *
+ * For some example codes, please see:
+ *  - @ref page_pjlib_atomic_test
+ */
+
+
+/**
+ * Create atomic variable.
+ *
+ * @param pool	    The pool.
+ * @param initial   The initial value of the atomic variable.
+ * @param atomic    Pointer to hold the atomic variable upon return.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool, 
+				       pj_atomic_value_t initial,
+				       pj_atomic_t **atomic );
+
+/**
+ * Destroy atomic variable.
+ *
+ * @param atomic_var	the atomic variable.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );
+
+/**
+ * Set the value of an atomic type, and return the previous value.
+ *
+ * @param atomic_var	the atomic variable.
+ * @param value		value to be set to the variable.
+ */
+PJ_DECL(void) pj_atomic_set( pj_atomic_t *atomic_var, 
+			     pj_atomic_value_t value);
+
+/**
+ * Get the value of an atomic type.
+ *
+ * @param atomic_var	the atomic variable.
+ *
+ * @return the value of the atomic variable.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);
+
+/**
+ * Increment the value of an atomic type.
+ *
+ * @param atomic_var	the atomic variable.
+ */
+PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var);
+
+/**
+ * Increment the value of an atomic type and get the result.
+ *
+ * @param atomic_var	the atomic variable.
+ *
+ * @return              The incremented value.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var);
+
+/**
+ * Decrement the value of an atomic type.
+ *
+ * @param atomic_var	the atomic variable.
+ */
+PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var);
+
+/**
+ * Decrement the value of an atomic type and get the result.
+ *
+ * @param atomic_var	the atomic variable.
+ *
+ * @return              The decremented value.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var);
+
+/**
+ * Add a value to an atomic type.
+ *
+ * @param atomic_var	The atomic variable.
+ * @param value		Value to be added.
+ */
+PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var,
+			     pj_atomic_value_t value);
+
+/**
+ * Add a value to an atomic type and get the result.
+ *
+ * @param atomic_var	The atomic variable.
+ * @param value		Value to be added.
+ *
+ * @return              The result after the addition.
+ */
+PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
+			                          pj_atomic_value_t value);
+
+/**
+ * @}
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup PJ_MUTEX Mutexes.
+ * @ingroup PJ_OS
+ * @{
+ *
+ * Mutex manipulation. Alternatively, application can use higher abstraction
+ * for lock objects, which provides uniform API for all kinds of lock 
+ * mechanisms, including mutex. See @ref PJ_LOCK for more information.
+ */
+
+/**
+ * Mutex types:
+ *  - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.
+ *  - PJ_MUTEX_SIMPLE: non-recursive mutex.
+ *  - PJ_MUTEX_RECURSIVE: recursive mutex.
+ */
+typedef enum pj_mutex_type_e
+{
+    PJ_MUTEX_DEFAULT,
+    PJ_MUTEX_SIMPLE,
+    PJ_MUTEX_RECURSE,
+} pj_mutex_type_e;
+
+
+/**
+ * Create mutex of the specified type.
+ *
+ * @param pool	    The pool.
+ * @param name	    Name to be associated with the mutex (for debugging).
+ * @param type	    The type of the mutex, of type #pj_mutex_type_e.
+ * @param mutex	    Pointer to hold the returned mutex instance.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool, 
+                                     const char *name,
+				     int type, 
+                                     pj_mutex_t **mutex);
+
+/**
+ * Create simple, non-recursive mutex.
+ * This function is a simple wrapper for #pj_mutex_create to create 
+ * non-recursive mutex.
+ *
+ * @param pool	    The pool.
+ * @param name	    Mutex name.
+ * @param mutex	    Pointer to hold the returned mutex instance.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
+					     pj_mutex_t **mutex );
+
+/**
+ * Create recursive mutex.
+ * This function is a simple wrapper for #pj_mutex_create to create 
+ * recursive mutex.
+ *
+ * @param pool	    The pool.
+ * @param name	    Mutex name.
+ * @param mutex	    Pointer to hold the returned mutex instance.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
+					        const char *name,
+						pj_mutex_t **mutex );
+
+/**
+ * Acquire mutex lock.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);
+
+/**
+ * Release mutex lock.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);
+
+/**
+ * Try to acquire mutex lock.
+ *
+ * @param mutex	    The mutex.
+ * @return	    PJ_SUCCESS on success, or the error code if the
+ *		    lock couldn't be acquired.
+ */
+PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);
+
+/**
+ * Destroy mutex.
+ *
+ * @param mutex	    Te mutex.
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);
+
+/**
+ * Determine whether calling thread is owning the mutex (only available when
+ * PJ_DEBUG is set).
+ * @param mutex	    The mutex.
+ * @return	    Non-zero if yes.
+ */
+#if defined(PJ_DEBUG) && PJ_DEBUG != 0
+   PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
+#else
+#  define pj_mutex_is_locked(mutex)	    1
+#endif
+
+/**
+ * @}
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup PJ_CRIT_SEC Critical sections.
+ * @ingroup PJ_OS
+ * @{
+ * Critical section protection can be used to protect regions where:
+ *  - mutual exclusion protection is needed.
+ *  - it's rather too expensive to create a mutex.
+ *  - the time spent in the region is very very brief.
+ *
+ * Critical section is a global object, and it prevents any threads from
+ * entering any regions that are protected by critical section once a thread
+ * is already in the section.
+ *
+ * Critial section is \a not recursive!
+ *
+ * Application <b>MUST NOT</b> call any functions that may cause current
+ * thread to block (such as allocating memory, performing I/O, locking mutex,
+ * etc.) while holding the critical section.
+ */
+/**
+ * Enter critical section.
+ */
+PJ_DECL(void) pj_enter_critical_section(void);
+
+/**
+ * Leave critical section.
+ */
+PJ_DECL(void) pj_leave_critical_section(void);
+
+/**
+ * @}
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
+/**
+ * @defgroup PJ_SEM Semaphores.
+ * @ingroup PJ_OS
+ * @{
+ *
+ * This module provides abstraction for semaphores, where available.
+ */
+
+/**
+ * Create semaphore.
+ *
+ * @param pool	    The pool.
+ * @param name	    Name to be assigned to the semaphore (for logging purpose)
+ * @param initial   The initial count of the semaphore.
+ * @param max	    The maximum count of the semaphore.
+ * @param sem	    Pointer to hold the semaphore created.
+ *
+ * @return	    PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool, 
+                                    const char *name,
+				    unsigned initial, 
+                                    unsigned max,
+				    pj_sem_t **sem);
+
+/**
+ * Wait for semaphore.
+ *
+ * @param sem	The semaphore.
+ *
+ * @return	PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
+
+/**
+ * Try wait for semaphore.
+ *
+ * @param sem	The semaphore.
+ *
+ * @return	PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
+
+/**
+ * Release semaphore.
+ *
+ * @param sem	The semaphore.
+ *
+ * @return	PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
+
+/**
+ * Destroy semaphore.
+ *
+ * @param sem	The semaphore.
+ *
+ * @return	PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
+
+/**
+ * @}
+ */
+#endif	/* PJ_HAS_SEMAPHORE */
+
+
+///////////////////////////////////////////////////////////////////////////////
+#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
+/**
+ * @defgroup PJ_EVENT Event Object.
+ * @ingroup PJ_OS
+ * @{
+ *
+ * This module provides abstraction to event object (e.g. Win32 Event) where
+ * available. Event objects can be used for synchronization among threads.
+ */
+
+/**
+ * Create event object.
+ *
+ * @param pool		The pool.
+ * @param name		The name of the event object (for logging purpose).
+ * @param manual_reset	Specify whether the event is manual-reset
+ * @param initial	Specify the initial state of the event object.
+ * @param event		Pointer to hold the returned event object.
+ *
+ * @return event handle, or NULL if failed.
+ */
+PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
+				     pj_bool_t manual_reset, pj_bool_t initial,
+				     pj_event_t **event);
+
+/**
+ * Wait for event to be signaled.
+ *
+ * @param event	    The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
+
+/**
+ * Try wait for event object to be signalled.
+ *
+ * @param event The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
+
+/**
+ * Set the event object state to signaled. For auto-reset event, this 
+ * will only release the first thread that are waiting on the event. For
+ * manual reset event, the state remains signaled until the event is reset.
+ * If there is no thread waiting on the event, the event object state 
+ * remains signaled.
+ *
+ * @param event	    The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
+
+/**
+ * Set the event object to signaled state to release appropriate number of
+ * waiting threads and then reset the event object to non-signaled. For
+ * manual-reset event, this function will release all waiting threads. For
+ * auto-reset event, this function will only release one waiting thread.
+ *
+ * @param event	    The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
+
+/**
+ * Set the event object state to non-signaled.
+ *
+ * @param event	    The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
+
+/**
+ * Destroy the event object.
+ *
+ * @param event	    The event object.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
+
+/**
+ * @}
+ */
+#endif	/* PJ_HAS_EVENT_OBJ */
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * @addtogroup PJ_TIME Time Data Type and Manipulation.
+ * @ingroup PJ_OS
+ * @{
+ * This module provides API for manipulating time.
+ *
+ * \section pj_time_examples_sec Examples
+ *
+ * For examples, please see:
+ *  - \ref page_pjlib_sleep_test
+ */
+
+/**
+ * Get current time of day in local representation.
+ *
+ * @param tv	Variable to store the result.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
+
+
+/**
+ * Parse time value into date/time representation.
+ *
+ * @param tv	The time.
+ * @param pt	Variable to store the date time result.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
+
+/**
+ * Encode date/time to time value.
+ *
+ * @param pt	The date/time.
+ * @param tv	Variable to store time value result.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
+
+/**
+ * Convert local time to GMT.
+ *
+ * @param tv	Time to convert.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
+
+/**
+ * Convert GMT to local time.
+ *
+ * @param tv	Time to convert.
+ *
+ * @return zero if successfull.
+ */
+PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
+
+/**
+ * @}
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
+
+/**
+ * @defgroup PJ_TERM Terminal
+ * @ingroup PJ_OS
+ * @{
+ */
+
+/**
+ * Set current terminal color.
+ *
+ * @param color	    The RGB color.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
+
+/**
+ * Get current terminal foreground color.
+ *
+ * @return RGB color.
+ */
+PJ_DECL(pj_color_t) pj_term_get_color(void);
+
+/**
+ * @}
+ */
+
+#endif	/* PJ_TERM_HAS_COLOR */
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup PJ_TIMESTAMP High Resolution Timestamp
+ * @ingroup PJ_OS
+ * @{
+ *
+ * PJLIB provides <b>High Resolution Timestamp</b> API to access highest 
+ * resolution timestamp value provided by the platform. The API is usefull
+ * to measure precise elapsed time, and can be used in applications such
+ * as profiling.
+ *
+ * The timestamp value is represented in cycles, and can be related to
+ * normal time (in seconds or sub-seconds) using various functions provided.
+ *
+ * \section pj_timestamp_examples_sec Examples
+ *
+ * For examples, please see:
+ *  - \ref page_pjlib_sleep_test
+ *  - \ref page_pjlib_timestamp_test
+ */
+
+/*
+ * High resolution timer.
+ */
+#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
+
+/**
+ * This structure represents high resolution (64bit) time value. The time
+ * values represent time in cycles, which is retrieved by calling
+ * #pj_get_timestamp().
+ */
+typedef union pj_timestamp
+{
+    struct
+    {
+#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
+	pj_uint32_t lo;     /**< Low 32-bit value of the 64-bit value. */
+	pj_uint32_t hi;     /**< high 32-bit value of the 64-bit value. */
+#else
+	pj_uint32_t hi;     /**< high 32-bit value of the 64-bit value. */
+	pj_uint32_t lo;     /**< Low 32-bit value of the 64-bit value. */
+#endif
+    } u32;                  /**< The 64-bit value as two 32-bit values. */
+
+#if PJ_HAS_INT64
+    pj_uint64_t u64;        /**< The whole 64-bit value, where available. */
+#endif
+} pj_timestamp;
+
+
+/**
+ * Acquire high resolution timer value. The time value are stored
+ * in cycles.
+ *
+ * @param ts	    High resolution timer value.
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ *
+ * @see pj_get_timestamp_freq().
+ */
+PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
+
+/**
+ * Get high resolution timer frequency, in cycles per second.
+ *
+ * @param freq	    Timer frequency, in cycles per second.
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
+
+/**
+ * Add timestamp t2 to t1.
+ * @param t1	    t1.
+ * @param t2	    t2.
+ */
+PJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
+{
+#if PJ_HAS_INT64
+    t1->u64 += t2->u64;
+#else
+    pj_uint32_t old = t1->u32.lo;
+    t1->u32.hi += t2->u32.hi;
+    t1->u32.lo += t2->u32.lo;
+    if (t1->u32.lo < old)
+	++t1->u32.hi;
+#endif
+}
+
+/**
+ * Substract timestamp t2 from t1.
+ * @param t1	    t1.
+ * @param t2	    t2.
+ */
+PJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
+{
+#if PJ_HAS_INT64
+    t1->u64 -= t2->u64;
+#else
+    t1->u32.hi -= t2->u32.hi;
+    if (t1->u32.lo >= t2->u32.lo)
+	t1->u32.lo -= t2->u32.lo;
+    else {
+	t1->u32.lo -= t2->u32.lo;
+	--t1->u32.hi;
+    }
+#endif
+}
+
+/**
+ * Calculate the elapsed time, and store it in pj_time_val.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available. 
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start     The starting timestamp.
+ * @param stop      The end timestamp.
+ *
+ * @return	    Elapsed time as #pj_time_val.
+ *
+ * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
+                                      const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time in 32-bit microseconds.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available. 
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start     The starting timestamp.
+ * @param stop      The end timestamp.
+ *
+ * @return	    Elapsed time in microsecond.
+ *
+ * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
+                                      const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time in 32-bit nanoseconds.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available. 
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start     The starting timestamp.
+ * @param stop      The end timestamp.
+ *
+ * @return	    Elapsed time in nanoseconds.
+ *
+ * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
+                                         const pj_timestamp *stop );
+
+/**
+ * Calculate the elapsed time in 32-bit cycles.
+ * This function calculates the elapsed time using highest precision
+ * calculation that is available for current platform, considering
+ * whether floating point or 64-bit precision arithmetic is available. 
+ * For maximum portability, application should prefer to use this function
+ * rather than calculating the elapsed time by itself.
+ *
+ * @param start     The starting timestamp.
+ * @param stop      The end timestamp.
+ *
+ * @return	    Elapsed time in cycles.
+ *
+ * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
+ */
+PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
+                                       const pj_timestamp *stop );
+
+
+#endif	/* PJ_HAS_HIGH_RES_TIMER */
+
+/** @} */
+
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * Internal PJLIB function to initialize the threading subsystem.
+ * @return          PJ_SUCCESS or the appropriate error code.
+ */
+pj_status_t pj_thread_init(void);
+
+
+PJ_END_DECL
+
+#endif  /* __PJ_OS_H__ */
+
diff --git a/pjlib/include/pj/pool.h b/pjlib/include/pj/pool.h
index b3037b3..c47195c 100644
--- a/pjlib/include/pj/pool.h
+++ b/pjlib/include/pj/pool.h
@@ -1,586 +1,586 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_POOL_H__

-#define __PJ_POOL_H__

-

-/**

- * @file pool.h

- * @brief Memory Pool.

- */

-

-#include <pj/list.h>

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup PJ_POOL_GROUP Memory Pool Management

- * @ingroup PJ

- * @brief

- * Memory pool management provides API to allocate and deallocate memory from

- * memory pool and to manage and establish policy for pool creation and

- * destruction in pool factory.

- *

- * \section PJ_POOL_FACTORY_SEC Pool Factory

- * See: \ref PJ_POOL_FACTORY "Pool Factory"

- *

- * A memory pool must be created through a factory. A factory not only provides

- * generic interface functions to create and release pool, but also provides 

- * strategy to manage the life time of pools. One sample implementation, 

- * \a pj_caching_pool, can be set to keep the pools released by application for

- * future use as long as the total memory is below the limit.

- * 

- * The pool factory interface declared in PJLIB is designed to be extensible.

- * Application can define its own strategy by creating it's own pool factory

- * implementation, and this strategy can be used even by existing library

- * without recompilation.

- *

- *

- * \section PJ_POOL_POLICY_SEC Pool Factory Policy

- * See: \ref PJ_POOL_FACTORY "Pool Factory Policy"

- *

- * A pool factory only defines functions to create and release pool and how

- * to manage pools, but the rest of the functionalities are controlled by

- * policy. A pool policy defines:

- *  - how memory block is allocated and deallocated (the default implementation

- *    allocates and deallocate memory by calling malloc() and free()).

- *  - callback to be called when memory allocation inside a pool fails (the

- *    default implementation will throw PJ_NO_MEMORY_EXCEPTION exception).

- *  - concurrency when creating and releasing pool from/to the factory.

- *

- * A pool factory can be given different policy during creation to make

- * it behave differently. For example, caching pool factory can be configured

- * to allocate and deallocate from a static/contiguous/preallocated memory 

- * instead of using malloc()/free().

- * 

- * What strategy/factory and what policy to use is not defined by PJLIB, but

- * instead is left to application to make use whichever is most efficient for

- * itself.

- *

- *

- * \section PJ_POOL_POOL_SEC The Pool

- * See: \ref PJ_POOL "Pool"

- *

- * The memory pool is an opaque object created by pool factory.

- * Application uses this object to request a memory chunk, by calling

- * #pj_pool_alloc or #pj_pool_calloc. When the application has finished using

- * the pool, it must call #pj_pool_release to free all the chunks previously

- * allocated and release the pool back to the factory.

- *

- * \section PJ_POOL_THREADING_SEC More on Threading Policies:

- * - By design, memory allocation from a pool is not thread safe. We assumed 

- *   that a pool will be owned by an object, and thread safety should be 

- *   handled by that object. Thus these functions are not thread safe: 

- *	- #pj_pool_alloc, 

- *	- #pj_pool_calloc, 

- *	- and other pool statistic functions.

- * - Threading in the pool factory is decided by the policy set for the

- *   factory when it was created.

- *

- * \section PJ_POOL_EXAMPLES_SEC Examples

- *

- * For some sample codes on how to use the pool, please see:

- *  - @ref page_pjlib_pool_test

- */

-

-/**

- * @defgroup PJ_POOL Memory Pool.

- * @ingroup PJ_POOL_GROUP

- * @brief

- * A memory pool is initialized with an initial amount of memory, which is

- * called a block. Pool can be configured to dynamically allocate more memory 

- * blocks when it runs out of memory. Subsequent memory allocations by user 

- * will use up portions of these block. 

- * The pool doesn't keep track of individual memory allocations

- * by user, and the user doesn't have to free these indidual allocations. This

- * makes memory allocation simple and very fast. All the memory allocated from

- * the pool will be destroyed when the pool itself is destroyed.

- * @{

- */

-

-/**

- * The type for function to receive callback from the pool when it is unable

- * to allocate memory. The elegant way to handle this condition is to throw

- * exception, and this is what is expected by most of this library 

- * components.

- */

-typedef void pj_pool_callback(pj_pool_t *pool, pj_size_t size);

-

-/**

- * This class, which is used internally by the pool, describes a single 

- * block of memory from which user memory allocations will be allocated from.

- */

-typedef struct pj_pool_block

-{

-    PJ_DECL_LIST_MEMBER(struct pj_pool_block);  /**< List's prev and next.  */

-    unsigned char    *buf;                      /**< Start of buffer.       */

-    unsigned char    *cur;                      /**< Current alloc ptr.     */

-    unsigned char    *end;                      /**< End of buffer.         */

-} pj_pool_block;

-

-

-/**

- * This structure describes the memory pool. Only implementors of pool factory

- * need to care about the contents of this structure.

- */

-struct pj_pool_t

-{

-    PJ_DECL_LIST_MEMBER(struct pj_pool_t);  /**< Standard list elements.    */

-

-    /** Pool name */

-    char	    obj_name[PJ_MAX_OBJ_NAME];

-

-    /** Pool factory. */

-    pj_pool_factory *factory;

-

-    /** Current capacity allocated by the pool. */

-    pj_size_t	    capacity;

-

-    /** Number of memory used/allocated. */

-    pj_size_t	    used_size;

-

-    /** Size of memory block to be allocated when the pool runs out of memory */

-    pj_size_t	    increment_size;

-

-    /** List of memory blocks allcoated by the pool. */

-    pj_pool_block   block_list;

-

-    /** The callback to be called when the pool is unable to allocate memory. */

-    pj_pool_callback *callback;

-

-};

-

-

-/**

- * Guidance on how much memory required for initial pool administrative data.

- */

-#define PJ_POOL_SIZE	        (sizeof(struct pj_pool_t))

-

-/** 

- * Pool memory alignment (must be power of 2). 

- */

-#ifndef PJ_POOL_ALIGNMENT

-#   define PJ_POOL_ALIGNMENT    4

-#endif

-

-/**

- * Create a new pool from the pool factory. This wrapper will call create_pool

- * member of the pool factory.

- *

- * @param factory	    The pool factory.

- * @param name		    The name to be assigned to the pool. The name should 

- *			    not be longer than PJ_MAX_OBJ_NAME (32 chars), or 

- *			    otherwise it will be truncated.

- * @param initial_size	    The size of initial memory blocks taken by the pool.

- *			    Note that the pool will take 68+20 bytes for 

- *			    administrative area from this block.

- * @param increment_size    the size of each additional blocks to be allocated

- *			    when the pool is running out of memory. If user 

- *			    requests memory which is larger than this size, then 

- *			    an error occurs.

- *			    Note that each time a pool allocates additional block, 

- *			    it needs PJ_POOL_SIZE more to store some 

- *			    administrative info.

- * @param callback	    Callback to be called when error occurs in the pool.

- *			    If this value is NULL, then the callback from pool

- *			    factory policy will be used.

- *			    Note that when an error occurs during pool creation, 

- *			    the callback itself is not called. Instead, NULL 

- *			    will be returned.

- *

- * @return                  The memory pool, or NULL.

- */

-PJ_IDECL(pj_pool_t*) pj_pool_create(pj_pool_factory *factory, 

-				    const char *name,

-				    pj_size_t initial_size, 

-				    pj_size_t increment_size,

-				    pj_pool_callback *callback);

-

-/**

- * Release the pool back to pool factory.

- *

- * @param pool	    Memory pool.

- */

-PJ_IDECL(void) pj_pool_release( pj_pool_t *pool );

-

-/**

- * Get pool object name.

- *

- * @param pool the pool.

- *

- * @return pool name as NULL terminated string.

- */

-PJ_IDECL(const char *) pj_pool_getobjname( const pj_pool_t *pool );

-

-/**

- * Reset the pool to its state when it was initialized.

- * This means that if additional blocks have been allocated during runtime, 

- * then they will be freed. Only the original block allocated during 

- * initialization is retained. This function will also reset the internal 

- * counters, such as pool capacity and used size.

- *

- * @param pool the pool.

- */

-PJ_DECL(void) pj_pool_reset( pj_pool_t *pool );

-

-

-/**

- * Get the pool capacity, that is, the system storage that have been allocated

- * by the pool, and have been used/will be used to allocate user requests.

- * There's no guarantee that the returned value represent a single

- * contiguous block, because the capacity may be spread in several blocks.

- *

- * @param pool	the pool.

- *

- * @return the capacity.

- */

-PJ_IDECL(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool );

-

-/**

- * Get the total size of user allocation request.

- *

- * @param pool	the pool.

- *

- * @return the total size.

- */

-PJ_IDECL(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool );

-

-/**

- * Allocate storage with the specified size from the pool.

- * If there's no storage available in the pool, then the pool can allocate more

- * blocks if the increment size is larger than the requested size.

- *

- * @param pool	    the pool.

- * @param size	    the requested size.

- *

- * @return pointer to the allocated memory.

- */

-PJ_IDECL(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size);

-

-/**

- * Allocate storage  from the pool, and initialize it to zero.

- * This function behaves like pj_pool_alloc(), except that the storage will

- * be initialized to zero.

- *

- * @param pool	    the pool.

- * @param count	    the number of elements in the array.

- * @param elem	    the size of individual element.

- *

- * @return pointer to the allocated memory.

- */

-PJ_IDECL(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, 

-				pj_size_t elem);

-

-

-/**

- * @def pj_pool_zalloc(pj_pool_t *pool, pj_size_t size)

- * Allocate storage from the pool and initialize it to zero.

- *

- * @param pool	    The pool.

- * @param size	    The size to be allocated.

- *

- * @return	    Pointer to the allocated memory.

- */

-#define pj_pool_zalloc(pool, size)  pj_pool_calloc(pool, 1, size)

-

-

-/**

- * @}	// PJ_POOL

- */

-

-///////////////////////////////////////////////////////////////////////////////

-/**

- * @defgroup PJ_POOL_FACTORY Pool Factory and Policy.

- * @ingroup PJ_POOL_GROUP

- * @brief

- * Pool factory declares an interface to create and destroy pool. There may

- * be several strategies for pool creation, and these strategies should 

- * implement the interface defined by pool factory.

- *

- * \section PJ_POOL_FACTORY_ITF Pool Factory Interface

- * The pool factory defines the following interface:

- *  - \a policy: the memory pool factory policy.

- *  - \a create_pool(): create a new memory pool.

- *  - \a release_pool(): release memory pool back to factory.

- *

- * \section PJ_POOL_FACTORY_POL Pool Factory Policy.

- * The pool factory policy controls the behaviour of memory factories, and

- * defines the following interface:

- *  - \a block_alloc(): allocate memory block from backend memory mgmt/system.

- *  - \a block_free(): free memory block back to backend memory mgmt/system.

- * @{

- */

-

-/* We unfortunately don't have support for factory policy options as now,

-   so we keep this commented at the moment.

-enum PJ_POOL_FACTORY_OPTION

-{

-    PJ_POOL_FACTORY_SERIALIZE = 1

-};

-*/

-

-/**

- * This structure declares pool factory interface.

- */

-typedef struct pj_pool_factory_policy

-{

-    /**

-     * Allocate memory block (for use by pool). This function is called

-     * by memory pool to allocate memory block.

-     * 

-     * @param factory	Pool factory.

-     * @param size	The size of memory block to allocate.

-     *

-     * @return		Memory block.

-     */

-    void* (*block_alloc)(pj_pool_factory *factory, pj_size_t size);

-

-    /**

-     * Free memory block.

-     *

-     * @param factory	Pool factory.

-     * @param mem	Memory block previously allocated by block_alloc().

-     * @param size	The size of memory block.

-     */

-    void (*block_free)(pj_pool_factory *factory, void *mem, pj_size_t size);

-

-    /**

-     * Default callback to be called when memory allocation fails.

-     */

-    pj_pool_callback *callback;

-

-    /**

-     * Option flags.

-     */

-    unsigned flags;

-

-} pj_pool_factory_policy;

-

-/**

- * This constant denotes the exception number that will be thrown by default

- * memory factory policy when memory allocation fails.

- */

-extern int PJ_NO_MEMORY_EXCEPTION;

-

-/**

- * This global variable points to default memory pool factory policy.

- * The behaviour of the default policy is:

- *  - block allocation and deallocation use malloc() and free().

- *  - callback will raise PJ_NO_MEMORY_EXCEPTION exception.

- *  - access to pool factory is not serialized (i.e. not thread safe).

- */

-extern pj_pool_factory_policy pj_pool_factory_default_policy;

-

-/**

- * This structure contains the declaration for pool factory interface.

- */

-struct pj_pool_factory

-{

-    /**

-     * Memory pool policy.

-     */

-    pj_pool_factory_policy policy;

-

-    /**

-    * Create a new pool from the pool factory.

-    *

-    * @param factory	The pool factory.

-    * @param name	the name to be assigned to the pool. The name should 

-    *			not be longer than PJ_MAX_OBJ_NAME (32 chars), or 

-    *			otherwise it will be truncated.

-    * @param initial_size the size of initial memory blocks taken by the pool.

-    *			Note that the pool will take 68+20 bytes for 

-    *			administrative area from this block.

-    * @param increment_size the size of each additional blocks to be allocated

-    *			when the pool is running out of memory. If user 

-    *			requests memory which is larger than this size, then 

-    *			an error occurs.

-    *			Note that each time a pool allocates additional block, 

-    *			it needs 20 bytes (equal to sizeof(pj_pool_block)) to 

-    *			store some administrative info.

-    * @param callback	Cllback to be called when error occurs in the pool.

-    *			Note that when an error occurs during pool creation, 

-    *			the callback itself is not called. Instead, NULL 

-    *			will be returned.

-    *

-    * @return the memory pool, or NULL.

-    */

-    pj_pool_t*	(*create_pool)( pj_pool_factory *factory,

-				const char *name,

-				pj_size_t initial_size, 

-				pj_size_t increment_size,

-				pj_pool_callback *callback);

-

-    /**

-     * Release the pool to the pool factory.

-     *

-     * @param factory	The pool factory.

-     * @param pool	The pool to be released.

-    */

-    void (*release_pool)( pj_pool_factory *factory, pj_pool_t *pool );

-

-    /**

-     * Dump pool status to log.

-     *

-     * @param factory	The pool factory.

-     */

-    void (*dump_status)( pj_pool_factory *factory, pj_bool_t detail );

-};

-

-/**

- * This function is intended to be used by pool factory implementors.

- * @param factory           Pool factory.

- * @param name              Pool name.

- * @param initial_size      Initial size.

- * @param increment_size    Increment size.

- * @param callback          Callback.

- * @return                  The pool object, or NULL.

- */

-PJ_DECL(pj_pool_t*) pj_pool_create_int(	pj_pool_factory *factory, 

-					const char *name,

-					pj_size_t initial_size, 

-					pj_size_t increment_size,

-					pj_pool_callback *callback);

-

-/**

- * This function is intended to be used by pool factory implementors.

- * @param pool              The pool.

- * @param name              Pool name.

- * @param increment_size    Increment size.

- * @param callback          Callback function.

- */

-PJ_DECL(void) pj_pool_init_int( pj_pool_t *pool, 

-				const char *name,

-				pj_size_t increment_size,

-				pj_pool_callback *callback);

-

-/**

- * This function is intended to be used by pool factory implementors.

- * @param pool      The memory pool.

- */

-PJ_DECL(void) pj_pool_destroy_int( pj_pool_t *pool );

-

-

-/**

- *  @}	// PJ_POOL_FACTORY

- */

-

-///////////////////////////////////////////////////////////////////////////////

-

-/**

- * @defgroup PJ_CACHING_POOL Caching Pool Factory.

- * @ingroup PJ_POOL_GROUP

- * @brief

- * Caching pool is one sample implementation of pool factory where the

- * factory can reuse memory to create a pool. Application defines what the 

- * maximum memory the factory can hold, and when a pool is released the

- * factory decides whether to destroy the pool or to keep it for future use.

- * If the total amount of memory in the internal cache is still within the

- * limit, the factory will keep the pool in the internal cache, otherwise the

- * pool will be destroyed, thus releasing the memory back to the system.

- *

- * @{

- */

-

-/**

- * Number of unique sizes, to be used as index to the free list.

- * Each pool in the free list is organized by it's size.

- */

-#define PJ_CACHING_POOL_ARRAY_SIZE	16

-

-/**

- * Declaration for caching pool. Application doesn't normally need to

- * care about the contents of this struct, it is only provided here because

- * application need to define an instance of this struct (we can not allocate

- * the struct from a pool since there is no pool factory yet!).

- */

-struct pj_caching_pool 

-{

-    /** Pool factory interface, must be declared first. */

-    pj_pool_factory factory;

-

-    /** Current factory's capacity, i.e. number of bytes that are allocated

-     *  and available for application in this factory. The factory's

-     *  capacity represents the size of all pools kept by this factory

-     *  in it's free list, which will be returned to application when it

-     *  requests to create a new pool.

-     */

-    pj_size_t	    capacity;

-

-    /** Maximum size that can be held by this factory. Once the capacity

-     *  has exceeded @a max_capacity, further #pj_pool_release() will

-     *  flush the pool. If the capacity is still below the @a max_capacity,

-     *  #pj_pool_release() will save the pool to the factory's free list.

-     */

-    pj_size_t       max_capacity;

-

-    /**

-     * Number of pools currently held by applications. This number gets

-     * incremented everytime #pj_pool_create() is called, and gets

-     * decremented when #pj_pool_release() is called.

-     */

-    pj_size_t       used_count;

-

-    /**

-     * Lists of pools in the cache, indexed by pool size.

-     */

-    pj_list	    free_list[PJ_CACHING_POOL_ARRAY_SIZE];

-

-    /**

-     * List of pools currently allocated by applications.

-     */

-    pj_list	    used_list;

-};

-

-

-

-/**

- * Initialize caching pool.

- *

- * @param ch_pool	The caching pool factory to be initialized.

- * @param policy	Pool factory policy.

- * @param max_capacity	The total capacity to be retained in the cache. When

- *			the pool is returned to the cache, it will be kept in

- *			recycling list if the total capacity of pools in this

- *			list plus the capacity of the pool is still below this

- *			value.

- */

-PJ_DECL(void) pj_caching_pool_init( pj_caching_pool *ch_pool, 

-				    const pj_pool_factory_policy *policy,

-				    pj_size_t max_capacity);

-

-

-/**

- * Destroy caching pool, and release all the pools in the recycling list.

- *

- * @param ch_pool	The caching pool.

- */

-PJ_DECL(void) pj_caching_pool_destroy( pj_caching_pool *ch_pool );

-

-/**

- * @}	// PJ_CACHING_POOL

- */

-

-#  if PJ_FUNCTIONS_ARE_INLINED

-#    include "pool_i.h"

-#  endif

-

-PJ_END_DECL

-    

-#endif	/* __PJ_POOL_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_POOL_H__
+#define __PJ_POOL_H__
+
+/**
+ * @file pool.h
+ * @brief Memory Pool.
+ */
+
+#include <pj/list.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_POOL_GROUP Memory Pool Management
+ * @ingroup PJ
+ * @brief
+ * Memory pool management provides API to allocate and deallocate memory from
+ * memory pool and to manage and establish policy for pool creation and
+ * destruction in pool factory.
+ *
+ * \section PJ_POOL_FACTORY_SEC Pool Factory
+ * See: \ref PJ_POOL_FACTORY "Pool Factory"
+ *
+ * A memory pool must be created through a factory. A factory not only provides
+ * generic interface functions to create and release pool, but also provides 
+ * strategy to manage the life time of pools. One sample implementation, 
+ * \a pj_caching_pool, can be set to keep the pools released by application for
+ * future use as long as the total memory is below the limit.
+ * 
+ * The pool factory interface declared in PJLIB is designed to be extensible.
+ * Application can define its own strategy by creating it's own pool factory
+ * implementation, and this strategy can be used even by existing library
+ * without recompilation.
+ *
+ *
+ * \section PJ_POOL_POLICY_SEC Pool Factory Policy
+ * See: \ref PJ_POOL_FACTORY "Pool Factory Policy"
+ *
+ * A pool factory only defines functions to create and release pool and how
+ * to manage pools, but the rest of the functionalities are controlled by
+ * policy. A pool policy defines:
+ *  - how memory block is allocated and deallocated (the default implementation
+ *    allocates and deallocate memory by calling malloc() and free()).
+ *  - callback to be called when memory allocation inside a pool fails (the
+ *    default implementation will throw PJ_NO_MEMORY_EXCEPTION exception).
+ *  - concurrency when creating and releasing pool from/to the factory.
+ *
+ * A pool factory can be given different policy during creation to make
+ * it behave differently. For example, caching pool factory can be configured
+ * to allocate and deallocate from a static/contiguous/preallocated memory 
+ * instead of using malloc()/free().
+ * 
+ * What strategy/factory and what policy to use is not defined by PJLIB, but
+ * instead is left to application to make use whichever is most efficient for
+ * itself.
+ *
+ *
+ * \section PJ_POOL_POOL_SEC The Pool
+ * See: \ref PJ_POOL "Pool"
+ *
+ * The memory pool is an opaque object created by pool factory.
+ * Application uses this object to request a memory chunk, by calling
+ * #pj_pool_alloc or #pj_pool_calloc. When the application has finished using
+ * the pool, it must call #pj_pool_release to free all the chunks previously
+ * allocated and release the pool back to the factory.
+ *
+ * \section PJ_POOL_THREADING_SEC More on Threading Policies:
+ * - By design, memory allocation from a pool is not thread safe. We assumed 
+ *   that a pool will be owned by an object, and thread safety should be 
+ *   handled by that object. Thus these functions are not thread safe: 
+ *	- #pj_pool_alloc, 
+ *	- #pj_pool_calloc, 
+ *	- and other pool statistic functions.
+ * - Threading in the pool factory is decided by the policy set for the
+ *   factory when it was created.
+ *
+ * \section PJ_POOL_EXAMPLES_SEC Examples
+ *
+ * For some sample codes on how to use the pool, please see:
+ *  - @ref page_pjlib_pool_test
+ */
+
+/**
+ * @defgroup PJ_POOL Memory Pool.
+ * @ingroup PJ_POOL_GROUP
+ * @brief
+ * A memory pool is initialized with an initial amount of memory, which is
+ * called a block. Pool can be configured to dynamically allocate more memory 
+ * blocks when it runs out of memory. Subsequent memory allocations by user 
+ * will use up portions of these block. 
+ * The pool doesn't keep track of individual memory allocations
+ * by user, and the user doesn't have to free these indidual allocations. This
+ * makes memory allocation simple and very fast. All the memory allocated from
+ * the pool will be destroyed when the pool itself is destroyed.
+ * @{
+ */
+
+/**
+ * The type for function to receive callback from the pool when it is unable
+ * to allocate memory. The elegant way to handle this condition is to throw
+ * exception, and this is what is expected by most of this library 
+ * components.
+ */
+typedef void pj_pool_callback(pj_pool_t *pool, pj_size_t size);
+
+/**
+ * This class, which is used internally by the pool, describes a single 
+ * block of memory from which user memory allocations will be allocated from.
+ */
+typedef struct pj_pool_block
+{
+    PJ_DECL_LIST_MEMBER(struct pj_pool_block);  /**< List's prev and next.  */
+    unsigned char    *buf;                      /**< Start of buffer.       */
+    unsigned char    *cur;                      /**< Current alloc ptr.     */
+    unsigned char    *end;                      /**< End of buffer.         */
+} pj_pool_block;
+
+
+/**
+ * This structure describes the memory pool. Only implementors of pool factory
+ * need to care about the contents of this structure.
+ */
+struct pj_pool_t
+{
+    PJ_DECL_LIST_MEMBER(struct pj_pool_t);  /**< Standard list elements.    */
+
+    /** Pool name */
+    char	    obj_name[PJ_MAX_OBJ_NAME];
+
+    /** Pool factory. */
+    pj_pool_factory *factory;
+
+    /** Current capacity allocated by the pool. */
+    pj_size_t	    capacity;
+
+    /** Number of memory used/allocated. */
+    pj_size_t	    used_size;
+
+    /** Size of memory block to be allocated when the pool runs out of memory */
+    pj_size_t	    increment_size;
+
+    /** List of memory blocks allcoated by the pool. */
+    pj_pool_block   block_list;
+
+    /** The callback to be called when the pool is unable to allocate memory. */
+    pj_pool_callback *callback;
+
+};
+
+
+/**
+ * Guidance on how much memory required for initial pool administrative data.
+ */
+#define PJ_POOL_SIZE	        (sizeof(struct pj_pool_t))
+
+/** 
+ * Pool memory alignment (must be power of 2). 
+ */
+#ifndef PJ_POOL_ALIGNMENT
+#   define PJ_POOL_ALIGNMENT    4
+#endif
+
+/**
+ * Create a new pool from the pool factory. This wrapper will call create_pool
+ * member of the pool factory.
+ *
+ * @param factory	    The pool factory.
+ * @param name		    The name to be assigned to the pool. The name should 
+ *			    not be longer than PJ_MAX_OBJ_NAME (32 chars), or 
+ *			    otherwise it will be truncated.
+ * @param initial_size	    The size of initial memory blocks taken by the pool.
+ *			    Note that the pool will take 68+20 bytes for 
+ *			    administrative area from this block.
+ * @param increment_size    the size of each additional blocks to be allocated
+ *			    when the pool is running out of memory. If user 
+ *			    requests memory which is larger than this size, then 
+ *			    an error occurs.
+ *			    Note that each time a pool allocates additional block, 
+ *			    it needs PJ_POOL_SIZE more to store some 
+ *			    administrative info.
+ * @param callback	    Callback to be called when error occurs in the pool.
+ *			    If this value is NULL, then the callback from pool
+ *			    factory policy will be used.
+ *			    Note that when an error occurs during pool creation, 
+ *			    the callback itself is not called. Instead, NULL 
+ *			    will be returned.
+ *
+ * @return                  The memory pool, or NULL.
+ */
+PJ_IDECL(pj_pool_t*) pj_pool_create(pj_pool_factory *factory, 
+				    const char *name,
+				    pj_size_t initial_size, 
+				    pj_size_t increment_size,
+				    pj_pool_callback *callback);
+
+/**
+ * Release the pool back to pool factory.
+ *
+ * @param pool	    Memory pool.
+ */
+PJ_IDECL(void) pj_pool_release( pj_pool_t *pool );
+
+/**
+ * Get pool object name.
+ *
+ * @param pool the pool.
+ *
+ * @return pool name as NULL terminated string.
+ */
+PJ_IDECL(const char *) pj_pool_getobjname( const pj_pool_t *pool );
+
+/**
+ * Reset the pool to its state when it was initialized.
+ * This means that if additional blocks have been allocated during runtime, 
+ * then they will be freed. Only the original block allocated during 
+ * initialization is retained. This function will also reset the internal 
+ * counters, such as pool capacity and used size.
+ *
+ * @param pool the pool.
+ */
+PJ_DECL(void) pj_pool_reset( pj_pool_t *pool );
+
+
+/**
+ * Get the pool capacity, that is, the system storage that have been allocated
+ * by the pool, and have been used/will be used to allocate user requests.
+ * There's no guarantee that the returned value represent a single
+ * contiguous block, because the capacity may be spread in several blocks.
+ *
+ * @param pool	the pool.
+ *
+ * @return the capacity.
+ */
+PJ_IDECL(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool );
+
+/**
+ * Get the total size of user allocation request.
+ *
+ * @param pool	the pool.
+ *
+ * @return the total size.
+ */
+PJ_IDECL(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool );
+
+/**
+ * Allocate storage with the specified size from the pool.
+ * If there's no storage available in the pool, then the pool can allocate more
+ * blocks if the increment size is larger than the requested size.
+ *
+ * @param pool	    the pool.
+ * @param size	    the requested size.
+ *
+ * @return pointer to the allocated memory.
+ */
+PJ_IDECL(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size);
+
+/**
+ * Allocate storage  from the pool, and initialize it to zero.
+ * This function behaves like pj_pool_alloc(), except that the storage will
+ * be initialized to zero.
+ *
+ * @param pool	    the pool.
+ * @param count	    the number of elements in the array.
+ * @param elem	    the size of individual element.
+ *
+ * @return pointer to the allocated memory.
+ */
+PJ_IDECL(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, 
+				pj_size_t elem);
+
+
+/**
+ * @def pj_pool_zalloc(pj_pool_t *pool, pj_size_t size)
+ * Allocate storage from the pool and initialize it to zero.
+ *
+ * @param pool	    The pool.
+ * @param size	    The size to be allocated.
+ *
+ * @return	    Pointer to the allocated memory.
+ */
+#define pj_pool_zalloc(pool, size)  pj_pool_calloc(pool, 1, size)
+
+
+/**
+ * @}	// PJ_POOL
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup PJ_POOL_FACTORY Pool Factory and Policy.
+ * @ingroup PJ_POOL_GROUP
+ * @brief
+ * Pool factory declares an interface to create and destroy pool. There may
+ * be several strategies for pool creation, and these strategies should 
+ * implement the interface defined by pool factory.
+ *
+ * \section PJ_POOL_FACTORY_ITF Pool Factory Interface
+ * The pool factory defines the following interface:
+ *  - \a policy: the memory pool factory policy.
+ *  - \a create_pool(): create a new memory pool.
+ *  - \a release_pool(): release memory pool back to factory.
+ *
+ * \section PJ_POOL_FACTORY_POL Pool Factory Policy.
+ * The pool factory policy controls the behaviour of memory factories, and
+ * defines the following interface:
+ *  - \a block_alloc(): allocate memory block from backend memory mgmt/system.
+ *  - \a block_free(): free memory block back to backend memory mgmt/system.
+ * @{
+ */
+
+/* We unfortunately don't have support for factory policy options as now,
+   so we keep this commented at the moment.
+enum PJ_POOL_FACTORY_OPTION
+{
+    PJ_POOL_FACTORY_SERIALIZE = 1
+};
+*/
+
+/**
+ * This structure declares pool factory interface.
+ */
+typedef struct pj_pool_factory_policy
+{
+    /**
+     * Allocate memory block (for use by pool). This function is called
+     * by memory pool to allocate memory block.
+     * 
+     * @param factory	Pool factory.
+     * @param size	The size of memory block to allocate.
+     *
+     * @return		Memory block.
+     */
+    void* (*block_alloc)(pj_pool_factory *factory, pj_size_t size);
+
+    /**
+     * Free memory block.
+     *
+     * @param factory	Pool factory.
+     * @param mem	Memory block previously allocated by block_alloc().
+     * @param size	The size of memory block.
+     */
+    void (*block_free)(pj_pool_factory *factory, void *mem, pj_size_t size);
+
+    /**
+     * Default callback to be called when memory allocation fails.
+     */
+    pj_pool_callback *callback;
+
+    /**
+     * Option flags.
+     */
+    unsigned flags;
+
+} pj_pool_factory_policy;
+
+/**
+ * This constant denotes the exception number that will be thrown by default
+ * memory factory policy when memory allocation fails.
+ */
+extern int PJ_NO_MEMORY_EXCEPTION;
+
+/**
+ * This global variable points to default memory pool factory policy.
+ * The behaviour of the default policy is:
+ *  - block allocation and deallocation use malloc() and free().
+ *  - callback will raise PJ_NO_MEMORY_EXCEPTION exception.
+ *  - access to pool factory is not serialized (i.e. not thread safe).
+ */
+extern pj_pool_factory_policy pj_pool_factory_default_policy;
+
+/**
+ * This structure contains the declaration for pool factory interface.
+ */
+struct pj_pool_factory
+{
+    /**
+     * Memory pool policy.
+     */
+    pj_pool_factory_policy policy;
+
+    /**
+    * Create a new pool from the pool factory.
+    *
+    * @param factory	The pool factory.
+    * @param name	the name to be assigned to the pool. The name should 
+    *			not be longer than PJ_MAX_OBJ_NAME (32 chars), or 
+    *			otherwise it will be truncated.
+    * @param initial_size the size of initial memory blocks taken by the pool.
+    *			Note that the pool will take 68+20 bytes for 
+    *			administrative area from this block.
+    * @param increment_size the size of each additional blocks to be allocated
+    *			when the pool is running out of memory. If user 
+    *			requests memory which is larger than this size, then 
+    *			an error occurs.
+    *			Note that each time a pool allocates additional block, 
+    *			it needs 20 bytes (equal to sizeof(pj_pool_block)) to 
+    *			store some administrative info.
+    * @param callback	Cllback to be called when error occurs in the pool.
+    *			Note that when an error occurs during pool creation, 
+    *			the callback itself is not called. Instead, NULL 
+    *			will be returned.
+    *
+    * @return the memory pool, or NULL.
+    */
+    pj_pool_t*	(*create_pool)( pj_pool_factory *factory,
+				const char *name,
+				pj_size_t initial_size, 
+				pj_size_t increment_size,
+				pj_pool_callback *callback);
+
+    /**
+     * Release the pool to the pool factory.
+     *
+     * @param factory	The pool factory.
+     * @param pool	The pool to be released.
+    */
+    void (*release_pool)( pj_pool_factory *factory, pj_pool_t *pool );
+
+    /**
+     * Dump pool status to log.
+     *
+     * @param factory	The pool factory.
+     */
+    void (*dump_status)( pj_pool_factory *factory, pj_bool_t detail );
+};
+
+/**
+ * This function is intended to be used by pool factory implementors.
+ * @param factory           Pool factory.
+ * @param name              Pool name.
+ * @param initial_size      Initial size.
+ * @param increment_size    Increment size.
+ * @param callback          Callback.
+ * @return                  The pool object, or NULL.
+ */
+PJ_DECL(pj_pool_t*) pj_pool_create_int(	pj_pool_factory *factory, 
+					const char *name,
+					pj_size_t initial_size, 
+					pj_size_t increment_size,
+					pj_pool_callback *callback);
+
+/**
+ * This function is intended to be used by pool factory implementors.
+ * @param pool              The pool.
+ * @param name              Pool name.
+ * @param increment_size    Increment size.
+ * @param callback          Callback function.
+ */
+PJ_DECL(void) pj_pool_init_int( pj_pool_t *pool, 
+				const char *name,
+				pj_size_t increment_size,
+				pj_pool_callback *callback);
+
+/**
+ * This function is intended to be used by pool factory implementors.
+ * @param pool      The memory pool.
+ */
+PJ_DECL(void) pj_pool_destroy_int( pj_pool_t *pool );
+
+
+/**
+ *  @}	// PJ_POOL_FACTORY
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup PJ_CACHING_POOL Caching Pool Factory.
+ * @ingroup PJ_POOL_GROUP
+ * @brief
+ * Caching pool is one sample implementation of pool factory where the
+ * factory can reuse memory to create a pool. Application defines what the 
+ * maximum memory the factory can hold, and when a pool is released the
+ * factory decides whether to destroy the pool or to keep it for future use.
+ * If the total amount of memory in the internal cache is still within the
+ * limit, the factory will keep the pool in the internal cache, otherwise the
+ * pool will be destroyed, thus releasing the memory back to the system.
+ *
+ * @{
+ */
+
+/**
+ * Number of unique sizes, to be used as index to the free list.
+ * Each pool in the free list is organized by it's size.
+ */
+#define PJ_CACHING_POOL_ARRAY_SIZE	16
+
+/**
+ * Declaration for caching pool. Application doesn't normally need to
+ * care about the contents of this struct, it is only provided here because
+ * application need to define an instance of this struct (we can not allocate
+ * the struct from a pool since there is no pool factory yet!).
+ */
+struct pj_caching_pool 
+{
+    /** Pool factory interface, must be declared first. */
+    pj_pool_factory factory;
+
+    /** Current factory's capacity, i.e. number of bytes that are allocated
+     *  and available for application in this factory. The factory's
+     *  capacity represents the size of all pools kept by this factory
+     *  in it's free list, which will be returned to application when it
+     *  requests to create a new pool.
+     */
+    pj_size_t	    capacity;
+
+    /** Maximum size that can be held by this factory. Once the capacity
+     *  has exceeded @a max_capacity, further #pj_pool_release() will
+     *  flush the pool. If the capacity is still below the @a max_capacity,
+     *  #pj_pool_release() will save the pool to the factory's free list.
+     */
+    pj_size_t       max_capacity;
+
+    /**
+     * Number of pools currently held by applications. This number gets
+     * incremented everytime #pj_pool_create() is called, and gets
+     * decremented when #pj_pool_release() is called.
+     */
+    pj_size_t       used_count;
+
+    /**
+     * Lists of pools in the cache, indexed by pool size.
+     */
+    pj_list	    free_list[PJ_CACHING_POOL_ARRAY_SIZE];
+
+    /**
+     * List of pools currently allocated by applications.
+     */
+    pj_list	    used_list;
+};
+
+
+
+/**
+ * Initialize caching pool.
+ *
+ * @param ch_pool	The caching pool factory to be initialized.
+ * @param policy	Pool factory policy.
+ * @param max_capacity	The total capacity to be retained in the cache. When
+ *			the pool is returned to the cache, it will be kept in
+ *			recycling list if the total capacity of pools in this
+ *			list plus the capacity of the pool is still below this
+ *			value.
+ */
+PJ_DECL(void) pj_caching_pool_init( pj_caching_pool *ch_pool, 
+				    const pj_pool_factory_policy *policy,
+				    pj_size_t max_capacity);
+
+
+/**
+ * Destroy caching pool, and release all the pools in the recycling list.
+ *
+ * @param ch_pool	The caching pool.
+ */
+PJ_DECL(void) pj_caching_pool_destroy( pj_caching_pool *ch_pool );
+
+/**
+ * @}	// PJ_CACHING_POOL
+ */
+
+#  if PJ_FUNCTIONS_ARE_INLINED
+#    include "pool_i.h"
+#  endif
+
+PJ_END_DECL
+    
+#endif	/* __PJ_POOL_H__ */
+
diff --git a/pjlib/include/pj/pool_i.h b/pjlib/include/pj/pool_i.h
index df9b45d..39c0487 100644
--- a/pjlib/include/pj/pool_i.h
+++ b/pjlib/include/pj/pool_i.h
@@ -1,91 +1,91 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-

-

-#include <pj/string.h>

-

-PJ_DECL(void*) pj_pool_allocate_find(pj_pool_t *pool, unsigned size);

-

-PJ_IDEF(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool )

-{

-    return pool->capacity;

-}

-

-PJ_IDEF(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool )

-{

-    return pool->used_size;

-}

-

-PJ_IDEF(void*) pj_pool_alloc_from_block( pj_pool_t *pool,

-					 pj_pool_block *block, pj_size_t size )

-{

-    /* The operation below is valid for size==0. 

-     * When size==0, the function will return the pointer to the pool

-     * memory address, but no memory will be allocated.

-     */

-    if (size & (PJ_POOL_ALIGNMENT-1)) {

-	size &= ~(PJ_POOL_ALIGNMENT-1);

-	size += PJ_POOL_ALIGNMENT;

-    }

-    if ((unsigned)(block->end - block->cur) >= size) {

-	void *ptr = block->cur;

-	block->cur += size;

-	pool->used_size += size;

-	return ptr;

-    }

-    return NULL;

-}

-

-PJ_IDEF(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size)

-{

-    pj_pool_block *block = pool->block_list.next;

-    void *ptr = pj_pool_alloc_from_block(pool, block, size);

-    if (!ptr)

-	ptr = pj_pool_allocate_find(pool, size);

-    return ptr;

-}

-

-

-PJ_IDEF(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, pj_size_t size)

-{

-    void *buf = pj_pool_alloc( pool, size*count);

-    if (buf)

-	pj_memset(buf, 0, size * count);

-    return buf;

-}

-

-PJ_IDEF(const char *) pj_pool_getobjname( const pj_pool_t *pool )

-{

-    return pool->obj_name;

-}

-

-PJ_IDEF(pj_pool_t*) pj_pool_create( pj_pool_factory *f, 

-				    const char *name,

-				    pj_size_t initial_size, 

-				    pj_size_t increment_size,

-				    pj_pool_callback *callback)

-{

-    return (*f->create_pool)(f, name, initial_size, increment_size, callback);

-}

-

-PJ_IDEF(void) pj_pool_release( pj_pool_t *pool )

-{

-    (*pool->factory->release_pool)(pool->factory, pool);

-}

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+
+
+#include <pj/string.h>
+
+PJ_DECL(void*) pj_pool_allocate_find(pj_pool_t *pool, unsigned size);
+
+PJ_IDEF(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool )
+{
+    return pool->capacity;
+}
+
+PJ_IDEF(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool )
+{
+    return pool->used_size;
+}
+
+PJ_IDEF(void*) pj_pool_alloc_from_block( pj_pool_t *pool,
+					 pj_pool_block *block, pj_size_t size )
+{
+    /* The operation below is valid for size==0. 
+     * When size==0, the function will return the pointer to the pool
+     * memory address, but no memory will be allocated.
+     */
+    if (size & (PJ_POOL_ALIGNMENT-1)) {
+	size &= ~(PJ_POOL_ALIGNMENT-1);
+	size += PJ_POOL_ALIGNMENT;
+    }
+    if ((unsigned)(block->end - block->cur) >= size) {
+	void *ptr = block->cur;
+	block->cur += size;
+	pool->used_size += size;
+	return ptr;
+    }
+    return NULL;
+}
+
+PJ_IDEF(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size)
+{
+    pj_pool_block *block = pool->block_list.next;
+    void *ptr = pj_pool_alloc_from_block(pool, block, size);
+    if (!ptr)
+	ptr = pj_pool_allocate_find(pool, size);
+    return ptr;
+}
+
+
+PJ_IDEF(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, pj_size_t size)
+{
+    void *buf = pj_pool_alloc( pool, size*count);
+    if (buf)
+	pj_memset(buf, 0, size * count);
+    return buf;
+}
+
+PJ_IDEF(const char *) pj_pool_getobjname( const pj_pool_t *pool )
+{
+    return pool->obj_name;
+}
+
+PJ_IDEF(pj_pool_t*) pj_pool_create( pj_pool_factory *f, 
+				    const char *name,
+				    pj_size_t initial_size, 
+				    pj_size_t increment_size,
+				    pj_pool_callback *callback)
+{
+    return (*f->create_pool)(f, name, initial_size, increment_size, callback);
+}
+
+PJ_IDEF(void) pj_pool_release( pj_pool_t *pool )
+{
+    (*pool->factory->release_pool)(pool->factory, pool);
+}
+
diff --git a/pjlib/include/pj/rand.h b/pjlib/include/pj/rand.h
index 36e5574..a1cd333 100644
--- a/pjlib/include/pj/rand.h
+++ b/pjlib/include/pj/rand.h
@@ -1,65 +1,65 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_RAND_H__

-#define __PJ_RAND_H__

-

-/**

- * @file rand.h

- * @brief Random Number Generator.

- */

-

-#include <pj/config.h>

-

-PJ_BEGIN_DECL

-

-

-/**

- * @defgroup PJ_RAND Random Number Generator

- * @ingroup PJ_MISC

- * @{

- * This module contains functions for generating random numbers.

- * This abstraction is needed not only because not all platforms have

- * \a rand() and \a srand(), but also on some platforms \a rand()

- * only has 16-bit randomness, which is not good enough.

- */

-

-/**

- * Put in seed to random number generator.

- *

- * @param seed	    Seed value.

- */

-PJ_DECL(void) pj_srand(unsigned int seed);

-

-

-/**

- * Generate random integer with 32bit randomness.

- *

- * @return a random integer.

- */

-PJ_DECL(int) pj_rand(void);

-

-

-/** @} */

-

-

-PJ_END_DECL

-

-

-#endif	/* __PJ_RAND_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_RAND_H__
+#define __PJ_RAND_H__
+
+/**
+ * @file rand.h
+ * @brief Random Number Generator.
+ */
+
+#include <pj/config.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJ_RAND Random Number Generator
+ * @ingroup PJ_MISC
+ * @{
+ * This module contains functions for generating random numbers.
+ * This abstraction is needed not only because not all platforms have
+ * \a rand() and \a srand(), but also on some platforms \a rand()
+ * only has 16-bit randomness, which is not good enough.
+ */
+
+/**
+ * Put in seed to random number generator.
+ *
+ * @param seed	    Seed value.
+ */
+PJ_DECL(void) pj_srand(unsigned int seed);
+
+
+/**
+ * Generate random integer with 32bit randomness.
+ *
+ * @return a random integer.
+ */
+PJ_DECL(int) pj_rand(void);
+
+
+/** @} */
+
+
+PJ_END_DECL
+
+
+#endif	/* __PJ_RAND_H__ */
+
diff --git a/pjlib/include/pj/rbtree.h b/pjlib/include/pj/rbtree.h
index 1d4df0b..ed6607f 100644
--- a/pjlib/include/pj/rbtree.h
+++ b/pjlib/include/pj/rbtree.h
@@ -1,209 +1,209 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_RBTREE_H__

-#define __PJ_RBTREE_H__

-

-/**

- * @file rbtree.h

- * @brief Red/Black Tree

- */

-

-#include <pj/types.h>

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup PJ_RBTREE Red/Black Balanced Tree

- * @ingroup PJ_DS

- * @brief

- * Red/Black tree is the variant of balanced tree, where the search, insert, 

- * and delete operation is \b guaranteed to take at most \a O( lg(n) ).

- * @{

- */

-/**

- * Color type for Red-Black tree.

- */ 

-typedef enum pj_rbcolor_t

-{

-    PJ_RBCOLOR_BLACK,

-    PJ_RBCOLOR_RED

-} pj_rbcolor_t;

-

-/**

- * The type of the node of the R/B Tree.

- */

-typedef struct pj_rbtree_node 

-{

-    /** Pointers to the node's parent, and left and right siblings. */

-    struct pj_rbtree_node *parent, *left, *right;

-

-    /** Key associated with the node. */

-    const void *key;

-

-    /** User data associated with the node. */

-    void *user_data;

-

-    /** The R/B Tree node color. */

-    pj_rbcolor_t color;

-

-} pj_rbtree_node;

-

-

-/**

- * The type of function use to compare key value of tree node.

- * @return

- *  0 if the keys are equal

- * <0 if key1 is lower than key2

- * >0 if key1 is greater than key2.

- */

-typedef int pj_rbtree_comp(const void *key1, const void *key2);

-

-

-/**

- * Declaration of a red-black tree. All elements in the tree must have UNIQUE

- * key.

- * A red black tree always maintains the balance of the tree, so that the

- * tree height will not be greater than lg(N). Insert, search, and delete

- * operation will take lg(N) on the worst case. But for insert and delete,

- * there is additional time needed to maintain the balance of the tree.

- */

-typedef struct pj_rbtree

-{

-    pj_rbtree_node null_node;   /**< Constant to indicate NULL node.    */

-    pj_rbtree_node *null;       /**< Constant to indicate NULL node.    */

-    pj_rbtree_node *root;       /**< Root tree node.                    */

-    unsigned size;              /**< Number of elements in the tree.    */

-    pj_rbtree_comp *comp;       /**< Key comparison function.           */

-} pj_rbtree;

-

-

-/**

- * Guidance on how much memory required for each of the node.

- */

-#define PJ_RBTREE_NODE_SIZE	    (sizeof(pj_rbtree_node))

-

-

-/**

- * Guidance on memory required for the tree.

- */

-#define PJ_RBTREE_SIZE		    (sizeof(pj_rbtree))

-

-

-/**

- * Initialize the tree.

- * @param tree the tree to be initialized.

- * @param comp key comparison function to be used for this tree.

- */

-PJ_DECL(void) pj_rbtree_init( pj_rbtree *tree, pj_rbtree_comp *comp);

-

-/**

- * Get the first element in the tree.

- * The first element always has the least value for the key, according to

- * the comparison function.

- * @param tree the tree.

- * @return the tree node, or NULL if the tree has no element.

- */

-PJ_DECL(pj_rbtree_node*) pj_rbtree_first( pj_rbtree *tree );

-

-/**

- * Get the last element in the tree.

- * The last element always has the greatest key value, according to the

- * comparison function defined for the tree.

- * @param tree the tree.

- * @return the tree node, or NULL if the tree has no element.

- */

-PJ_DECL(pj_rbtree_node*) pj_rbtree_last( pj_rbtree *tree );

-

-/**

- * Get the successive element for the specified node.

- * The successive element is an element with greater key value.

- * @param tree the tree.

- * @param node the node.

- * @return the successive node, or NULL if the node has no successor.

- */

-PJ_DECL(pj_rbtree_node*) pj_rbtree_next( pj_rbtree *tree, 

-					 pj_rbtree_node *node );

-

-/**

- * The the previous node for the specified node.

- * The previous node is an element with less key value.

- * @param tree the tree.

- * @param node the node.

- * @return the previous node, or NULL if the node has no previous node.

- */

-PJ_DECL(pj_rbtree_node*) pj_rbtree_prev( pj_rbtree *tree, 

-					 pj_rbtree_node *node );

-

-/**

- * Insert a new node. 

- * The node will be inserted at sorted location. The key of the node must 

- * be UNIQUE, i.e. it hasn't existed in the tree.

- * @param tree the tree.

- * @param node the node to be inserted.

- * @return zero on success, or -1 if the key already exist.

- */

-PJ_DECL(int) pj_rbtree_insert( pj_rbtree *tree, 

-			       pj_rbtree_node *node );

-

-/**

- * Find a node which has the specified key.

- * @param tree the tree.

- * @param key the key to search.

- * @return the tree node with the specified key, or NULL if the key can not

- *         be found.

- */

-PJ_DECL(pj_rbtree_node*) pj_rbtree_find( pj_rbtree *tree,

-					 const void *key );

-

-/**

- * Erase a node from the tree.

- * @param tree the tree.

- * @param node the node to be erased.

- * @return the tree node itself.

- */

-PJ_DECL(pj_rbtree_node*) pj_rbtree_erase( pj_rbtree *tree,

-					  pj_rbtree_node *node );

-

-/**

- * Get the maximum tree height from the specified node.

- * @param tree the tree.

- * @param node the node, or NULL to get the root of the tree.

- * @return the maximum height, which should be at most lg(N)

- */

-PJ_DECL(unsigned) pj_rbtree_max_height( pj_rbtree *tree,

-					pj_rbtree_node *node );

-

-/**

- * Get the minumum tree height from the specified node.

- * @param tree the tree.

- * @param node the node, or NULL to get the root of the tree.

- * @return the height

- */

-PJ_DECL(unsigned) pj_rbtree_min_height( pj_rbtree *tree,

-					pj_rbtree_node *node );

-

-

-/**

- * @}

- */

-

-PJ_END_DECL

-

-#endif	/* __PJ_RBTREE_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_RBTREE_H__
+#define __PJ_RBTREE_H__
+
+/**
+ * @file rbtree.h
+ * @brief Red/Black Tree
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_RBTREE Red/Black Balanced Tree
+ * @ingroup PJ_DS
+ * @brief
+ * Red/Black tree is the variant of balanced tree, where the search, insert, 
+ * and delete operation is \b guaranteed to take at most \a O( lg(n) ).
+ * @{
+ */
+/**
+ * Color type for Red-Black tree.
+ */ 
+typedef enum pj_rbcolor_t
+{
+    PJ_RBCOLOR_BLACK,
+    PJ_RBCOLOR_RED
+} pj_rbcolor_t;
+
+/**
+ * The type of the node of the R/B Tree.
+ */
+typedef struct pj_rbtree_node 
+{
+    /** Pointers to the node's parent, and left and right siblings. */
+    struct pj_rbtree_node *parent, *left, *right;
+
+    /** Key associated with the node. */
+    const void *key;
+
+    /** User data associated with the node. */
+    void *user_data;
+
+    /** The R/B Tree node color. */
+    pj_rbcolor_t color;
+
+} pj_rbtree_node;
+
+
+/**
+ * The type of function use to compare key value of tree node.
+ * @return
+ *  0 if the keys are equal
+ * <0 if key1 is lower than key2
+ * >0 if key1 is greater than key2.
+ */
+typedef int pj_rbtree_comp(const void *key1, const void *key2);
+
+
+/**
+ * Declaration of a red-black tree. All elements in the tree must have UNIQUE
+ * key.
+ * A red black tree always maintains the balance of the tree, so that the
+ * tree height will not be greater than lg(N). Insert, search, and delete
+ * operation will take lg(N) on the worst case. But for insert and delete,
+ * there is additional time needed to maintain the balance of the tree.
+ */
+typedef struct pj_rbtree
+{
+    pj_rbtree_node null_node;   /**< Constant to indicate NULL node.    */
+    pj_rbtree_node *null;       /**< Constant to indicate NULL node.    */
+    pj_rbtree_node *root;       /**< Root tree node.                    */
+    unsigned size;              /**< Number of elements in the tree.    */
+    pj_rbtree_comp *comp;       /**< Key comparison function.           */
+} pj_rbtree;
+
+
+/**
+ * Guidance on how much memory required for each of the node.
+ */
+#define PJ_RBTREE_NODE_SIZE	    (sizeof(pj_rbtree_node))
+
+
+/**
+ * Guidance on memory required for the tree.
+ */
+#define PJ_RBTREE_SIZE		    (sizeof(pj_rbtree))
+
+
+/**
+ * Initialize the tree.
+ * @param tree the tree to be initialized.
+ * @param comp key comparison function to be used for this tree.
+ */
+PJ_DECL(void) pj_rbtree_init( pj_rbtree *tree, pj_rbtree_comp *comp);
+
+/**
+ * Get the first element in the tree.
+ * The first element always has the least value for the key, according to
+ * the comparison function.
+ * @param tree the tree.
+ * @return the tree node, or NULL if the tree has no element.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_first( pj_rbtree *tree );
+
+/**
+ * Get the last element in the tree.
+ * The last element always has the greatest key value, according to the
+ * comparison function defined for the tree.
+ * @param tree the tree.
+ * @return the tree node, or NULL if the tree has no element.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_last( pj_rbtree *tree );
+
+/**
+ * Get the successive element for the specified node.
+ * The successive element is an element with greater key value.
+ * @param tree the tree.
+ * @param node the node.
+ * @return the successive node, or NULL if the node has no successor.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_next( pj_rbtree *tree, 
+					 pj_rbtree_node *node );
+
+/**
+ * The the previous node for the specified node.
+ * The previous node is an element with less key value.
+ * @param tree the tree.
+ * @param node the node.
+ * @return the previous node, or NULL if the node has no previous node.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_prev( pj_rbtree *tree, 
+					 pj_rbtree_node *node );
+
+/**
+ * Insert a new node. 
+ * The node will be inserted at sorted location. The key of the node must 
+ * be UNIQUE, i.e. it hasn't existed in the tree.
+ * @param tree the tree.
+ * @param node the node to be inserted.
+ * @return zero on success, or -1 if the key already exist.
+ */
+PJ_DECL(int) pj_rbtree_insert( pj_rbtree *tree, 
+			       pj_rbtree_node *node );
+
+/**
+ * Find a node which has the specified key.
+ * @param tree the tree.
+ * @param key the key to search.
+ * @return the tree node with the specified key, or NULL if the key can not
+ *         be found.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_find( pj_rbtree *tree,
+					 const void *key );
+
+/**
+ * Erase a node from the tree.
+ * @param tree the tree.
+ * @param node the node to be erased.
+ * @return the tree node itself.
+ */
+PJ_DECL(pj_rbtree_node*) pj_rbtree_erase( pj_rbtree *tree,
+					  pj_rbtree_node *node );
+
+/**
+ * Get the maximum tree height from the specified node.
+ * @param tree the tree.
+ * @param node the node, or NULL to get the root of the tree.
+ * @return the maximum height, which should be at most lg(N)
+ */
+PJ_DECL(unsigned) pj_rbtree_max_height( pj_rbtree *tree,
+					pj_rbtree_node *node );
+
+/**
+ * Get the minumum tree height from the specified node.
+ * @param tree the tree.
+ * @param node the node, or NULL to get the root of the tree.
+ * @return the height
+ */
+PJ_DECL(unsigned) pj_rbtree_min_height( pj_rbtree *tree,
+					pj_rbtree_node *node );
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif	/* __PJ_RBTREE_H__ */
+
diff --git a/pjlib/include/pj/sock.h b/pjlib/include/pj/sock.h
index ebadcf3..02d88c1 100644
--- a/pjlib/include/pj/sock.h
+++ b/pjlib/include/pj/sock.h
@@ -1,700 +1,700 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_SOCK_H__

-#define __PJ_SOCK_H__

-

-/**

- * @file sock.h

- * @brief Socket Abstraction.

- */

-

-#include <pj/types.h>

-

-PJ_BEGIN_DECL 

-

-

-/**

- * @defgroup PJ_SOCK Socket Abstraction

- * @ingroup PJ_IO

- * @{

- *

- * The PJLIB socket abstraction layer is a thin and very portable abstraction

- * for socket API. It provides API similar to BSD socket API. The abstraction

- * is needed because BSD socket API is not always available on all platforms,

- * therefore it wouldn't be possible to create a trully portable network

- * programs unless we provide such abstraction.

- *

- * Applications can use this API directly in their application, just

- * as they would when using traditional BSD socket API, provided they

- * call #pj_init() first.

- *

- * \section pj_sock_examples_sec Examples

- *

- * For some examples on how to use the socket API, please see:

- *

- *  - \ref page_pjlib_sock_test

- *  - \ref page_pjlib_select_test

- *  - \ref page_pjlib_sock_perf_test

- */

-

-

-/**

- * Supported address families. 

- * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL AF_*, BECAUSE

- * THE LIBRARY WILL DO TRANSLATION TO THE NATIVE VALUE.

- */

-extern const pj_uint16_t PJ_AF_UNIX;    /**< Unix domain socket.	*/

-#define PJ_AF_LOCAL	 PJ_AF_UNIX;    /**< POSIX name for AF_UNIX	*/

-extern const pj_uint16_t PJ_AF_INET;    /**< Internet IP protocol.	*/

-extern const pj_uint16_t PJ_AF_INET6;   /**< IP version 6.		*/

-extern const pj_uint16_t PJ_AF_PACKET;  /**< Packet family.		*/

-extern const pj_uint16_t PJ_AF_IRDA;    /**< IRDA sockets.		*/

-

-

-/**

- * Supported types of sockets.

- * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL SOCK_*, BECAUSE

- * THE LIBRARY WILL TRANSLATE THE VALUE TO THE NATIVE VALUE.

- */

-

-extern const pj_uint16_t PJ_SOCK_STREAM; /**< Sequenced, reliable, connection-

-					      based byte streams.           */

-extern const pj_uint16_t PJ_SOCK_DGRAM;  /**< Connectionless, unreliable 

-					      datagrams of fixed maximum 

-					      lengths.                      */

-extern const pj_uint16_t PJ_SOCK_RAW;    /**< Raw protocol interface.       */

-extern const pj_uint16_t PJ_SOCK_RDM;    /**< Reliably-delivered messages.  */

-

-

-/**

- * Socket level specified in #pj_sock_setsockopt() or #pj_sock_getsockopt().

- * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL SOL_*, BECAUSE

- * THE LIBRARY WILL TRANSLATE THE VALUE TO THE NATIVE VALUE.

- */

-extern const pj_uint16_t PJ_SOL_SOCKET;	/**< Socket level.  */

-extern const pj_uint16_t PJ_SOL_IP;	/**< IP level.	    */

-extern const pj_uint16_t PJ_SOL_TCP;	/**< TCP level.	    */

-extern const pj_uint16_t PJ_SOL_UDP;	/**< UDP level.	    */

-extern const pj_uint16_t PJ_SOL_IPV6;	/**< IP version 6   */

-

-/**

- * Values to be specified as \c optname when calling #pj_sock_setsockopt() 

- * or #pj_sock_getsockopt().

- */

-extern const pj_uint16_t PJ_SO_TYPE;    /**< Socket type.               */

-extern const pj_uint16_t PJ_SO_RCVBUF;  /**< Buffer size for receive.   */

-extern const pj_uint16_t PJ_SO_SNDBUF;  /**< Buffer size for send.      */

-

-

-/**

- * Flags to be specified in #pj_sock_recv, #pj_sock_send, etc.

- */

-typedef enum pj_sock_msg_flag

-{

-    PJ_MSG_OOB		= 0x01,	    /**< Out-of-band messages.		 */

-    PJ_MSG_PEEK		= 0x02,	    /**< Peek, don't remove from buffer. */

-    PJ_MSG_DONTROUTE	= 0x04,	    /**< Don't route.			 */

-} pj_sock_msg_flag;

-

-

-/**

- * Flag to be specified in #pj_sock_shutdown.

- */

-typedef enum pj_socket_sd_type

-{

-    PJ_SD_RECEIVE   = 0,    /**< No more receive.	    */

-    PJ_SHUT_RD	    = 0,    /**< Alias for SD_RECEIVE.	    */

-    PJ_SD_SEND	    = 1,    /**< No more sending.	    */

-    PJ_SHUT_WR	    = 1,    /**< Alias for SD_SEND.	    */

-    PJ_SD_BOTH	    = 2,    /**< No more send and receive.  */

-    PJ_SHUT_RDWR    = 2,    /**< Alias for SD_BOTH.	    */

-} pj_socket_sd_type;

-

-

-

-/** Address to accept any incoming messages. */

-#define PJ_INADDR_ANY	    ((pj_uint32_t)0)

-

-/** Address indicating an error return */

-#define PJ_INADDR_NONE	    ((pj_uint32_t)0xffffffff)

-

-/** Address to send to all hosts. */

-#define PJ_INADDR_BROADCAST ((pj_uint32_t)0xffffffff)

-

-

-/** 

- * Maximum length specifiable by #pj_sock_listen().

- * If the build system doesn't override this value, then the lowest 

- * denominator (five, in Win32 systems) will be used.

- */

-#if !defined(PJ_SOMAXCONN)

-#  define PJ_SOMAXCONN	5

-#endif

-

-

-/**

- * Constant for invalid socket returned by #pj_sock_socket() and

- * #pj_sock_accept().

- */

-#define PJ_INVALID_SOCKET   (-1)

-

-/**

- * Structure describing a generic socket address.

- */

-typedef struct pj_sockaddr

-{

-    pj_uint16_t	sa_family;	/**< Common data: address family.   */

-    char	sa_data[14];	/**< Address data.		    */

-} pj_sockaddr;

-

-

-/**

- * This structure describes Internet address.

- */

-typedef struct pj_in_addr

-{

-    pj_uint32_t	s_addr;		/**< The 32bit IP address.	    */

-} pj_in_addr;

-

-

-/**

- * This structure describes Internet socket address.

- */

-typedef struct pj_sockaddr_in

-{

-    pj_uint16_t	sin_family;	/**< Address family.		    */

-    pj_uint16_t	sin_port;	/**< Transport layer port number.   */

-    pj_in_addr	sin_addr;	/**< IP address.		    */

-    char	sin_zero[8];	/**< Padding.			    */

-} pj_sockaddr_in;

-

-

-/**

- * This structure describes IPv6 address.

- */

-typedef struct pj_in6_addr

-{

-    /** Union of address formats. */

-    union {

-	pj_uint8_t  u6_addr8[16];   /**< u6_addr8   */

-	pj_uint16_t u6_addr16[8];   /**< u6_addr16  */

-	pj_uint32_t u6_addr32[4];   /**< u6_addr32  */

-    } in6_u;

-/** Shortcut to access in6_u.u6_addr8. */

-#define s6_addr                 in6_u.u6_addr8

-/** Shortcut to access in6_u.u6_addr16. */

-#define s6_addr16               in6_u.u6_addr16

-/** Shortcut to access in6_u.u6_addr32. */

-#define s6_addr32               in6_u.u6_addr32

-} pj_in6_addr;

-

-/** Initializer value for pj_in6_addr. */

-#define PJ_IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }

-

-/** Initializer value for pj_in6_addr. */

-#define PJ_IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }

-

-/**

- * This structure describes IPv6 socket address.

- */

-typedef struct pj_sockaddr_in6

-{

-    pj_uint16_t	sin6_family;	    /**< Address family		    */

-    pj_uint16_t	sin6_port;	    /**< Transport layer port number. */

-    pj_uint32_t	sin6_flowinfo;	    /**< IPv6 flow information	    */

-    pj_in6_addr sin6_addr;	    /**< IPv6 address.		    */

-    pj_uint32_t sin6_scope_id;	    /**< IPv6 scope-id		    */

-} pj_sockaddr_in6;

-

-

-/*****************************************************************************

- *

- * SOCKET ADDRESS MANIPULATION.

- *

- *****************************************************************************

- */

-

-/**

- * Convert 16-bit value from network byte order to host byte order.

- *

- * @param netshort  16-bit network value.

- * @return	    16-bit host value.

- */

-PJ_DECL(pj_uint16_t) pj_ntohs(pj_uint16_t netshort);

-

-/**

- * Convert 16-bit value from host byte order to network byte order.

- *

- * @param hostshort 16-bit host value.

- * @return	    16-bit network value.

- */

-PJ_DECL(pj_uint16_t) pj_htons(pj_uint16_t hostshort);

-

-/**

- * Convert 32-bit value from network byte order to host byte order.

- *

- * @param netlong   32-bit network value.

- * @return	    32-bit host value.

- */

-PJ_DECL(pj_uint32_t) pj_ntohl(pj_uint32_t netlong);

-

-/**

- * Convert 32-bit value from host byte order to network byte order.

- *

- * @param hostlong  32-bit host value.

- * @return	    32-bit network value.

- */

-PJ_DECL(pj_uint32_t) pj_htonl(pj_uint32_t hostlong);

-

-/**

- * Convert an Internet host address given in network byte order

- * to string in standard numbers and dots notation.

- *

- * @param inaddr    The host address.

- * @return	    The string address.

- */

-PJ_DECL(char*) pj_inet_ntoa(pj_in_addr inaddr);

-

-/**

- * This function converts the Internet host address cp from the standard

- * numbers-and-dots notation into binary data and stores it in the structure

- * that inp points to. 

- *

- * @param cp	IP address in standard numbers-and-dots notation.

- * @param inp	Structure that holds the output of the conversion.

- *

- * @return	nonzero if the address is valid, zero if not.

- */

-PJ_DECL(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp);

-

-/**

- * Convert address string with numbers and dots to binary IP address.

- * 

- * @param cp	    The IP address in numbers and dots notation.

- * @return	    If success, the IP address is returned in network

- *		    byte order. If failed, PJ_INADDR_NONE will be

- *		    returned.

- * @remark

- * This is an obsolete interface to #pj_inet_aton(); it is obsolete

- * because -1 is a valid address (255.255.255.255), and #pj_inet_aton()

- * provides a cleaner way to indicate error return.

- */

-PJ_DECL(pj_in_addr) pj_inet_addr(const pj_str_t *cp);

-

-

-/**

- * Get the transport layer port number of an Internet socket address.

- * The port is returned in host byte order.

- *

- * @param addr	    The IP socket address.

- * @return	    Port number, in host byte order.

- */

-PJ_INLINE(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr)

-{

-    return pj_ntohs(addr->sin_port);

-}

-

-/**

- * Set the port number of an Internet socket address.

- *

- * @param addr	    The IP socket address.

- * @param hostport  The port number, in host byte order.

- */

-PJ_INLINE(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr, 

-					pj_uint16_t hostport)

-{

-    addr->sin_port = pj_htons(hostport);

-}

-

-/**

- * Get the IP address of an Internet socket address.

- * The address is returned as 32bit value in host byte order.

- *

- * @param addr	    The IP socket address.

- * @return	    32bit address, in host byte order.

- */

-PJ_INLINE(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr)

-{

-    pj_in_addr in_addr;

-    in_addr.s_addr = pj_ntohl(addr->sin_addr.s_addr);

-    return in_addr;

-};

-

-/**

- * Set the IP address of an Internet socket address.

- *

- * @param addr	    The IP socket address.

- * @param hostaddr  The host address, in host byte order.

- */

-PJ_INLINE(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr,

-					pj_uint32_t hostaddr)

-{

-    addr->sin_addr.s_addr = pj_htonl(hostaddr);

-}

-

-/**

- * Set the IP address of an IP socket address from string address, 

- * with resolving the host if necessary. The string address may be in a

- * standard numbers and dots notation or may be a hostname. If hostname

- * is specified, then the function will resolve the host into the IP

- * address.

- *

- * @param addr	    The IP socket address to be set.

- * @param cp	    The address string, which can be in a standard 

- *		    dotted numbers or a hostname to be resolved.

- *

- * @return	    Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr,

-					          const pj_str_t *cp);

-

-/**

- * Set the IP address and port of an IP socket address.

- * The string address may be in a standard numbers and dots notation or 

- * may be a hostname. If hostname is specified, then the function will 

- * resolve the host into the IP address.

- *

- * @param addr	    The IP socket address to be set.

- * @param cp	    The address string, which can be in a standard 

- *		    dotted numbers or a hostname to be resolved.

- * @param port	    The port number, in host byte order.

- *

- * @return	    Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr,

-				          const pj_str_t *cp,

-					  pj_uint16_t port);

-

-

-/*****************************************************************************

- *

- * HOST NAME AND ADDRESS.

- *

- *****************************************************************************

- */

-

-/**

- * Get system's host name.

- *

- * @return	    The hostname, or empty string if the hostname can not

- *		    be identified.

- */

-PJ_DECL(const pj_str_t*) pj_gethostname(void);

-

-/**

- * Get host's IP address, which the the first IP address that is resolved

- * from the hostname.

- *

- * @return	    The host's IP address, PJ_INADDR_NONE if the host

- *		    IP address can not be identified.

- */

-PJ_DECL(pj_in_addr) pj_gethostaddr(void);

-

-

-/*****************************************************************************

- *

- * SOCKET API.

- *

- *****************************************************************************

- */

-

-/**

- * Create new socket/endpoint for communication.

- *

- * @param family    Specifies a communication domain; this selects the

- *		    protocol family which will be used for communication.

- * @param type	    The socket has the indicated type, which specifies the 

- *		    communication semantics.

- * @param protocol  Specifies  a  particular  protocol  to  be used with the

- *		    socket.  Normally only a single protocol exists to support 

- *		    a particular socket  type  within  a given protocol family, 

- *		    in which a case protocol can be specified as 0.

- * @param sock	    New socket descriptor, or PJ_INVALID_SOCKET on error.

- *

- * @return	    Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sock_socket(int family, 

-				    int type, 

-				    int protocol,

-				    pj_sock_t *sock);

-

-/**

- * Close the socket descriptor.

- *

- * @param sockfd    The socket descriptor.

- *

- * @return	    Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sock_close(pj_sock_t sockfd);

-

-

-/**

- * This function gives the socket sockfd the local address my_addr. my_addr is

- * addrlen bytes long.  Traditionally, this is called assigning a name to

- * a socket. When a socket is created with #pj_sock_socket(), it exists in a

- * name space (address family) but has no name assigned.

- *

- * @param sockfd    The socket desriptor.

- * @param my_addr   The local address to bind the socket to.

- * @param addrlen   The length of the address.

- *

- * @return	    Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sock_bind( pj_sock_t sockfd, 

-				   const pj_sockaddr_t *my_addr,

-				   int addrlen);

-

-/**

- * Bind the IP socket sockfd to the given address and port.

- *

- * @param sockfd    The socket descriptor.

- * @param addr	    Local address to bind the socket to, in host byte order.

- * @param port	    The local port to bind the socket to, in host byte order.

- *

- * @return	    Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sock_bind_in( pj_sock_t sockfd, 

-				      pj_uint32_t addr,

-				      pj_uint16_t port);

-

-#if PJ_HAS_TCP

-/**

- * Listen for incoming connection. This function only applies to connection

- * oriented sockets (such as PJ_SOCK_STREAM or PJ_SOCK_SEQPACKET), and it

- * indicates the willingness to accept incoming connections.

- *

- * @param sockfd	The socket descriptor.

- * @param backlog	Defines the maximum length the queue of pending

- *			connections may grow to.

- *

- * @return		Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sock_listen( pj_sock_t sockfd, 

-				     int backlog );

-

-/**

- * Accept new connection on the specified connection oriented server socket.

- *

- * @param serverfd  The server socket.

- * @param newsock   New socket on success, of PJ_INVALID_SOCKET if failed.

- * @param addr	    A pointer to sockaddr type. If the argument is not NULL,

- *		    it will be filled by the address of connecting entity.

- * @param addrlen   Initially specifies the length of the address, and upon

- *		    return will be filled with the exact address length.

- *

- * @return	    Zero on success, or the error number.

- */

-PJ_DECL(pj_status_t) pj_sock_accept( pj_sock_t serverfd,

-				     pj_sock_t *newsock,

-				     pj_sockaddr_t *addr,

-				     int *addrlen);

-#endif

-

-/**

- * The file descriptor sockfd must refer to a socket.  If the socket is of

- * type PJ_SOCK_DGRAM  then the serv_addr address is the address to which

- * datagrams are sent by default, and the only address from which datagrams

- * are received. If the socket is of type PJ_SOCK_STREAM or PJ_SOCK_SEQPACKET,

- * this call attempts to make a connection to another socket.  The

- * other socket is specified by serv_addr, which is an address (of length

- * addrlen) in the communications space of the  socket.  Each  communications

- * space interprets the serv_addr parameter in its own way.

- *

- * @param sockfd	The socket descriptor.

- * @param serv_addr	Server address to connect to.

- * @param addrlen	The length of server address.

- *

- * @return		Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sock_connect( pj_sock_t sockfd,

-				      const pj_sockaddr_t *serv_addr,

-				      int addrlen);

-

-/**

- * Return the address of peer which is connected to socket sockfd.

- *

- * @param sockfd	The socket descriptor.

- * @param addr		Pointer to sockaddr structure to which the address

- *			will be returned.

- * @param namelen	Initially the length of the addr. Upon return the value

- *			will be set to the actual length of the address.

- *

- * @return		Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sock_getpeername(pj_sock_t sockfd,

-					  pj_sockaddr_t *addr,

-					  int *namelen);

-

-/**

- * Return the current name of the specified socket.

- *

- * @param sockfd	The socket descriptor.

- * @param addr		Pointer to sockaddr structure to which the address

- *			will be returned.

- * @param namelen	Initially the length of the addr. Upon return the value

- *			will be set to the actual length of the address.

- *

- * @return		Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sock_getsockname( pj_sock_t sockfd,

-					  pj_sockaddr_t *addr,

-					  int *namelen);

-

-/**

- * Get socket option associated with a socket. Options may exist at multiple

- * protocol levels; they are always present at the uppermost socket level.

- *

- * @param sockfd	The socket descriptor.

- * @param level		The level which to get the option from.

- * @param optname	The option name.

- * @param optval	Identifies the buffer which the value will be

- *			returned.

- * @param optlen	Initially contains the length of the buffer, upon

- *			return will be set to the actual size of the value.

- *

- * @return		Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sock_getsockopt( pj_sock_t sockfd,

-					 pj_uint16_t level,

-					 pj_uint16_t optname,

-					 void *optval,

-					 int *optlen);

-/**

- * Manipulate the options associated with a socket. Options may exist at 

- * multiple protocol levels; they are always present at the uppermost socket 

- * level.

- *

- * @param sockfd	The socket descriptor.

- * @param level		The level which to get the option from.

- * @param optname	The option name.

- * @param optval	Identifies the buffer which contain the value.

- * @param optlen	The length of the value.

- *

- * @return		PJ_SUCCESS or the status code.

- */

-PJ_DECL(pj_status_t) pj_sock_setsockopt( pj_sock_t sockfd,

-					 pj_uint16_t level,

-					 pj_uint16_t optname,

-					 const void *optval,

-					 int optlen);

-

-

-/**

- * Receives data stream or message coming to the specified socket.

- *

- * @param sockfd	The socket descriptor.

- * @param buf		The buffer to receive the data or message.

- * @param len		On input, the length of the buffer. On return,

- *			contains the length of data received.

- * @param flags		Combination of #pj_sock_msg_flag.

- *

- * @return		PJ_SUCCESS or the error code.

- */

-PJ_DECL(pj_status_t) pj_sock_recv(pj_sock_t sockfd,

-				  void *buf,

-				  pj_ssize_t *len,

-				  unsigned flags);

-

-/**

- * Receives data stream or message coming to the specified socket.

- *

- * @param sockfd	The socket descriptor.

- * @param buf		The buffer to receive the data or message.

- * @param len		On input, the length of the buffer. On return,

- *			contains the length of data received.

- * @param flags		Bitmask combination of #pj_sock_msg_flag.

- * @param from		If not NULL, it will be filled with the source

- *			address of the connection.

- * @param fromlen	Initially contains the length of from address,

- *			and upon return will be filled with the actual

- *			length of the address.

- *

- * @return		PJ_SUCCESS or the error code.

- */

-PJ_DECL(pj_status_t) pj_sock_recvfrom( pj_sock_t sockfd,

-				      void *buf,

-				      pj_ssize_t *len,

-				      unsigned flags,

-				      pj_sockaddr_t *from,

-				      int *fromlen);

-

-/**

- * Transmit data to the socket.

- *

- * @param sockfd	Socket descriptor.

- * @param buf		Buffer containing data to be sent.

- * @param len		On input, the length of the data in the buffer.

- *			Upon return, it will be filled with the length

- *			of data sent.

- * @param flags		Bitmask combination of #pj_sock_msg_flag.

- *

- * @return		PJ_SUCCESS or the status code.

- */

-PJ_DECL(pj_status_t) pj_sock_send(pj_sock_t sockfd,

-				  const void *buf,

-				  pj_ssize_t *len,

-				  unsigned flags);

-

-/**

- * Transmit data to the socket to the specified address.

- *

- * @param sockfd	Socket descriptor.

- * @param buf		Buffer containing data to be sent.

- * @param len		On input, the length of the data in the buffer.

- *			Upon return, it will be filled with the length

- *			of data sent.

- * @param flags		Bitmask combination of #pj_sock_msg_flag.

- * @param to		The address to send.

- * @param tolen		The length of the address in bytes.

- *

- * @return		The length of data successfully sent.

- */

-PJ_DECL(pj_status_t) pj_sock_sendto(pj_sock_t sockfd,

-				    const void *buf,

-				    pj_ssize_t *len,

-				    unsigned flags,

-				    const pj_sockaddr_t *to,

-				    int tolen);

-

-#if PJ_HAS_TCP

-/**

- * The shutdown call causes all or part of a full-duplex connection on the

- * socket associated with sockfd to be shut down.

- *

- * @param sockfd	The socket descriptor.

- * @param how		If how is PJ_SHUT_RD, further receptions will be 

- *			disallowed. If how is PJ_SHUT_WR, further transmissions

- *			will be disallowed. If how is PJ_SHUT_RDWR, further 

- *			receptions andtransmissions will be disallowed.

- *

- * @return		Zero on success.

- */

-PJ_DECL(pj_status_t) pj_sock_shutdown( pj_sock_t sockfd,

-				       int how);

-#endif

-

-/**

- * @}

- */

-

-

-PJ_END_DECL

-

-#endif	/* __PJ_SOCK_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_SOCK_H__
+#define __PJ_SOCK_H__
+
+/**
+ * @file sock.h
+ * @brief Socket Abstraction.
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL 
+
+
+/**
+ * @defgroup PJ_SOCK Socket Abstraction
+ * @ingroup PJ_IO
+ * @{
+ *
+ * The PJLIB socket abstraction layer is a thin and very portable abstraction
+ * for socket API. It provides API similar to BSD socket API. The abstraction
+ * is needed because BSD socket API is not always available on all platforms,
+ * therefore it wouldn't be possible to create a trully portable network
+ * programs unless we provide such abstraction.
+ *
+ * Applications can use this API directly in their application, just
+ * as they would when using traditional BSD socket API, provided they
+ * call #pj_init() first.
+ *
+ * \section pj_sock_examples_sec Examples
+ *
+ * For some examples on how to use the socket API, please see:
+ *
+ *  - \ref page_pjlib_sock_test
+ *  - \ref page_pjlib_select_test
+ *  - \ref page_pjlib_sock_perf_test
+ */
+
+
+/**
+ * Supported address families. 
+ * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL AF_*, BECAUSE
+ * THE LIBRARY WILL DO TRANSLATION TO THE NATIVE VALUE.
+ */
+extern const pj_uint16_t PJ_AF_UNIX;    /**< Unix domain socket.	*/
+#define PJ_AF_LOCAL	 PJ_AF_UNIX;    /**< POSIX name for AF_UNIX	*/
+extern const pj_uint16_t PJ_AF_INET;    /**< Internet IP protocol.	*/
+extern const pj_uint16_t PJ_AF_INET6;   /**< IP version 6.		*/
+extern const pj_uint16_t PJ_AF_PACKET;  /**< Packet family.		*/
+extern const pj_uint16_t PJ_AF_IRDA;    /**< IRDA sockets.		*/
+
+
+/**
+ * Supported types of sockets.
+ * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL SOCK_*, BECAUSE
+ * THE LIBRARY WILL TRANSLATE THE VALUE TO THE NATIVE VALUE.
+ */
+
+extern const pj_uint16_t PJ_SOCK_STREAM; /**< Sequenced, reliable, connection-
+					      based byte streams.           */
+extern const pj_uint16_t PJ_SOCK_DGRAM;  /**< Connectionless, unreliable 
+					      datagrams of fixed maximum 
+					      lengths.                      */
+extern const pj_uint16_t PJ_SOCK_RAW;    /**< Raw protocol interface.       */
+extern const pj_uint16_t PJ_SOCK_RDM;    /**< Reliably-delivered messages.  */
+
+
+/**
+ * Socket level specified in #pj_sock_setsockopt() or #pj_sock_getsockopt().
+ * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL SOL_*, BECAUSE
+ * THE LIBRARY WILL TRANSLATE THE VALUE TO THE NATIVE VALUE.
+ */
+extern const pj_uint16_t PJ_SOL_SOCKET;	/**< Socket level.  */
+extern const pj_uint16_t PJ_SOL_IP;	/**< IP level.	    */
+extern const pj_uint16_t PJ_SOL_TCP;	/**< TCP level.	    */
+extern const pj_uint16_t PJ_SOL_UDP;	/**< UDP level.	    */
+extern const pj_uint16_t PJ_SOL_IPV6;	/**< IP version 6   */
+
+/**
+ * Values to be specified as \c optname when calling #pj_sock_setsockopt() 
+ * or #pj_sock_getsockopt().
+ */
+extern const pj_uint16_t PJ_SO_TYPE;    /**< Socket type.               */
+extern const pj_uint16_t PJ_SO_RCVBUF;  /**< Buffer size for receive.   */
+extern const pj_uint16_t PJ_SO_SNDBUF;  /**< Buffer size for send.      */
+
+
+/**
+ * Flags to be specified in #pj_sock_recv, #pj_sock_send, etc.
+ */
+typedef enum pj_sock_msg_flag
+{
+    PJ_MSG_OOB		= 0x01,	    /**< Out-of-band messages.		 */
+    PJ_MSG_PEEK		= 0x02,	    /**< Peek, don't remove from buffer. */
+    PJ_MSG_DONTROUTE	= 0x04,	    /**< Don't route.			 */
+} pj_sock_msg_flag;
+
+
+/**
+ * Flag to be specified in #pj_sock_shutdown.
+ */
+typedef enum pj_socket_sd_type
+{
+    PJ_SD_RECEIVE   = 0,    /**< No more receive.	    */
+    PJ_SHUT_RD	    = 0,    /**< Alias for SD_RECEIVE.	    */
+    PJ_SD_SEND	    = 1,    /**< No more sending.	    */
+    PJ_SHUT_WR	    = 1,    /**< Alias for SD_SEND.	    */
+    PJ_SD_BOTH	    = 2,    /**< No more send and receive.  */
+    PJ_SHUT_RDWR    = 2,    /**< Alias for SD_BOTH.	    */
+} pj_socket_sd_type;
+
+
+
+/** Address to accept any incoming messages. */
+#define PJ_INADDR_ANY	    ((pj_uint32_t)0)
+
+/** Address indicating an error return */
+#define PJ_INADDR_NONE	    ((pj_uint32_t)0xffffffff)
+
+/** Address to send to all hosts. */
+#define PJ_INADDR_BROADCAST ((pj_uint32_t)0xffffffff)
+
+
+/** 
+ * Maximum length specifiable by #pj_sock_listen().
+ * If the build system doesn't override this value, then the lowest 
+ * denominator (five, in Win32 systems) will be used.
+ */
+#if !defined(PJ_SOMAXCONN)
+#  define PJ_SOMAXCONN	5
+#endif
+
+
+/**
+ * Constant for invalid socket returned by #pj_sock_socket() and
+ * #pj_sock_accept().
+ */
+#define PJ_INVALID_SOCKET   (-1)
+
+/**
+ * Structure describing a generic socket address.
+ */
+typedef struct pj_sockaddr
+{
+    pj_uint16_t	sa_family;	/**< Common data: address family.   */
+    char	sa_data[14];	/**< Address data.		    */
+} pj_sockaddr;
+
+
+/**
+ * This structure describes Internet address.
+ */
+typedef struct pj_in_addr
+{
+    pj_uint32_t	s_addr;		/**< The 32bit IP address.	    */
+} pj_in_addr;
+
+
+/**
+ * This structure describes Internet socket address.
+ */
+typedef struct pj_sockaddr_in
+{
+    pj_uint16_t	sin_family;	/**< Address family.		    */
+    pj_uint16_t	sin_port;	/**< Transport layer port number.   */
+    pj_in_addr	sin_addr;	/**< IP address.		    */
+    char	sin_zero[8];	/**< Padding.			    */
+} pj_sockaddr_in;
+
+
+/**
+ * This structure describes IPv6 address.
+ */
+typedef struct pj_in6_addr
+{
+    /** Union of address formats. */
+    union {
+	pj_uint8_t  u6_addr8[16];   /**< u6_addr8   */
+	pj_uint16_t u6_addr16[8];   /**< u6_addr16  */
+	pj_uint32_t u6_addr32[4];   /**< u6_addr32  */
+    } in6_u;
+/** Shortcut to access in6_u.u6_addr8. */
+#define s6_addr                 in6_u.u6_addr8
+/** Shortcut to access in6_u.u6_addr16. */
+#define s6_addr16               in6_u.u6_addr16
+/** Shortcut to access in6_u.u6_addr32. */
+#define s6_addr32               in6_u.u6_addr32
+} pj_in6_addr;
+
+/** Initializer value for pj_in6_addr. */
+#define PJ_IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+
+/** Initializer value for pj_in6_addr. */
+#define PJ_IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+
+/**
+ * This structure describes IPv6 socket address.
+ */
+typedef struct pj_sockaddr_in6
+{
+    pj_uint16_t	sin6_family;	    /**< Address family		    */
+    pj_uint16_t	sin6_port;	    /**< Transport layer port number. */
+    pj_uint32_t	sin6_flowinfo;	    /**< IPv6 flow information	    */
+    pj_in6_addr sin6_addr;	    /**< IPv6 address.		    */
+    pj_uint32_t sin6_scope_id;	    /**< IPv6 scope-id		    */
+} pj_sockaddr_in6;
+
+
+/*****************************************************************************
+ *
+ * SOCKET ADDRESS MANIPULATION.
+ *
+ *****************************************************************************
+ */
+
+/**
+ * Convert 16-bit value from network byte order to host byte order.
+ *
+ * @param netshort  16-bit network value.
+ * @return	    16-bit host value.
+ */
+PJ_DECL(pj_uint16_t) pj_ntohs(pj_uint16_t netshort);
+
+/**
+ * Convert 16-bit value from host byte order to network byte order.
+ *
+ * @param hostshort 16-bit host value.
+ * @return	    16-bit network value.
+ */
+PJ_DECL(pj_uint16_t) pj_htons(pj_uint16_t hostshort);
+
+/**
+ * Convert 32-bit value from network byte order to host byte order.
+ *
+ * @param netlong   32-bit network value.
+ * @return	    32-bit host value.
+ */
+PJ_DECL(pj_uint32_t) pj_ntohl(pj_uint32_t netlong);
+
+/**
+ * Convert 32-bit value from host byte order to network byte order.
+ *
+ * @param hostlong  32-bit host value.
+ * @return	    32-bit network value.
+ */
+PJ_DECL(pj_uint32_t) pj_htonl(pj_uint32_t hostlong);
+
+/**
+ * Convert an Internet host address given in network byte order
+ * to string in standard numbers and dots notation.
+ *
+ * @param inaddr    The host address.
+ * @return	    The string address.
+ */
+PJ_DECL(char*) pj_inet_ntoa(pj_in_addr inaddr);
+
+/**
+ * This function converts the Internet host address cp from the standard
+ * numbers-and-dots notation into binary data and stores it in the structure
+ * that inp points to. 
+ *
+ * @param cp	IP address in standard numbers-and-dots notation.
+ * @param inp	Structure that holds the output of the conversion.
+ *
+ * @return	nonzero if the address is valid, zero if not.
+ */
+PJ_DECL(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp);
+
+/**
+ * Convert address string with numbers and dots to binary IP address.
+ * 
+ * @param cp	    The IP address in numbers and dots notation.
+ * @return	    If success, the IP address is returned in network
+ *		    byte order. If failed, PJ_INADDR_NONE will be
+ *		    returned.
+ * @remark
+ * This is an obsolete interface to #pj_inet_aton(); it is obsolete
+ * because -1 is a valid address (255.255.255.255), and #pj_inet_aton()
+ * provides a cleaner way to indicate error return.
+ */
+PJ_DECL(pj_in_addr) pj_inet_addr(const pj_str_t *cp);
+
+
+/**
+ * Get the transport layer port number of an Internet socket address.
+ * The port is returned in host byte order.
+ *
+ * @param addr	    The IP socket address.
+ * @return	    Port number, in host byte order.
+ */
+PJ_INLINE(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr)
+{
+    return pj_ntohs(addr->sin_port);
+}
+
+/**
+ * Set the port number of an Internet socket address.
+ *
+ * @param addr	    The IP socket address.
+ * @param hostport  The port number, in host byte order.
+ */
+PJ_INLINE(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr, 
+					pj_uint16_t hostport)
+{
+    addr->sin_port = pj_htons(hostport);
+}
+
+/**
+ * Get the IP address of an Internet socket address.
+ * The address is returned as 32bit value in host byte order.
+ *
+ * @param addr	    The IP socket address.
+ * @return	    32bit address, in host byte order.
+ */
+PJ_INLINE(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr)
+{
+    pj_in_addr in_addr;
+    in_addr.s_addr = pj_ntohl(addr->sin_addr.s_addr);
+    return in_addr;
+};
+
+/**
+ * Set the IP address of an Internet socket address.
+ *
+ * @param addr	    The IP socket address.
+ * @param hostaddr  The host address, in host byte order.
+ */
+PJ_INLINE(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr,
+					pj_uint32_t hostaddr)
+{
+    addr->sin_addr.s_addr = pj_htonl(hostaddr);
+}
+
+/**
+ * Set the IP address of an IP socket address from string address, 
+ * with resolving the host if necessary. The string address may be in a
+ * standard numbers and dots notation or may be a hostname. If hostname
+ * is specified, then the function will resolve the host into the IP
+ * address.
+ *
+ * @param addr	    The IP socket address to be set.
+ * @param cp	    The address string, which can be in a standard 
+ *		    dotted numbers or a hostname to be resolved.
+ *
+ * @return	    Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr,
+					          const pj_str_t *cp);
+
+/**
+ * Set the IP address and port of an IP socket address.
+ * The string address may be in a standard numbers and dots notation or 
+ * may be a hostname. If hostname is specified, then the function will 
+ * resolve the host into the IP address.
+ *
+ * @param addr	    The IP socket address to be set.
+ * @param cp	    The address string, which can be in a standard 
+ *		    dotted numbers or a hostname to be resolved.
+ * @param port	    The port number, in host byte order.
+ *
+ * @return	    Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr,
+				          const pj_str_t *cp,
+					  pj_uint16_t port);
+
+
+/*****************************************************************************
+ *
+ * HOST NAME AND ADDRESS.
+ *
+ *****************************************************************************
+ */
+
+/**
+ * Get system's host name.
+ *
+ * @return	    The hostname, or empty string if the hostname can not
+ *		    be identified.
+ */
+PJ_DECL(const pj_str_t*) pj_gethostname(void);
+
+/**
+ * Get host's IP address, which the the first IP address that is resolved
+ * from the hostname.
+ *
+ * @return	    The host's IP address, PJ_INADDR_NONE if the host
+ *		    IP address can not be identified.
+ */
+PJ_DECL(pj_in_addr) pj_gethostaddr(void);
+
+
+/*****************************************************************************
+ *
+ * SOCKET API.
+ *
+ *****************************************************************************
+ */
+
+/**
+ * Create new socket/endpoint for communication.
+ *
+ * @param family    Specifies a communication domain; this selects the
+ *		    protocol family which will be used for communication.
+ * @param type	    The socket has the indicated type, which specifies the 
+ *		    communication semantics.
+ * @param protocol  Specifies  a  particular  protocol  to  be used with the
+ *		    socket.  Normally only a single protocol exists to support 
+ *		    a particular socket  type  within  a given protocol family, 
+ *		    in which a case protocol can be specified as 0.
+ * @param sock	    New socket descriptor, or PJ_INVALID_SOCKET on error.
+ *
+ * @return	    Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_socket(int family, 
+				    int type, 
+				    int protocol,
+				    pj_sock_t *sock);
+
+/**
+ * Close the socket descriptor.
+ *
+ * @param sockfd    The socket descriptor.
+ *
+ * @return	    Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_close(pj_sock_t sockfd);
+
+
+/**
+ * This function gives the socket sockfd the local address my_addr. my_addr is
+ * addrlen bytes long.  Traditionally, this is called assigning a name to
+ * a socket. When a socket is created with #pj_sock_socket(), it exists in a
+ * name space (address family) but has no name assigned.
+ *
+ * @param sockfd    The socket desriptor.
+ * @param my_addr   The local address to bind the socket to.
+ * @param addrlen   The length of the address.
+ *
+ * @return	    Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_bind( pj_sock_t sockfd, 
+				   const pj_sockaddr_t *my_addr,
+				   int addrlen);
+
+/**
+ * Bind the IP socket sockfd to the given address and port.
+ *
+ * @param sockfd    The socket descriptor.
+ * @param addr	    Local address to bind the socket to, in host byte order.
+ * @param port	    The local port to bind the socket to, in host byte order.
+ *
+ * @return	    Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_bind_in( pj_sock_t sockfd, 
+				      pj_uint32_t addr,
+				      pj_uint16_t port);
+
+#if PJ_HAS_TCP
+/**
+ * Listen for incoming connection. This function only applies to connection
+ * oriented sockets (such as PJ_SOCK_STREAM or PJ_SOCK_SEQPACKET), and it
+ * indicates the willingness to accept incoming connections.
+ *
+ * @param sockfd	The socket descriptor.
+ * @param backlog	Defines the maximum length the queue of pending
+ *			connections may grow to.
+ *
+ * @return		Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_listen( pj_sock_t sockfd, 
+				     int backlog );
+
+/**
+ * Accept new connection on the specified connection oriented server socket.
+ *
+ * @param serverfd  The server socket.
+ * @param newsock   New socket on success, of PJ_INVALID_SOCKET if failed.
+ * @param addr	    A pointer to sockaddr type. If the argument is not NULL,
+ *		    it will be filled by the address of connecting entity.
+ * @param addrlen   Initially specifies the length of the address, and upon
+ *		    return will be filled with the exact address length.
+ *
+ * @return	    Zero on success, or the error number.
+ */
+PJ_DECL(pj_status_t) pj_sock_accept( pj_sock_t serverfd,
+				     pj_sock_t *newsock,
+				     pj_sockaddr_t *addr,
+				     int *addrlen);
+#endif
+
+/**
+ * The file descriptor sockfd must refer to a socket.  If the socket is of
+ * type PJ_SOCK_DGRAM  then the serv_addr address is the address to which
+ * datagrams are sent by default, and the only address from which datagrams
+ * are received. If the socket is of type PJ_SOCK_STREAM or PJ_SOCK_SEQPACKET,
+ * this call attempts to make a connection to another socket.  The
+ * other socket is specified by serv_addr, which is an address (of length
+ * addrlen) in the communications space of the  socket.  Each  communications
+ * space interprets the serv_addr parameter in its own way.
+ *
+ * @param sockfd	The socket descriptor.
+ * @param serv_addr	Server address to connect to.
+ * @param addrlen	The length of server address.
+ *
+ * @return		Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_connect( pj_sock_t sockfd,
+				      const pj_sockaddr_t *serv_addr,
+				      int addrlen);
+
+/**
+ * Return the address of peer which is connected to socket sockfd.
+ *
+ * @param sockfd	The socket descriptor.
+ * @param addr		Pointer to sockaddr structure to which the address
+ *			will be returned.
+ * @param namelen	Initially the length of the addr. Upon return the value
+ *			will be set to the actual length of the address.
+ *
+ * @return		Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_getpeername(pj_sock_t sockfd,
+					  pj_sockaddr_t *addr,
+					  int *namelen);
+
+/**
+ * Return the current name of the specified socket.
+ *
+ * @param sockfd	The socket descriptor.
+ * @param addr		Pointer to sockaddr structure to which the address
+ *			will be returned.
+ * @param namelen	Initially the length of the addr. Upon return the value
+ *			will be set to the actual length of the address.
+ *
+ * @return		Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_getsockname( pj_sock_t sockfd,
+					  pj_sockaddr_t *addr,
+					  int *namelen);
+
+/**
+ * Get socket option associated with a socket. Options may exist at multiple
+ * protocol levels; they are always present at the uppermost socket level.
+ *
+ * @param sockfd	The socket descriptor.
+ * @param level		The level which to get the option from.
+ * @param optname	The option name.
+ * @param optval	Identifies the buffer which the value will be
+ *			returned.
+ * @param optlen	Initially contains the length of the buffer, upon
+ *			return will be set to the actual size of the value.
+ *
+ * @return		Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_getsockopt( pj_sock_t sockfd,
+					 pj_uint16_t level,
+					 pj_uint16_t optname,
+					 void *optval,
+					 int *optlen);
+/**
+ * Manipulate the options associated with a socket. Options may exist at 
+ * multiple protocol levels; they are always present at the uppermost socket 
+ * level.
+ *
+ * @param sockfd	The socket descriptor.
+ * @param level		The level which to get the option from.
+ * @param optname	The option name.
+ * @param optval	Identifies the buffer which contain the value.
+ * @param optlen	The length of the value.
+ *
+ * @return		PJ_SUCCESS or the status code.
+ */
+PJ_DECL(pj_status_t) pj_sock_setsockopt( pj_sock_t sockfd,
+					 pj_uint16_t level,
+					 pj_uint16_t optname,
+					 const void *optval,
+					 int optlen);
+
+
+/**
+ * Receives data stream or message coming to the specified socket.
+ *
+ * @param sockfd	The socket descriptor.
+ * @param buf		The buffer to receive the data or message.
+ * @param len		On input, the length of the buffer. On return,
+ *			contains the length of data received.
+ * @param flags		Combination of #pj_sock_msg_flag.
+ *
+ * @return		PJ_SUCCESS or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sock_recv(pj_sock_t sockfd,
+				  void *buf,
+				  pj_ssize_t *len,
+				  unsigned flags);
+
+/**
+ * Receives data stream or message coming to the specified socket.
+ *
+ * @param sockfd	The socket descriptor.
+ * @param buf		The buffer to receive the data or message.
+ * @param len		On input, the length of the buffer. On return,
+ *			contains the length of data received.
+ * @param flags		Bitmask combination of #pj_sock_msg_flag.
+ * @param from		If not NULL, it will be filled with the source
+ *			address of the connection.
+ * @param fromlen	Initially contains the length of from address,
+ *			and upon return will be filled with the actual
+ *			length of the address.
+ *
+ * @return		PJ_SUCCESS or the error code.
+ */
+PJ_DECL(pj_status_t) pj_sock_recvfrom( pj_sock_t sockfd,
+				      void *buf,
+				      pj_ssize_t *len,
+				      unsigned flags,
+				      pj_sockaddr_t *from,
+				      int *fromlen);
+
+/**
+ * Transmit data to the socket.
+ *
+ * @param sockfd	Socket descriptor.
+ * @param buf		Buffer containing data to be sent.
+ * @param len		On input, the length of the data in the buffer.
+ *			Upon return, it will be filled with the length
+ *			of data sent.
+ * @param flags		Bitmask combination of #pj_sock_msg_flag.
+ *
+ * @return		PJ_SUCCESS or the status code.
+ */
+PJ_DECL(pj_status_t) pj_sock_send(pj_sock_t sockfd,
+				  const void *buf,
+				  pj_ssize_t *len,
+				  unsigned flags);
+
+/**
+ * Transmit data to the socket to the specified address.
+ *
+ * @param sockfd	Socket descriptor.
+ * @param buf		Buffer containing data to be sent.
+ * @param len		On input, the length of the data in the buffer.
+ *			Upon return, it will be filled with the length
+ *			of data sent.
+ * @param flags		Bitmask combination of #pj_sock_msg_flag.
+ * @param to		The address to send.
+ * @param tolen		The length of the address in bytes.
+ *
+ * @return		The length of data successfully sent.
+ */
+PJ_DECL(pj_status_t) pj_sock_sendto(pj_sock_t sockfd,
+				    const void *buf,
+				    pj_ssize_t *len,
+				    unsigned flags,
+				    const pj_sockaddr_t *to,
+				    int tolen);
+
+#if PJ_HAS_TCP
+/**
+ * The shutdown call causes all or part of a full-duplex connection on the
+ * socket associated with sockfd to be shut down.
+ *
+ * @param sockfd	The socket descriptor.
+ * @param how		If how is PJ_SHUT_RD, further receptions will be 
+ *			disallowed. If how is PJ_SHUT_WR, further transmissions
+ *			will be disallowed. If how is PJ_SHUT_RDWR, further 
+ *			receptions andtransmissions will be disallowed.
+ *
+ * @return		Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_shutdown( pj_sock_t sockfd,
+				       int how);
+#endif
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+#endif	/* __PJ_SOCK_H__ */
+
diff --git a/pjlib/include/pj/sock_select.h b/pjlib/include/pj/sock_select.h
index 4a97438..0b94de8 100644
--- a/pjlib/include/pj/sock_select.h
+++ b/pjlib/include/pj/sock_select.h
@@ -1,136 +1,136 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_SELECT_H__

-#define __PJ_SELECT_H__

-

-/**

- * @file sock_select.h

- * @brief Socket select().

- */

-

-#include <pj/types.h>

-

-PJ_BEGIN_DECL 

-

-/**

- * @defgroup PJ_SOCK_SELECT Socket select() API.

- * @ingroup PJ_IO

- * @{

- * This module provides portable abstraction for \a select() like API.

- * The abstraction is needed so that it can utilize various event

- * dispatching mechanisms that are available across platforms.

- *

- * The API is very similar to normal \a select() usage. 

- *

- * \section pj_sock_select_examples_sec Examples

- *

- * For some examples on how to use the select API, please see:

- *

- *  - \ref page_pjlib_select_test

- */

-

-/**

- * Portable structure declarations for pj_fd_set.

- * The implementation of pj_sock_select() does not use this structure 

- * per-se, but instead it will use the native fd_set structure. However,

- * we must make sure that the size of pj_fd_set_t can accomodate the

- * native fd_set structure.

- */

-typedef struct pj_fd_set_t

-{

-    pj_sock_t	data[FD_SETSIZE + 4];   /**< Opaque buffer for fd_set */

-} pj_fd_set_t;

-

-

-/**

- * Initialize the descriptor set pointed to by fdsetp to the null set.

- *

- * @param fdsetp    The descriptor set.

- */

-PJ_DECL(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp);

-

-

-/**

- * Add the file descriptor fd to the set pointed to by fdsetp. 

- * If the file descriptor fd is already in this set, there shall be no effect

- * on the set, nor will an error be returned.

- *

- * @param fd	    The socket descriptor.

- * @param fdsetp    The descriptor set.

- */

-PJ_DECL(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp);

-

-/**

- * Remove the file descriptor fd from the set pointed to by fdsetp. 

- * If fd is not a member of this set, there shall be no effect on the set, 

- * nor will an error be returned.

- *

- * @param fd	    The socket descriptor.

- * @param fdsetp    The descriptor set.

- */

-PJ_DECL(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp);

-

-

-/**

- * Evaluate to non-zero if the file descriptor fd is a member of the set 

- * pointed to by fdsetp, and shall evaluate to zero otherwise.

- *

- * @param fd	    The socket descriptor.

- * @param fdsetp    The descriptor set.

- *

- * @return	    Nonzero if fd is member of the descriptor set.

- */

-PJ_DECL(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp);

-

-

-/**

- * This function wait for a number of file  descriptors to change status.

- * The behaviour is the same as select() function call which appear in

- * standard BSD socket libraries.

- *

- * @param n	    On Unices, this specifies the highest-numbered

- *		    descriptor in any of the three set, plus 1. On Windows,

- *		    the value is ignored.

- * @param readfds   Optional pointer to a set of sockets to be checked for 

- *		    readability.

- * @param writefds  Optional pointer to a set of sockets to be checked for 

- *		    writability.

- * @param exceptfds Optional pointer to a set of sockets to be checked for 

- *		    errors.

- * @param timeout   Maximum time for select to wait, or null for blocking 

- *		    operations.

- *

- * @return	    The total number of socket handles that are ready, or

- *		    zero if the time limit expired, or -1 if an error occurred.

- */

-PJ_DECL(int) pj_sock_select( int n, 

-			     pj_fd_set_t *readfds, 

-			     pj_fd_set_t *writefds,

-			     pj_fd_set_t *exceptfds, 

-			     const pj_time_val *timeout);

-

-

-/**

- * @}

- */

-

-

-PJ_END_DECL

-

-#endif	/* __PJ_SELECT_H__ */

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_SELECT_H__
+#define __PJ_SELECT_H__
+
+/**
+ * @file sock_select.h
+ * @brief Socket select().
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL 
+
+/**
+ * @defgroup PJ_SOCK_SELECT Socket select() API.
+ * @ingroup PJ_IO
+ * @{
+ * This module provides portable abstraction for \a select() like API.
+ * The abstraction is needed so that it can utilize various event
+ * dispatching mechanisms that are available across platforms.
+ *
+ * The API is very similar to normal \a select() usage. 
+ *
+ * \section pj_sock_select_examples_sec Examples
+ *
+ * For some examples on how to use the select API, please see:
+ *
+ *  - \ref page_pjlib_select_test
+ */
+
+/**
+ * Portable structure declarations for pj_fd_set.
+ * The implementation of pj_sock_select() does not use this structure 
+ * per-se, but instead it will use the native fd_set structure. However,
+ * we must make sure that the size of pj_fd_set_t can accomodate the
+ * native fd_set structure.
+ */
+typedef struct pj_fd_set_t
+{
+    pj_sock_t	data[FD_SETSIZE + 4];   /**< Opaque buffer for fd_set */
+} pj_fd_set_t;
+
+
+/**
+ * Initialize the descriptor set pointed to by fdsetp to the null set.
+ *
+ * @param fdsetp    The descriptor set.
+ */
+PJ_DECL(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp);
+
+
+/**
+ * Add the file descriptor fd to the set pointed to by fdsetp. 
+ * If the file descriptor fd is already in this set, there shall be no effect
+ * on the set, nor will an error be returned.
+ *
+ * @param fd	    The socket descriptor.
+ * @param fdsetp    The descriptor set.
+ */
+PJ_DECL(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp);
+
+/**
+ * Remove the file descriptor fd from the set pointed to by fdsetp. 
+ * If fd is not a member of this set, there shall be no effect on the set, 
+ * nor will an error be returned.
+ *
+ * @param fd	    The socket descriptor.
+ * @param fdsetp    The descriptor set.
+ */
+PJ_DECL(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp);
+
+
+/**
+ * Evaluate to non-zero if the file descriptor fd is a member of the set 
+ * pointed to by fdsetp, and shall evaluate to zero otherwise.
+ *
+ * @param fd	    The socket descriptor.
+ * @param fdsetp    The descriptor set.
+ *
+ * @return	    Nonzero if fd is member of the descriptor set.
+ */
+PJ_DECL(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp);
+
+
+/**
+ * This function wait for a number of file  descriptors to change status.
+ * The behaviour is the same as select() function call which appear in
+ * standard BSD socket libraries.
+ *
+ * @param n	    On Unices, this specifies the highest-numbered
+ *		    descriptor in any of the three set, plus 1. On Windows,
+ *		    the value is ignored.
+ * @param readfds   Optional pointer to a set of sockets to be checked for 
+ *		    readability.
+ * @param writefds  Optional pointer to a set of sockets to be checked for 
+ *		    writability.
+ * @param exceptfds Optional pointer to a set of sockets to be checked for 
+ *		    errors.
+ * @param timeout   Maximum time for select to wait, or null for blocking 
+ *		    operations.
+ *
+ * @return	    The total number of socket handles that are ready, or
+ *		    zero if the time limit expired, or -1 if an error occurred.
+ */
+PJ_DECL(int) pj_sock_select( int n, 
+			     pj_fd_set_t *readfds, 
+			     pj_fd_set_t *writefds,
+			     pj_fd_set_t *exceptfds, 
+			     const pj_time_val *timeout);
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+#endif	/* __PJ_SELECT_H__ */
diff --git a/pjlib/include/pj/string.h b/pjlib/include/pj/string.h
index 8edcba8..c7310b5 100644
--- a/pjlib/include/pj/string.h
+++ b/pjlib/include/pj/string.h
@@ -1,561 +1,561 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_STRING_H__

-#define __PJ_STRING_H__

-

-/**

- * @file string.h

- * @brief PJLIB String Operations.

- */

-

-#include <pj/types.h>

-#include <pj/compat/string.h>

-#include <pj/compat/sprintf.h>

-#include <pj/compat/vsprintf.h>

-

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup PJ_PSTR String Operations

- * @ingroup PJ_DS

- * @{

- * This module provides string manipulation API.

- *

- * \section pj_pstr_not_null_sec PJLIB String is NOT Null Terminated!

- *

- * That is the first information that developers need to know. Instead

- * of using normal C string, strings in PJLIB are represented as

- * pj_str_t structure below:

- *

- * <pre>

- *   typedef struct pj_str_t

- *   {

- *       char      *ptr;

- *       pj_size_t  slen;

- *   } pj_str_t;

- * </pre>

- *

- * There are some advantages of using this approach:

- *  - the string can point to arbitrary location in memory even

- *    if the string in that location is not null terminated. This is

- *    most usefull for text parsing, where the parsed text can just

- *    point to the original text in the input. If we use C string,

- *    then we will have to copy the text portion from the input

- *    to a string variable.

- *  - because the length of the string is known, string copy operation

- *    can be made more efficient.

- *

- * Most of APIs in PJLIB that expect or return string will represent

- * the string as pj_str_t instead of normal C string.

- *

- * \section pj_pstr_examples_sec Examples

- *

- * For some examples, please see:

- *  - @ref page_pjlib_string_test

- */

-

-/**

- * Create string initializer from a normal C string.

- *

- * @param str	Null terminated string to be stored.

- *

- * @return	pj_str_t.

- */

-PJ_IDECL(pj_str_t) pj_str(char *str);

-

-/**

- * Create constant string from normal C string.

- *

- * @param str	The string to be initialized.

- * @param s	Null terminated string.

- *

- * @return	pj_str_t.

- */

-PJ_INLINE(const pj_str_t*) pj_cstr(pj_str_t *str, const char *s)

-{

-    str->ptr = (char*)s;

-    str->slen = s ? strlen(s) : 0;

-    return str;

-}

-

-/**

- * Set the pointer and length to the specified value.

- *

- * @param str	    the string.

- * @param ptr	    pointer to set.

- * @param length    length to set.

- *

- * @return the string.

- */

-PJ_INLINE(pj_str_t*) pj_strset( pj_str_t *str, char *ptr, pj_size_t length)

-{

-    str->ptr = ptr;

-    str->slen = length;

-    return str;

-}

-

-/**

- * Set the pointer and length of the string to the source string, which

- * must be NULL terminated.

- *

- * @param str	    the string.

- * @param src	    pointer to set.

- *

- * @return the string.

- */

-PJ_INLINE(pj_str_t*) pj_strset2( pj_str_t *str, char *src)

-{

-    str->ptr = src;

-    str->slen = src ? strlen(src) : 0;

-    return str;

-}

-

-/**

- * Set the pointer and the length of the string.

- *

- * @param str	    The target string.

- * @param begin	    The start of the string.

- * @param end	    The end of the string.

- *

- * @return the target string.

- */

-PJ_INLINE(pj_str_t*) pj_strset3( pj_str_t *str, char *begin, char *end )

-{

-    str->ptr = begin;

-    str->slen = end-begin;

-    return str;

-}

-

-/**

- * Assign string.

- *

- * @param dst	    The target string.

- * @param src	    The source string.

- *

- * @return the target string.

- */

-PJ_IDECL(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src );

-

-/**

- * Copy string contents.

- *

- * @param dst	    The target string.

- * @param src	    The source string.

- *

- * @return the target string.

- */

-PJ_IDECL(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src);

-

-/**

- * Copy string contents.

- *

- * @param dst	    The target string.

- * @param src	    The source string.

- *

- * @return the target string.

- */

-PJ_IDECL(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src);

-

-/**

- * Copy source string to destination up to the specified max length.

- *

- * @param dst	    The target string.

- * @param src	    The source string.

- * @param max	    Maximum characters to copy.

- *

- * @return the target string.

- */

-PJ_IDECL(pj_str_t*) pj_strncpy(pj_str_t *dst, const pj_str_t *src, 

-			       pj_ssize_t max);

-

-/**

- * Copy source string to destination up to the specified max length,

- * and NULL terminate the destination. If source string length is

- * greater than or equal to max, then max-1 will be copied.

- *

- * @param dst	    The target string.

- * @param src	    The source string.

- * @param max	    Maximum characters to copy.

- *

- * @return the target string.

- */

-PJ_IDECL(pj_str_t*) pj_strncpy_with_null(pj_str_t *dst, const pj_str_t *src,

-					 pj_ssize_t max);

-

-/**

- * Duplicate string.

- *

- * @param pool	    The pool.

- * @param dst	    The string result.

- * @param src	    The string to duplicate.

- *

- * @return the string result.

- */

-PJ_IDECL(pj_str_t*) pj_strdup(pj_pool_t *pool,

-			      pj_str_t *dst,

-			      const pj_str_t *src);

-

-/**

- * Duplicate string and NULL terminate the destination string.

- *

- * @param pool

- * @param dst

- * @param src

- */

-PJ_IDECL(pj_str_t*) pj_strdup_with_null(pj_pool_t *pool,

-					pj_str_t *dst,

-					const pj_str_t *src);

-

-/**

- * Duplicate string.

- *

- * @param pool	    The pool.

- * @param dst	    The string result.

- * @param src	    The string to duplicate.

- *

- * @return the string result.

- */

-PJ_IDECL(pj_str_t*) pj_strdup2(pj_pool_t *pool,

-			       pj_str_t *dst,

-			       const char *src);

-

-/**

- * Duplicate string.

- *

- * @param pool	    The pool.

- * @param src	    The string to duplicate.

- *

- * @return the string result.

- */

-PJ_IDECL(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src);

-

-/**

- * Return the length of the string.

- *

- * @param str	    The string.

- *

- * @return the length of the string.

- */

-PJ_INLINE(pj_size_t) pj_strlen( const pj_str_t *str )

-{

-    return str->slen;

-}

-

-/**

- * Return the pointer to the string data.

- *

- * @param str	    The string.

- *

- * @return the pointer to the string buffer.

- */

-PJ_INLINE(const char*) pj_strbuf( const pj_str_t *str )

-{

-    return str->ptr;

-}

-

-/**

- * Compare strings. 

- *

- * @param str1	    The string to compare.

- * @param str2	    The string to compare.

- *

- * @return 

- *	- < 0 if str1 is less than str2

- *      - 0   if str1 is identical to str2

- *      - > 0 if str1 is greater than str2

- */

-PJ_IDECL(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2);

-

-/**

- * Compare strings.

- *

- * @param str1	    The string to compare.

- * @param str2	    The string to compare.

- *

- * @return 

- *	- < 0 if str1 is less than str2

- *      - 0   if str1 is identical to str2

- *      - > 0 if str1 is greater than str2

- */

-PJ_IDECL(int) pj_strcmp2( const pj_str_t *str1, const char *str2 );

-

-/**

- * Compare strings. 

- *

- * @param str1	    The string to compare.

- * @param str2	    The string to compare.

- * @param len	    The maximum number of characters to compare.

- *

- * @return 

- *	- < 0 if str1 is less than str2

- *      - 0   if str1 is identical to str2

- *      - > 0 if str1 is greater than str2

- */

-PJ_IDECL(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2, 

-			  pj_size_t len);

-

-/**

- * Compare strings. 

- *

- * @param str1	    The string to compare.

- * @param str2	    The string to compare.

- * @param len	    The maximum number of characters to compare.

- *

- * @return 

- *	- < 0 if str1 is less than str2

- *      - 0   if str1 is identical to str2

- *      - > 0 if str1 is greater than str2

- */

-PJ_IDECL(int) pj_strncmp2( const pj_str_t *str1, const char *str2, 

-			   pj_size_t len);

-

-/**

- * Perform lowercase comparison to the strings.

- *

- * @param str1	    The string to compare.

- * @param str2	    The string to compare.

- *

- * @return 

- *	- < 0 if str1 is less than str2

- *      - 0   if str1 is identical to str2

- *      - > 0 if str1 is greater than str2

- */

-PJ_IDECL(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2);

-

-/**

- * Perform lowercase comparison to the strings.

- *

- * @param str1	    The string to compare.

- * @param str2	    The string to compare.

- *

- * @return 

- *	- < 0 if str1 is less than str2

- *      - 0   if str1 is identical to str2

- *      - > 0 if str1 is greater than str2

- */

-PJ_IDECL(int) pj_stricmp2( const pj_str_t *str1, const char *str2);

-

-/**

- * Perform lowercase comparison to the strings.

- *

- * @param str1	    The string to compare.

- * @param str2	    The string to compare.

- * @param len	    The maximum number of characters to compare.

- *

- * @return 

- *	- < 0 if str1 is less than str2

- *      - 0   if str1 is identical to str2

- *      - > 0 if str1 is greater than str2

- */

-PJ_IDECL(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2, 

-			   pj_size_t len);

-

-/**

- * Perform lowercase comparison to the strings.

- *

- * @param str1	    The string to compare.

- * @param str2	    The string to compare.

- * @param len	    The maximum number of characters to compare.

- *

- * @return 

- *	- < 0 if str1 is less than str2

- *      - 0   if str1 is identical to str2

- *      - > 0 if str1 is greater than str2

- */

-PJ_IDECL(int) pj_strnicmp2( const pj_str_t *str1, const char *str2, 

-			    pj_size_t len);

-

-/**

- * Concatenate strings.

- *

- * @param dst	    The destination string.

- * @param src	    The source string.

- */

-PJ_IDECL(void) pj_strcat(pj_str_t *dst, const pj_str_t *src);

-

-/**

- * Finds a character in a string.

- *

- * @param str	    The string.

- * @param chr	    The character to find.

- *

- * @return the pointer to first character found, or NULL.

- */

-PJ_INLINE(char*) pj_strchr( const pj_str_t *str, int chr)

-{

-    return (char*) memchr(str->ptr, chr, str->slen);

-}

-

-/**

- * Remove (trim) leading whitespaces from the string.

- *

- * @param str	    The string.

- *

- * @return the string.

- */

-PJ_DECL(pj_str_t*) pj_strltrim( pj_str_t *str );

-

-/**

- * Remove (trim) the trailing whitespaces from the string.

- *

- * @param str	    The string.

- *

- * @return the string.

- */

-PJ_DECL(pj_str_t*) pj_strrtrim( pj_str_t *str );

-

-/**

- * Remove (trim) leading and trailing whitespaces from the string.

- *

- * @param str	    The string.

- *

- * @return the string.

- */

-PJ_IDECL(pj_str_t*) pj_strtrim( pj_str_t *str );

-

-/**

- * Initialize the buffer with some random string.

- *

- * @param str	    the string to store the result.

- * @param length    the length of the random string to generate.

- *

- * @return the string.

- */

-PJ_DECL(char*) pj_create_random_string(char *str, pj_size_t length);

-

-/**

- * Convert string to unsigned integer.

- *

- * @param str	the string.

- *

- * @return the unsigned integer.

- */

-PJ_DECL(unsigned long) pj_strtoul(const pj_str_t *str);

-

-/**

- * Utility to convert unsigned integer to string. Note that the

- * string will be NULL terminated.

- *

- * @param val	    the unsigned integer value.

- * @param buf	    the buffer

- *

- * @return the number of characters written

- */

-PJ_DECL(int) pj_utoa(unsigned long val, char *buf);

-

-/**

- * Convert unsigned integer to string with minimum digits. Note that the

- * string will be NULL terminated.

- *

- * @param val	    The unsigned integer value.

- * @param buf	    The buffer.

- * @param min_dig   Minimum digits to be printed, or zero to specify no

- *		    minimum digit.

- * @param pad	    The padding character to be put in front of the string

- *		    when the digits is less than minimum.

- *

- * @return the number of characters written.

- */

-PJ_DECL(int) pj_utoa_pad( unsigned long val, char *buf, int min_dig, int pad);

-

-/**

- * Fill the memory location with value.

- *

- * @param dst	    The destination buffer.

- * @param c	    Character to set.

- * @param size	    The number of characters.

- *

- * @return the value of dst.

- */

-PJ_INLINE(void*) pj_memset(void *dst, int c, pj_size_t size)

-{

-    return memset(dst, c, size);

-}

-

-/**

- * Copy buffer.

- *

- * @param dst	    The destination buffer.

- * @param src	    The source buffer.

- * @param size	    The size to copy.

- *

- * @return the destination buffer.

- */

-PJ_INLINE(void*) pj_memcpy(void *dst, const void *src, pj_size_t size)

-{

-    return memcpy(dst, src, size);

-}

-

-/**

- * Move memory.

- *

- * @param dst	    The destination buffer.

- * @param src	    The source buffer.

- * @param size	    The size to copy.

- *

- * @return the destination buffer.

- */

-PJ_INLINE(void*) pj_memmove(void *dst, const void *src, pj_size_t size)

-{

-    return memmove(dst, src, size);

-}

-

-/**

- * Compare buffers.

- *

- * @param buf1	    The first buffer.

- * @param buf2	    The second buffer.

- * @param size	    The size to compare.

- *

- * @return negative, zero, or positive value.

- */

-PJ_INLINE(int) pj_memcmp(const void *buf1, const void *buf2, pj_size_t size)

-{

-    return memcmp(buf1, buf2, size);

-}

-

-/**

- * Find character in the buffer.

- *

- * @param buf	    The buffer.

- * @param c	    The character to find.

- * @param size	    The size to check.

- *

- * @return the pointer to location where the character is found, or NULL if

- *         not found.

- */

-PJ_INLINE(void*) pj_memchr(const void *buf, int c, pj_size_t size)

-{

-    return memchr(buf, c, size);

-}

-

-

-/**

- * @}

- */

-

-#if PJ_FUNCTIONS_ARE_INLINED

-#  include <pj/string_i.h>

-#endif

-

-PJ_END_DECL

-

-#endif	/* __PJ_STRING_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_STRING_H__
+#define __PJ_STRING_H__
+
+/**
+ * @file string.h
+ * @brief PJLIB String Operations.
+ */
+
+#include <pj/types.h>
+#include <pj/compat/string.h>
+#include <pj/compat/sprintf.h>
+#include <pj/compat/vsprintf.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_PSTR String Operations
+ * @ingroup PJ_DS
+ * @{
+ * This module provides string manipulation API.
+ *
+ * \section pj_pstr_not_null_sec PJLIB String is NOT Null Terminated!
+ *
+ * That is the first information that developers need to know. Instead
+ * of using normal C string, strings in PJLIB are represented as
+ * pj_str_t structure below:
+ *
+ * <pre>
+ *   typedef struct pj_str_t
+ *   {
+ *       char      *ptr;
+ *       pj_size_t  slen;
+ *   } pj_str_t;
+ * </pre>
+ *
+ * There are some advantages of using this approach:
+ *  - the string can point to arbitrary location in memory even
+ *    if the string in that location is not null terminated. This is
+ *    most usefull for text parsing, where the parsed text can just
+ *    point to the original text in the input. If we use C string,
+ *    then we will have to copy the text portion from the input
+ *    to a string variable.
+ *  - because the length of the string is known, string copy operation
+ *    can be made more efficient.
+ *
+ * Most of APIs in PJLIB that expect or return string will represent
+ * the string as pj_str_t instead of normal C string.
+ *
+ * \section pj_pstr_examples_sec Examples
+ *
+ * For some examples, please see:
+ *  - @ref page_pjlib_string_test
+ */
+
+/**
+ * Create string initializer from a normal C string.
+ *
+ * @param str	Null terminated string to be stored.
+ *
+ * @return	pj_str_t.
+ */
+PJ_IDECL(pj_str_t) pj_str(char *str);
+
+/**
+ * Create constant string from normal C string.
+ *
+ * @param str	The string to be initialized.
+ * @param s	Null terminated string.
+ *
+ * @return	pj_str_t.
+ */
+PJ_INLINE(const pj_str_t*) pj_cstr(pj_str_t *str, const char *s)
+{
+    str->ptr = (char*)s;
+    str->slen = s ? strlen(s) : 0;
+    return str;
+}
+
+/**
+ * Set the pointer and length to the specified value.
+ *
+ * @param str	    the string.
+ * @param ptr	    pointer to set.
+ * @param length    length to set.
+ *
+ * @return the string.
+ */
+PJ_INLINE(pj_str_t*) pj_strset( pj_str_t *str, char *ptr, pj_size_t length)
+{
+    str->ptr = ptr;
+    str->slen = length;
+    return str;
+}
+
+/**
+ * Set the pointer and length of the string to the source string, which
+ * must be NULL terminated.
+ *
+ * @param str	    the string.
+ * @param src	    pointer to set.
+ *
+ * @return the string.
+ */
+PJ_INLINE(pj_str_t*) pj_strset2( pj_str_t *str, char *src)
+{
+    str->ptr = src;
+    str->slen = src ? strlen(src) : 0;
+    return str;
+}
+
+/**
+ * Set the pointer and the length of the string.
+ *
+ * @param str	    The target string.
+ * @param begin	    The start of the string.
+ * @param end	    The end of the string.
+ *
+ * @return the target string.
+ */
+PJ_INLINE(pj_str_t*) pj_strset3( pj_str_t *str, char *begin, char *end )
+{
+    str->ptr = begin;
+    str->slen = end-begin;
+    return str;
+}
+
+/**
+ * Assign string.
+ *
+ * @param dst	    The target string.
+ * @param src	    The source string.
+ *
+ * @return the target string.
+ */
+PJ_IDECL(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src );
+
+/**
+ * Copy string contents.
+ *
+ * @param dst	    The target string.
+ * @param src	    The source string.
+ *
+ * @return the target string.
+ */
+PJ_IDECL(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src);
+
+/**
+ * Copy string contents.
+ *
+ * @param dst	    The target string.
+ * @param src	    The source string.
+ *
+ * @return the target string.
+ */
+PJ_IDECL(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src);
+
+/**
+ * Copy source string to destination up to the specified max length.
+ *
+ * @param dst	    The target string.
+ * @param src	    The source string.
+ * @param max	    Maximum characters to copy.
+ *
+ * @return the target string.
+ */
+PJ_IDECL(pj_str_t*) pj_strncpy(pj_str_t *dst, const pj_str_t *src, 
+			       pj_ssize_t max);
+
+/**
+ * Copy source string to destination up to the specified max length,
+ * and NULL terminate the destination. If source string length is
+ * greater than or equal to max, then max-1 will be copied.
+ *
+ * @param dst	    The target string.
+ * @param src	    The source string.
+ * @param max	    Maximum characters to copy.
+ *
+ * @return the target string.
+ */
+PJ_IDECL(pj_str_t*) pj_strncpy_with_null(pj_str_t *dst, const pj_str_t *src,
+					 pj_ssize_t max);
+
+/**
+ * Duplicate string.
+ *
+ * @param pool	    The pool.
+ * @param dst	    The string result.
+ * @param src	    The string to duplicate.
+ *
+ * @return the string result.
+ */
+PJ_IDECL(pj_str_t*) pj_strdup(pj_pool_t *pool,
+			      pj_str_t *dst,
+			      const pj_str_t *src);
+
+/**
+ * Duplicate string and NULL terminate the destination string.
+ *
+ * @param pool
+ * @param dst
+ * @param src
+ */
+PJ_IDECL(pj_str_t*) pj_strdup_with_null(pj_pool_t *pool,
+					pj_str_t *dst,
+					const pj_str_t *src);
+
+/**
+ * Duplicate string.
+ *
+ * @param pool	    The pool.
+ * @param dst	    The string result.
+ * @param src	    The string to duplicate.
+ *
+ * @return the string result.
+ */
+PJ_IDECL(pj_str_t*) pj_strdup2(pj_pool_t *pool,
+			       pj_str_t *dst,
+			       const char *src);
+
+/**
+ * Duplicate string.
+ *
+ * @param pool	    The pool.
+ * @param src	    The string to duplicate.
+ *
+ * @return the string result.
+ */
+PJ_IDECL(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src);
+
+/**
+ * Return the length of the string.
+ *
+ * @param str	    The string.
+ *
+ * @return the length of the string.
+ */
+PJ_INLINE(pj_size_t) pj_strlen( const pj_str_t *str )
+{
+    return str->slen;
+}
+
+/**
+ * Return the pointer to the string data.
+ *
+ * @param str	    The string.
+ *
+ * @return the pointer to the string buffer.
+ */
+PJ_INLINE(const char*) pj_strbuf( const pj_str_t *str )
+{
+    return str->ptr;
+}
+
+/**
+ * Compare strings. 
+ *
+ * @param str1	    The string to compare.
+ * @param str2	    The string to compare.
+ *
+ * @return 
+ *	- < 0 if str1 is less than str2
+ *      - 0   if str1 is identical to str2
+ *      - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2);
+
+/**
+ * Compare strings.
+ *
+ * @param str1	    The string to compare.
+ * @param str2	    The string to compare.
+ *
+ * @return 
+ *	- < 0 if str1 is less than str2
+ *      - 0   if str1 is identical to str2
+ *      - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strcmp2( const pj_str_t *str1, const char *str2 );
+
+/**
+ * Compare strings. 
+ *
+ * @param str1	    The string to compare.
+ * @param str2	    The string to compare.
+ * @param len	    The maximum number of characters to compare.
+ *
+ * @return 
+ *	- < 0 if str1 is less than str2
+ *      - 0   if str1 is identical to str2
+ *      - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2, 
+			  pj_size_t len);
+
+/**
+ * Compare strings. 
+ *
+ * @param str1	    The string to compare.
+ * @param str2	    The string to compare.
+ * @param len	    The maximum number of characters to compare.
+ *
+ * @return 
+ *	- < 0 if str1 is less than str2
+ *      - 0   if str1 is identical to str2
+ *      - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strncmp2( const pj_str_t *str1, const char *str2, 
+			   pj_size_t len);
+
+/**
+ * Perform lowercase comparison to the strings.
+ *
+ * @param str1	    The string to compare.
+ * @param str2	    The string to compare.
+ *
+ * @return 
+ *	- < 0 if str1 is less than str2
+ *      - 0   if str1 is identical to str2
+ *      - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2);
+
+/**
+ * Perform lowercase comparison to the strings.
+ *
+ * @param str1	    The string to compare.
+ * @param str2	    The string to compare.
+ *
+ * @return 
+ *	- < 0 if str1 is less than str2
+ *      - 0   if str1 is identical to str2
+ *      - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_stricmp2( const pj_str_t *str1, const char *str2);
+
+/**
+ * Perform lowercase comparison to the strings.
+ *
+ * @param str1	    The string to compare.
+ * @param str2	    The string to compare.
+ * @param len	    The maximum number of characters to compare.
+ *
+ * @return 
+ *	- < 0 if str1 is less than str2
+ *      - 0   if str1 is identical to str2
+ *      - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2, 
+			   pj_size_t len);
+
+/**
+ * Perform lowercase comparison to the strings.
+ *
+ * @param str1	    The string to compare.
+ * @param str2	    The string to compare.
+ * @param len	    The maximum number of characters to compare.
+ *
+ * @return 
+ *	- < 0 if str1 is less than str2
+ *      - 0   if str1 is identical to str2
+ *      - > 0 if str1 is greater than str2
+ */
+PJ_IDECL(int) pj_strnicmp2( const pj_str_t *str1, const char *str2, 
+			    pj_size_t len);
+
+/**
+ * Concatenate strings.
+ *
+ * @param dst	    The destination string.
+ * @param src	    The source string.
+ */
+PJ_IDECL(void) pj_strcat(pj_str_t *dst, const pj_str_t *src);
+
+/**
+ * Finds a character in a string.
+ *
+ * @param str	    The string.
+ * @param chr	    The character to find.
+ *
+ * @return the pointer to first character found, or NULL.
+ */
+PJ_INLINE(char*) pj_strchr( const pj_str_t *str, int chr)
+{
+    return (char*) memchr(str->ptr, chr, str->slen);
+}
+
+/**
+ * Remove (trim) leading whitespaces from the string.
+ *
+ * @param str	    The string.
+ *
+ * @return the string.
+ */
+PJ_DECL(pj_str_t*) pj_strltrim( pj_str_t *str );
+
+/**
+ * Remove (trim) the trailing whitespaces from the string.
+ *
+ * @param str	    The string.
+ *
+ * @return the string.
+ */
+PJ_DECL(pj_str_t*) pj_strrtrim( pj_str_t *str );
+
+/**
+ * Remove (trim) leading and trailing whitespaces from the string.
+ *
+ * @param str	    The string.
+ *
+ * @return the string.
+ */
+PJ_IDECL(pj_str_t*) pj_strtrim( pj_str_t *str );
+
+/**
+ * Initialize the buffer with some random string.
+ *
+ * @param str	    the string to store the result.
+ * @param length    the length of the random string to generate.
+ *
+ * @return the string.
+ */
+PJ_DECL(char*) pj_create_random_string(char *str, pj_size_t length);
+
+/**
+ * Convert string to unsigned integer.
+ *
+ * @param str	the string.
+ *
+ * @return the unsigned integer.
+ */
+PJ_DECL(unsigned long) pj_strtoul(const pj_str_t *str);
+
+/**
+ * Utility to convert unsigned integer to string. Note that the
+ * string will be NULL terminated.
+ *
+ * @param val	    the unsigned integer value.
+ * @param buf	    the buffer
+ *
+ * @return the number of characters written
+ */
+PJ_DECL(int) pj_utoa(unsigned long val, char *buf);
+
+/**
+ * Convert unsigned integer to string with minimum digits. Note that the
+ * string will be NULL terminated.
+ *
+ * @param val	    The unsigned integer value.
+ * @param buf	    The buffer.
+ * @param min_dig   Minimum digits to be printed, or zero to specify no
+ *		    minimum digit.
+ * @param pad	    The padding character to be put in front of the string
+ *		    when the digits is less than minimum.
+ *
+ * @return the number of characters written.
+ */
+PJ_DECL(int) pj_utoa_pad( unsigned long val, char *buf, int min_dig, int pad);
+
+/**
+ * Fill the memory location with value.
+ *
+ * @param dst	    The destination buffer.
+ * @param c	    Character to set.
+ * @param size	    The number of characters.
+ *
+ * @return the value of dst.
+ */
+PJ_INLINE(void*) pj_memset(void *dst, int c, pj_size_t size)
+{
+    return memset(dst, c, size);
+}
+
+/**
+ * Copy buffer.
+ *
+ * @param dst	    The destination buffer.
+ * @param src	    The source buffer.
+ * @param size	    The size to copy.
+ *
+ * @return the destination buffer.
+ */
+PJ_INLINE(void*) pj_memcpy(void *dst, const void *src, pj_size_t size)
+{
+    return memcpy(dst, src, size);
+}
+
+/**
+ * Move memory.
+ *
+ * @param dst	    The destination buffer.
+ * @param src	    The source buffer.
+ * @param size	    The size to copy.
+ *
+ * @return the destination buffer.
+ */
+PJ_INLINE(void*) pj_memmove(void *dst, const void *src, pj_size_t size)
+{
+    return memmove(dst, src, size);
+}
+
+/**
+ * Compare buffers.
+ *
+ * @param buf1	    The first buffer.
+ * @param buf2	    The second buffer.
+ * @param size	    The size to compare.
+ *
+ * @return negative, zero, or positive value.
+ */
+PJ_INLINE(int) pj_memcmp(const void *buf1, const void *buf2, pj_size_t size)
+{
+    return memcmp(buf1, buf2, size);
+}
+
+/**
+ * Find character in the buffer.
+ *
+ * @param buf	    The buffer.
+ * @param c	    The character to find.
+ * @param size	    The size to check.
+ *
+ * @return the pointer to location where the character is found, or NULL if
+ *         not found.
+ */
+PJ_INLINE(void*) pj_memchr(const void *buf, int c, pj_size_t size)
+{
+    return memchr(buf, c, size);
+}
+
+
+/**
+ * @}
+ */
+
+#if PJ_FUNCTIONS_ARE_INLINED
+#  include <pj/string_i.h>
+#endif
+
+PJ_END_DECL
+
+#endif	/* __PJ_STRING_H__ */
+
diff --git a/pjlib/include/pj/string_i.h b/pjlib/include/pj/string_i.h
index 7163b13..3fdcd2c 100644
--- a/pjlib/include/pj/string_i.h
+++ b/pjlib/include/pj/string_i.h
@@ -1,207 +1,207 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-

-PJ_IDEF(pj_str_t) pj_str(char *str)

-{

-    pj_str_t dst;

-    dst.ptr = str;

-    dst.slen = str ? pj_native_strlen(str) : 0;

-    return dst;

-}

-

-PJ_IDEF(pj_str_t*) pj_strdup(pj_pool_t *pool,

-			      pj_str_t *dst,

-			      const pj_str_t *src)

-{

-    if (src->slen) {

-	dst->ptr = (char*)pj_pool_alloc(pool, src->slen);

-	pj_memcpy(dst->ptr, src->ptr, src->slen);

-    }

-    dst->slen = src->slen;

-    return dst;

-}

-

-PJ_IDEF(pj_str_t*) pj_strdup_with_null( pj_pool_t *pool,

-					pj_str_t *dst,

-					const pj_str_t *src)

-{

-    if (src->slen) {

-	dst->ptr = (char*)pj_pool_alloc(pool, src->slen+1);

-	pj_memcpy(dst->ptr, src->ptr, src->slen);

-    } else {

-	dst->ptr = (char*)pj_pool_alloc(pool, 1);

-    }

-    dst->slen = src->slen;

-    dst->ptr[dst->slen] = '\0';

-    return dst;

-}

-

-PJ_IDEF(pj_str_t*) pj_strdup2(pj_pool_t *pool,

-			      pj_str_t *dst,

-			      const char *src)

-{

-    dst->slen = src ? pj_native_strlen(src) : 0;

-    if (dst->slen) {

-	dst->ptr = (char*)pj_pool_alloc(pool, dst->slen);

-	pj_memcpy(dst->ptr, src, dst->slen);

-    } else {

-	dst->ptr = NULL;

-    }

-    return dst;

-}

-

-

-PJ_IDEF(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src)

-{

-    pj_str_t temp;

-    pj_strdup2(pool, &temp, src);

-    return temp;

-}

-

-PJ_IDEF(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src )

-{

-    dst->ptr = src->ptr;

-    dst->slen = src->slen;

-    return dst;

-}

-

-PJ_IDEF(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src)

-{

-    dst->slen = src->slen;

-    if (src->slen > 0)

-	pj_memcpy(dst->ptr, src->ptr, src->slen);

-    return dst;

-}

-

-PJ_IDEF(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src)

-{

-    dst->slen = src ? pj_native_strlen(src) : 0;

-    if (dst->slen > 0)

-	pj_memcpy(dst->ptr, src, dst->slen);

-    return dst;

-}

-

-PJ_IDEF(pj_str_t*) pj_strncpy( pj_str_t *dst, const pj_str_t *src, 

-			       pj_ssize_t max)

-{

-    if (max > src->slen) max = src->slen;

-    pj_memcpy(dst->ptr, src->ptr, max);

-    dst->slen = max;

-    return dst;

-}

-

-PJ_IDEF(pj_str_t*) pj_strncpy_with_null( pj_str_t *dst, const pj_str_t *src,

-					 pj_ssize_t max)

-{

-    if (max <= src->slen)

-	max = max-1;

-    else

-	max = src->slen;

-

-    pj_memcpy(dst->ptr, src->ptr, max);

-    dst->ptr[max] = '\0';

-    dst->slen = max;

-    return dst;

-}

-

-

-PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2)

-{

-    pj_ssize_t diff;

-

-    diff = str1->slen - str2->slen;

-    if (diff) {

-	return (int)diff;

-    } else if (str1->ptr && str1->slen) {

-	return pj_native_strncmp(str1->ptr, str2->ptr, str1->slen);

-    } else {

-	return 0;

-    }

-}

-

-PJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2, 

-			 pj_size_t len)

-{

-    return (str1->ptr && str2->ptr) ? 

-	    pj_native_strncmp(str1->ptr, str2->ptr, len) :

-	    (str1->ptr == str2->ptr ? 0 : 1);

-}

-

-PJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2, 

-			  pj_size_t len)

-{

-    return (str1->ptr && str2) ? pj_native_strncmp(str1->ptr, str2, len) :

-	   (str1->ptr==str2 ? 0 : 1);

-}

-

-PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 )

-{

-    return pj_strncmp2( str1, str2, str1->slen);

-}

-

-PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)

-{

-    pj_ssize_t diff;

-

-    diff = str1->slen - str2->slen;

-    if (diff) {

-	return (int)diff;

-    } else {

-	return pj_native_strnicmp(str1->ptr, str2->ptr, str1->slen);

-    }

-}

-

-PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2)

-{

-    return (str1->ptr && str2) ? 

-	    pj_native_strnicmp(str1->ptr, str2, str1->slen) :

-	    (str1->ptr==str2 ? 0 : 1);

-}

-

-PJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2, 

-			  pj_size_t len)

-{

-    return (str1->ptr && str2->ptr) ? 

-	    pj_native_strnicmp(str1->ptr, str2->ptr, len) :

-	    (str1->ptr == str2->ptr ? 0 : 1);

-}

-

-PJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2, 

-			   pj_size_t len)

-{

-    return (str1->ptr && str2) ? 

-	    pj_native_strnicmp(str1->ptr, str2, len) :

-	    (str1->ptr == str2 ? 0 : 1);

-}

-

-PJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src)

-{

-    if (src->slen) {

-	pj_memcpy(dst->ptr + dst->slen, src->ptr, src->slen);

-	dst->slen += src->slen;

-    }

-}

-

-PJ_IDEF(pj_str_t*) pj_strtrim( pj_str_t *str )

-{

-    pj_strltrim(str);

-    pj_strrtrim(str);

-    return str;

-}

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+
+PJ_IDEF(pj_str_t) pj_str(char *str)
+{
+    pj_str_t dst;
+    dst.ptr = str;
+    dst.slen = str ? pj_native_strlen(str) : 0;
+    return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strdup(pj_pool_t *pool,
+			      pj_str_t *dst,
+			      const pj_str_t *src)
+{
+    if (src->slen) {
+	dst->ptr = (char*)pj_pool_alloc(pool, src->slen);
+	pj_memcpy(dst->ptr, src->ptr, src->slen);
+    }
+    dst->slen = src->slen;
+    return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strdup_with_null( pj_pool_t *pool,
+					pj_str_t *dst,
+					const pj_str_t *src)
+{
+    if (src->slen) {
+	dst->ptr = (char*)pj_pool_alloc(pool, src->slen+1);
+	pj_memcpy(dst->ptr, src->ptr, src->slen);
+    } else {
+	dst->ptr = (char*)pj_pool_alloc(pool, 1);
+    }
+    dst->slen = src->slen;
+    dst->ptr[dst->slen] = '\0';
+    return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strdup2(pj_pool_t *pool,
+			      pj_str_t *dst,
+			      const char *src)
+{
+    dst->slen = src ? pj_native_strlen(src) : 0;
+    if (dst->slen) {
+	dst->ptr = (char*)pj_pool_alloc(pool, dst->slen);
+	pj_memcpy(dst->ptr, src, dst->slen);
+    } else {
+	dst->ptr = NULL;
+    }
+    return dst;
+}
+
+
+PJ_IDEF(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src)
+{
+    pj_str_t temp;
+    pj_strdup2(pool, &temp, src);
+    return temp;
+}
+
+PJ_IDEF(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src )
+{
+    dst->ptr = src->ptr;
+    dst->slen = src->slen;
+    return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src)
+{
+    dst->slen = src->slen;
+    if (src->slen > 0)
+	pj_memcpy(dst->ptr, src->ptr, src->slen);
+    return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src)
+{
+    dst->slen = src ? pj_native_strlen(src) : 0;
+    if (dst->slen > 0)
+	pj_memcpy(dst->ptr, src, dst->slen);
+    return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strncpy( pj_str_t *dst, const pj_str_t *src, 
+			       pj_ssize_t max)
+{
+    if (max > src->slen) max = src->slen;
+    pj_memcpy(dst->ptr, src->ptr, max);
+    dst->slen = max;
+    return dst;
+}
+
+PJ_IDEF(pj_str_t*) pj_strncpy_with_null( pj_str_t *dst, const pj_str_t *src,
+					 pj_ssize_t max)
+{
+    if (max <= src->slen)
+	max = max-1;
+    else
+	max = src->slen;
+
+    pj_memcpy(dst->ptr, src->ptr, max);
+    dst->ptr[max] = '\0';
+    dst->slen = max;
+    return dst;
+}
+
+
+PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2)
+{
+    pj_ssize_t diff;
+
+    diff = str1->slen - str2->slen;
+    if (diff) {
+	return (int)diff;
+    } else if (str1->ptr && str1->slen) {
+	return pj_native_strncmp(str1->ptr, str2->ptr, str1->slen);
+    } else {
+	return 0;
+    }
+}
+
+PJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2, 
+			 pj_size_t len)
+{
+    return (str1->ptr && str2->ptr) ? 
+	    pj_native_strncmp(str1->ptr, str2->ptr, len) :
+	    (str1->ptr == str2->ptr ? 0 : 1);
+}
+
+PJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2, 
+			  pj_size_t len)
+{
+    return (str1->ptr && str2) ? pj_native_strncmp(str1->ptr, str2, len) :
+	   (str1->ptr==str2 ? 0 : 1);
+}
+
+PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 )
+{
+    return pj_strncmp2( str1, str2, str1->slen);
+}
+
+PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)
+{
+    pj_ssize_t diff;
+
+    diff = str1->slen - str2->slen;
+    if (diff) {
+	return (int)diff;
+    } else {
+	return pj_native_strnicmp(str1->ptr, str2->ptr, str1->slen);
+    }
+}
+
+PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2)
+{
+    return (str1->ptr && str2) ? 
+	    pj_native_strnicmp(str1->ptr, str2, str1->slen) :
+	    (str1->ptr==str2 ? 0 : 1);
+}
+
+PJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2, 
+			  pj_size_t len)
+{
+    return (str1->ptr && str2->ptr) ? 
+	    pj_native_strnicmp(str1->ptr, str2->ptr, len) :
+	    (str1->ptr == str2->ptr ? 0 : 1);
+}
+
+PJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2, 
+			   pj_size_t len)
+{
+    return (str1->ptr && str2) ? 
+	    pj_native_strnicmp(str1->ptr, str2, len) :
+	    (str1->ptr == str2 ? 0 : 1);
+}
+
+PJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src)
+{
+    if (src->slen) {
+	pj_memcpy(dst->ptr + dst->slen, src->ptr, src->slen);
+	dst->slen += src->slen;
+    }
+}
+
+PJ_IDEF(pj_str_t*) pj_strtrim( pj_str_t *str )
+{
+    pj_strltrim(str);
+    pj_strrtrim(str);
+    return str;
+}
+
diff --git a/pjlib/include/pj/timer.h b/pjlib/include/pj/timer.h
index eac6ba5..bcc4bb9 100644
--- a/pjlib/include/pj/timer.h
+++ b/pjlib/include/pj/timer.h
@@ -1,265 +1,265 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-

-#ifndef __PJ_TIMER_H__

-#define __PJ_TIMER_H__

-

-/**

- * @file timer.h

- * @brief Timer Heap

- */

-

-#include <pj/types.h>

-

-PJ_BEGIN_DECL

-

-/**

- * @defgroup PJ_TIMER Timer Heap Management.

- * @ingroup PJ_MISC

- * @brief

- * The timer scheduling implementation here is based on ACE library's 

- * ACE_Timer_Heap, with only little modification to suit our library's style

- * (I even left most of the comments in the original source).

- *

- * To quote the original quote in ACE_Timer_Heap_T class:

- *

- *      This implementation uses a heap-based callout queue of

- *      absolute times.  Therefore, in the average and worst case,

- *      scheduling, canceling, and expiring timers is O(log N) (where

- *      N is the total number of timers).  In addition, we can also

- *      preallocate as many \a ACE_Timer_Nodes as there are slots in

- *      the heap.  This allows us to completely remove the need for

- *      dynamic memory allocation, which is important for real-time

- *      systems.

- * @{

- *

- * \section pj_timer_examples_sec Examples

- *

- * For some examples on how to use the timer heap, please see the link below.

- *

- *  - \ref page_pjlib_timer_test

- */

-

-

-/**

- * The type for internal timer ID.

- */

-typedef int pj_timer_id_t;

-

-/** 

- * Forward declaration for pj_timer_entry. 

- */

-struct pj_timer_entry;

-

-/**

- * The type of callback function to be called by timer scheduler when a timer

- * has expired.

- *

- * @param timer_heap    The timer heap.

- * @param entry         Timer entry which timer's has expired.

- */

-typedef void pj_timer_heap_callback(pj_timer_heap_t *timer_heap,

-				    struct pj_timer_entry *entry);

-

-

-/**

- * This structure represents an entry to the timer.

- */

-struct pj_timer_entry

-{

-    /** 

-     * User data to be associated with this entry. 

-     * Applications normally will put the instance of object that

-     * owns the timer entry in this field.

-     */

-    void *user_data;

-

-    /** 

-     * Arbitrary ID assigned by the user/owner of this entry. 

-     * Applications can use this ID to distinguish multiple

-     * timer entries that share the same callback and user_data.

-     */

-    int id;

-

-    /** 

-     * Callback to be called when the timer expires. 

-     */

-    pj_timer_heap_callback *cb;

-

-    /** 

-     * Internal unique timer ID, which is assigned by the timer heap. 

-     * Application should not touch this ID.

-     */

-    pj_timer_id_t _timer_id;

-

-    /** 

-     * The future time when the timer expires, which the value is updated

-     * by timer heap when the timer is scheduled.

-     */

-    pj_time_val _timer_value;

-};

-

-

-/**

- * Calculate memory size required to create a timer heap.

- *

- * @param count     Number of timer entries to be supported.

- * @return          Memory size requirement in bytes.

- */

-PJ_DECL(pj_size_t) pj_timer_heap_mem_size(pj_size_t count);

-

-/**

- * Create a timer heap.

- *

- * @param pool      The pool where allocations in the timer heap will be 

- *                  allocated. The timer heap will dynamicly allocate 

- *                  more storate from the pool if the number of timer 

- *                  entries registered is more than the size originally 

- *                  requested when calling this function.

- * @param count     The maximum number of timer entries to be supported 

- *                  initially. If the application registers more entries 

- *                  during runtime, then the timer heap will resize.

- * @param ht        Pointer to receive the created timer heap.

- *

- * @return          PJ_SUCCESS, or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_timer_heap_create( pj_pool_t *pool,

-					   pj_size_t count,

-                                           pj_timer_heap_t **ht);

-

-/**

- * Destroy the timer heap.

- *

- * @param ht        The timer heap.

- */

-PJ_DECL(void) pj_timer_heap_destroy( pj_timer_heap_t *ht );

-

-

-/**

- * Set lock object to be used by the timer heap. By default, the timer heap

- * uses dummy synchronization.

- *

- * @param ht        The timer heap.

- * @param lock      The lock object to be used for synchronization.

- * @param auto_del  If nonzero, the lock object will be destroyed when

- *                  the timer heap is destroyed.

- */

-PJ_DECL(void) pj_timer_heap_set_lock( pj_timer_heap_t *ht,

-                                      pj_lock_t *lock,

-                                      pj_bool_t auto_del );

-

-/**

- * Set maximum number of timed out entries to process in a single poll.

- *

- * @param ht        The timer heap.

- * @param count     Number of entries.

- *

- * @return          The old number.

- */

-PJ_DECL(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht,

-                                                           unsigned count );

-

-/**

- * Initialize a timer entry. Application should call this function at least

- * once before scheduling the entry to the timer heap, to properly initialize

- * the timer entry.

- *

- * @param entry     The timer entry to be initialized.

- * @param id        Arbitrary ID assigned by the user/owner of this entry.

- *                  Applications can use this ID to distinguish multiple

- *                  timer entries that share the same callback and user_data.

- * @param user_data User data to be associated with this entry. 

- *                  Applications normally will put the instance of object that

- *                  owns the timer entry in this field.

- * @param cb        Callback function to be called when the timer elapses.

- *

- * @return          The timer entry itself.

- */

-PJ_DECL(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,

-                                              int id,

-                                              void *user_data,

-                                              pj_timer_heap_callback *cb );

-

-/**

- * Schedule a timer entry which will expire AFTER the specified delay.

- *

- * @param ht        The timer heap.

- * @param entry     The entry to be registered. 

- * @param delay     The interval to expire.

- * @return          PJ_SUCCESS, or the appropriate error code.

- */

-PJ_DECL(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht,

-					     pj_timer_entry *entry, 

-					     const pj_time_val *delay);

-

-/**

- * Cancel a previously registered timer.

- *

- * @param ht        The timer heap.

- * @param entry     The entry to be cancelled.

- * @return          The number of timer cancelled, which should be one if the

- *                  entry has really been registered, or zero if no timer was

- *                  cancelled.

- */

-PJ_DECL(int) pj_timer_heap_cancel( pj_timer_heap_t *ht,

-				   pj_timer_entry *entry);

-

-/**

- * Get the number of timer entries.

- *

- * @param ht        The timer heap.

- * @return          The number of timer entries.

- */

-PJ_DECL(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht );

-

-/**

- * Get the earliest time registered in the timer heap. The timer heap

- * MUST have at least one timer being scheduled (application should use

- * #pj_timer_heap_count() before calling this function).

- *

- * @param ht        The timer heap.

- * @param timeval   The time deadline of the earliest timer entry.

- *

- * @return          PJ_SUCCESS, or PJ_ENOTFOUND if no entry is scheduled.

- */

-PJ_DECL(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t *ht, 

-					          pj_time_val *timeval);

-

-/**

- * Poll the timer heap, check for expired timers and call the callback for

- * each of the expired timers.

- *

- * @param ht         The timer heap.

- * @param next_delay If this parameter is not NULL, it will be filled up with

- *		     the time delay until the next timer elapsed, or -1 in

- *		     the sec part if no entry exist.

- *

- * @return           The number of timers expired.

- */

-PJ_DECL(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, 

-                                      pj_time_val *next_delay);

-

-/**

- * @}

- */

-

-PJ_END_DECL

-

-#endif	/* __PJ_TIMER_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+
+#ifndef __PJ_TIMER_H__
+#define __PJ_TIMER_H__
+
+/**
+ * @file timer.h
+ * @brief Timer Heap
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_TIMER Timer Heap Management.
+ * @ingroup PJ_MISC
+ * @brief
+ * The timer scheduling implementation here is based on ACE library's 
+ * ACE_Timer_Heap, with only little modification to suit our library's style
+ * (I even left most of the comments in the original source).
+ *
+ * To quote the original quote in ACE_Timer_Heap_T class:
+ *
+ *      This implementation uses a heap-based callout queue of
+ *      absolute times.  Therefore, in the average and worst case,
+ *      scheduling, canceling, and expiring timers is O(log N) (where
+ *      N is the total number of timers).  In addition, we can also
+ *      preallocate as many \a ACE_Timer_Nodes as there are slots in
+ *      the heap.  This allows us to completely remove the need for
+ *      dynamic memory allocation, which is important for real-time
+ *      systems.
+ * @{
+ *
+ * \section pj_timer_examples_sec Examples
+ *
+ * For some examples on how to use the timer heap, please see the link below.
+ *
+ *  - \ref page_pjlib_timer_test
+ */
+
+
+/**
+ * The type for internal timer ID.
+ */
+typedef int pj_timer_id_t;
+
+/** 
+ * Forward declaration for pj_timer_entry. 
+ */
+struct pj_timer_entry;
+
+/**
+ * The type of callback function to be called by timer scheduler when a timer
+ * has expired.
+ *
+ * @param timer_heap    The timer heap.
+ * @param entry         Timer entry which timer's has expired.
+ */
+typedef void pj_timer_heap_callback(pj_timer_heap_t *timer_heap,
+				    struct pj_timer_entry *entry);
+
+
+/**
+ * This structure represents an entry to the timer.
+ */
+struct pj_timer_entry
+{
+    /** 
+     * User data to be associated with this entry. 
+     * Applications normally will put the instance of object that
+     * owns the timer entry in this field.
+     */
+    void *user_data;
+
+    /** 
+     * Arbitrary ID assigned by the user/owner of this entry. 
+     * Applications can use this ID to distinguish multiple
+     * timer entries that share the same callback and user_data.
+     */
+    int id;
+
+    /** 
+     * Callback to be called when the timer expires. 
+     */
+    pj_timer_heap_callback *cb;
+
+    /** 
+     * Internal unique timer ID, which is assigned by the timer heap. 
+     * Application should not touch this ID.
+     */
+    pj_timer_id_t _timer_id;
+
+    /** 
+     * The future time when the timer expires, which the value is updated
+     * by timer heap when the timer is scheduled.
+     */
+    pj_time_val _timer_value;
+};
+
+
+/**
+ * Calculate memory size required to create a timer heap.
+ *
+ * @param count     Number of timer entries to be supported.
+ * @return          Memory size requirement in bytes.
+ */
+PJ_DECL(pj_size_t) pj_timer_heap_mem_size(pj_size_t count);
+
+/**
+ * Create a timer heap.
+ *
+ * @param pool      The pool where allocations in the timer heap will be 
+ *                  allocated. The timer heap will dynamicly allocate 
+ *                  more storate from the pool if the number of timer 
+ *                  entries registered is more than the size originally 
+ *                  requested when calling this function.
+ * @param count     The maximum number of timer entries to be supported 
+ *                  initially. If the application registers more entries 
+ *                  during runtime, then the timer heap will resize.
+ * @param ht        Pointer to receive the created timer heap.
+ *
+ * @return          PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_timer_heap_create( pj_pool_t *pool,
+					   pj_size_t count,
+                                           pj_timer_heap_t **ht);
+
+/**
+ * Destroy the timer heap.
+ *
+ * @param ht        The timer heap.
+ */
+PJ_DECL(void) pj_timer_heap_destroy( pj_timer_heap_t *ht );
+
+
+/**
+ * Set lock object to be used by the timer heap. By default, the timer heap
+ * uses dummy synchronization.
+ *
+ * @param ht        The timer heap.
+ * @param lock      The lock object to be used for synchronization.
+ * @param auto_del  If nonzero, the lock object will be destroyed when
+ *                  the timer heap is destroyed.
+ */
+PJ_DECL(void) pj_timer_heap_set_lock( pj_timer_heap_t *ht,
+                                      pj_lock_t *lock,
+                                      pj_bool_t auto_del );
+
+/**
+ * Set maximum number of timed out entries to process in a single poll.
+ *
+ * @param ht        The timer heap.
+ * @param count     Number of entries.
+ *
+ * @return          The old number.
+ */
+PJ_DECL(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht,
+                                                           unsigned count );
+
+/**
+ * Initialize a timer entry. Application should call this function at least
+ * once before scheduling the entry to the timer heap, to properly initialize
+ * the timer entry.
+ *
+ * @param entry     The timer entry to be initialized.
+ * @param id        Arbitrary ID assigned by the user/owner of this entry.
+ *                  Applications can use this ID to distinguish multiple
+ *                  timer entries that share the same callback and user_data.
+ * @param user_data User data to be associated with this entry. 
+ *                  Applications normally will put the instance of object that
+ *                  owns the timer entry in this field.
+ * @param cb        Callback function to be called when the timer elapses.
+ *
+ * @return          The timer entry itself.
+ */
+PJ_DECL(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,
+                                              int id,
+                                              void *user_data,
+                                              pj_timer_heap_callback *cb );
+
+/**
+ * Schedule a timer entry which will expire AFTER the specified delay.
+ *
+ * @param ht        The timer heap.
+ * @param entry     The entry to be registered. 
+ * @param delay     The interval to expire.
+ * @return          PJ_SUCCESS, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht,
+					     pj_timer_entry *entry, 
+					     const pj_time_val *delay);
+
+/**
+ * Cancel a previously registered timer.
+ *
+ * @param ht        The timer heap.
+ * @param entry     The entry to be cancelled.
+ * @return          The number of timer cancelled, which should be one if the
+ *                  entry has really been registered, or zero if no timer was
+ *                  cancelled.
+ */
+PJ_DECL(int) pj_timer_heap_cancel( pj_timer_heap_t *ht,
+				   pj_timer_entry *entry);
+
+/**
+ * Get the number of timer entries.
+ *
+ * @param ht        The timer heap.
+ * @return          The number of timer entries.
+ */
+PJ_DECL(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht );
+
+/**
+ * Get the earliest time registered in the timer heap. The timer heap
+ * MUST have at least one timer being scheduled (application should use
+ * #pj_timer_heap_count() before calling this function).
+ *
+ * @param ht        The timer heap.
+ * @param timeval   The time deadline of the earliest timer entry.
+ *
+ * @return          PJ_SUCCESS, or PJ_ENOTFOUND if no entry is scheduled.
+ */
+PJ_DECL(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t *ht, 
+					          pj_time_val *timeval);
+
+/**
+ * Poll the timer heap, check for expired timers and call the callback for
+ * each of the expired timers.
+ *
+ * @param ht         The timer heap.
+ * @param next_delay If this parameter is not NULL, it will be filled up with
+ *		     the time delay until the next timer elapsed, or -1 in
+ *		     the sec part if no entry exist.
+ *
+ * @return           The number of timers expired.
+ */
+PJ_DECL(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, 
+                                      pj_time_val *next_delay);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif	/* __PJ_TIMER_H__ */
+
diff --git a/pjlib/include/pj/types.h b/pjlib/include/pj/types.h
index e1e0df4..62e2c0f 100644
--- a/pjlib/include/pj/types.h
+++ b/pjlib/include/pj/types.h
@@ -1,442 +1,442 @@
-/* $Id$ */

-/* 

- * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>

- *

- * This program is free software; you can redistribute it and/or modify

- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2 of the License, or

- * (at your option) any later version.

- *

- * This program is distributed in the hope that it will be useful,

- * but WITHOUT ANY WARRANTY; without even the implied warranty of

- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

- * GNU General Public License for more details.

- *

- * You should have received a copy of the GNU General Public License

- * along with this program; if not, write to the Free Software

- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

- */

-#ifndef __PJ_TYPES_H__

-#define __PJ_TYPES_H__

-

-

-/**

- * @defgroup PJ PJ Library

- */

-/**

- * @file types.h

- * @brief Declaration of basic types and utility.

- */

-/**

- * @defgroup PJ_BASIC Basic Data Types and Library Functionality.

- * @ingroup PJ_DS

- * @{

- */

-#include <pj/config.h>

-

-PJ_BEGIN_DECL

-

-///////////////////////////////////////////////////////////////////////////////

-

-/** Unsigned 32bit integer. */

-typedef int		pj_int32_t;

-

-/** Signed 32bit integer. */

-typedef unsigned int	pj_uint32_t;

-

-/** Unsigned 16bit integer. */

-typedef short		pj_int16_t;

-

-/** Signed 16bit integer. */

-typedef unsigned short	pj_uint16_t;

-

-/** Unsigned 8bit integer. */

-typedef signed char	pj_int8_t;

-

-/** Signed 16bit integer. */

-typedef unsigned char	pj_uint8_t;

-

-/** Large unsigned integer. */

-typedef size_t		pj_size_t;

-

-/** Large signed integer. */

-typedef long		pj_ssize_t;

-

-/** Status code. */

-typedef int		pj_status_t;

-

-/** Boolean. */

-typedef int		pj_bool_t;

-

-/** Status is OK. */

-#define PJ_SUCCESS  0

-

-/** True value. */

-#define PJ_TRUE	    1

-

-/** False value. */

-#define PJ_FALSE    0

-

-/**

- * File offset type.

- */

-#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0

-typedef pj_int64_t pj_off_t;

-#else

-typedef pj_ssize_t pj_off_t;

-#endif

-

-///////////////////////////////////////////////////////////////////////////////

-/*

- * Data structure types.

- */

-/**

- * This type is used as replacement to legacy C string, and used throughout

- * the library. By convention, the string is NOT null terminated.

- */

-struct pj_str_t

-{

-    /** Buffer pointer, which is by convention NOT null terminated. */

-    char       *ptr;

-

-    /** The length of the string. */

-    pj_ssize_t  slen;

-};

-

-

-/**

- * The opaque data type for linked list, which is used as arguments throughout

- * the linked list operations.

- */

-typedef void pj_list_type;

-

-/** 

- * List.

- */

-typedef struct pj_list pj_list;

-

-/**

- * Opaque data type for hash tables.

- */

-typedef struct pj_hash_table_t pj_hash_table_t;

-

-/**

- * Opaque data type for hash entry (only used internally by hash table).

- */

-typedef struct pj_hash_entry pj_hash_entry;

-

-/**

- * Data type for hash search iterator.

- * This structure should be opaque, however applications need to declare

- * concrete variable of this type, that's why the declaration is visible here.

- */

-typedef struct pj_hash_iterator_t

-{

-    pj_uint32_t	     index;     /**< Internal index.     */

-    pj_hash_entry   *entry;     /**< Internal entry.     */

-} pj_hash_iterator_t;

-

-

-/**

- * Forward declaration for memory pool factory.

- */

-typedef struct pj_pool_factory pj_pool_factory;

-

-/**

- * Opaque data type for memory pool.

- */

-typedef struct pj_pool_t pj_pool_t;

-

-/**

- * Forward declaration for caching pool, a pool factory implementation.

- */

-typedef struct pj_caching_pool pj_caching_pool;

-

-/**

- * This type is used as replacement to legacy C string, and used throughout

- * the library.

- */

-typedef struct pj_str_t pj_str_t;

-

-/**

- * Opaque data type for I/O Queue structure.

- */

-typedef struct pj_ioqueue_t pj_ioqueue_t;

-

-/**

- * Opaque data type for key that identifies a handle registered to the

- * I/O queue framework.

- */

-typedef struct pj_ioqueue_key_t pj_ioqueue_key_t;

-

-/**

- * Opaque data to identify timer heap.

- */

-typedef struct pj_timer_heap_t pj_timer_heap_t;

-

-/**

- * Forward declaration for timer entry.

- */

-typedef struct pj_timer_entry pj_timer_entry;

-

-/** 

- * Opaque data type for atomic operations.

- */

-typedef struct pj_atomic_t pj_atomic_t;

-

-/**

- * Value type of an atomic variable.

- */

-typedef PJ_ATOMIC_VALUE_TYPE pj_atomic_value_t;

- 

-///////////////////////////////////////////////////////////////////////////////

-

-/** Thread handle. */

-typedef struct pj_thread_t pj_thread_t;

-

-/** Lock object. */

-typedef struct pj_lock_t pj_lock_t;

-

-/** Mutex handle. */

-typedef struct pj_mutex_t pj_mutex_t;

-

-/** Semaphore handle. */

-typedef struct pj_sem_t pj_sem_t;

-

-/** Event object. */

-typedef struct pj_event_t pj_event_t;

-

-/** Unidirectional stream pipe object. */

-typedef struct pj_pipe_t pj_pipe_t;

-

-/** Operating system handle. */

-typedef void *pj_oshandle_t;

-

-/** Socket handle. */

-typedef long pj_sock_t;

-

-/** Generic socket address. */

-typedef void pj_sockaddr_t;

-

-/** Color type. */

-typedef unsigned int pj_color_t;

-

-/** Exception id. */

-typedef int pj_exception_id_t;

-

-///////////////////////////////////////////////////////////////////////////////

-

-/** Utility macro to compute the number of elements in static array. */

-#define PJ_ARRAY_SIZE(a)    (sizeof(a)/sizeof(a[0]))

-

-/** Maximum value for signed 32-bit integer. */

-#define PJ_MAXINT32  0x7FFFFFFFL

-

-/**

- * Length of object names.

- */

-#define PJ_MAX_OBJ_NAME	16

-

-///////////////////////////////////////////////////////////////////////////////

-/*

- * General.

- */

-/**

- * Initialize the PJ Library.

- * This function must be called before using the library. The purpose of this

- * function is to initialize static library data, such as character table used

- * in random string generation, and to initialize operating system dependent

- * functionality (such as WSAStartup() in Windows).

- */

-PJ_DECL(pj_status_t) pj_init(void);

-

-

-/**

- * @}

- */

-/**

- * @addtogroup PJ_TIME Time Data Type and Manipulation.

- * @ingroup PJ_MISC

- * @{

- */

-

-/**

- * Representation of time value in this library.

- * This type can be used to represent either an interval or a specific time

- * or date. 

- */

-typedef struct pj_time_val

-{

-    /** The seconds part of the time. */

-    long    sec;

-

-    /** The miliseconds fraction of the time. */

-    long    msec;

-

-} pj_time_val;

-

-/**

- * Normalize the value in time value.

- * @param t     Time value to be normalized.

- */

-PJ_DECL(void) pj_time_val_normalize(pj_time_val *t);

-

-/**

- * Get the total time value in miliseconds. This is the same as

- * multiplying the second part with 1000 and then add the miliseconds

- * part to the result.

- *

- * @param t     The time value.

- * @return      Total time in miliseconds.

- * @hideinitializer

- */

-#define PJ_TIME_VAL_MSEC(t)	((t).sec * 1000 + (t).msec)

-

-/**

- * This macro will check if \a t1 is equal to \a t2.

- *

- * @param t1    The first time value to compare.

- * @param t2    The second time value to compare.

- * @return      Non-zero if both time values are equal.

- * @hideinitializer

- */

-#define PJ_TIME_VAL_EQ(t1, t2)	((t1).sec==(t2).sec && (t1).msec==(t2).msec)

-

-/**

- * This macro will check if \a t1 is greater than \a t2

- *

- * @param t1    The first time value to compare.

- * @param t2    The second time value to compare.

- * @return      Non-zero if t1 is greater than t2.

- * @hideinitializer

- */

-#define PJ_TIME_VAL_GT(t1, t2)	((t1).sec>(t2).sec || \

-                                ((t1).sec==(t2).sec && (t1).msec>(t2).msec))

-

-/**

- * This macro will check if \a t1 is greater than or equal to \a t2

- *

- * @param t1    The first time value to compare.

- * @param t2    The second time value to compare.

- * @return      Non-zero if t1 is greater than or equal to t2.

- * @hideinitializer

- */

-#define PJ_TIME_VAL_GTE(t1, t2)	(PJ_TIME_VAL_GT(t1,t2) || \

-                                 PJ_TIME_VAL_EQ(t1,t2))

-

-/**

- * This macro will check if \a t1 is less than \a t2

- *

- * @param t1    The first time value to compare.

- * @param t2    The second time value to compare.

- * @return      Non-zero if t1 is less than t2.

- * @hideinitializer

- */

-#define PJ_TIME_VAL_LT(t1, t2)	(!(PJ_TIME_VAL_GTE(t1,t2)))

-

-/**

- * This macro will check if \a t1 is less than or equal to \a t2.

- *

- * @param t1    The first time value to compare.

- * @param t2    The second time value to compare.

- * @return      Non-zero if t1 is less than or equal to t2.

- * @hideinitializer

- */

-#define PJ_TIME_VAL_LTE(t1, t2)	(!PJ_TIME_VAL_GT(t1, t2))

-

-/**

- * Add \a t2 to \a t1 and store the result in \a t1. Effectively

- *

- * this macro will expand as: (\a t1 += \a t2).

- * @param t1    The time value to add.

- * @param t2    The time value to be added to \a t1.

- * @hideinitializer

- */

-#define PJ_TIME_VAL_ADD(t1, t2)	    do {			    \

-					(t1).sec += (t2).sec;	    \

-					(t1).msec += (t2).msec;	    \

-					pj_time_val_normalize(&(t1)); \

-				    } while (0)

-

-

-/**

- * Substract \a t2 from \a t1 and store the result in \a t1. Effectively

- * this macro will expand as (\a t1 -= \a t2).

- *

- * @param t1    The time value to subsctract.

- * @param t2    The time value to be substracted from \a t1.

- * @hideinitializer

- */

-#define PJ_TIME_VAL_SUB(t1, t2)	    do {			    \

-					(t1).sec -= (t2).sec;	    \

-					(t1).msec -= (t2).msec;	    \

-					pj_time_val_normalize(&(t1)); \

-				    } while (0)

-

-

-/**

- * This structure represent the parsed representation of time.

- * It is acquired by calling #pj_time_decode().

- */

-typedef struct pj_parsed_time

-{

-    /** This represents day of week where value zero means Sunday */

-    int wday;

-

-    /** This represents day of the year, 0-365, where zero means

-     *  1st of January.

-     */

-    int yday;

-

-    /** This represents day of month: 1-31 */

-    int day;

-

-    /** This represents month, with the value is 0 - 11 (zero is January) */

-    int mon;

-

-    /** This represent the actual year (unlike in ANSI libc where

-     *  the value must be added by 1900).

-     */

-    int year;

-

-    /** This represents the second part, with the value is 0-59 */

-    int sec;

-

-    /** This represents the minute part, with the value is: 0-59 */

-    int min;

-

-    /** This represents the hour part, with the value is 0-23 */

-    int hour;

-

-    /** This represents the milisecond part, with the value is 0-999 */

-    int msec;

-

-} pj_parsed_time;

-

-

-/**

- * @}	// Time Management

- */

-

-///////////////////////////////////////////////////////////////////////////////

-/*

- * Terminal.

- */

-/**

- * Color code combination.

- */

-enum {

-    PJ_TERM_COLOR_R	= 2,    /**< Red            */

-    PJ_TERM_COLOR_G	= 4,    /**< Green          */

-    PJ_TERM_COLOR_B	= 1,    /**< Blue.          */

-    PJ_TERM_COLOR_BRIGHT = 8    /**< Bright mask.   */

-};

-

-

-

-

-PJ_END_DECL

-

-

-#endif /* __PJ_TYPES_H__ */

-

+/* $Id$ */
+/* 
+ * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJ_TYPES_H__
+#define __PJ_TYPES_H__
+
+
+/**
+ * @defgroup PJ PJ Library
+ */
+/**
+ * @file types.h
+ * @brief Declaration of basic types and utility.
+ */
+/**
+ * @defgroup PJ_BASIC Basic Data Types and Library Functionality.
+ * @ingroup PJ_DS
+ * @{
+ */
+#include <pj/config.h>
+
+PJ_BEGIN_DECL
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** Unsigned 32bit integer. */
+typedef int		pj_int32_t;
+
+/** Signed 32bit integer. */
+typedef unsigned int	pj_uint32_t;
+
+/** Unsigned 16bit integer. */
+typedef short		pj_int16_t;
+
+/** Signed 16bit integer. */
+typedef unsigned short	pj_uint16_t;
+
+/** Unsigned 8bit integer. */
+typedef signed char	pj_int8_t;
+
+/** Signed 16bit integer. */
+typedef unsigned char	pj_uint8_t;
+
+/** Large unsigned integer. */
+typedef size_t		pj_size_t;
+
+/** Large signed integer. */
+typedef long		pj_ssize_t;
+
+/** Status code. */
+typedef int		pj_status_t;
+
+/** Boolean. */
+typedef int		pj_bool_t;
+
+/** Status is OK. */
+#define PJ_SUCCESS  0
+
+/** True value. */
+#define PJ_TRUE	    1
+
+/** False value. */
+#define PJ_FALSE    0
+
+/**
+ * File offset type.
+ */
+#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0
+typedef pj_int64_t pj_off_t;
+#else
+typedef pj_ssize_t pj_off_t;
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Data structure types.
+ */
+/**
+ * This type is used as replacement to legacy C string, and used throughout
+ * the library. By convention, the string is NOT null terminated.
+ */
+struct pj_str_t
+{
+    /** Buffer pointer, which is by convention NOT null terminated. */
+    char       *ptr;
+
+    /** The length of the string. */
+    pj_ssize_t  slen;
+};
+
+
+/**
+ * The opaque data type for linked list, which is used as arguments throughout
+ * the linked list operations.
+ */
+typedef void pj_list_type;
+
+/** 
+ * List.
+ */
+typedef struct pj_list pj_list;
+
+/**
+ * Opaque data type for hash tables.
+ */
+typedef struct pj_hash_table_t pj_hash_table_t;
+
+/**
+ * Opaque data type for hash entry (only used internally by hash table).
+ */
+typedef struct pj_hash_entry pj_hash_entry;
+
+/**
+ * Data type for hash search iterator.
+ * This structure should be opaque, however applications need to declare
+ * concrete variable of this type, that's why the declaration is visible here.
+ */
+typedef struct pj_hash_iterator_t
+{
+    pj_uint32_t	     index;     /**< Internal index.     */
+    pj_hash_entry   *entry;     /**< Internal entry.     */
+} pj_hash_iterator_t;
+
+
+/**
+ * Forward declaration for memory pool factory.
+ */
+typedef struct pj_pool_factory pj_pool_factory;
+
+/**
+ * Opaque data type for memory pool.
+ */
+typedef struct pj_pool_t pj_pool_t;
+
+/**
+ * Forward declaration for caching pool, a pool factory implementation.
+ */
+typedef struct pj_caching_pool pj_caching_pool;
+
+/**
+ * This type is used as replacement to legacy C string, and used throughout
+ * the library.
+ */
+typedef struct pj_str_t pj_str_t;
+
+/**
+ * Opaque data type for I/O Queue structure.
+ */
+typedef struct pj_ioqueue_t pj_ioqueue_t;
+
+/**
+ * Opaque data type for key that identifies a handle registered to the
+ * I/O queue framework.
+ */
+typedef struct pj_ioqueue_key_t pj_ioqueue_key_t;
+
+/**
+ * Opaque data to identify timer heap.
+ */
+typedef struct pj_timer_heap_t pj_timer_heap_t;
+
+/**
+ * Forward declaration for timer entry.
+ */
+typedef struct pj_timer_entry pj_timer_entry;
+
+/** 
+ * Opaque data type for atomic operations.
+ */
+typedef struct pj_atomic_t pj_atomic_t;
+
+/**
+ * Value type of an atomic variable.
+ */
+typedef PJ_ATOMIC_VALUE_TYPE pj_atomic_value_t;
+ 
+///////////////////////////////////////////////////////////////////////////////
+
+/** Thread handle. */
+typedef struct pj_thread_t pj_thread_t;
+
+/** Lock object. */
+typedef struct pj_lock_t pj_lock_t;
+
+/** Mutex handle. */
+typedef struct pj_mutex_t pj_mutex_t;
+
+/** Semaphore handle. */
+typedef struct pj_sem_t pj_sem_t;
+
+/** Event object. */
+typedef struct pj_event_t pj_event_t;
+
+/** Unidirectional stream pipe object. */
+typedef struct pj_pipe_t pj_pipe_t;
+
+/** Operating system handle. */
+typedef void *pj_oshandle_t;
+
+/** Socket handle. */
+typedef long pj_sock_t;
+
+/** Generic socket address. */
+typedef void pj_sockaddr_t;
+
+/** Color type. */
+typedef unsigned int pj_color_t;
+
+/** Exception id. */
+typedef int pj_exception_id_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** Utility macro to compute the number of elements in static array. */
+#define PJ_ARRAY_SIZE(a)    (sizeof(a)/sizeof(a[0]))
+
+/** Maximum value for signed 32-bit integer. */
+#define PJ_MAXINT32  0x7FFFFFFFL
+
+/**
+ * Length of object names.
+ */
+#define PJ_MAX_OBJ_NAME	16
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * General.
+ */
+/**
+ * Initialize the PJ Library.
+ * This function must be called before using the library. The purpose of this
+ * function is to initialize static library data, such as character table used
+ * in random string generation, and to initialize operating system dependent
+ * functionality (such as WSAStartup() in Windows).
+ */
+PJ_DECL(pj_status_t) pj_init(void);
+
+
+/**
+ * @}
+ */
+/**
+ * @addtogroup PJ_TIME Time Data Type and Manipulation.
+ * @ingroup PJ_MISC
+ * @{
+ */
+
+/**
+ * Representation of time value in this library.
+ * This type can be used to represent either an interval or a specific time
+ * or date. 
+ */
+typedef struct pj_time_val
+{
+    /** The seconds part of the time. */
+    long    sec;
+
+    /** The miliseconds fraction of the time. */
+    long    msec;
+
+} pj_time_val;
+
+/**
+ * Normalize the value in time value.
+ * @param t     Time value to be normalized.
+ */
+PJ_DECL(void) pj_time_val_normalize(pj_time_val *t);
+
+/**
+ * Get the total time value in miliseconds. This is the same as
+ * multiplying the second part with 1000 and then add the miliseconds
+ * part to the result.
+ *
+ * @param t     The time value.
+ * @return      Total time in miliseconds.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_MSEC(t)	((t).sec * 1000 + (t).msec)
+
+/**
+ * This macro will check if \a t1 is equal to \a t2.
+ *
+ * @param t1    The first time value to compare.
+ * @param t2    The second time value to compare.
+ * @return      Non-zero if both time values are equal.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_EQ(t1, t2)	((t1).sec==(t2).sec && (t1).msec==(t2).msec)
+
+/**
+ * This macro will check if \a t1 is greater than \a t2
+ *
+ * @param t1    The first time value to compare.
+ * @param t2    The second time value to compare.
+ * @return      Non-zero if t1 is greater than t2.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_GT(t1, t2)	((t1).sec>(t2).sec || \
+                                ((t1).sec==(t2).sec && (t1).msec>(t2).msec))
+
+/**
+ * This macro will check if \a t1 is greater than or equal to \a t2
+ *
+ * @param t1    The first time value to compare.
+ * @param t2    The second time value to compare.
+ * @return      Non-zero if t1 is greater than or equal to t2.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_GTE(t1, t2)	(PJ_TIME_VAL_GT(t1,t2) || \
+                                 PJ_TIME_VAL_EQ(t1,t2))
+
+/**
+ * This macro will check if \a t1 is less than \a t2
+ *
+ * @param t1    The first time value to compare.
+ * @param t2    The second time value to compare.
+ * @return      Non-zero if t1 is less than t2.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_LT(t1, t2)	(!(PJ_TIME_VAL_GTE(t1,t2)))
+
+/**
+ * This macro will check if \a t1 is less than or equal to \a t2.
+ *
+ * @param t1    The first time value to compare.
+ * @param t2    The second time value to compare.
+ * @return      Non-zero if t1 is less than or equal to t2.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_LTE(t1, t2)	(!PJ_TIME_VAL_GT(t1, t2))
+
+/**
+ * Add \a t2 to \a t1 and store the result in \a t1. Effectively
+ *
+ * this macro will expand as: (\a t1 += \a t2).
+ * @param t1    The time value to add.
+ * @param t2    The time value to be added to \a t1.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_ADD(t1, t2)	    do {			    \
+					(t1).sec += (t2).sec;	    \
+					(t1).msec += (t2).msec;	    \
+					pj_time_val_normalize(&(t1)); \
+				    } while (0)
+
+
+/**
+ * Substract \a t2 from \a t1 and store the result in \a t1. Effectively
+ * this macro will expand as (\a t1 -= \a t2).
+ *
+ * @param t1    The time value to subsctract.
+ * @param t2    The time value to be substracted from \a t1.
+ * @hideinitializer
+ */
+#define PJ_TIME_VAL_SUB(t1, t2)	    do {			    \
+					(t1).sec -= (t2).sec;	    \
+					(t1).msec -= (t2).msec;	    \
+					pj_time_val_normalize(&(t1)); \
+				    } while (0)
+
+
+/**
+ * This structure represent the parsed representation of time.
+ * It is acquired by calling #pj_time_decode().
+ */
+typedef struct pj_parsed_time
+{
+    /** This represents day of week where value zero means Sunday */
+    int wday;
+
+    /** This represents day of the year, 0-365, where zero means
+     *  1st of January.
+     */
+    int yday;
+
+    /** This represents day of month: 1-31 */
+    int day;
+
+    /** This represents month, with the value is 0 - 11 (zero is January) */
+    int mon;
+
+    /** This represent the actual year (unlike in ANSI libc where
+     *  the value must be added by 1900).
+     */
+    int year;
+
+    /** This represents the second part, with the value is 0-59 */
+    int sec;
+
+    /** This represents the minute part, with the value is: 0-59 */
+    int min;
+
+    /** This represents the hour part, with the value is 0-23 */
+    int hour;
+
+    /** This represents the milisecond part, with the value is 0-999 */
+    int msec;
+
+} pj_parsed_time;
+
+
+/**
+ * @}	// Time Management
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Terminal.
+ */
+/**
+ * Color code combination.
+ */
+enum {
+    PJ_TERM_COLOR_R	= 2,    /**< Red            */
+    PJ_TERM_COLOR_G	= 4,    /**< Green          */
+    PJ_TERM_COLOR_B	= 1,    /**< Blue.          */
+    PJ_TERM_COLOR_BRIGHT = 8    /**< Bright mask.   */
+};
+
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJ_TYPES_H__ */
+