C++ 使用 libzpaq 压缩到 char* 缓冲区

c++ compress with libzpaq to char* buffer

我有一个 std::vector<short> 并且想用 libzpaq 从 https://github.com/zpaq/zpaq/ 压缩(然后解压缩)到 char* buffer.

之类的东西

但是我不明白头文件中提到的这个ReaderWriterclass的概念。如何将我的 std::vector 放入压缩后的 buffer 中?

目前我有类似下面的代码。

#include <vector>
#include <string>
#include <stdio.h>
#include "libzpaq.h"

struct writer: public libzpaq::Writer {

  void put(int c) {

  }
};


struct reader: public libzpaq::Reader {

  int get() {

  }  
};


void libzpaq::error(const char* msg) { 
    fprintf(stderr, "Oops: %s\n", msg);
    exit(1);
}

int main() {


  short a[] = {2,5,8,2,4,2,2,2,6,5,4,3,4,2,2};
  std::vector<short> v(a, a+15);

  char* buffer;


  reader in;
  writer out;

  libzpaq::compress(&in, &out, "5");  

}

而且我不想将向量 v 压缩成 buffer。 (稍后再次解压。)

但是我不明白ReaderWriterstruct/class的概念。

文档 (http://mattmahoney.net/dc/libzpaq.3.html) 还提到了 ReaderWriter 的函数 virtual int read(char* buf, int n)virtual void write(const char* buf, int n)。我怎样才能将 std::vector<short> 转换为 char* buf 最终得到这个 bufn 字节的长度?

编辑 1:我在 libzpaq.h 行 1376 中找到了一个 class StringBuffer。但是像

buffer = reinterpret_cast<char*> (&v[0]);
length = sizeof(short)*v.size();


libzpaq::StringBuffer inString, outString;

inString.read(buffer, length);

libzpaq::compress(&inString, &outString, "5");

std::cout << "size outstring: " << outString.size() << std::endl;
std::cout << "size instring: " << inString.size() << std::endl;

总是给我

size outstring: 0
size instring: 0

即使我尝试使用包含几千个随机元素的更大的向量 v

使用Reader,您可以逐字节访问要压缩的数据。所以 std::vector<short> 看起来像这样。

struct reader : public libzpaq::Reader {
    reader(const std::vector<short>& v) :
    m_v(v),
    m_offset(0) {

    }
    int get() {
        if (m_offset < m_v.size() * sizeof (short)) {
            return *((char*) m_v.data() + m_offset++);
        } else {
            return -1;
        }
    }
    int m_offset;
    std::vector<short> m_v;
};

Writer 应该收集 Reader 的输出数据。如果您想将其收集在 char 数组中,我建议您这样做。

struct writer : public libzpaq::Writer {
    void put(int c) {
        m_buffer.push_back(c);
    }
    int size() {
        m_buffer.size();
    }
    void copy_to(char* dst) {
        memcpy(dst, m_buffer.data(), m_buffer.size());
    }
    std::vector<char> m_buffer;
};

然后调用它:

writer w;
reader r(v1);

libzpaq::compress(&r, &w, "5");

char* buffer = new char[w.size()];
w.copy_to(buffer);

如果你想使用 StringBuffer 那么你应该在读取之前写入一些数据到缓冲区,这就是为什么 returns 0。看例子:

char* buffer = reinterpret_cast<char*> (&v[0]);
int length = sizeof (short)*v.size();

libzpaq::StringBuffer in, out1, out2;

// fill buffer with source data
in.write(buffer, length);

// compress to out1
libzpaq::compress(&in, &out1, "5");

// decompress out1 to out2
libzpaq::decompress(&out1, &out2);

// check result
short* b = (short*)out2.data();

for(int i = 0; i < 15; ++i) {
    std::cout << b[i] << std::endl;
}