Index: trunk/src/cf_codec.c
===================================================================
--- trunk/src/cf_codec.c	(revision 89)
+++ trunk/src/cf_codec.c	(revision 90)
@@ -34,5 +34,5 @@
 
 const static char g_table_Base64Encode[] = {
-#define PADDING_CHAR_INDEX	64
+#define BASE64_PADDING_CHAR_INDEX	64
 	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',		/* 00 - 07 */
 	'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',		/* 08 - 15 */
@@ -110,9 +110,8 @@
  * hex-decode
  *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ * @return 성공 시, 디코딩된 바이너리 데이터의 길이; 실패 시, 오류 코드
  *
  * @param hex	16진수 문자열
  * @param bin	바이너리 데이터를 저장할 주소
- * @param len	바이너리 데이터의 길이를 저장할 주소
  *
  * @remark
@@ -121,12 +120,9 @@
 int
 CF_Codec_Hex_Decode (const char		* hex,
-					 unsigned char	* bin,
-					 size_t			* len)
-{
-	int		result = 0;
-
+					 unsigned char	* bin)
+{
 	size_t	length = strlen (hex);	/* absolutely even-number */
 	size_t	iter = 0;
-	size_t	binlen = length / 2;
+	int		binlen = (int)length / 2;
 
 	const char		* ptr = hex;
@@ -137,5 +133,4 @@
 	ASSERT_ARGS (hex == NULL);
 	ASSERT_ARGS (bin == NULL);
-	ASSERT_ARGS (len == NULL);
 
 	for (iter = 0 ; iter < binlen ; iter++)
@@ -164,7 +159,5 @@
 	}
 
-	*len = binlen;
-
-	return result;
+	return binlen;
 }
 
@@ -179,7 +172,6 @@
  *
  * @remark
- * base64는 할당된 메모리이며, 크기는 '\0'를 포함하여 (((len + 2) / 3) * 4) + 1
- *
- * @see http://sourceforge.net/p/predef/wiki/Endianness/
+ * base64는 할당된 메모리이며, 크기는 ((len + 2) / 3) * 4
+ * (null-character 제외)
  */
 int
@@ -188,46 +180,46 @@
 						char				* base64)
 {
-	size_t	iter = 0;
-	char	* ptr = base64;
-
-	ASSERT_ARGS (bin	== NULL);
-	ASSERT_ARGS (base64	== NULL);
-
-#define SEXTUPLE_E_1(__x,_idx)	((__x[_idx    ] >> 2) & 0x3f)
-#define SEXTUPLE_E_2(__x,_idx)	((__x[_idx    ] << 4) & 0x30)
-#define SEXTUPLE_E_3(__x,_idx)	((__x[_idx + 1] >> 4) & 0x0f)
-#define SEXTUPLE_E_4(__x,_idx)	((__x[_idx + 1] << 2) & 0x3c)
-#define SEXTUPLE_E_5(__x,_idx)	((__x[_idx + 2] >> 6) & 0x03)
-#define SEXTUPLE_E_6(__x,_idx)	((__x[_idx + 2]     ) & 0x3f)
-
-	for (iter = 0 ; iter < len - 2 ; iter += 3)
-	{
-		*ptr++ = g_table_Base64Encode[SEXTUPLE_E_1 (bin, iter)];
-		*ptr++ = g_table_Base64Encode[SEXTUPLE_E_2 (bin, iter)|
-									  SEXTUPLE_E_3 (bin, iter)];
-		*ptr++ = g_table_Base64Encode[SEXTUPLE_E_4 (bin, iter)|
-									  SEXTUPLE_E_5 (bin, iter)];
-		*ptr++ = g_table_Base64Encode[SEXTUPLE_E_6 (bin, iter)];
-	}
-
-	if (iter < len)
-	{
-		*ptr++ = g_table_Base64Encode[SEXTUPLE_E_1 (bin, iter)];
-
-		if (iter == (len - 1))
+	const unsigned char	* src = bin;
+	char				* dst = base64;
+
+	ASSERT_ARGS (src == NULL);
+	ASSERT_ARGS (dst == NULL);
+
+#define SEXTUPLE_E_1(__x)	(((__x[0]) >> 2) & 0x3f)
+#define SEXTUPLE_E_2(__x)	(((__x[0]) << 4) & 0x30)
+#define SEXTUPLE_E_3(__x)	(((__x[1]) >> 4) & 0x0f)
+#define SEXTUPLE_E_4(__x)	(((__x[1]) << 2) & 0x3c)
+#define SEXTUPLE_E_5(__x)	(((__x[2]) >> 6) & 0x03)
+#define SEXTUPLE_E_6(__x)	(((__x[2])     ) & 0x3f)
+
+	for ( ; src - bin < len - 2 ; src += 3)
+	{
+		*dst++ = g_table_Base64Encode[SEXTUPLE_E_1 (src)];
+		*dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (src)|
+									  SEXTUPLE_E_3 (src)];
+		*dst++ = g_table_Base64Encode[SEXTUPLE_E_4 (src)|
+									  SEXTUPLE_E_5 (src)];
+		*dst++ = g_table_Base64Encode[SEXTUPLE_E_6 (src)];
+	}
+
+	if (src - bin < len)
+	{
+		*dst++ = g_table_Base64Encode[SEXTUPLE_E_1 (src)];
+
+		if (src - bin == len - 1)
 		{
-			*ptr++ = g_table_Base64Encode[SEXTUPLE_E_2 (bin, iter)];
-			*ptr++ = g_table_Base64Encode[PADDING_CHAR_INDEX];
+			*dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (bin)];
+			*dst++ = g_table_Base64Encode[BASE64_PADDING_CHAR_INDEX];
 		}
 		else
 		{
-			*ptr++ = g_table_Base64Encode[SEXTUPLE_E_2 (bin, iter)|
-										  SEXTUPLE_E_3 (bin, iter)];
-			*ptr++ = g_table_Base64Encode[SEXTUPLE_E_4 (bin, iter)];
+			*dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (bin)|
+										  SEXTUPLE_E_3 (bin)];
+			*dst++ = g_table_Base64Encode[SEXTUPLE_E_4 (bin)];
 		}
 
-		*ptr++ = g_table_Base64Encode[PADDING_CHAR_INDEX];
-	}
-	*ptr = '\0';
+		*dst++ = g_table_Base64Encode[BASE64_PADDING_CHAR_INDEX];
+	}
+	*dst = '\0';
 
 	return CF_OK;
@@ -237,35 +229,30 @@
  * Base64-decode
  *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ * @return 성공 시, 디코딩된 바이너리 데이터의 길이; 실패 시, 오류 코드
  *
  * @param base64	base64 문자열
  * @param bin		바이너리 데이터를 저장할 주소
- * @param len		바이너리 데이터의 길이를 저장할 주소
- *
- * @remark
- * base64는 할당된 메모리이며, 크기는 (strlen (base64) - <'=' 개수>) / 4 * 3
- *
- * @see http://sourceforge.net/p/predef/wiki/Endianness/
+ *
+ * @remark
+ * base64는 할당된 메모리이며, 크기는 (strlen (base64) - <패딩 길이>) / 4 * 3
  */
 int
 CF_Codec_Base64_Decode (const char		* base64,
-						unsigned char	* bin,
-						size_t			* len)
-{
-	size_t			remain = 0;
+						unsigned char	* bin)
+{
+	int				remain = 0;
 	const char		* src = base64;
 	unsigned char	* dst = bin;
-	size_t			binlen = 0;
-
-	ASSERT_ARGS (base64	== NULL);
-	ASSERT_ARGS (bin	== NULL);
-	ASSERT_ARGS (len	== NULL);
-
-	while (*src && g_ascii_Base64Decode[(int)*src] < PADDING_CHAR_INDEX) src++;
+	int				binlen = 0;
+
+	ASSERT_ARGS (src == NULL);
+	ASSERT_ARGS (dst == NULL);
+
+	while (g_ascii_Base64Decode[(int)*src] < BASE64_PADDING_CHAR_INDEX) src++;
 
 	if (*src)
 		return CF_ERROR_CODEC_NOT_BASE64;
 
-	remain = (size_t)(src - base64);
+	remain = (int)(src - base64);
 	binlen = ((remain + 3) / 4) * 3;
 
@@ -286,14 +273,9 @@
 	if (remain > 1)
 		*dst++ = (unsigned char)(SEXTUPLE_D_1 (src) | SEXTUPLE_D_2 (src));
-
 	if (remain > 2)
 		*dst++ = (unsigned char)(SEXTUPLE_D_3 (src) | SEXTUPLE_D_4 (src));
-
 	if (remain > 3)
 		*dst++ = (unsigned char)(SEXTUPLE_D_5 (src) | SEXTUPLE_D_6 (src));
 
-	*dst++ = '\0';
-	*len = binlen;
-
-	return CF_OK;
-}
+	return binlen;
+}
