📄 net_ascii.c
字号:
* characters are trapped as invalid, including any leading or trailing characters.
*
* (b) (1) Include EXACTLY four decimal values ...
* (2) ... separated ...
* (3) ... by EXACTLY three dot characters.
*
* (c) Ensure that each decimal value does NOT exceed the maximum octet value (i.e. 255).
*
* (d) Ensure that each decimal value's number of decimal digits, including leading zeros,
* does NOT exceed the maximum number of digits, NET_ASCII_CHAR_MAX_OCTET_ADDR_IP (3).
*********************************************************************************************************
*/
/*$PAGE*/
NET_IP_ADDR NetASCII_Str_to_IP (CPU_CHAR *paddr_ip_ascii,
NET_ERR *perr)
{
CPU_CHAR *pchar_cur;
CPU_CHAR *pchar_prev;
NET_IP_ADDR addr_ip;
CPU_INT16U addr_octet_val;
CPU_INT32U addr_nbr_octet;
CPU_INT08U addr_nbr_octet_dig;
/* --------------- VALIDATE PTR --------------- */
if (paddr_ip_ascii == (CPU_CHAR *)0) {
*perr = NET_ASCII_ERR_NULL_PTR;
return (NET_IP_ADDR_NONE);
}
pchar_cur = (CPU_CHAR *)paddr_ip_ascii;
pchar_prev = (CPU_CHAR *)0;
addr_ip = NET_IP_ADDR_NONE;
addr_octet_val = 0x0000;
addr_nbr_octet = 0;
addr_nbr_octet_dig = 0;
while ((pchar_cur != (CPU_CHAR *)0) && /* Parse ALL non-NULL chars in ASCII str. */
(*pchar_cur != (CPU_CHAR )0)) {
switch (*pchar_cur) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
addr_nbr_octet_dig++; /* If nbr digs > max (see Note #2d), ... */
if (addr_nbr_octet_dig > NET_ASCII_CHAR_MAX_OCTET_ADDR_IP) {
*perr = NET_ASCII_ERR_INVALID_CHAR_LEN; /* ... rtn err. */
return (NET_IP_ADDR_NONE);
}
/* Convert & merge ASCII char into decimal val. */
addr_octet_val *= (CPU_INT16U)10;
addr_octet_val += (CPU_INT16U)(*pchar_cur - '0');
if (addr_octet_val > NET_ASCII_VAL_MAX_OCTET_ADDR_IP) {/* If octet val > max (see Note #2c), ... */
*perr = NET_ASCII_ERR_INVALID_CHAR_VAL; /* ... rtn err. */
return (NET_IP_ADDR_NONE);
}
break;
case '.':
if (pchar_prev == (CPU_CHAR *)0) { /* If NO prev char (see Note #2b2), ... */
*perr = NET_ASCII_ERR_INVALID_CHAR_SEQ; /* ... rtn err. */
return (NET_IP_ADDR_NONE);
}
if (*pchar_prev == (CPU_CHAR)'.') { /* If prev char a dot (see Note #2b2), ... */
*perr = NET_ASCII_ERR_INVALID_CHAR_SEQ; /* ... rtn err. */
return (NET_IP_ADDR_NONE);
}
addr_nbr_octet++;
if (addr_nbr_octet >= NET_ASCII_NBR_OCTET_ADDR_IP) { /* If nbr octets > max (see Note #2b1), ... */
*perr = NET_ASCII_ERR_INVALID_LEN; /* ... rtn err. */
return (NET_IP_ADDR_NONE);
}
/* Merge decimal octet val into IP addr. */
addr_ip <<= DEF_OCTET_NBR_BITS;
addr_ip += (CPU_INT08U)addr_octet_val;
addr_octet_val = 0x0000;
addr_nbr_octet_dig = 0;
break;
default: /* See Note #2a. */
*perr = NET_ASCII_ERR_INVALID_CHAR;
return (NET_IP_ADDR_NONE); /* Prevent 'break NOT reachable' warning. */
}
pchar_prev = pchar_cur;
pchar_cur++;
}
/*$PAGE*/
if (pchar_cur == (CPU_CHAR *)0) { /* If ANY NULL ptr in ASCII str, .. */
*perr = NET_ASCII_ERR_NULL_PTR; /* .. rtn err. */
return (NET_IP_ADDR_NONE);
}
if (*pchar_prev == (CPU_CHAR)'.') { /* If last char a dot (see Note #2b2), .. */
*perr = NET_ASCII_ERR_INVALID_CHAR_SEQ; /* .. rtn err. */
return (NET_IP_ADDR_NONE);
}
addr_nbr_octet++;
if (addr_nbr_octet != NET_ASCII_NBR_OCTET_ADDR_IP) { /* If != nbr IP addr octets (see Note #2b1), .. */
*perr = NET_ASCII_ERR_INVALID_LEN; /* .. rtn err. */
return (NET_IP_ADDR_NONE);
}
/* Merge decimal octet val into final IP addr. */
addr_ip <<= DEF_OCTET_NBR_BITS;
addr_ip += (CPU_INT08U)addr_octet_val;
*perr = NET_ASCII_ERR_NONE;
return (addr_ip);
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetASCII_IP_to_Str()
*
* Description : Convert a network protocol IPv4 address in host-order into a dotted-decimal notation ASCII
* string.
*
* Argument(s) : addr_ip IPv4 address.
*
* paddr_ip_ascii Pointer to an ASCII character array that will receive the return ASCII
* string from this function (see Note #2).
*
* lead_zeros Prepend leading zeros option (see Note #3) :
*
* DEF_NO Do NOT prepend leading zeros to each decimal octet value.
* DEF_YES Prepend leading zeros to each decimal octet value.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_ASCII_ERR_NONE ASCII string successfully formatted.
* NET_ASCII_ERR_NULL_PTR Argument 'paddr_ip_ascii' passed a
* NULL pointer.
* NET_ASCII_ERR_INVALID_CHAR_LEN Invalid ASCII character length.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* This function is a network protocol suite application interface (API) function & MAY be
* called by application function(s).
*
* Note(s) : (1) RFC #1983 states that "dotted decimal notation ... refers [to] IP addresses of the
* form A.B.C.D; where each letter represents, in decimal, one byte of a four byte IP
* address".
*
* In other words, the dotted-decimal notation separates four decimal octet values by
* the dot, or period, character ('.'). Each decimal value represents one octet of
* the IP address starting with the most significant octet in network order.
*
* IP Address Examples :
*
* DOTTED DECIMAL NOTATION HEXADECIMAL EQUIVALENT
*
* 127.0.0.1 = 0x7F000001
* 192.168.1.64 = 0xC0A80140
* 255.255.255.0 = 0xFFFFFF00
* --- - -- --
* ^ ^ ^ ^
* | | | |
* MSO LSO MSO LSO
*
* where
*
* MSO Most Significant Octet in Dotted Decimal IP Address
* LSO Least Significant Octet in Dotted Decimal IP Address
*
*
* (2) The size of the ASCII character array that will receive the return ASCII string MUST
* be greater than or equal to NET_ASCII_LEN_MAX_ADDR_IP.
*
* (3) (a) Leading zeros option prepends leading '0's prior to the first non-zero digit
* in each decimal octet value. The number of leading zeros is such that the
* decimal octet's number of decimal digits is equal to the maximum number of
* digits, NET_ASCII_CHAR_MAX_OCTET_ADDR_IP (3).
*
* (b) (1) If leading zeros option DISABLED ...
* (2) ... & the decimal value of the octet is zero; ...
* (3) ... then one digit of '0' value is formatted.
*
* This is NOT a leading zero; but a single decimal digit of '0' value.
*********************************************************************************************************
*/
/*$PAGE*/
void NetASCII_IP_to_Str (NET_IP_ADDR addr_ip,
CPU_CHAR *paddr_ip_ascii,
CPU_BOOLEAN lead_zeros,
NET_ERR *perr)
{
CPU_CHAR *pchar;
CPU_INT08U base_10_val_start;
CPU_INT08U base_10_val;
CPU_INT08U addr_octet_nbr_shifts;
CPU_INT08U addr_octet_val;
CPU_INT08U addr_octet_dig_nbr;
CPU_INT08U addr_octet_dig_val;
CPU_INT16U i;
/* --------------- VALIDATE PTR --------------- */
if (paddr_ip_ascii == (CPU_CHAR *)0) {
*perr = NET_ASCII_ERR_NULL_PTR;
return;
}
/* ------------ VALIDATE NBR CHAR ------------- */
#if ((NET_ASCII_CHAR_MAX_OCTET_ADDR_IP < NET_ASCII_CHAR_MIN_OCTET ) || \
(NET_ASCII_CHAR_MAX_OCTET_ADDR_IP > NET_ASCII_CHAR_MAX_OCTET_08))
*paddr_ip_ascii = (CPU_CHAR)0;
*perr = NET_ASCII_ERR_INVALID_CHAR_LEN;
return;
#endif
pchar = paddr_ip_ascii;
base_10_val_start = 1;
for (i = 1; i < NET_ASCII_CHAR_MAX_OCTET_ADDR_IP; i++) { /* Calc starting dig val. */
base_10_val_start *= 10;
}
for (i = NET_ASCII_NBR_OCTET_ADDR_IP; i > 0; i--) { /* Parse ALL addr octets. */
/* Calc cur addr octet val. */
addr_octet_nbr_shifts = (i - 1) * DEF_OCTET_NBR_BITS;
addr_octet_val = (CPU_INT08U)((addr_ip >> addr_octet_nbr_shifts) & DEF_OCTET_MASK);
base_10_val = base_10_val_start;
while (base_10_val > 0) { /* Parse ALL octet digs. */
addr_octet_dig_nbr = addr_octet_val / base_10_val;
if ((addr_octet_dig_nbr > 0) || /* If octet dig val > 0, .. */
(base_10_val == 1) || /* .. OR on least-significant octet dig, .. */
(lead_zeros == DEF_YES)) { /* .. OR lead zeros opt ENABLED (see Note #3), */
/* .. calc & insert octet val ASCII dig. */
addr_octet_dig_val = (CPU_INT08U)(addr_octet_dig_nbr % 10 );
*pchar++ = (CPU_CHAR )(addr_octet_dig_val + '0');
}
base_10_val /= 10; /* Shift to next least-significant octet dig. */
}
if (i > 1) { /* If NOT on last octet, append a dot char. */
*pchar++ = '.';
}
}
*pchar = (CPU_CHAR)0; /* Append NULL char. */
*perr = NET_ASCII_ERR_NONE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -