2015-02-23 160 views
1

我有一个std::vector<short>,并希望压缩(并随后解压缩)与libzpaq从https://github.com/zpaq/zpaq/char* bufferC++压缩libzpaq到char *缓冲区

但是我没有看到头文件中提到的ReaderWriter类的概念。我怎么把我的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"); 

} 

我wan't到矢量v压缩为buffer。 (后来再次解压缩。)

但我不明白ReaderWriter结构/类的概念。

的实况(http://mattmahoney.net/dc/libzpaq.3.html)也提到的功能为ReaderWritervirtual int read(char* buf, int n)virtual void write(const char* buf, int n)。我怎么能投到char* buf结束得到这个bufn字节的长度?

编辑1:我发现在libzpaq.h线1376。可是事情一类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一些thousend随机元素。

回答

1

使用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,那么你应该写一些数据缓冲,前阅读,那为什么它返回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; 
}