2017-04-21 122 views
1

我使用以下代码解码base64编码数据时遇到问题。我有大约3.5 MB的数据解码。它几乎没有问题,直到最后的东西丢失。base64使用openssl BIO块解码

以下代码读取100 kB源数据块,将其写入BIO_s_mem,然后多次读取1024字节的解码数据。当没有更多内容要读取时,另一个100 kB块将被检索并再次使用。它一直很好,直到收到最后一个块。它没有完整的100 kB(仅25685字节)。我把它写入BIO,获得18倍解码的1024字节,然后是另一个435,就是这样。但并非全部。大约100个字节的解码数据仍然没有被读取。

所有编码数据都被正确接收(将它们保存到文件中,并通过shell命令手动解码以提供完整的输出)。我应该如何从BIO中获得其余的?我想我应该以某种方式说这是一切。我尝试了多种方式,例如BIO_flush,一些标志,将新行添加到编码数据,但还没有成功。

BIO *bmem, *b64; 
b64 = BIO_new(BIO_f_base64()); 
bmem = BIO_new(BIO_s_mem()); 
BIO_push(b64, bmem); 
vector<char> buf(1024); 

while (!end) { 
    end = task->nextChunk(chunk, chunkSize); // this reads encoded data block 
    BIO_write(bmem, (void*)chunk, chunkSize); 
    cout << "Chunk size: " << chunkSize << endl; 
    if (end || chunkSize == 0) { 
     BIO_flush(bmem); // I tried multiple things 
     BIO_flush(b64); // flush here and there, nothing helped 
     BIO_set_close(bmem, BIO_CLOSE); // and other things... ;-) 
    } 

    string result; 
    int nread; 
    while ((nread = BIO_read(b64, buf.data(), buf.size())) > 0) { 
     cout << "Decoded bytes read: " << nread << endl; 
     result.append(buf.data(), nread); 
    } 
    ret->appendRaw(result.c_str(), result.size()); // store result somehow 
} 

最后输出序列:

Chunk size: 25685 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 1024 
Decoded bytes read: 435 
Chunk size: 0 

所以再次:解码输出是二进制文件。它被正确编码,正确发送到我的代码,但没有解码,最后大约有100个字节丢失。 谢谢你的提示。

+0

I *认为*'(NREAD = BIO_READ(B64,buf.data(),buf.size()))> 0'可能不完全正确。我认为在生物上进行的测试是'do {len = BIO_read(b64,...); } while(len> 0 || BIO_should_retry(b64));'但是这是一个套接字生物;我不确定文件或内存生物的差异。 – jww

+0

谢谢你的提示。我已经尝试过这一点。当所有块写入我的BIO_s_mem时,从b64读取给出-1和BIO_should_retry(b64)保持为真,所以它永远不会结束。这就是为什么我认为我需要说“这一切”,最后一部分将被解码,返回,循环可以完成。 – Martin

回答

0

诀窍是在最后的序列BIO_READ之前加入以下两行:

 BIO_write(bmem, "\n", 1); 
     BIO_set_mem_eof_return(bmem, BIO_NOCLOSE);