enhanced qse_getnwifcfg() for linux.
added qse_mbshextobin(), qse_wcshextobin()
This commit is contained in:
		| @ -526,7 +526,7 @@ int qse_memcmp (const void* s1, const void* s2, qse_size_t n) | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void* qse_memchr (const void* s, int val, qse_size_t n) | ||||
| void* qse_membyte (const void* s, int val, qse_size_t n) | ||||
| { | ||||
| 	const qse_byte_t* x = (const qse_byte_t*)s; | ||||
|  | ||||
| @ -539,7 +539,7 @@ void* qse_memchr (const void* s, int val, qse_size_t n) | ||||
| 	return QSE_NULL; | ||||
| } | ||||
|  | ||||
| void* qse_memrchr (const void* s, int val, qse_size_t n) | ||||
| void* qse_memrbyte (const void* s, int val, qse_size_t n) | ||||
| { | ||||
| 	const qse_byte_t* x = (qse_byte_t*)s + n - 1; | ||||
|  | ||||
|  | ||||
| @ -23,6 +23,8 @@ | ||||
|  | ||||
| #include <qse/cmn/mem.h> | ||||
|  | ||||
| #define MINIMIZE_PLATFORM_DEPENDENCY | ||||
|  | ||||
| #ifdef MINIMIZE_PLATFORM_DEPENDENCY | ||||
| #	define QSE_MEMCPY(dst,src,len)  qse_memcpy(dst,src,len) | ||||
| #	define QSE_MEMMOVE(dst,src,len) qse_memmove(dst,src,len) | ||||
|  | ||||
| @ -21,6 +21,7 @@ | ||||
| #include <qse/cmn/nwif.h> | ||||
| #include <qse/cmn/str.h> | ||||
| #include <qse/cmn/mbwc.h> | ||||
| #include <qse/cmn/sio.h> | ||||
| #include "mem.h" | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| @ -286,24 +287,81 @@ void qse_freenwifcfg (qse_nwifcfg_t* cfg) | ||||
| #if defined(__linux) | ||||
| static void read_proc_net_if_inet6 (qse_nwifcfg_t* cfg, struct ifreq* ifr) | ||||
| { | ||||
| #if 0 | ||||
| 	/* | ||||
|      * | ||||
| 	 * # cat /proc/net/if_inet6 | ||||
| 	 * 00000000000000000000000000000001 01 80 10 80 lo | ||||
| 	 * +------------------------------+ ++ ++ ++ ++ ++ | ||||
| 	 * |                                |  |  |  |  | | ||||
| 	 * 1                                2  3  4  5  6 | ||||
| 	 *  | ||||
| 	 * 1. IPv6 address displayed in 32 hexadecimal chars without colons as separator | ||||
| 	 * 2. Netlink device number (interface index) in hexadecimal (see “ip addr” , too) | ||||
| 	 * 3. Prefix length in hexadecimal | ||||
| 	 * 4. Scope value (see kernel source “ include/net/ipv6.h” and “net/ipv6/addrconf.c” for more) | ||||
| 	 * 5. Interface flags (see “include/linux/rtnetlink.h” and “net/ipv6/addrconf.c” for more) | ||||
| 	 * 6. Device name | ||||
| 	 */ | ||||
|  | ||||
| 	qse_sio_t* sio; | ||||
| 	qse_mchar_t line[128]; | ||||
| 	qse_mchar_t* ptr, * ptr2; | ||||
| 	qse_ssize_t len; | ||||
| 	qse_mcstr_t tok[6]; | ||||
| 	int count, index; | ||||
|  | ||||
| 	/* TODO */ | ||||
|  | ||||
| 	sio = qse_sio_open (QSE_MMGR_GETDFL(), 0,  | ||||
| 		QSE_T("proc/net/if_inet6"), QSE_SIO_IGNOREMBWCERR | QSE_SIO_READ);  | ||||
| 		QSE_T("/proc/net/if_inet6"), QSE_SIO_IGNOREMBWCERR | QSE_SIO_READ);  | ||||
| 	if (sio) | ||||
| 	{ | ||||
| 		qse_ssize_t x; | ||||
| 		 | ||||
| 		while (1) | ||||
| 		{ | ||||
| 			x = qse_sio_getmbs (sio, line, QSE_COUNTOF(line)); | ||||
| 			if (x == -1) break; | ||||
| 			len = qse_sio_getmbs (sio, line, QSE_COUNTOF(line)); | ||||
| 			if (len <= 0) break; | ||||
|  | ||||
| 			count = 0; | ||||
| 			ptr = line; | ||||
|  | ||||
| 			while (ptr && count < 6) | ||||
| 			{ | ||||
| 				ptr2 = qse_mbsxtok (ptr, len, QSE_MT(" \t"), &tok[count]); | ||||
|  | ||||
| 				len -= ptr2 - ptr; | ||||
| 				ptr = ptr2; | ||||
| 				count++; | ||||
| 			} | ||||
|  | ||||
| 			if (count >= 6) | ||||
| 			{ | ||||
| 				index = qse_mbsxtoi (tok[1].ptr, tok[1].len, 16); | ||||
| 				if (index == cfg->index) | ||||
| 				{ | ||||
| 					int ti; | ||||
|  | ||||
| 					if (qse_mbshextobin (tok[0].ptr, tok[0].len, cfg->addr.u.in6.addr.value, QSE_COUNTOF(cfg->addr.u.in6.addr.value)) <= -1) break; | ||||
|  | ||||
| 					/* tok[3] is the scope type, not the actual scope.  | ||||
| 					 * i leave this code for reference only. | ||||
| 					cfg->addr.u.in6.scope = qse_mbsxtoi (tok[3].ptr, tok[3].len, 16); */ | ||||
| 			 | ||||
|  | ||||
| 					cfg->addr.type = QSE_NWAD_IN6; | ||||
|  | ||||
| 					ti = qse_mbsxtoi (tok[2].ptr, tok[0].len, 16); | ||||
| 					qse_prefixtoip6ad (ti, &cfg->mask.u.in6.addr); | ||||
|  | ||||
| 					cfg->mask.type = QSE_NWAD_IN6; | ||||
| 					goto done; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 	done: | ||||
| 		qse_sio_close (sio); | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -385,7 +443,7 @@ static int get_nwifcfg (int s, qse_nwifcfg_t* cfg, struct ifreq* ifr) | ||||
| 	qse_size_t ml, wl; | ||||
| 	 | ||||
| 	#if defined(SIOCGIFINDEX) | ||||
| 	if (ioctl (s, SIOCGIFINDEX, ifr) <= -1) return -1;		 | ||||
| 	if (ioctl (s, SIOCGIFINDEX, ifr) <= -1) return -1; | ||||
| 	#if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) | ||||
| 	cfg->index = ifr->ifr_ifindex; | ||||
| 	#else | ||||
| @ -497,12 +555,14 @@ static int get_nwifcfg (int s, qse_nwifcfg_t* cfg, struct ifreq* ifr) | ||||
| #elif defined(SIOCGIFADDR) | ||||
|  | ||||
| 	#if defined(SIOCGIFINDEX) | ||||
| 	if (ioctl (s, SIOCGIFINDEX, ifr) <= -1) return -1;		 | ||||
| 	if (ioctl (s, SIOCGIFINDEX, ifr) <= -1) return -1; | ||||
|  | ||||
| 	#if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) | ||||
| 	cfg->index = ifr->ifr_ifindex; | ||||
| 	#else | ||||
| 	cfg->index = ifr->ifr_index; | ||||
| 	#endif | ||||
|  | ||||
| 	#else | ||||
| 	cfg->index = 0; | ||||
| 	#endif | ||||
| @ -537,13 +597,12 @@ static int get_nwifcfg (int s, qse_nwifcfg_t* cfg, struct ifreq* ifr) | ||||
| 		qse_skadtonwad (&ifr->ifr_addr, &cfg->mask); | ||||
|  | ||||
| 	#if defined(__linux) | ||||
| 	if (cfg->addr.type == QSE_NWAD_NX && cfg->mask.type == QSE_NWAD_NX) | ||||
| 	if (cfg->addr.type == QSE_NWAD_NX && cfg->mask.type == QSE_NWAD_NX && cfg->type == QSE_NWIFCFG_IN6) | ||||
| 	{ | ||||
| 		/* access /proc/net/if_inet6 */ | ||||
| 		read_proc_net_if_inet6 (cfg, ifr); | ||||
| 	} | ||||
| 	#endif | ||||
| 		 | ||||
|  | ||||
| 	if ((cfg->flags & QSE_NWIFCFG_BCAST) && | ||||
| 	    ioctl (s, SIOCGIFBRDADDR, ifr) >= 0) | ||||
|  | ||||
| @ -22,120 +22,241 @@ | ||||
| #include <qse/cmn/chr.h> | ||||
| #include "mem.h" | ||||
|  | ||||
| int qse_strtoi (const qse_char_t* str) | ||||
|  | ||||
| /*--------------------------------------------------------------- | ||||
|  * multi-byte string to number conversion  | ||||
|  *---------------------------------------------------------------*/ | ||||
| int qse_mbstoi (const qse_mchar_t* mbs, int base) | ||||
| { | ||||
| 	int v; | ||||
| 	QSE_STRTONUM (v, str, QSE_NULL, 10); | ||||
| 	QSE_MBSTONUM (v, mbs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| long qse_strtol (const qse_char_t* str) | ||||
| long qse_mbstol (const qse_mchar_t* mbs, int base) | ||||
| { | ||||
| 	long v; | ||||
| 	QSE_STRTONUM (v, str, QSE_NULL, 10); | ||||
| 	QSE_MBSTONUM (v, mbs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| unsigned int qse_strtoui (const qse_char_t* str) | ||||
| unsigned int qse_mbstoui (const qse_mchar_t* mbs, int base) | ||||
| { | ||||
| 	unsigned int v; | ||||
| 	QSE_STRTONUM (v, str, QSE_NULL, 10); | ||||
| 	QSE_MBSTONUM (v, mbs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| unsigned long qse_strtoul (const qse_char_t* str) | ||||
| unsigned long qse_mbstoul (const qse_mchar_t* mbs, int base) | ||||
| { | ||||
| 	unsigned long v; | ||||
| 	QSE_STRTONUM (v, str, QSE_NULL, 10); | ||||
| 	QSE_MBSTONUM (v, mbs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| int qse_strxtoi (const qse_char_t* str, qse_size_t len) | ||||
| int qse_mbsxtoi (const qse_mchar_t* mbs, qse_size_t len, int base) | ||||
| { | ||||
| 	int v; | ||||
| 	QSE_STRXTONUM (v, str, len, QSE_NULL, 10); | ||||
| 	QSE_MBSXTONUM (v, mbs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| long qse_strxtol (const qse_char_t* str, qse_size_t len) | ||||
| long qse_mbsxtol (const qse_mchar_t* mbs, qse_size_t len, int base) | ||||
| { | ||||
| 	long v; | ||||
| 	QSE_STRXTONUM (v, str, len, QSE_NULL, 10); | ||||
| 	QSE_MBSXTONUM (v, mbs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| unsigned int qse_strxtoui (const qse_char_t* str, qse_size_t len) | ||||
| unsigned int qse_mbsxtoui (const qse_mchar_t* mbs, qse_size_t len, int base) | ||||
| { | ||||
| 	unsigned int v; | ||||
| 	QSE_STRXTONUM (v, str, len, QSE_NULL, 10); | ||||
| 	QSE_MBSXTONUM (v, mbs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| unsigned long qse_strxtoul (const qse_char_t* str, qse_size_t len) | ||||
| unsigned long qse_mbsxtoul (const qse_mchar_t* mbs, qse_size_t len, int base) | ||||
| { | ||||
| 	unsigned long v; | ||||
| 	QSE_STRXTONUM (v, str, len, QSE_NULL, 10); | ||||
| 	QSE_MBSXTONUM (v, mbs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_int_t qse_strtoint (const qse_char_t* str) | ||||
| qse_int_t qse_mbstoint (const qse_mchar_t* mbs, int base) | ||||
| { | ||||
| 	qse_int_t v; | ||||
| 	QSE_STRTONUM (v, str, QSE_NULL, 10); | ||||
| 	QSE_MBSTONUM (v, mbs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_long_t qse_strtolong (const qse_char_t* str) | ||||
| qse_long_t qse_mbstolong (const qse_mchar_t* mbs, int base) | ||||
| { | ||||
| 	qse_long_t v; | ||||
| 	QSE_STRTONUM (v, str, QSE_NULL, 10); | ||||
| 	QSE_MBSTONUM (v, mbs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_uint_t qse_strtouint (const qse_char_t* str) | ||||
| qse_uint_t qse_mbstouint (const qse_mchar_t* mbs, int base) | ||||
| { | ||||
| 	qse_uint_t v; | ||||
| 	QSE_STRTONUM (v, str, QSE_NULL, 10); | ||||
| 	QSE_MBSTONUM (v, mbs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_ulong_t qse_strtoulong (const qse_char_t* str) | ||||
| qse_ulong_t qse_mbstoulong (const qse_mchar_t* mbs, int base) | ||||
| { | ||||
| 	qse_ulong_t v; | ||||
| 	QSE_STRTONUM (v, str, QSE_NULL, 10); | ||||
| 	QSE_MBSTONUM (v, mbs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_int_t qse_strxtoint (const qse_char_t* str, qse_size_t len) | ||||
| qse_int_t qse_mbsxtoint (const qse_mchar_t* mbs, qse_size_t len, int base) | ||||
| { | ||||
| 	qse_int_t v; | ||||
| 	QSE_STRXTONUM (v, str, len, QSE_NULL, 10); | ||||
| 	QSE_MBSXTONUM (v, mbs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_long_t qse_strxtolong (const qse_char_t* str, qse_size_t len) | ||||
| qse_long_t qse_mbsxtolong (const qse_mchar_t* mbs, qse_size_t len, int base) | ||||
| { | ||||
| 	qse_long_t v; | ||||
| 	QSE_STRXTONUM (v, str, len, QSE_NULL, 10); | ||||
| 	QSE_MBSXTONUM (v, mbs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_uint_t qse_strxtouint (const qse_char_t* str, qse_size_t len) | ||||
| qse_uint_t qse_mbsxtouint (const qse_mchar_t* mbs, qse_size_t len, int base) | ||||
| { | ||||
| 	qse_uint_t v; | ||||
| 	QSE_STRXTONUM (v, str, len, QSE_NULL, 10); | ||||
| 	QSE_MBSXTONUM (v, mbs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_ulong_t qse_strxtoulong (const qse_char_t* str, qse_size_t len) | ||||
| qse_ulong_t qse_mbsxtoulong (const qse_mchar_t* mbs, qse_size_t len, int base) | ||||
| { | ||||
| 	qse_ulong_t v; | ||||
| 	QSE_STRXTONUM (v, str, len, QSE_NULL, 10); | ||||
| 	QSE_MBSXTONUM (v, mbs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| /* case conversion */ | ||||
|  | ||||
| /*--------------------------------------------------------------- | ||||
|  * wide string to number conversion  | ||||
|  *---------------------------------------------------------------*/ | ||||
| int qse_wcstoi (const qse_wchar_t* wcs, int base) | ||||
| { | ||||
| 	int v; | ||||
| 	QSE_WCSTONUM (v, wcs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| long qse_wcstol (const qse_wchar_t* wcs, int base) | ||||
| { | ||||
| 	long v; | ||||
| 	QSE_WCSTONUM (v, wcs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| unsigned int qse_wcstoui (const qse_wchar_t* wcs, int base) | ||||
| { | ||||
| 	unsigned int v; | ||||
| 	QSE_WCSTONUM (v, wcs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| unsigned long qse_wcstoul (const qse_wchar_t* wcs, int base) | ||||
| { | ||||
| 	unsigned long v; | ||||
| 	QSE_WCSTONUM (v, wcs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| int qse_wcsxtoi (const qse_wchar_t* wcs, qse_size_t len, int base) | ||||
| { | ||||
| 	int v; | ||||
| 	QSE_WCSXTONUM (v, wcs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| long qse_wcsxtol (const qse_wchar_t* wcs, qse_size_t len, int base) | ||||
| { | ||||
| 	long v; | ||||
| 	QSE_WCSXTONUM (v, wcs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| unsigned int qse_wcsxtoui (const qse_wchar_t* wcs, qse_size_t len, int base) | ||||
| { | ||||
| 	unsigned int v; | ||||
| 	QSE_WCSXTONUM (v, wcs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| unsigned long qse_wcsxtoul (const qse_wchar_t* wcs, qse_size_t len, int base) | ||||
| { | ||||
| 	unsigned long v; | ||||
| 	QSE_WCSXTONUM (v, wcs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_int_t qse_wcstoint (const qse_wchar_t* wcs, int base) | ||||
| { | ||||
| 	qse_int_t v; | ||||
| 	QSE_WCSTONUM (v, wcs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_long_t qse_wcstolong (const qse_wchar_t* wcs, int base) | ||||
| { | ||||
| 	qse_long_t v; | ||||
| 	QSE_WCSTONUM (v, wcs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_uint_t qse_wcstouint (const qse_wchar_t* wcs, int base) | ||||
| { | ||||
| 	qse_uint_t v; | ||||
| 	QSE_WCSTONUM (v, wcs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_ulong_t qse_wcstoulong (const qse_wchar_t* wcs, int base) | ||||
| { | ||||
| 	qse_ulong_t v; | ||||
| 	QSE_WCSTONUM (v, wcs, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_int_t qse_wcsxtoint (const qse_wchar_t* wcs, qse_size_t len, int base) | ||||
| { | ||||
| 	qse_int_t v; | ||||
| 	QSE_WCSXTONUM (v, wcs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_long_t qse_wcsxtolong (const qse_wchar_t* wcs, qse_size_t len, int base) | ||||
| { | ||||
| 	qse_long_t v; | ||||
| 	QSE_WCSXTONUM (v, wcs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_uint_t qse_wcsxtouint (const qse_wchar_t* wcs, qse_size_t len, int base) | ||||
| { | ||||
| 	qse_uint_t v; | ||||
| 	QSE_WCSXTONUM (v, wcs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_ulong_t qse_wcsxtoulong (const qse_wchar_t* wcs, qse_size_t len, int base) | ||||
| { | ||||
| 	qse_ulong_t v; | ||||
| 	QSE_WCSXTONUM (v, wcs, len, QSE_NULL, base); | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| /*--------------------------------------------------------------- | ||||
|  * case conversion | ||||
|  *---------------------------------------------------------------*/ | ||||
| qse_size_t qse_mbslwr (qse_mchar_t* str) | ||||
| { | ||||
| 	qse_mchar_t* p = str; | ||||
| @ -163,3 +284,76 @@ qse_size_t qse_wcsupr (qse_wchar_t* str) | ||||
| 	for (p = str; *p != QSE_WT('\0'); p++) *p = QSE_TOWUPPER (*p); | ||||
| 	return p - str; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /*--------------------------------------------------------------- | ||||
|  * Hexadecimal string conversion | ||||
|  *---------------------------------------------------------------*/ | ||||
|  | ||||
| int qse_mbshextobin (const qse_mchar_t* hex, qse_size_t hexlen, qse_uint8_t* buf, qse_size_t buflen) | ||||
| { | ||||
| 	const qse_mchar_t* end = hex + hexlen; | ||||
| 	qse_size_t bi = 0; | ||||
|  | ||||
| 	while (hex < end && bi < buflen) | ||||
| 	{ | ||||
| 		int v; | ||||
|  | ||||
| 		if (*hex >= QSE_MT('0') && *hex <= QSE_MT('9')) v = *hex - QSE_MT('0'); | ||||
| 		else if (*hex >= QSE_MT('a') && *hex <= QSE_MT('f')) v = *hex - QSE_MT('a') + 10; | ||||
| 		else if (*hex >= QSE_MT('A') && *hex <= QSE_MT('F')) v = *hex - QSE_MT('A') + 10; | ||||
| 		else return -1; | ||||
|  | ||||
| 		buf[bi] = buf[bi] * 16 + v; | ||||
|  | ||||
| 		hex++; | ||||
| 		if (hex >= end) return -1; | ||||
|  | ||||
| 		if (*hex >= QSE_MT('0') && *hex <= QSE_MT('9')) v = *hex - QSE_MT('0'); | ||||
| 		else if (*hex >= QSE_MT('a') && *hex <= QSE_MT('f')) v = *hex - QSE_MT('a') + 10; | ||||
| 		else if (*hex >= QSE_MT('A') && *hex <= QSE_MT('F')) v = *hex - QSE_MT('A') + 10; | ||||
| 		else return -1; | ||||
|  | ||||
| 		buf[bi] = buf[bi] * 16 + v; | ||||
|  | ||||
| 		hex++; | ||||
| 		bi++; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| int qse_wcshextobin (const qse_wchar_t* hex, qse_size_t hexlen, qse_uint8_t* buf, qse_size_t buflen) | ||||
| { | ||||
| 	const qse_wchar_t* end = hex + hexlen; | ||||
| 	qse_size_t bi = 0; | ||||
|  | ||||
| 	while (hex < end && bi < buflen) | ||||
| 	{ | ||||
| 		int v; | ||||
|  | ||||
| 		if (*hex >= QSE_WT('0') && *hex <= QSE_WT('9')) v = *hex - QSE_WT('0'); | ||||
| 		else if (*hex >= QSE_WT('a') && *hex <= QSE_WT('f')) v = *hex - QSE_WT('a') + 10; | ||||
| 		else if (*hex >= QSE_WT('A') && *hex <= QSE_WT('F')) v = *hex - QSE_WT('A') + 10; | ||||
| 		else return -1; | ||||
|  | ||||
| 		buf[bi] = buf[bi] * 16 + v; | ||||
|  | ||||
| 		hex++; | ||||
| 		if (hex >= end) return -1; | ||||
|  | ||||
| 		if (*hex >= QSE_WT('0') && *hex <= QSE_WT('9')) v = *hex - QSE_WT('0'); | ||||
| 		else if (*hex >= QSE_WT('a') && *hex <= QSE_WT('f')) v = *hex - QSE_WT('a') + 10; | ||||
| 		else if (*hex >= QSE_WT('A') && *hex <= QSE_WT('F')) v = *hex - QSE_WT('A') + 10; | ||||
| 		else return -1; | ||||
|  | ||||
| 		buf[bi] = buf[bi] * 16 + v; | ||||
|  | ||||
| 		hex++; | ||||
| 		bi++; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user