2
0
forked from Ivasoft/DSView

More flexible conversion of numeric formats

This commit is contained in:
dreamsourcelabTAI
2022-01-10 17:47:27 +08:00
parent d2bab86a8f
commit be2514f009
333 changed files with 489 additions and 274 deletions

View File

@@ -21,36 +21,169 @@
#include "AnnotationResTable.h"
#include <assert.h>
#include "../../dsvdef.h"
#define DECODER_MAX_DATA_BLOCK_LEN 25
#define FORMAT_TMP_BUFFER_SIZE 100
const char g_bin_cvt_table[] = "0000000100100011010001010110011110001001101010111100110111101111";
char g_bin_format_tmp_buffer[FORMAT_TMP_BUFFER_SIZE + 3];
char g_oct_format_tmp_buffer[FORMAT_TMP_BUFFER_SIZE + 6];
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
AnnotationResTable::AnnotationResTable(){
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;
}
AnnotationResTable::~AnnotationResTable(){
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, AnnotationStringList *&ls)
int AnnotationResTable::MakeIndex(const std::string &key, AnnotationSourceItem* &newItem)
{
auto fd =m_indexs.find(key);
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_numerical = false;
newItem = item;
int dex = m_indexs.size();
m_indexs[key] = dex;
//make a new string vector
m_resourceTable.push_back(AnnotationStringList());
ls = &m_resourceTable[dex];
return dex;
}
const AnnotationStringList& AnnotationResTable::GetString(int index){
int num = m_resourceTable.size();
assert(index >= 0 && index < num);
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 + FORMAT_TMP_BUFFER_SIZE;
*(buf + 1) = 0; //set the end flag
*buf = 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;
}
return data;
}

View File

@@ -26,23 +26,27 @@
#include <vector>
#include <QString>
typedef std::vector<QString> AnnotationStringList;
struct AnnotationSourceItem
{
bool is_numerical;
char str_number_hex[18]; //numerical value hex format string
std::vector<QString> src_lines; //the origin source string lines
std::vector<QString> cvt_lines; //the converted to bin/hex/oct format string lines
int cur_display_format; //current format as bin/ex/oct..., init with -1
};
class AnnotationResTable{
class AnnotationResTable
{
public:
AnnotationResTable();
int MakeIndex(const std::string &key, AnnotationSourceItem* &newItem);
AnnotationSourceItem* GetItem(int index);
~AnnotationResTable();
inline int GetCount(){
return m_resourceTable.size();}
int MakeIndex(const std::string &key, AnnotationStringList *&ls);
const AnnotationStringList& GetString(int index);
inline int GetCount(){return m_resourceTable.size();}
static const char* format_numberic(const char *hex_str, int fmt);
private:
std::map<std::string, int> m_indexs;
std::vector<AnnotationStringList> m_resourceTable;
std::map<std::string, int> m_indexs;
std::vector<AnnotationSourceItem*> m_resourceTable;
};

View File

@@ -32,134 +32,84 @@
#include "../../config/appconfig.h"
#include "decoderstatus.h"
#include "../../dsvdef.h"
//a find talbe instance
AnnotationResTable annTable;
char sz_format_tmp_buf[50];
#define DECODER_MAX_DATA_BLOCK_LEN 300
#define FORMAT_TMP_BUFFER_SIZE 1200
bool is_hex_number_str(const char *str)
{
char c = *str;
const char g_bin_cvt_table[] = "0000000100100011010001010110011110001001101010111100110111101111";
char g_bin_format_tmp_buffer[FORMAT_TMP_BUFFER_SIZE + 3];
char g_oct_format_tmp_buffer[FORMAT_TMP_BUFFER_SIZE + 6];
std::vector<QString> g_format_ret_vector;
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)
while (c)
{
if (*rd == '1')
{
bv = 1 << dex;
value += bv;
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')){
c = *str;
str++;
continue;
}
rd--;
++dex;
return false;
}
return value;
return true;
}
namespace pv {
namespace data {
namespace decode {
//a find talbe instance
AnnotationResTable *Annotation::m_resTable = new AnnotationResTable();
Annotation::Annotation(const srd_proto_data *const pdata, DecoderStatus *status) :
_start_sample(pdata->start_sample),
_end_sample(pdata->end_sample)
Annotation::Annotation(const srd_proto_data *const pdata, DecoderStatus *status)
{
assert(pdata);
const srd_proto_data_annotation *const pda =
(const srd_proto_data_annotation*)pdata->data;
assert(pda);
_format = pda->ann_class;
_type = pda->ann_type;
_status = status;
//have numerical
if (_type >= 100 && _type < 200){
status->m_bNumerical = true;
}
_strIndex = 0;
std::string key;
_start_sample = pdata->start_sample;
_end_sample = pdata->end_sample;
_format = pda->ann_class;
_type = pda->ann_type;
_resIndex = 0;
_status = status;
//make resource find key
const char *const *annotations = (char**)pda->ann_text;
while(*annotations) {
const char *ptr = *annotations;
key.append(ptr, strlen(ptr));
std::string key;
char **annotations = pda->ann_text;
while(annotations && *annotations) {
key.append(*annotations, strlen(*annotations));
annotations++;
}
AnnotationStringList *annotationArray = NULL;
_strIndex = Annotation::m_resTable->MakeIndex(key, annotationArray);
if (pda->str_number_hex[0]){
//append numeric string
key.append(pda->str_number_hex, strlen(pda->str_number_hex));
}
AnnotationSourceItem *resItem = NULL;
_resIndex = annTable.MakeIndex(key, resItem);
//save new string lines
if (annotationArray){
annotations = (char **)pda->ann_text;
while (*annotations)
{
annotationArray->push_back(QString::fromUtf8(*annotations));
annotations++;
//is a new item
if (resItem != NULL){
char **annotations = pda->ann_text;
while(annotations && *annotations) {
resItem->src_lines.push_back(QString::fromUtf8(*annotations));
annotations++;
}
}
//get numerical data
if (pda->str_number_hex[0]){
strcpy(resItem->str_number_hex, pda->str_number_hex);
resItem->is_numerical = true;
}
else if (resItem->src_lines.size() == 1 && _type >= 100 && _type < 200){
if (is_hex_number_str(resItem->src_lines[0].toLatin1().data())){
resItem->is_numerical = true;
}
}
_status->m_bNumerical |= resItem->is_numerical;
}
}
Annotation::Annotation()
@@ -172,93 +122,52 @@ Annotation::~Annotation()
{
}
const std::vector<QString>& Annotation::annotations() const
{
assert(_status);
int fmt = _status->m_format;
const std::vector<QString>& vct = Annotation::m_resTable->GetString(_strIndex);
if (!(_type >= 100 && _type < 200) || fmt == DecoderDataFormat::ascii || fmt == DecoderDataFormat::hex){
return vct;
AnnotationSourceItem &resItem = *annTable.GetItem(_resIndex);
//get origin data, is not a numberical value
if (!resItem.is_numerical){
return resItem.src_lines;
}
if (vct.size() != 1){
return vct;
if (resItem.cur_display_format != _status->m_format){
resItem.cur_display_format = _status->m_format;
resItem.cvt_lines.clear();
if (resItem.src_lines.size() > 0)
{
for (QString &rd_src : resItem.src_lines)
{
if (resItem.str_number_hex[0] != 0)
{
QString src = rd_src.replace("{$}", "%s");
const char *num_str = AnnotationResTable::format_numberic(resItem.str_number_hex, resItem.cur_display_format);
sprintf(sz_format_tmp_buf, src.toLatin1().data(), num_str);
resItem.cvt_lines.push_back(QString(sz_format_tmp_buf));
}
else
{
const char *src_str = rd_src.toLatin1().data();
const char *num_str = AnnotationResTable::format_numberic(src_str, resItem.cur_display_format);
if (src_str != num_str)
resItem.cvt_lines.push_back(QString(num_str));
else
resItem.cvt_lines.push_back(QString(rd_src));
}
}
}
else{
const char *num_str = AnnotationResTable::format_numberic(resItem.str_number_hex, resItem.cur_display_format);
resItem.cvt_lines.push_back(QString(num_str));
}
}
//flow, convert to oct\dec\bin format
const char *data = vct[0].toStdString().c_str();
if (*data == 0 || *data == '['){
return vct;
}
//convert to bin format
char *buf = g_bin_format_tmp_buffer + FORMAT_TMP_BUFFER_SIZE;
*(buf + 1) = 0; //set the end flag
*buf = 0;
int len = strlen(data);
//buffer is not enough
if (len > DECODER_MAX_DATA_BLOCK_LEN){
return vct;
}
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--;
}
std::vector<QString> &vct2 = g_format_ret_vector;
if (vct2.size() == 0){
vct2.push_back(QString());
}
//get bin format
if (fmt == DecoderDataFormat::bin){
vct2[0].clear();
vct2[0].append(buf);
return vct2;
}
//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);
vct2[0].clear();
vct2[0].append(oct_buf);
return vct2;
}
//64 bit integer
if (fmt == DecoderDataFormat::dec && len * 4 <= 64){
long long lv = bin2long_string(buf, len *4);
char vbuf[30] = {0};
sprintf(vbuf, "%lld", lv);
vct2[0].clear();
vct2[0].append(vbuf);
return vct2;
}
return vct2;
}
return resItem.cvt_lines;
}
} // namespace decode

View File

@@ -66,14 +66,12 @@ public:
const std::vector<QString>& annotations() const;
private:
uint64_t _start_sample;
uint64_t _end_sample;
short _format;
short _type; //100-199: is a numerical value type,can show hex/oct format
short _strIndex;
DecoderStatus *_status;
static AnnotationResTable * m_resTable;
uint64_t _start_sample;
uint64_t _end_sample;
short _format;
short _type;
short _resIndex;
DecoderStatus *_status; /*a global variable*/
};
} // namespace decode

View File

@@ -127,9 +127,7 @@ srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session)
GHashTable *const probes = g_hash_table_new_full(g_str_hash,
g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
for(std::map<const srd_channel*, int>::
const_iterator i = _probes.begin();
i != _probes.end(); i++)
for(auto i = _probes.begin(); i != _probes.end(); i++)
{
GVariant *const gvar = g_variant_new_int32((*i).second);
g_variant_ref_sink(gvar);

View File

@@ -463,6 +463,8 @@ void DecoderStack::decode_data(const uint64_t decode_start, const uint64_t decod
{
decode_task_status *status = _stask_stauts;
// qDebug()<<"decode start:"<<decode_start<<", decode end:"<<decode_end;
//uint8_t *chunk = NULL;
uint64_t last_cnt = 0;
uint64_t notify_cnt = (decode_end - decode_start + 1)/100;
@@ -530,6 +532,7 @@ void DecoderStack::decode_data(const uint64_t decode_start, const uint64_t decod
i = chunk_end;
//use mutex
{
std::lock_guard<std::mutex> lock(_output_mutex);
_samples_decoded = i - decode_start + 1;

View File

@@ -484,6 +484,8 @@ void ProtocolDock::item_clicked(const QModelIndex &index)
decoder_stack->set_mark_index((ann.start_sample()+ann.end_sample())/2);
_session->show_region(ann.start_sample(), ann.end_sample(), false);
// qDebug()<<ann.annotations().at(0)<<"type:"<<ann.type();
}
}
_table_view->resizeRowToContents(index.row());
@@ -652,31 +654,44 @@ void ProtocolDock::search_nxt()
_cur_search_index = -1;
return;
}
int i = 0;
uint64_t rowCount = _model_proxy.rowCount();
QModelIndex matchingIndex;
pv::data::DecoderModel *decoder_model = _session->get_decoder_model();
auto decoder_stack = decoder_model->getDecoderStack();
if (decoder_stack == NULL){
qDebug()<<"decoder_stack is null";
return;
}
auto decoder_stack = decoder_model->getDecoderStack();
do {
_cur_search_index++;
if (_cur_search_index < 0 || _cur_search_index >= _model_proxy.rowCount())
_cur_search_index = 0;
matchingIndex = _model_proxy.mapToSource(_model_proxy.index(floor(_cur_search_index),_model_proxy.filterKeyColumn()));
if (!decoder_stack || !matchingIndex.isValid())
if (!matchingIndex.isValid())
break;
// qDebug()<<"row:"<<matchingIndex.row();
i = 1;
uint64_t row = matchingIndex.row() + 1;
uint64_t col = matchingIndex.column();
pv::data::decode::Annotation ann;
bool ann_valid;
while(i < _str_list.size()) {
QString nxt = _str_list.at(i);
do {
ann_valid = decoder_stack->list_annotation(ann, col, row);
row++;
}while(ann_valid && (ann.type() < 100 || ann.type() > 999));
auto strlist = ann.annotations();
QString source = ann.annotations().at(0);
if (ann_valid && source.contains(nxt))
i++;
@@ -748,7 +763,6 @@ void ProtocolDock::search_update()
search_done();
}
_search_edited = false;
//search_done();
}
//-------------------IProtocolItemLayerCallback

View File

@@ -117,7 +117,7 @@ private:
SigSession *_session;
view::View &_view;
QSortFilterProxyModel _model_proxy;
double _cur_search_index;
int _cur_search_index;
QStringList _str_list;
QSplitter *_split_widget;

View File

@@ -120,20 +120,14 @@ void ProtocolItemLayer::LoadFormatSelect(bool bSingle)
m_singleFlag = bSingle;
m_bSetting = true;
_format_combox->clear();
_format_combox->addItem("ascii");
int dex = 0;
_format_combox->clear();
if (!bSingle)
{
_format_combox->addItem("dec");
_format_combox->addItem("hex");
_format_combox->addItem("oct");
_format_combox->addItem("bin");
dex = 2;
}
_format_combox->addItem("hex");
_format_combox->addItem("dec");
_format_combox->addItem("oct");
_format_combox->addItem("bin");
_format_combox->setCurrentIndex(dex);
_format_combox->setCurrentIndex(0);
m_bSetting = false;
}

View File

@@ -41,9 +41,6 @@
namespace DecoderDataFormat
{
int Parse(const char *name){
if (strcmp(name, "ascii") == 0){
return (int)ascii;
}
if (strcmp(name, "dec") == 0){
return (int)dec;
}
@@ -56,7 +53,7 @@ namespace DecoderDataFormat
if (strcmp(name, "bin") == 0){
return (int)bin;
}
return (int)ascii;
return (int)hex;
}
}

View File

@@ -49,9 +49,8 @@ namespace DecoderDataFormat
{
enum _data_format
{
ascii = 0,
dec,
hex,
dec,
oct,
bin
};