Index: pjproject/trunk/pjlib/build/pjlib.dsp
===================================================================
--- pjproject/trunk/pjlib/build/pjlib.dsp	(revision 61)
+++ pjproject/trunk/pjlib/build/pjlib.dsp	(revision 62)
@@ -179,4 +179,8 @@
 # Begin Source File
 
+SOURCE=..\src\pj\ctype.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\src\pj\equeue_winnt.c
 # End Source File
@@ -235,11 +239,4 @@
 
 SOURCE=..\src\pj\ioqueue_winnt.c
-
-!IF  "$(CFG)" == "pjlib - Win32 Release"
-
-!ELSEIF  "$(CFG)" == "pjlib - Win32 Debug"
-
-!ENDIF 
-
 # End Source File
 # Begin Source File
Index: pjproject/trunk/pjlib/include/pj/compat/string.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/compat/string.h	(revision 61)
+++ pjproject/trunk/pjlib/include/pj/compat/string.h	(revision 62)
@@ -45,4 +45,5 @@
 
 #define pj_native_strcmp        strcmp
+#define pj_native_strncmp	strncmp
 #define pj_native_strlen        strlen
 #define pj_native_strcpy        strcpy
@@ -50,6 +51,7 @@
 #define pj_native_strchr        strchr
 #define pj_native_strcasecmp    strcasecmp
+#define pj_native_stricmp	strcasecmp
 #define pj_native_strncasecmp   strncasecmp
-
+#define pj_native_strnicmp	strncasecmp
 
 #endif	/* __PJ_COMPAT_STRING_H__ */
Index: pjproject/trunk/pjlib/include/pj/ctype.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/ctype.h	(revision 61)
+++ pjproject/trunk/pjlib/include/pj/ctype.h	(revision 62)
@@ -25,5 +25,8 @@
  */
 
+#include <pj/types.h>
 #include <pj/compat/ctype.h>
+
+PJ_BEGIN_DECL
 
 /**
@@ -100,13 +103,4 @@
 
 /**
- * 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); }
-
-/**
  * Returns a non-zero value if c is a either a space (' ') or horizontal
  * tab ('\\t') character.
@@ -131,5 +125,48 @@
 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__ */
Index: pjproject/trunk/pjlib/include/pj/errno.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/errno.h	(revision 61)
+++ pjproject/trunk/pjlib/include/pj/errno.h	(revision 62)
@@ -165,75 +165,75 @@
  * Unknown error has been reported.
  */
-#define PJ_EUNKNOWN	    (PJ_ERRNO_START_STATUS + 1)
+#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)
+#define PJ_EPENDING	    (PJ_ERRNO_START_STATUS + 2)	/* 70002 */
 /**
  * @hideinitializer
  * Too many connecting sockets.
  */
-#define PJ_ETOOMANYCONN	    (PJ_ERRNO_START_STATUS + 3)
+#define PJ_ETOOMANYCONN	    (PJ_ERRNO_START_STATUS + 3)	/* 70003 */
 /**
  * @hideinitializer
  * Invalid argument.
  */
-#define PJ_EINVAL	    (PJ_ERRNO_START_STATUS + 4)
+#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)
+#define PJ_ENAMETOOLONG	    (PJ_ERRNO_START_STATUS + 5)	/* 70005 */
 /**
  * @hideinitializer
  * Not found.
  */
-#define PJ_ENOTFOUND	    (PJ_ERRNO_START_STATUS + 6)
+#define PJ_ENOTFOUND	    (PJ_ERRNO_START_STATUS + 6)	/* 70006 */
 /**
  * @hideinitializer
  * Not enough memory.
  */
-#define PJ_ENOMEM	    (PJ_ERRNO_START_STATUS + 7)
+#define PJ_ENOMEM	    (PJ_ERRNO_START_STATUS + 7)	/* 70007 */
 /**
  * @hideinitializer
  * Bug detected!
  */
-#define PJ_EBUG             (PJ_ERRNO_START_STATUS + 8)
+#define PJ_EBUG             (PJ_ERRNO_START_STATUS + 8)	/* 70008 */
 /**
  * @hideinitializer
  * Operation timed out.
  */
-#define PJ_ETIMEDOUT        (PJ_ERRNO_START_STATUS + 9)
+#define PJ_ETIMEDOUT        (PJ_ERRNO_START_STATUS + 9)	/* 70009 */
 /**
  * @hideinitializer
  * Too many objects.
  */
-#define PJ_ETOOMANY         (PJ_ERRNO_START_STATUS + 10)
+#define PJ_ETOOMANY         (PJ_ERRNO_START_STATUS + 10)/* 70010 */
 /**
  * @hideinitializer
  * Object is busy.
  */
-#define PJ_EBUSY            (PJ_ERRNO_START_STATUS + 11)
+#define PJ_EBUSY            (PJ_ERRNO_START_STATUS + 11)/* 70011 */
 /**
  * @hideinitializer
  * The specified option is not supported.
  */
-#define PJ_ENOTSUP	    (PJ_ERRNO_START_STATUS + 12)
+#define PJ_ENOTSUP	    (PJ_ERRNO_START_STATUS + 12)/* 70012 */
 /**
  * @hideinitializer
  * Invalid operation.
  */
-#define PJ_EINVALIDOP	    (PJ_ERRNO_START_STATUS + 13)
+#define PJ_EINVALIDOP	    (PJ_ERRNO_START_STATUS + 13)/* 70013 */
 /**
  * @hideinitializer
  * Operation is cancelled.
  */
-#define PJ_ECANCELLED	    (PJ_ERRNO_START_STATUS + 14)
+#define PJ_ECANCELLED	    (PJ_ERRNO_START_STATUS + 14)/* 70014 */
 /**
  * @hideinitializer
  * Object already exists.
  */
-#define PJ_EEXISTS          (PJ_ERRNO_START_STATUS + 14)
+#define PJ_EEXISTS          (PJ_ERRNO_START_STATUS + 15)/* 70015 */
 
 /** @} */   /* pj_errnum */
@@ -255,4 +255,5 @@
 /**
  * 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)
@@ -261,4 +262,5 @@
  * 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)
@@ -267,4 +269,5 @@
  * 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)
Index: pjproject/trunk/pjlib/include/pj/log.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/log.h	(revision 61)
+++ pjproject/trunk/pjlib/include/pj/log.h	(revision 62)
@@ -26,5 +26,5 @@
 
 #include <pj/types.h>
-
+#include <stdarg.h>
 
 PJ_BEGIN_DECL
@@ -125,4 +125,15 @@
 
 /**
+ * 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. 
Index: pjproject/trunk/pjlib/include/pj/string.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/string.h	(revision 61)
+++ pjproject/trunk/pjlib/include/pj/string.h	(revision 62)
@@ -175,4 +175,30 @@
 
 /**
+ * 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.
  *
@@ -521,4 +547,5 @@
 }
 
+
 /**
  * @}
Index: pjproject/trunk/pjlib/include/pj/string_i.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/string_i.h	(revision 61)
+++ pjproject/trunk/pjlib/include/pj/string_i.h	(revision 62)
@@ -22,5 +22,5 @@
     pj_str_t dst;
     dst.ptr = str;
-    dst.slen = str ? strlen(str) : 0;
+    dst.slen = str ? pj_native_strlen(str) : 0;
     return dst;
 }
@@ -57,5 +57,5 @@
 			      const char *src)
 {
-    dst->slen = src ? strlen(src) : 0;
+    dst->slen = src ? pj_native_strlen(src) : 0;
     if (dst->slen) {
 	dst->ptr = (char*)pj_pool_alloc(pool, dst->slen);
@@ -92,9 +92,33 @@
 PJ_IDEF(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src)
 {
-    dst->slen = src ? strlen(src) : 0;
+    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)
@@ -105,6 +129,6 @@
     if (diff) {
 	return (int)diff;
-    } else if (str1->ptr) {
-	return strncmp(str1->ptr, str2->ptr, str1->slen);
+    } else if (str1->ptr && str1->slen) {
+	return pj_native_strncmp(str1->ptr, str2->ptr, str1->slen);
     } else {
 	return 0;
@@ -115,6 +139,7 @@
 			 pj_size_t len)
 {
-    return (str1->ptr && str2->ptr) ? strncmp(str1->ptr, str2->ptr, len) :
-	   (str1->ptr == str2->ptr ? 0 : 1);
+    return (str1->ptr && str2->ptr) ? 
+	    pj_native_strncmp(str1->ptr, str2->ptr, len) :
+	    (str1->ptr == str2->ptr ? 0 : 1);
 }
 
@@ -122,5 +147,5 @@
 			  pj_size_t len)
 {
-    return (str1->ptr && str2) ? strncmp(str1->ptr, str2, len) :
+    return (str1->ptr && str2) ? pj_native_strncmp(str1->ptr, str2, len) :
 	   (str1->ptr==str2 ? 0 : 1);
 }
@@ -139,5 +164,5 @@
 	return (int)diff;
     } else {
-	return strnicmp(str1->ptr, str2->ptr, str1->slen);
+	return pj_native_strnicmp(str1->ptr, str2->ptr, str1->slen);
     }
 }
@@ -145,6 +170,7 @@
 PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2)
 {
-    return (str1->ptr && str2) ? strnicmp(str1->ptr, str2, str1->slen) :
-	   (str1->ptr==str2 ? 0 : 1);
+    return (str1->ptr && str2) ? 
+	    pj_native_strnicmp(str1->ptr, str2, str1->slen) :
+	    (str1->ptr==str2 ? 0 : 1);
 }
 
@@ -152,6 +178,7 @@
 			  pj_size_t len)
 {
-    return (str1->ptr && str2->ptr) ? strnicmp(str1->ptr, str2->ptr, len) :
-	   (str1->ptr == str2->ptr ? 0 : 1);
+    return (str1->ptr && str2->ptr) ? 
+	    pj_native_strnicmp(str1->ptr, str2->ptr, len) :
+	    (str1->ptr == str2->ptr ? 0 : 1);
 }
 
@@ -159,6 +186,7 @@
 			   pj_size_t len)
 {
-    return (str1->ptr && str2) ? strnicmp(str1->ptr, str2, len) :
-	   (str1->ptr == str2 ? 0 : 1);
+    return (str1->ptr && str2) ? 
+	    pj_native_strnicmp(str1->ptr, str2, len) :
+	    (str1->ptr == str2 ? 0 : 1);
 }
 
Index: pjproject/trunk/pjlib/src/pj/ctype.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/ctype.c	(revision 62)
+++ pjproject/trunk/pjlib/src/pj/ctype.c	(revision 62)
@@ -0,0 +1,24 @@
+/* $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/ctype.h>
+
+
+char pj_hex_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+			'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
Index: pjproject/trunk/pjlib/src/pj/log.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/log.c	(revision 61)
+++ pjproject/trunk/pjlib/src/pj/log.c	(revision 62)
@@ -65,6 +65,6 @@
 }
 
-static void pj_log(const char *sender, int level, 
-		   const char *format, va_list marker)
+PJ_DEF(void) pj_log( const char *sender, int level, 
+		     const char *format, va_list marker)
 {
     pj_time_val now;
Index: pjproject/trunk/pjlib/src/pj/os_core_win32.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/os_core_win32.c	(revision 61)
+++ pjproject/trunk/pjlib/src/pj/os_core_win32.c	(revision 62)
@@ -130,9 +130,6 @@
     pj_status_t rc;
 
-    PJ_LOG(5, ("pj_init", "Initializing PJ Library.."));
-
     /* Init Winsock.. */
     if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {
-	PJ_LOG(1, ("pj_init", "Winsock initialization has returned an error"));
 	return PJ_RETURN_OS_ERROR(WSAGetLastError());
     }
@@ -140,5 +137,4 @@
     /* Init this thread's TLS. */
     if ((rc=pj_thread_init()) != PJ_SUCCESS) {
-	PJ_LOG(1, ("pj_init", "Thread initialization has returned an error"));
 	return rc;
     }
Index: pjproject/trunk/pjlib/src/pj/string.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/string.c	(revision 61)
+++ pjproject/trunk/pjlib/src/pj/string.c	(revision 62)
@@ -28,7 +28,4 @@
 
 
-static char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7',
-		     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-
 PJ_DEF(pj_str_t*) pj_strltrim( pj_str_t *str )
 {
@@ -51,10 +48,4 @@
 }
 
-PJ_INLINE(void) pj_val_to_hex_digit(unsigned value, char *p)
-{
-    *p++ = hex[ (value & 0xF0) >> 4 ];
-    *p++ = hex[ (value & 0x0F) ];
-}
-
 PJ_DEF(char*) pj_create_random_string(char *str, pj_size_t len)
 {
@@ -73,5 +64,5 @@
     }
     for (i=i * 8; i<len; ++i) {
-	*p++ = hex[ pj_rand() & 0x0F ];
+	*p++ = pj_hex_digits[ pj_rand() & 0x0F ];
     }
     return str;
@@ -130,2 +121,3 @@
 }
 
+
