2011-04-21 7 views
2

Qt의 zlib 라이브러리를 사용하여 http 서버에서받은 gzip 데이터의 압축을 푸는 중입니다. (Qt를 사용하여 gzip 데이터를 압축 해제하는 중 오류가 발생했습니다.

QByteArray gzipDecompress(QByteArray compressData) 
{ 
    //strip header 
    compressData.remove(0, 10); 

    const int buffer_size = 16384; 
    quint8 buffer[buffer_size]; 

    z_stream cmpr_stream; 
    cmpr_stream.next_in = (unsigned char *)compressData.data(); 
    cmpr_stream.avail_in = compressData.size(); 
    cmpr_stream.total_in = 0; 

    cmpr_stream.next_out = buffer; 
    cmpr_stream.avail_out = buffer_size; 
    cmpr_stream.total_out = 0; 

    cmpr_stream.zalloc = Z_NULL; 
    cmpr_stream.zfree = Z_NULL; 
    cmpr_stream.opaque = Z_NULL; 

    int status = inflateInit2(&cmpr_stream, -8); 
    if (status != Z_OK) { 
     qDebug() << "cmpr_stream error!"; 
    } 

    QByteArray uncompressed; 
    do { 
     cmpr_stream.next_out = buffer; 
     cmpr_stream.avail_out = buffer_size; 

     status = inflate(&cmpr_stream, Z_NO_FLUSH); 

     if (status == Z_OK || status == Z_STREAM_END) 
     { 
      QByteArray chunk = QByteArray::fromRawData((char *)buffer, buffer_size - cmpr_stream.avail_out); 
      uncompressed.append(chunk); 
     } 
     else 
     { 
      inflateEnd(&cmpr_stream); 
      break; 
     } 

     if (status == Z_STREAM_END) 
     { 
      inflateEnd(&cmpr_stream); 
      break; 
     } 
    } 
    while (cmpr_stream.avail_out == 0); 

    return uncompressed; 
} 

Eveything은 압축 해제 데이터를 출력 버퍼에 맞는 경우 잘 작동하는 것 같다 : qUncompress 더 좋은 없었기 때문에, 나는 충고가 여기에 주어진 다음 : Qt quncompress gzip data을이 같은 GZIP 데이터를 압축 해제하는 내 자신의 방법을 만들어 즉 .16 Kb보다 작음). 그렇지 않으면 두 번째 inflate 호출은 Z_DATA_ERROR를 반환합니다. 출력 버퍼가 충분히 커지면 동일한 데이터 청크가 올바르게 압축 해제되므로 데이터가 올바른지 확인합니다.

서버는 압축되지 않은 데이터 (압축 된 하나의 크기)의 크기에 헤더를 반환하지 않습니다 그래서 ZLIB에서 사용 지침 다음 : http://www.zlib.net/zlib_how.html

을 그리고 그들은 난 정확히 무엇을 할 하기. 내가 놓칠 수있는 어떤 생각? 스트림의 next_in 및 avail_in 멤버가 첫 번째 반복 후에 올바르게 업데이트 된 것처럼 보입니다. 아, 그리고 그것이 유용하다면, 데이터 오류가 발행 될 때의 오류 메시지는 "잘못된 거리가 너무 멀습니다."입니다.

의견이 있으십니까? 감사.

답변

3

/Deflate 방식 부풀려 압축/압축 해제 알고리즘으로 32Kb는 원형 버퍼를 사용한다. 압축 해제 된 데이터가 16Kb보다 큰 경우 16Kb 버퍼가 작동하지 않습니다. 데이터가 블록으로 분할 될 수 있기 때문에 엄격하게 사실이 아니지만 거기에 32KB 블록이 있다고 가정해야합니다. 따라서 buffer_size = 32768으로 설정하면됩니다.

+0

동일한 문제가 있으며 folowing 메서드를 사용하여이 문제를 해결했습니다. – pranavjayadev

관련 문제