C++ 使用 libzpaq 压缩到 char* 缓冲区
c++ compress with libzpaq to char* buffer
我有一个 std::vector<short>
并且想用 libzpaq 从 https://github.com/zpaq/zpaq/ 压缩(然后解压缩)到 char* buffer
.
之类的东西
但是我不明白头文件中提到的这个Reader
和Writer
class的概念。如何将我的 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
。 (稍后再次解压。)
但是我不明白Reader
和Writer
struct/class的概念。
文档 (http://mattmahoney.net/dc/libzpaq.3.html) 还提到了 Reader
和 Writer
的函数 virtual int read(char* buf, int n)
和 virtual void write(const char* buf, int n)
。我怎样才能将 std::vector<short>
转换为 char* buf
最终得到这个 buf
的 n
字节的长度?
编辑 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;
}
我有一个 std::vector<short>
并且想用 libzpaq 从 https://github.com/zpaq/zpaq/ 压缩(然后解压缩)到 char* buffer
.
但是我不明白头文件中提到的这个Reader
和Writer
class的概念。如何将我的 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
。 (稍后再次解压。)
但是我不明白Reader
和Writer
struct/class的概念。
文档 (http://mattmahoney.net/dc/libzpaq.3.html) 还提到了 Reader
和 Writer
的函数 virtual int read(char* buf, int n)
和 virtual void write(const char* buf, int n)
。我怎样才能将 std::vector<short>
转换为 char* buf
最终得到这个 buf
的 n
字节的长度?
编辑 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;
}