2012-07-25 3 views
1

2048보다 큰 크기의 데이터를 압축 해제하려고하면 zlib 압축 해제 호출이 Z_OK를 반환합니다. 따라서 2980 크기의 데이터를 압축 해제하면 2048 개 (2 루프)까지 압축을 풀고 Z_OK를 반환합니다. 내가 무엇을 놓치고 있습니까?zlib이 버퍼 확장시 멈춤

바이트는 벡터 < 부호없는 문자입니다>;

Bytes uncompressIt(const Bytes& data) 
    { 
     size_t buffer_length = 1024; 

     Byte* buffer = nullptr; 

     int status = 0; 

     do 
     { 
      buffer = (Byte*) calloc(buffer_length + 1, sizeof(Byte)); 

      int status = uncompress(buffer, &buffer_length, &data[ 0 ], data.size()); 

      if (status == Z_OK) 
      { 
       break; 
      } 
      else if (status == Z_MEM_ERROR) 
      { 
       throw runtime_error("GZip decompress ran out of memory."); 
      } 
      else if (status == Z_DATA_ERROR) 
      { 
       throw runtime_error("GZip decompress input data was corrupted or incomplete."); 
      } 
      else //if (status == Z_BUF_ERROR) 
      { 
       free(buffer); 

       buffer_length *= 2; 
      } 
     } while (status == Z_BUF_ERROR); //then the output buffer wasn't large enough 

     Bytes result; 

     for(size_t index = 0; index != buffer_length; index++) 
     { 
      result.push_back(buffer[ index ]); 
     } 

     return result; 
    } 

편집 :

감사 @Michael realloc을 잡기 위해. 나는 구현을 망쳤다. 그리고 그것을 놓쳤다. 게시하기 전에 변명의 여지가 없습니다.

+0

실제 문제는 무엇입니까? 그것은 2048 바이트보다 크거나 작은 것을 압축하지 않는다는 것인가? – slugonamission

+0

buffer_length를 두 배로 늘리고 calloc()으로 다시 점프하는 경우 realloc()이 필요하지 않습니다. 에러 케이스에서 uncompress에 의해 buffer_length가 변경되면 어떨까요? 두 배로하는 것이 올바른 일이겠습니까? 아마도 buffer_length를 보존하기 위해 다른 값을 사용하여 압축되지 않은 데이터의 길이를 캡처해야합니다. – brandx

+0

@brandx buffer_length의 압축되지 않은 변경 제안에 감사드립니다. 그러나이 경우와 그렇지 않은 경우를 확인했습니다. – Corvusoft

답변

1

알겠습니다.

int status 

은 루프의 내부와 외부에서 정의됩니다. 여기 수업은 결코 &을 마시지 않습니다.

0

zlib 설명서에서 "충분한 여유 공간이없는 경우 uncompress()가 해당 지점까지 압축되지 않은 데이터로 출력 버퍼를 채 웁니다."

최대 1024 바이트가 이미 압축되지 않은 경우 Z_BUF_ERROR을 얻고 2048 바이트의 공간을 제공하는 버퍼 크기를 두 배로 늘리고 두 번째 압축을 풀면 총 3072 압축되지 않은 데이터의 바이트.

또한 을 얻은 후 realloc 뒤에 불필요하게 calloc을 수행하는 것처럼 보입니다.

+0

본 설명서를 읽었으며 귀하의 의견을 읽는 데 새로운 것이 없습니다. 압축 풀기 호출이 이전 호출을 기억하고 있음을 당신은 믿고 있습니다. 그렇습니다? 그러나 나는 이것을 제안 할만한 것을 읽지 못했다. – Corvusoft

0

코드에 문제가없는 것으로 나타났습니다. 압축되지 않은 데이터의 길이를 잘못 예측했을 수 있습니다. uncompress()은 완전한 zlib 스트림의 압축을 해제하고 압축되지 않은 데이터의 검사 값이 스트림의 끝에서 검사 값과 일치하는 경우에만 Z_OK을 리턴합니다.