解码字节流

时间:2008-12-16 16:57:14

标签: parsing decoder

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

我有超过1000条不同的消息需要解码,因此我不确定是否在XML中定义所有结构格式,然后使用XSL或某些翻译是可行的方法,或者是否有更好的方法来执行此操作。

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

有关创建解码器/解析器的技术/工具/算法的任何建议吗?

struct:
struct {
  dword messageid;
  dword datavalue1;
  dword datavalue2;
} struct1;

示例原始数据:

0101010A0A0A0A0F0F0F0F

解码消息(所需输出):

message id: 0x01010101, datavalue1: 0x0A0A0A0A, datavalue2: 0x0F0F0F0F

我正在使用C ++进行此开发。

4 个答案:

答案 0 :(得分:0)

关于“性能” - 如果你正在使用磁盘IO和可能的显示IO我怀疑你的解析器/解码器会有很大的影响,除非你使用一个真正可怕的算法。

我也不确定问题是什么 - 现在问题 - 你在一个结构中有3个DWORD,你声称有超过1000个基于这些值的唯一消息。

您的解码消息并不意味着您需要任何类型的解析 - 只需直接输出似乎可行(从字节转换为十六进制值的ascii表示)

如果你有一个从值到字符串的映射,那么一个大的switch语句很简单 - 或者如果你想能够动态添加这些语句或更改显示,那么我会提供键/值在配置文件(text,xml等)中配对(映射),然后在读取日志文件/原始数据时进行查找。

地图是我在那种情况下会使用的。

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

答案 1 :(得分:0)

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

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

目前,建议使用ANTLR作为解析器生成器,使用任何ANTLR语言进行实际编译(Java,Python,Ruby,C#,C ++)。那个编译器应该输出C代码,它完成整个解码和漂亮打印。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

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
        }
    }
}

大部分的锅炉板因此编写一个程序来生成它应该不会很难。

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


重新阅读问题后,

编辑:,看起来您可能已经定义了结构。在这种情况下,您只需#include他们并直接使用它们。但是,您最终会遇到如何解析结构以生成格式化函数输入的问题。 awk或sed可能会派上用场。