Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 解码字节流_Parsing_Decoder - Fatal编程技术网

Parsing 解码字节流

Parsing 解码字节流,parsing,decoder,Parsing,Decoder,我有一系列由独立结构定义的消息。这些结构共享在应用程序之间发送的公共头。我正在创建一个解码器,它将获取使用这些结构构建的消息中的原始数据捕获,并将它们解码/解析为一些纯文本 我有1000多条不同的消息需要解码,因此我不确定是否应该用XML定义所有结构格式,然后使用XSL或一些翻译,或者是否有更好的方法来实现这一点 有时我需要解码包含超过一百万条消息的日志,因此性能是一个问题 关于创建解码器/解析器的技术/工具/算法有什么建议吗 struct: struct { dword messageid

我有一系列由独立结构定义的消息。这些结构共享在应用程序之间发送的公共头。我正在创建一个解码器,它将获取使用这些结构构建的消息中的原始数据捕获,并将它们解码/解析为一些纯文本

我有1000多条不同的消息需要解码,因此我不确定是否应该用XML定义所有结构格式,然后使用XSL或一些翻译,或者是否有更好的方法来实现这一点

有时我需要解码包含超过一百万条消息的日志,因此性能是一个问题

关于创建解码器/解析器的技术/工具/算法有什么建议吗

struct:
struct {
  dword messageid;
  dword datavalue1;
  dword datavalue2;
} struct1;
原始数据示例:

0101010A0A0A0A0F0F0F0F
解码消息(所需输出):

我用C++做这个开发。

关于“性能”——如果你使用磁盘IO和可能的显示IO,我怀疑你的解析器/解码器将不会有什么效果,除非你使用一个真正可怕的算法。 我也不确定问题出在哪里-现在的问题是-一个结构中有3个DWORD,并且您声称基于这些值有1000多条唯一消息

您解码的消息并没有向我暗示您需要任何类型的解析-直接输出似乎可以工作(从字节转换为十六进制值的ascii表示)

如果您确实有一个从值到字符串的映射,那么大开关语句很简单——或者,如果您希望能够动态添加这些语句或更改显示,那么我将在配置文件(文本、xml等)中提供键/值对(映射),然后在读取日志文件/原始数据时进行查找

在这种情况下,我会使用地图


如果您提供了值和解码输出的另一个具体示例,我可能会提出一个更合适的建议。

如果您已经在示例中使用的语法中给出了消息定义,您绝对不应该尝试手动将其转换为其他语法(XML或其他)

相反,您应该尝试编写一个接受这些方法定义的编译器,并将它们编译成一个解码器函数


现在,建议使用ANTLR作为解析器生成器,使用任何一种ANTLR语言作为实际编译器(Java、Python、Ruby、C#、C++)。然后,编译器应该输出C代码,完成整个解码和漂亮的打印。

您可以使用yacc或antlr,添加适当的解析规则,在解析时从中填充一些数据结构(可能是树),然后遍历数据结构并执行任何您喜欢的操作。

我假设您所需要做的就是格式化记录并输出它们

使用自定义代码生成器。生成的代码如下所示:

typedef struct { word messageid; } Header;

//repeated for each record type
typedef struct {
    word messageid;
    // <members here>
} Record_##;
//END


void Process(Input inp, Output out) {
    char buffer[BIG_ENOUGH];
    char *offset;

    offset = &buffer[BIG_ENOUGH];

    while(notEnd) {
        if(&offset[sizeof(LargestStruct)] >= &buffer[BIG_ENOUGH])
            // move remaining buffer to start and fill tail from inp

        Header *hpt = (Header*)offset;

        switch(hpt->messageid)
        {
            //repeated for each record type
            case <recond ID for given type>: 
            {
                Record_##* rpt = (Record_##*)offset;
                outp.format("name1: %t, ...\n", rpt->name1, ...);
                offset += sizeof(Record_##);
                break;
            }
            //END
        }
    }
}
typedef结构{word messageid;}头;
//对每种记录类型重复
类型定义结构{
单词messageid;
// 
}记录;
//结束
无效处理(输入输入,输出){
字符缓冲区[足够大];
字符*偏移量;
偏移量=&缓冲区[足够大];
while(notEnd){
if(&offset[sizeof(LargestStruct)]>=&buffer[BIG_-ough])
//将剩余缓冲区移动到起始位置,并从inp填充尾部
页眉*hpt=(页眉*)偏移量;
开关(hpt->messageid)
{
//对每种记录类型重复
案例:
{
记录###*rpt=(记录###*)偏移量;
输出格式(“名称1:%t,…\n”,rpt->name1,…);
偏移量+=sizeof(记录);
打破
}
//结束
}
}
}
大部分是锅炉板,所以编写一个程序来生成它应该不难

如果你需要更多的处理,我认为这个想法可以调整一些,使之工作以及


编辑:重读问题后,您可能已经定义了结构。在这种情况下,您可以将它们包括在内并直接使用。然而,接下来的问题是如何解析结构以生成格式化函数的输入。Awk或sed可能很方便

typedef struct { word messageid; } Header;

//repeated for each record type
typedef struct {
    word messageid;
    // <members here>
} Record_##;
//END


void Process(Input inp, Output out) {
    char buffer[BIG_ENOUGH];
    char *offset;

    offset = &buffer[BIG_ENOUGH];

    while(notEnd) {
        if(&offset[sizeof(LargestStruct)] >= &buffer[BIG_ENOUGH])
            // move remaining buffer to start and fill tail from inp

        Header *hpt = (Header*)offset;

        switch(hpt->messageid)
        {
            //repeated for each record type
            case <recond ID for given type>: 
            {
                Record_##* rpt = (Record_##*)offset;
                outp.format("name1: %t, ...\n", rpt->name1, ...);
                offset += sizeof(Record_##);
                break;
            }
            //END
        }
    }
}