📄 phb_utils.c
字号:
/*****************************************************************************
* FUNCTION
* istring_char_at
* DESCRIPTION
* Returns the `offset'th UCS2 character in `istr' according to its charset.
* PARAMETERS
* istr [IN] The istring
* offset [IN] Offset
* RETURNS
* The `offset'th character in `istr' according to its charset.
*****************************************************************************/
kal_uint16 istring_char_at(istring_type *istr, kal_uint8 offset)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
/* error, invalid offset */
if (offset >= istring_len(istr))
{
return (kal_uint16) PHB_UTILS_INVALID_VALUE;
}
if (get_0338_charset_bits(istr->charset) == CHARSET_ASCII)
{
return 0 << 8 | istr->data[offset];
}
else if (offset <= istring_len(istr))
{
return (istr->data[offset * 2] << 8 | istr->data[offset * 2 + 1]);
}
else
{
return (kal_uint16) PHB_UTILS_INVALID_VALUE;
}
} /* end of get_char_len */
/*****************************************************************************
* FUNCTION
* is_chars_equal
* DESCRIPTION
* Determines whether the two characters are equal. A ascii character is treated as equal
* if its corresponding UCS2 character is compared with.
* PARAMETERS
* char1 [IN] Character to compare
* char2 [IN] Character to compare
* RETURNS
* true if the two characters are equal, false else.
*****************************************************************************/
kal_bool is_chars_equal(kal_uint16 char1, kal_uint16 char2)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
/* try UCS2 matching */
if (char1 == char2)
{
return KAL_TRUE;
}
/* if not, try ASCII case-insensitive matching */
else if ((char1 < 0x007E) && (char2 < 0x007E))
{
if ((char1 <= 0x007b) && (char1 >= 0x0061))
{
char1 -= 0x20;
}
if ((char2 <= 0x007b) && (char2 >= 0x0061))
{
char2 -= 0x20;
}
if (char1 == char2)
{
return KAL_TRUE;
}
}
/* no match */
return KAL_FALSE;
}
/*****************************************************************************
* FUNCTION
* compare_chars
* DESCRIPTION
* Determines whether the two characters are equal. A ascii character is treated as equal
* if its corresponding UCS2 character is compared with.
* PARAMETERS
* char1 [IN] Character to compare
* char2 [IN] Character to compare
* RETURNS
* true if the two characters are equal, false else.
*****************************************************************************/
kal_int32 compare_chars(kal_uint16 char1, kal_uint16 char2)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
/* try UCS2 matching */
if (char1 == char2)
{
return 0;
}
/* if not, try ASCII case-insensitive matching */
else if ((char1 < 0x007E) && (char2 < 0x007E))
{
if ((char1 <= 0x007b) && (char1 >= 0x0061))
{
char1 -= 0x20;
}
if ((char2 <= 0x007b) && (char2 >= 0x0061))
{
char2 -= 0x20;
}
return char1 - char2;
}
/* no match */
/**
* Return value must be wide enough.
* If width is signed 16 bits,
* consider a char greater than 0x8000 minus 0x0000 could become
* negative number, which leads to char1 less than char2.
*/
return char1 - char2;
}
/*****************************************************************************
* FUNCTION
* bcd2string
* DESCRIPTION
* Converts BCD digits to character array representation.
* eg,
* from 0x123456
* to "123456"
* PARAMETERS
* length [IN] Length of `tel_number'
* tel_number [IN] Input BCD digits
* bcd_array [IN] Caller provided buffer where the converted BCD digits stored. Size should be 2 * (length of `tel_number') + 1. Null terminated string.
* RETURNS
* Total characters in bcd_array.
*****************************************************************************/
kal_uint16 bcd2string(kal_uint8 length, kal_uint8 *tel_number, char *bcd_array)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_uint8 i, j, k = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
for (i = 0, j = 0; i < length; ++i)
{
for (k = 0; k < 2; ++k)
{
char bcd;
bcd = (k == 0) ? (tel_number[i] >> 4) & 0x0F : tel_number[i] & 0x0F;
if (bcd > 0x0a)
{
bcd_array[k++] = bcd;
}
else
{
bcd_array[k++] = bcd | 0x30;
}
}
}
bcd_array[k] = '\0';
return k;
} /* end of bcd2string */
/*****************************************************************************
* FUNCTION
* bcd2char
* DESCRIPTION
* Converts a single BCD digit to character representation.
* eg,
* from 0x01
* to '1'
* PARAMETERS
* bcd [IN]
* tel_number(?) [IN] Input BCD digit
* RETURNS
* character.
*****************************************************************************/
kal_uint8 bcd2char(kal_uint8 bcd)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
return (bcd < 0x0A) ? bcd | 0x30 : bcd;
} /* end of bcd2char */
/*****************************************************************************
* FUNCTION
* get_next_bcd_digit
* DESCRIPTION
* Get next bcd digit in first byte of bcd_array.
*
* A typical usage:
*
* kal_uint16 offset;
* kal_bool flag = KAL_FALSE;
* kal_uint8 digit;
*
* while (offset < length of bcd_array) {
* offset = get_next_bcd_digit(bcd_array, offset, &flag, &digit);
* do_something_using_the_digit(digit);
* }
* PARAMETERS
* bcd_array [IN] Bcd_array
* offset [IN]
* is_first [IN] Get first digit in `bcd_byte' or second digit. This flag is a toggle. It will be toggled when returned.
* digit [OUT] The converted digit.
* RETURNS
* Next offset that contains the next BCD digit.
*****************************************************************************/
kal_uint16 get_next_bcd_digit(kal_uint8 *bcd_array, kal_uint16 offset, kal_bool *is_first, kal_uint8 *digit)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
/* Second BCD, more significant half */
if (*is_first == KAL_FALSE)
{
*digit = (bcd_array[offset] >> 4) & 0x0F;
*is_first = KAL_TRUE;
return ++offset;
}
/* First BCD, less significant half */
else
{
*digit = bcd_array[offset] & 0x0F;
*is_first = KAL_FALSE;
return offset;
}
} /* end of get_next_bcd_digit */
/*****************************************************************************
* FUNCTION
* compare_n_string_bcd
* DESCRIPTION
* Compare not more than `n' character or length of `istr', each character
* of which is 8-bits char, and digit in `bcd_array', each digit of which is
* a 4-bits BCD digit.
* PARAMETERS
* str [IN]
* bcd_array [IN] BCD digit array
* n [IN] Compare at most n elements.
* istr(?) [IN] Char array
* RETURNS
* An 8-bits integer greater than, equal to, or less than 0, according as istr is greater than,
* equal to, or less than bcd_array.
*****************************************************************************/
kal_int8 compare_n_string_bcd(char const *str, kal_uint8 *bcd_array, kal_uint16 n)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
unsigned char c1 = '\0';
unsigned char c2 = '\0';
kal_bool flag = KAL_TRUE;
kal_uint16 offset = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
while (n > 0)
{
c1 = (unsigned char)*str++;
offset = get_next_bcd_digit(bcd_array, offset, &flag, &c2);
c2 = bcd2char(c2);
if (c1 == '\0' || c1 != c2)
{
return c1 - c2;
}
n--;
}
return c1 - c2;
}
/*****************************************************************************
* FUNCTION
* compare_n_bcd
* DESCRIPTION
* Compare not more than `n' digits, or length of `first_bcd_array' (ie,
* number of digits before first 0xF is encountered), for `first_bcd_array'
* and `second_bcd_array', each digit is a 4-bits BCD digit.
* PARAMETERS
* first_bcd_array [?]
* second_bcd_array [?]
* n [IN] Compare at most n elements.
* bcd_array(?) [IN] BCD digit array
* istr(?) [IN] Char array
* RETURNS
* An 8-bits integer greater than, equal to, or less than 0, according as istr is greater than,
* equal to, or less than bcd_array.
*****************************************************************************/
kal_int8 compare_n_bcd(kal_uint8 *first_bcd_array, kal_uint8 *second_bcd_array, kal_uint16 n)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_uint8 c1 = 0;
kal_uint8 c2 = 0;
kal_bool first_flag = KAL_TRUE;
kal_uint16 first_offset = 0;
kal_bool second_flag = KAL_TRUE;
kal_uint16 second_offset = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
while (n > 0)
{
first_offset = get_next_bcd_digit(first_bcd_array, first_offset, &first_flag, &c1);
second_offset = get_next_bcd_digit(second_bcd_array, second_offset, &second_flag, &c2);
if (c1 == 0x0F || c1 != c2)
{
return c1 - c2;
}
n--;
}
return c1 - c2;
}
/*****************************************************************************
* FUNCTION
* bcd_len
* DESCRIPTION
* Calculate number of digits of 0xF terminated bcd_array.
* Scan not more than n bytes.
* PARAMETERS
* bcd_array [IN] BCD digit array
* n [IN] Compare at most n elements.
* RETURNS
* An 8-bits integer greater than, equal to, or less than 0, according as istr is greater than,
* equal to, or less than bcd_array.
*****************************************************************************/
kal_int16 bcd_len(kal_uint8 *bcd_array, kal_uint16 n)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_int16 len = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
for (len = 0; n > 0; --n)
{
if (phb_less_significant_nibble(*bcd_array) != 0x0F)
{
++len;
}
if (phb_more_significant_nibble(*bcd_array) != 0x0F)
{
++len;
}
++bcd_array;
}
return len;
}
/*****************************************************************************
* FUNCTION
* bcd_exact_len
* DESCRIPTION
* Calculate number of digits of 0xF terminated bcd_array.
* Scan not more than n bytes and stop until 0xF.
* PARAMETERS
* bcd_array [IN] BCD digit array
* n [IN] Compare at most n elements.
* RETURNS
* An 8-bits integer greater than, equal to, or less than 0, according as istr is greater than,
* equal to, or less than bcd_array.
*****************************************************************************/
kal_int16 bcd_exact_len(kal_uint8 *bcd_array, kal_uint16 n)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_int16 len = 0;
/*----------------------------------------------------------------*/
/* Code Body */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -