发明内容
为解决现有技术的不足,本发明的目的在于提供一种能够不通过编译,直接将数据模型转化为ASN.1信息或将ASN.1信息转化为数据模型的根据ASN.1信息动态创建数据模型的方法。
本发明的又一目的在于提供一种减少模型占用的内存,使之能够应用于嵌入式系统,并提供方便、高效的检索方法的根据ASN.1信息动态创建数据模型的方法。
本发明的动态创建方法包括:
(1)直接读取ASN.1数据流,将ASN.1信息转换为数据模型,或将数据模型转换为ASN.1信息;
(2)采用多叉树表示数据模型,包括数据的名称、类型和数值,保持数据的层次关系和先后次序,提供目录检索和数据属性检索两种检索方法;
(3)数据采用池式存储方法,保存在一块线性内存区域中,根据数据的实际长度动态分配空间。
为了实现上述目的,本发明是采取以下的技术方案来实现的:
一种根据ASN.1信息动态创建数据模型的方法,包括:
(1)、建立内存池,在内存池的头部放置模型树,并初始化模型树;
(2)、读取ASN.1信息流,获得标签类型和数据长度;
(3)、根据标签类型调用不同的处理函数:
a)如果是SEQUENCE或ARRAY类型,表示后续的数据是一个序列或一个数组,跳过去继续分析后面的信息;
b)如果是STRUCT类型,表示紧接着的数据是一个结构体,每一个元素是结构体的一个成员,此时就在模型树中插入一个子节点,表示它是一个数据结构的根;
c)如果是简单类型,包括BOOL、INT、UINT、BITSTRING、FLOAT、VSTR、OCTSTR、BTIME、UTF8STR或UTCTIME,就在模型树中创建一个叶节点,所述的叶节点包括数据属性的名称、类型、长度和值;
(4)、继续读取、处理后面的ASN.1信息,直至信息流结束,得到一个完整的多叉树数据模型。
前述的根据ASN.1信息动态创建数据模型的方法,其特征在于还包括步骤(5):按顺序连接所有的叶节点,生成单向链表。
前述的根据ASN.1信息动态创建数据模型的方法,其特征在于所述的多叉树,其根表示主结构,每一个子节点表示一个子结构,叶节点表示数据属性;每一个子节点包括4个内容,分别是节点名称、父节点指针、兄弟节点指针和
子节点指针;从根结点开始,采用先根遍历的方式检索得到的数据是整个数据模型的目录,同时,所有数据属性之间以链表相连,采用遍历叶节点链表的方式检索得到的数据是所有的数据属性。
前述的根据ASN.1信息动态创建数据模型的方法,其特征在于所有节点都保存在事先分配好的一块线性内存中,每一个节点都是在使用时才根据实际需要的内存大小动态在线性内存中分配。
本发明的有益效果是:在本发明中,披露了将顺序的ASN.1信息流转换为使用多叉树表示的数据模型的方法。这种转换方法,不需要事先定义ASN.1源规范,也不需要编译ASN.1描述文件的过程,而是直接解析ASN.1信息流,根据获得的标签类型和数据长度,选择在模型树中插入一个子节点或一个叶节点。采用这种方式表示的数据模型可以很方便的体现出数据之间的层次结构,尤其适用于表示结构化的数据。
同时,本发明披露了在多叉树数据模型的基础上,增加一个叶节点链表的方法。通过这种方法可以提供目录检索和属性检索两种检索方式。采用先根遍历的方式进行目录检索,采用遍历叶节点链表的方式进行属性检索,可以快速得到所需数据。
另外,在本发明中还披露了使用内存池保存多叉树数据模型的方法。由于在建立多叉树数据模型的过程中,需要频繁申请内存,导致效率下降和内存浪费,如果用于嵌入式装置,这是一个很大的缺点。本方法中使用了一个简单的内存池来管理内存,由于建立多叉树数据模型的过程中,只有申请而不需要释放内存,所以采用了一种线性的内存池,对于每一个申请内存的请求,内存池在可用内存的头部划出一块区域返回给请求的函数,这块区域的大小是8的倍数,同时从可用内存中减去这一块区域。因为不需要考虑内存释放的问题,所以内存的申请只需要常数时间;同时,除了考虑到内存对齐浪费的几个字节外,内存的利用率已是最大。
具体实施方式
图2是本发明根据ASN.1信息动态创建数据模型的流程框图。下面是一个根据ASN.1信息动态创建数据模型的实施例。对于如下所示的一段ASN.1信息,(A2 54 A1 52 30 0C 80 06 73 75 62 45 6E 61 A1 02 83 00 30 27 80 06 7375 62 4D 61 67 A1 1D A2 1B A1 19 30 08 80 01 69 A1 03 85 01 20 30 0D 8001 66 A1 08 A7 06 02 01 20 02 01 08 30 0B 80 04 73 75 62 51 A1 03 84 01F3 30 0C 80 05 73 75 62 49 44 A1 03 8A 01 0C)
首先建立一个内存池mbuf,图中步骤①,在mbuf的头部放置模型树mtree,调用mtree_init初始化模型树,图中步骤②。
然后开始读取ASN.1信息流,图中步骤③,调用decode_head获得标签类型tag_type和数据长度data_len,图中步骤④。如果tag_type等于SEQUENCE或ARRAY类型,则跳过data_len长度的信息继续分析后面的数据;如果tag_type等于STRUCT类型,则调用mtree_insert_child在模型树中插入一个子节点,图中步骤⑤;如果tag_type等于BOOL、INT、UINT、BITSTRING、FLOAT、VSTR、OCTSTR、BTIME、UTF8STR和UTCTIME类型,则调用decode_data得到具体的数值,同时调用mtree_insert_child在模型树中创建一个叶节点,图中步骤⑥。此叶节点就是一个AcsiVar数据结构,其中包含了数据属性的名称、类型、长度和值。
接着继续读取后面的ASN.1信息,直到信息流结束,就可以得到一个完整的多叉树。
最后按顺序连接所有的叶节点,生成一个单向链表,图中步骤⑦。
模型树mtree的所有节点都是根据所需大小调用mbuf_alloc动态分配的。对于最后生成的模型树,如果采用先根遍历的方式,就可以按照根-子节点-数据属性的顺序列出所有数据的目录。此外,通过遍历叶节点链表,可以快速得到所有的数据属性。
上述实施例不以任何形式限制本发明,凡采取等同替换或等效变换的方式所获得的技术方案,均落在本发明的保护范围内。