使用asn1c将XER编码为缓冲区

时间:2012-06-18 00:41:29

标签: asn.1

我使用asn1c对DER编码数据进行de /编码。这工作正常。但是,对于日志记录,能够以XER格式(类似XML)编写发送/接收的数据将是很好的。 asn1c生成的文件包含将XER编码数据写入FILE *的例程,例如stdout。但是,我想编码成一个缓冲区,以便我可以在打印之前处理数据。谁能告诉我怎么做?

我想要一个类似于encode_to_buffer()的接口,它编码DER数据中的结构。

1 个答案:

答案 0 :(得分:0)

我刚刚发现它是如何完成的:asn1c生成的xer_encode()函数接受一个回调,它获取一个XER片段及其大小(以字节为单位)以及一个userdata指针。通过编写适当的回调,我们可以将XER编码数据放在缓冲区中。

以下是我解决问题的方法。我实现了一个xer_buffer_t,它保存一个缓冲区,它的大小并跟踪缓冲区的填充程度,以便在必要时回调可以重新分配。

void init_xer_buffer(xer_buffer_t* xer_buffer) {
    xer_buffer->buffer = malloc(1024);
    assert(xer_buffer->buffer != NULL);
    xer_buffer->buffer_size = 1024;
    xer_buffer->buffer_filled = 0;
}

void free_xer_buffer(xer_buffer_t* xer_buffer) {
    free(xer_buffer->buffer);
    xer_buffer->buffer_size = 0;
    xer_buffer->buffer_filled = 0;
}

static int xer_print2xerbuf_cb(const void *buffer, size_t size, void *app_key) {
    xer_buffer_t* xb = (xer_buffer_t*) app_key;
    while (xb->buffer_size - xb->buffer_filled <= size+1) {
        xb->buffer_size *= 2;
        xb->buffer_size += 1;
        xb->buffer = realloc(xb->buffer, xb->buffer_size);
        assert(xb->buffer != NULL);
    }
    memcpy(xb->buffer+xb->buffer_filled, buffer, size);
    xb->buffer_filled += size;
    *(xb->buffer+xb->buffer_filled) = '\0';
    return 1;
}

int xer_encode_to_buffer(xer_buffer_t* xb, asn_TYPE_descriptor_t *td, void *sptr) {
    asn_enc_rval_t er;
    if (!td || !sptr) return -1;
    er = xer_encode(td, sptr, XER_F_BASIC, xer_print2xerbuf_cb, xb);
    if (er.encoded == -1) return -1;
    return 0;
}