c - 在 ANSI C 中表示 BER TLV 数据结构?

标签 c data-structures asn.1

昨天我了解到使用 TLV 表示信息格式。

如果您要用 ANSI C 编写可移植 BER TLV 编码器/解码器,您会使用什么数据结构 (*)?

像下面这样的事情会做吗?

struct TlvElement
{
    int nTag;
    int nLength;
    unsigned char *pValue; // Byte array
    TlvElement *pNext;
}; 

(*) 不幸的是我不能为此使用 C++ 和 STL。

最佳答案

来自维基文章:

The type and length are fixed in size (typically 1-4 bytes)

因此,我会将 nTagnLength 更改为某种固定长度的类型。 int 的大小是特定于平台的,这可能会给您带来一些麻烦。为您的协议(protocol)固定它们的大小并使用 int8_tint16_tint32_t 等。对于 nLength,您甚至可以使用无符号。


由于值可以是任何类型,我将使用 void* 作为 pValue,而不是 unsigned char*


你将如何使用这个数据结构?您希望如何访问不同的 TLV?
我的观点是 - 您需要链表吗?或者,对于您的案例/应用程序/用途/等,链表是否是最佳选项?

我想说的是,您可以删除 pNext 元素,只将 TLV 视为(动态增长的)数组的元素。这实际上取决于您的需求。

很可能,当您实现 TLV 时,您需要通过某种连接发送它们,对吗?如果是这样,您需要考虑一些协议(protocol)。我会做这样的事情——在一开始就发送 TLV 的总数,我不会使用链表,而是使用动态数组。
你应该小心通过网络发送这样的数据结构 - pNext 指针将无效,它们必须在连接的另一端重置。
您还需要小心发送数据,但我想您知道这些事情。我只是想提一下他们。


编辑 我发现您在理解嵌套 TLV 的含义时遇到一些问题。

嵌套的 TLV 只是一个 TLV 元素,它具有 TLV 类型的值。而这与 TLV 的“容器”——动态数组或链表无关。

这里有一个未经测试的例子,只是为了理解这个想法。我会这样做:

struct TLV
{
    uint32_t nTag;
    uint32_t nLength;
    void* pValue;
};

// created dynamic array with 3 TLVs:
TLV* pMyTLVs = malloc( 3 * sizeof( struct TLV ) );

// set the first 2 TLVs, some primitives, for example
// ..

// now, set the third TLV to be nested:
pMyTLVs[ 2 ].nTag = ...; // set some tag, that will indicate nested TLV
pMyTLVs[ 2 ].nLength = ...; // set length of the TLV element
pMyTLVs[ 2 ].pValue = malloc( sizeof( struct TLV ) );

// get pointer to the new, _nested_ TLV:
TLV* pNested = (TLV*)pMyTLVs[ 2 ].pValue; 

// now use the pNested TLV as an usual TLV:
pNested->nTag = ...;
pNested->nLength = ...;
pNested->pValue = ...;

// of course, pNested is not absolutely necessary, you may use directly
// pMyTLVs[ 2 ].pValue->...;
// but using pNested, makes the code more clear

注意:再说一次,这不是经过测试的代码,但我想您已经明白了。希望对您有所帮助。

关于c - 在 ANSI C 中表示 BER TLV 数据结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11913299/

相关文章:

algorithm - 具有 16 位元素的 10000 数组,查找位集(无限 RAM)- Google 访谈

encoding - 对 BER(基本编码规则)感到困惑

java - 通过socket将asn1数据从客户端发送到服务器

c - 从c程序中读取文件中的行得到错误的输出

c++ - 如何从 C 调用在 MATLAB 中创建并在 C 中编译的函数?

c - 从/到 OpenGL 模型 View 矩阵获取和设置 Pitch Yaw Roll

java - 实现 ASN.1 描述

c - C中数据文件的二维数组

c++ - 为什么代码创建错误的二叉搜索树

python - 如何在 Python 中使用变量作为数组索引?