【问题标题】:Encode XER to Buffer with asn1c使用 asn1c 将 XER 编码为缓冲区
【发布时间】:2025-11-25 06:50:01
【问题描述】:

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

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

【问题讨论】:

    标签: asn.1


    【解决方案1】:

    我刚刚发现了它是如何完成的:asn1c 生成的 xer_encode() 函数接受一个回调,该回调获取一个 XER sn-p 及其大小(以字节为单位)以及一个用户数据指针。通过编写适当的回调,我们可以将 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;
    }
    

    【讨论】: