2014-02-21 7 views
1

와 메모리에 gzip으로 압축을 푸는 것은 나는 간단한 수 있습니다 : 나는이 코드 조각이 :압축 함수/부스트

QByteArray MyNBT::decompressData(QByteArray data) 
{ 
    filtering_streambuf<input> in; 

    std::string _data = data.data(); 

    in.push(gzip_decompressor()); 
    in.push(boost::iostreams::back_inserter(_data)); 
    //in.push(std::back_inserter(_data)); 

    std::stringstream _sstream; 
    boost::iostreams::copy(in, _sstream); 

    QByteArray out = _sstream.rdbuf()->str().c_str(); 

    return out; 
} 

을 그리고이 라인 (들)에 오류가 있습니다 :

in.push(boost::iostreams::back_inserter(_data)); 
//in.push(std::back_inserter(_data)); 

오류 :

/usr/include/boost/iostreams/chain.hpp:244: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>' 
    BOOST_STATIC_ASSERT((is_convertible<category, Mode>::value)); 
    ^

컴파일러는 부스트의 하나 한 번 std::back_inserter(_data)에 두 번이 오류가 발생합니다.

미리 감사드립니다.

답변

2

back_inserter의 기능은 무엇입니까?

실제로. 컨테이너의 뒤쪽에 요소를 삽입합니다.

그래도 이후로 보이는 것은 front_reader 또는 container_source입니다.

글쎄, 내가 Qt를이없는,하지만 난 당신의 입력 (이 std::string, std::vector, std::array 또는 단지 const char [] 입력 잘 동일하게 작동하는 방법 주) 적응 array_source를 사용하여 운이 :

#include <fstream> 
#include <iostream> 

#include <boost/iostreams/filtering_stream.hpp> 
#include <boost/iostreams/filter/gzip.hpp> 
#include <boost/iostreams/copy.hpp> 
#include <sstream> 

int main() { 
    using namespace boost::iostreams; 
    filtering_streambuf<input> in; 

#if 0 
    std::string _data { 
#else 
    std::vector<char> _data { 
#endif 
     char(0x1f), char(0x8b), char(0x08), char(0x00), char(0xca), char(0xb5), 
     char(0x07), char(0x53), char(0x00), char(0x03), char(0xcb), char(0x48), 
     char(0xcd), char(0xc9), char(0xc9), char(0x57), char(0x28), char(0xcf), 
     char(0x2f), char(0xca), char(0x49), char(0xe1), char(0x02), char(0x00), 
     char(0x2d), char(0x3b), char(0x08), char(0xaf), char(0x0c), char(0x00), 
     char(0x00), char(0x00) 
    }; 

    in.push(gzip_decompressor()); 
    in.push(boost::iostreams::array_source(_data.data(), _data.size())); 

    std::stringstream _sstream; 
    boost::iostreams::copy(in, _sstream); 

    std::cout << _sstream.rdbuf(); 
} 

을 프로그램의 출력은 물론 hello world

+0

는 있지만에서 예외가 발생합니다 런타임'gzip 오류 '. 내가 사용한 gzips는 괜찮습니다. 나는 당신의 코드를 시험해 보았다. gzip은 나를 만든 것이고, 다른 예제는 잘 동작한다. ... – azteca1998

+0

나는 내 코드가 아니라 내 코드를 참조하고 있다고 가정한다. Zip 데이터가 손상되었다고 추측 할 수 있습니다. 어쩌면 당신은 이진 스트림을 사용하거나 길을 따라 어딘가에 NUL 문자를 끝내는 데 실패합니다. – sehe

+0

내 코드가 모든 이진 파일을 문자열로 읽은 다음 일부 함수 (변경하지 않고) 사이에 전달한 다음 압축 된 것으로 표시하면 함수 위의 압축을 풉니 다. 아주 간단합니다. – azteca1998

0

@sehe의 답변을 사용하여 수정했습니다. 여기

는 결과 코드입니다 :

QByteArray MyNBT::decompressData(QByteArray data) 
{ 
    filtering_streambuf<input> in; 

    std::vector<char> _data; 
    foreach(char ch, data) 
     _data.push_back(ch); 

    in.push(gzip_decompressor()); 
    in.push(boost::iostreams::array_source(_data.data(), _data.size())); 

    QByteArray out; 
    while (in.sgetc() != -1) 
     out += (unsigned char)in.sbumpc(); 

    std::cout << "out size! :: " << in.in_avail() << std::endl; 
    //std::cout << "out size! :: " << _sstream.str().size() << std::endl; 
    std::cout << "out size! :: " << out.size() << std::endl; 

    return out; 
} 
+0

'std :: copy_n'을 살펴 보겠습니다. (std :: vector )를 사용할 수 있어야합니다. (std :: vector const _data (data.begin(), data.end());' 'array_source (data.data(), data.size())'를 복사하지 않고 직접 사용하면 어떨까요? – sehe

0

가 나는 또한 간단한 문자 배열을 사용하고, 효율성을 위하여 (이 같은 오류가있는 사람들을 위해 유용 바랍니다)를 만들어야합니다 싶지 않았다 벡터 및 버퍼 내용을 복사하십시오. 그래서, 여기에 압축을 해제 또는 다른 문자 배열에 와이어에서 읽은 문자 배열에서 직접 압축하는 간단한에서-RAM 압축/압축 해제 유틸리티 클래스에 내 걸릴 : 그것은 지금 컴파일

/* 
* GzipUtil.h 
* 
* Created on: Nov 3, 2015 
*  Author: tprice 
*/ 

#ifndef GZIPUTIL_H_ 
#define GZIPUTIL_H_ 

#include <unistd.h> 
#include <stdint.h> 
#include <vector> 
#include <stdlib.h> 

#include <boost/iostreams/filtering_stream.hpp> 
#include <boost/iostreams/filter/gzip.hpp> 

namespace BIO = boost::iostreams; 

class GzipUtil { 
public: 
GzipUtil() {} 
virtual ~GzipUtil() {} 

static ssize_t compress(char *src, char *dest, ssize_t len) 
{ 
    ssize_t retval = 0; 

    BIO::filtering_streambuf<BIO::input> in; 
    in.push(BIO::gzip_compressor()); 
    in.push(BIO::array_source(src, len)); 
    for(retval = 0; in.sgetc() != -1; retval++) 
    { 
     dest[retval] = (char) in.sbumpc(); 
    } 

    return retval; 
} 

static ssize_t decompress(char *src, ssize_t srclen, std::vector<char*> & dest, ssize_t destChunkLen) 
{ 
    ssize_t retval = 0; 
    char* chunkPtr = NULL; 
    ssize_t chunkUsed = 0; 

    BIO::filtering_streambuf<BIO::input> in; 
    in.push(BIO::gzip_decompressor()); 
    in.push(BIO::array_source(src, srclen)); 
    for(retval = 0; in.sgetc() != -1; retval++) 
    { 
     if((chunkPtr == NULL) || (chunkUsed >= destChunkLen)) 
     { 
      chunkPtr = (char*) malloc(destChunkLen); 
      dest.push_back(chunkPtr); 
      chunkUsed = 0; 
     } 
     chunkPtr[chunkUsed++] = (char) in.sbumpc(); 
    } 

    return retval; 
} 

}; 


#endif /* GZIPUTIL_H_ */