-// Returns a pointer to an English language string describing the given result code.
-// If the result code is not a valid member of the Result_t enum, the string
-// "**UNKNOWN**" will be returned.
-const char*
-ASDCP::GetResultString(Result_t result)
-{
- if ( result >= 0 )
- return "No error.";
-
- ui32_t idx = (- result);
-
- if ( idx > s_MessageCount )
- return "**UNKNOWN**";
-
- return s_ErrorMessages[--idx];
-}
-
-
-// convert utf-8 hext string to bin
-i32_t
-ASDCP::hex2bin(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* conv_size)
-{
- ASDCP_TEST_NULL(str);
- ASDCP_TEST_NULL(buf);
- ASDCP_TEST_NULL(conv_size);
-
- *conv_size = 0;
-
- if ( str[0] == 0 ) // nothing to convert
- return 0;
-
- for ( int j = 0; str[j]; j++ )
- {
- if ( isxdigit(str[j]) )
- (*conv_size)++;
- }
-
- if ( *conv_size & 0x01 ) (*conv_size)++;
- *conv_size /= 2;
-
- if ( *conv_size > buf_len )// maximum possible data size
- return -1;
-
- *conv_size = 0;
-
- int phase = 0; // track high/low nybble
-
- // for each character, fill in the high nybble then the low
- for ( int i = 0; str[i]; i++ )
- {
- if ( ! isxdigit(str[i]) )
- continue;
-
- byte_t val = str[i] - ( isdigit(str[i]) ? 0x30 : ( isupper(str[i]) ? 0x37 : 0x57 ) );
-
- if ( phase == 0 )
- {
- buf[*conv_size] = val << 4;
- phase++;
- }
- else
- {
- buf[*conv_size] |= val;
- phase = 0;
- (*conv_size)++;
- }
- }
-
- return 0;
-}
-
-
-// convert a memory region to a NULL-terminated hexadecimal string
-//
-const char*
-ASDCP::bin2hex(const byte_t* bin_buf, ui32_t bin_len, char* str_buf, ui32_t str_len)
-{
- if ( bin_buf == 0
- || str_buf == 0
- || ((bin_len * 2) + 1) > str_len )
- return 0;
-
- char* p = str_buf;
-
- for ( ui32_t i = 0; i < bin_len; i++ )
- {
- *p = (bin_buf[i] >> 4) & 0x0f;
- *p += *p < 10 ? 0x30 : 0x61 - 10;
- p++;
-
- *p = bin_buf[i] & 0x0f;
- *p += *p < 10 ? 0x30 : 0x61 - 10;
- p++;
- }
-
- *p = '\0';
- return str_buf;
-}
-
-
-// spew a range of bin data as hex
-void
-ASDCP::hexdump(const byte_t* buf, ui32_t dump_len, FILE* stream)
-{
- if ( buf == 0 )
- return;
-
- if ( stream == 0 )
- stream = stderr;
-
- static ui32_t row_len = 16;
- const byte_t* p = buf;
- const byte_t* end_p = p + dump_len;
-
- for ( ui32_t line = 0; p < end_p; line++ )
- {
- fprintf(stream, " %06x: ", line);
- ui32_t i;
- const byte_t* pp;
-
- for ( pp = p, i = 0; i < row_len && pp < end_p; i++, pp++ )
- fprintf(stream, "%02x ", *pp);
-
- while ( i++ < row_len )
- fputs(" ", stream);
-
- for ( pp = p, i = 0; i < row_len && pp < end_p; i++, pp++ )
- fputc((isprint(*pp) ? *pp : '.'), stream);
-
- fputc('\n', stream);
- p += row_len;
- }
-}
-
-//------------------------------------------------------------------------------------------
-
-// read a ber value from the buffer and compare with test value.
-// Advances buffer to first character after BER value.
-//
-bool
-ASDCP::read_test_BER(byte_t **buf, ui64_t test_value)
-{
- if ( buf == 0 )
- return false;
-
- if ( ( **buf & 0x80 ) == 0 )
- return false;
-
- ui64_t val = 0;
- ui8_t ber_size = ( **buf & 0x0f ) + 1;
-
- if ( ber_size > 9 )
- return false;
-
- for ( ui8_t i = 1; i < ber_size; i++ )
- {
- if ( (*buf)[i] > 0 )
- val |= (ui64_t)((*buf)[i]) << ( ( ( ber_size - 1 ) - i ) * 8 );
- }
-
- *buf += ber_size;
- return ( val == test_value );
-}
-
-
-//
-bool
-ASDCP::read_BER(const byte_t* buf, ui64_t* val)
-{
- ui8_t ber_size, i;
-
- if ( buf == 0 || val == 0 )
- return false;
-
- if ( ( *buf & 0x80 ) == 0 )
- return false;
-
- *val = 0;
- ber_size = ( *buf & 0x0f ) + 1;
-
- if ( ber_size > 9 )
- return false;
-
- for ( i = 1; i < ber_size; i++ )
- {
- if ( buf[i] > 0 )
- *val |= (ui64_t)buf[i] << ( ( ( ber_size - 1 ) - i ) * 8 );
- }
-
- return true;
-}
-
-
-static const ui64_t ber_masks[9] =
- { ui64_C(0xffffffffffffffff), ui64_C(0xffffffffffffff00),
- ui64_C(0xffffffffffff0000), ui64_C(0xffffffffff000000),
- ui64_C(0xffffffff00000000), ui64_C(0xffffff0000000000),
- ui64_C(0xffff000000000000), ui64_C(0xff00000000000000),
- 0
- };
-
-
-//
-bool
-ASDCP::write_BER(byte_t* buf, ui64_t val, ui32_t ber_len)
-{
- if ( buf == 0 )
- return false;
-
- if ( ber_len == 0 )
- { // calculate default length
- if ( val < 0x01000000L )
- ber_len = 4;
- else if ( val < ui64_C(0x0100000000000000) )
- ber_len = 8;
- else
- ber_len = 9;
- }
- else
- { // sanity check BER length
- if ( ber_len > 9 )
- {
- DefaultLogSink().Error("BER size %lu exceeds maximum size of 9\n", ber_len);
- return false;
- }
-
- if ( val & ber_masks[ber_len - 1] )
- {
- char intbuf[IntBufferLen];
- DefaultLogSink().Error("BER size %lu too small for value %s\n",
- ber_len, ui64sz(val, intbuf));
- return false;
- }
- }
-
- buf[0] = 0x80 + ( ber_len - 1 );
-
- for ( ui32_t i = ber_len - 1; i > 0; i-- )
- {
- buf[i] = (ui8_t)(val & 0xff);
- val >>= 8;
- }
-
- return true;
-}
-