我有一系列由独立结构定义的消息。这些结构共享一个在应用程序之间发送的公共头。我正在创建一个解码器,它将使用这些结构构建的消息中的原始数据捕获并将它们解析/解析为一些纯文本。
我有超过1000条不同的消息需要解码,因此我不确定是否在XML中定义所有结构格式,然后使用XSL或某些翻译是可行的方法,或者是否有更好的方法来执行此操作。
有些时候我需要解码包含超过一百万条消息的日志,因此性能是一个问题。
有关创建解码器/解析器的技术/工具/算法的任何建议吗?
struct:
struct {
dword messageid;
dword datavalue1;
dword datavalue2;
} struct1;
示例原始数据:
0101010A0A0A0A0F0F0F0F
解码消息(所需输出):
message id: 0x01010101, datavalue1: 0x0A0A0A0A, datavalue2: 0x0F0F0F0F
我正在使用C ++进行此开发。
答案 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可能会派上用场。