2
0
forked from Ivasoft/DSView
Files
DSView/DSView/pv/data/decode/AnnotationResTable.cpp

207 lines
4.9 KiB
C++

/*
* This file is part of the PulseView project.
*
* Copyright (C) 2013 Joel Holdsworth <joel@airwebreathe.org.uk>
* Copyright (C) 2014 DreamSourceLab <support@dreamsourcelab.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "AnnotationResTable.h"
#include <assert.h>
#include "../../dsvdef.h"
#define DECODER_MAX_DATA_BLOCK_LEN 25
const char g_bin_cvt_table[] = "0000000100100011010001010110011110001001101010111100110111101111";
char g_bin_format_tmp_buffer[DECODER_MAX_DATA_BLOCK_LEN * 4 + 2];
char g_oct_format_tmp_buffer[DECODER_MAX_DATA_BLOCK_LEN * 3 + 2];
char g_number_tmp_64[30];
char* bin2oct_string(char *buf, int size, const char *bin, int len){
char *wr = buf + size - 1;
*wr = 0; //end flag
char *rd = (char*)bin + len - 1; //move to last byte
char tmp[3];
while (rd >= bin && wr > buf)
{
wr--;
int num = 0;
while (rd >= bin && num < 3)
{
tmp[2-num] = *rd;
rd--;
num++;
}
//fill
while (num < 3)
{
tmp[2-num] = '0';
++num;
}
if (strncmp(tmp, "000", 3) == 0)
*wr = '0';
else if (strncmp(tmp, "001", 3) == 0)
*wr = '1';
else if (strncmp(tmp, "010", 3) == 0)
*wr = '2';
else if (strncmp(tmp, "011", 3) == 0)
*wr = '3';
else if (strncmp(tmp, "100", 3) == 0)
*wr = '4';
else if (strncmp(tmp, "101", 3) == 0)
*wr = '5';
else if (strncmp(tmp, "110", 3) == 0)
*wr = '6';
else if (strncmp(tmp, "111", 3) == 0)
*wr = '7';
}
return wr;
}
long long bin2long_string(const char *bin, int len)
{
char *rd = (char *)bin + len - 1; //move to last byte
int dex = 0;
long long value = 0;
long long bv = 0;
while (rd >= bin)
{
if (*rd == '1')
{
bv = 1 << dex;
value += bv;
}
rd--;
++dex;
}
return value;
}
int AnnotationResTable::MakeIndex(const std::string &key, AnnotationSourceItem* &newItem)
{
auto fd = m_indexs.find(key);
if (fd != m_indexs.end()){
return (*fd).second;
}
AnnotationSourceItem *item = new AnnotationSourceItem();
m_resourceTable.push_back(item);
item->cur_display_format = -1;
item->is_numeric = false;
newItem = item;
int dex = m_indexs.size();
m_indexs[key] = dex;
return dex;
}
AnnotationSourceItem* AnnotationResTable::GetItem(int index){
assert(index >= 0 && index < m_resourceTable.size());
return m_resourceTable[index];
}
const char* AnnotationResTable::format_numberic(const char *hex_str, int fmt)
{
assert(hex_str);
//flow, convert to oct\dec\bin format
const char *data = hex_str;
if (data[0] == 0 || fmt == DecoderDataFormat::hex){
return data;
}
//convert to bin format
char *buf = g_bin_format_tmp_buffer + sizeof(g_bin_format_tmp_buffer) - 2;
buf[1] = 0; //set the end flag
buf[0] = 0;
int len = strlen(data);
//buffer is not enough
if (len > DECODER_MAX_DATA_BLOCK_LEN){
return data;
}
char *rd = (char*)data + len - 1; //move to last byte
char c = 0;
int dex = 0;
while (rd >= data)
{
c = *rd;
dex = (int)(c <= '9' ? (c - '0') : (c - 'A' + 10));
char *ptable = (char*)g_bin_cvt_table + dex * 4;
buf -= 4; //move to left for 4 bytes
buf[0] = ptable[0];
buf[1] = ptable[1];
buf[2] = ptable[2];
buf[3] = ptable[3];
rd--;
}
//get bin format
if (fmt == DecoderDataFormat::bin){
return buf;
}
//get oct format
if (fmt == DecoderDataFormat::oct){
char *oct_buf = bin2oct_string(g_oct_format_tmp_buffer,
sizeof(g_oct_format_tmp_buffer), buf, len * 4);
return oct_buf;
}
//64 bit integer
if (fmt == DecoderDataFormat::dec && len * 4 <= 64){
long long lv = bin2long_string(buf, len * 4);
g_number_tmp_64[0] = 0;
sprintf(g_number_tmp_64, "%lld", lv);
return g_number_tmp_64;
}
//ascii
if (fmt == DecoderDataFormat::ascii && len < 30 - 3){
if (len == 2){
int lv = (int)bin2long_string(buf, len * 4);
//can display chars
if (lv >= 33 && lv <= 126){
sprintf(g_number_tmp_64, "%c", (char)lv);
return g_number_tmp_64;
}
}
char * const wr_buf = g_number_tmp_64;
g_number_tmp_64[0] = '[';
strcpy(g_number_tmp_64 + 1, data);
g_number_tmp_64[len+1] = ']';
g_number_tmp_64[len+2] = 0;
return g_number_tmp_64;
}
return data;
}