Beispiel #1
1
void UncompressInc(
	std::vector<unsigned char> &outBuf,
	const std::vector<unsigned char> &inBuf)
{
	CLzmaDec dec;

	UInt64 unpackSize = 0;
	for (int i = 0; i < 8; i++)
		unpackSize += (UInt64)inBuf[5 + i] << (i * 8);

	LzmaDec_Construct(&dec);
	SRes res = LzmaDec_Allocate(&dec, &inBuf[0], LZMA_PROPS_SIZE, &SzAllocForLzma);
	assert(res == SZ_OK);

	LzmaDec_Init(&dec);

	//printf("uint64 resLen : %" PRIu64 "\n", unpackSize);		//print uint64

	outBuf.resize(unpackSize);
	unsigned outPos = 0, inPos = LZMA_PROPS_SIZE;
	ELzmaStatus status;
	const unsigned BUF_SIZE = 10240;
	while (outPos < outBuf.size())
	{
		unsigned destLen = min(BUF_SIZE, outBuf.size() - outPos);
		unsigned srcLen = min(BUF_SIZE, inBuf.size() - 8 - inPos);

		res = LzmaDec_DecodeToBuf(&dec,
			&outBuf[outPos], &destLen,
			&inBuf[inPos+8], &srcLen,
			(outPos + destLen == outBuf.size())
			? LZMA_FINISH_END : LZMA_FINISH_ANY, &status);
		assert(res == SZ_OK);
		inPos += srcLen;
		outPos += destLen;
		if (status == LZMA_STATUS_FINISHED_WITH_MARK)
			break;
	}

	LzmaDec_Free(&dec, &g_Alloc);
	outBuf.resize(outPos);

	FILE *fout = fopen("data33.dc", "wb+");
	fwrite(&outBuf[0], 1, outBuf.size(), fout);
	fclose(fout);

}
int cli_LzmaDecode(struct CLI_LZMA *L) {
    SRes res;
    SizeT outbytes, inbytes;
    ELzmaStatus status;
    ELzmaFinishMode finish;

    if(!L->freeme) return cli_LzmaInit(L, 0);

    inbytes = L->avail_in;
    if(~L->usize && L->avail_out > L->usize) {
	outbytes = L->usize;
	finish = LZMA_FINISH_END;
    } else {
	outbytes = L->avail_out;
	finish = LZMA_FINISH_ANY;
    }
    res = LzmaDec_DecodeToBuf(&L->state, L->next_out, &outbytes, L->next_in, &inbytes, finish, &status);
    L->avail_in -= inbytes;
    L->next_in += inbytes;
    L->avail_out -= outbytes;
    L->next_out += outbytes;
    if(~L->usize) L->usize -= outbytes;
    if(res != SZ_OK)
	return LZMA_RESULT_DATA_ERROR;
    if(!L->usize || status == LZMA_STATUS_FINISHED_WITH_MARK)
	return LZMA_STREAM_END;
    return LZMA_RESULT_OK;
}
Beispiel #3
0
void* lzma_decode(struct lzma_dec_state *state, void *src, size_t src_len, size_t *dest_len) {
  ELzmaStatus status;
  size_t current_size = 4096;
  void *target = malloc(current_size);
  *dest_len = 0;
  int done = 0;
  size_t pos_in = 0;

  while (!done) {
    size_t remain_out = current_size - *dest_len;
    size_t remain_in  = src_len - pos_in;
    
    LzmaDec_DecodeToBuf(
			&state->decoder,
			target + *dest_len, &remain_out,
			src    + pos_in , &remain_in,
			LZMA_FINISH_ANY,
			&status);
    
    pos_in  += remain_in;
    *dest_len += remain_out;

    switch (status) {
    case LZMA_STATUS_NOT_FINISHED:
      current_size *= 2;
      target = realloc(target, current_size);
      break;
    default:
      done = 1;
    }
  }
  
  return target;
}
Beispiel #4
0
        inline size_t DecompressPortion() {
            size_t bufLen = sizeof(UncompressedBuf_);
            size_t availLen = InSize_ - InPos_;
            ELzmaStatus status;

            Check(LzmaDec_DecodeToBuf(&H_, (Byte*)UncompressedBuf_, &bufLen, (Byte*)In_ + InPos_, &availLen, LZMA_FINISH_ANY, &status));

            InPos_ += availLen;

            return bufLen;
        }
Beispiel #5
0
static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
    UInt64 unpackSize)
{
  int thereIsSize = (unpackSize != (UInt64)(Int64)-1);
  Byte inBuf[IN_BUF_SIZE];
  Byte outBuf[OUT_BUF_SIZE];
  size_t inPos = 0, inSize = 0, outPos = 0;
  LzmaDec_Init(state);
  for (;;)
  {
    if (inPos == inSize)
    {
      inSize = IN_BUF_SIZE;
      RINOK(inStream->Read(inStream, inBuf, &inSize));
      inPos = 0;
    }
    {
      SRes res;
      SizeT inProcessed = inSize - inPos;
      SizeT outProcessed = OUT_BUF_SIZE - outPos;
      ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
      ELzmaStatus status;
      if (thereIsSize && outProcessed > unpackSize)
      {
        outProcessed = (SizeT)unpackSize;
        finishMode = LZMA_FINISH_END;
      }
      
      res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,
        inBuf + inPos, &inProcessed, finishMode, &status);
      inPos += inProcessed;
      outPos += outProcessed;
      unpackSize -= outProcessed;
      
      if (outStream)
        if (outStream->Write(outStream, outBuf, outPos) != outPos)
          return SZ_ERROR_WRITE;
        
      outPos = 0;
      
      if (res != SZ_OK || (thereIsSize && unpackSize == 0))
        return res;
      
      if (inProcessed == 0 && outProcessed == 0)
      {
        if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
          return SZ_ERROR_DATA;
        return res;
      }
    }
  }
}
Beispiel #6
0
long FileReaderLZMA::Read (void *buffer, long len)
{
	int err;
	Byte *next_out = (Byte *)buffer;

	do
	{
		ELzmaFinishMode finish_mode = LZMA_FINISH_ANY;
		ELzmaStatus status;
		size_t out_processed = len;
		size_t in_processed = InSize;

		err = LzmaDec_DecodeToBuf(&Streamp->Stream, next_out, &out_processed, InBuff + InPos, &in_processed, finish_mode, &status);
		InPos += in_processed;
		InSize -= in_processed;
		next_out += out_processed;
		len = (long)(len - out_processed);
		if (err != SZ_OK)
		{
			I_Error ("Corrupt LZMA stream");
		}
		if (in_processed == 0 && out_processed == 0)
		{
			if (status != LZMA_STATUS_FINISHED_WITH_MARK)
			{
				I_Error ("Corrupt LZMA stream");
			}
		}
		if (InSize == 0 && !SawEOF)
		{
			FillBuffer ();
		}
	} while (err == SZ_OK && len != 0);

	if (err != Z_OK && err != Z_STREAM_END)
	{
		I_Error ("Corrupt LZMA stream");
	}

	if (len != 0)
	{
		I_Error ("Ran out of data in LZMA stream");
	}

	return (long)(next_out - (Byte *)buffer);
}
Beispiel #7
0
STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
  if (processedSize)
    *processedSize = 0;
  do
  {
    if (_inPos == _inSize)
    {
      _inPos = _inSize = 0;
      RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize));
    }
    {
      SizeT inProcessed = _inSize - _inPos;

      if (_outSizeDefined)
      {
        const UInt64 rem = _outSize - _outSizeProcessed;
        if (rem < size)
          size = (UInt32)rem;
      }

      SizeT outProcessed = size;
      ELzmaStatus status;
      SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
          _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status);
      _inPos += (UInt32)inProcessed;
      _inSizeProcessed += inProcessed;
      _outSizeProcessed += outProcessed;
      size -= (UInt32)outProcessed;
      data = (Byte *)data + outProcessed;
      if (processedSize)
        *processedSize += (UInt32)outProcessed;
      RINOK(SResToHRESULT(res));
      if (inProcessed == 0 && outProcessed == 0)
        return S_OK;
    }
  }
  while (size != 0);
  return S_OK;
}
Beispiel #8
0
int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hFileIn  = ::CreateFile(_T("C:\\Users\\Christoph\\Desktop\\S.csv.lzma"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	HANDLE hFileOut = ::CreateFile(_T("C:\\Users\\Christoph\\Desktop\\S.csv.decd"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

	BYTE header[LZMA_PROPS_SIZE + 8];
	DWORD dwBytesRead = 0;
	DWORD dwBytesWritten = 0;
	::ReadFile(hFileIn, header, sizeof(header), &dwBytesRead, NULL);

	ELzmaStatus status;
	CLzmaDec state;
	LzmaDec_Construct(&state);
	LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
	LzmaDec_Init(&state);

	__int64 nSize = *reinterpret_cast<__int64*>(header + LZMA_PROPS_SIZE);
	_tprintf(_T("Extracted size: %d\n"), nSize);

	BYTE *pDataIn  = new BYTE[BUFFER_SIZE];
	BYTE *pDataOut = new BYTE[BUFFER_SIZE];

	size_t nTotalSize = (size_t)nSize;
	size_t nInSize = BUFFER_SIZE, nInPos = 0;
	size_t nOutSize = BUFFER_SIZE;

	while (nTotalSize)
	{
		if (!::ReadFile(hFileIn, pDataIn, BUFFER_SIZE, &dwBytesRead, NULL)) break;
		if (dwBytesRead == 0) break;
		nInSize = dwBytesRead;
		nInPos = 0;
		_tprintf(_T("."));
		
		while (nInPos < nInSize)
		{
			size_t nInProcessed  = nInSize - nInPos;
			size_t nOutProcessed = BUFFER_SIZE;
			LzmaDec_DecodeToBuf(&state, pDataOut, &nOutProcessed,
				                        pDataIn + nInPos, &nInProcessed,
										(nOutProcessed > nTotalSize)? LZMA_FINISH_END : LZMA_FINISH_ANY,
										&status);
			::WriteFile(hFileOut, pDataOut, nOutProcessed, &dwBytesRead, NULL);
			nInPos += nInProcessed;
			nTotalSize -= nOutProcessed;

			if (nInProcessed == 0 && nOutProcessed == 0)
			{
				nInPos = nInSize = 0;
				nTotalSize = 0;
			}
		}
	}

	delete[] pDataOut;
	delete[] pDataIn;

	LzmaDec_Free(&state, &g_Alloc);

	::CloseHandle(hFileOut);
	::CloseHandle(hFileIn);

#ifdef _DEBUG
	_tsystem(_T("pause"));
#endif
	return 0;
}
Beispiel #9
0
int
BCMINITFN(_nvram_read)(void *buf, int idx)
{
	uint32 *src, *dst;
	uint i;

	if (!nvram_header)
		return -19; /* -ENODEV */

#if defined(_CFE_) && defined(BCM_DEVINFO)
	if ((!devinfo_nvram_header) && (idx == 1)) {
		return -19; /* -ENODEV */
	}

	src = idx == 0 ? (uint32 *) nvram_header : (uint32 *) devinfo_nvram_nvh;
#else
	src = (uint32 *) nvram_header;
#endif /* _CFE_ && BCM_DEVINFO */

	dst = (uint32 *) buf;

	for (i = 0; i < sizeof(struct nvram_header); i += 4)
		*dst++ = *src++;

	/* Since we know what the first 3 bytes of the lzma properties
	 * should be based on what we used to compress, check them
	 * to see if we need to decompress (uncompressed this would show up a
	 * a single [ and then the end of nvram marker so its invalid in an
	 * uncompressed nvram block
	 */
	if ((((unsigned char *)src)[0] == 0x5d) &&
	    (((unsigned char *)src)[1] == 0) &&
	    (((unsigned char *)src)[2] == 0)) {
		unsigned int dstlen = nvram_header->len;
		unsigned int srclen = MAX_NVRAM_SPACE-LZMA_PROPS_SIZE-NVRAM_HEADER_SIZE;
		unsigned char *cp = (unsigned char *)src;
		CLzmaDec state;
		SRes res;
		ELzmaStatus status;

		LzmaDec_Construct(&state);
		res = LzmaDec_Allocate(&state, cp, LZMA_PROPS_SIZE, &g_Alloc);
		if (res != SZ_OK) {
			printf("Error Initializing LZMA Library\n");
			return -19;
		}
		LzmaDec_Init(&state);
		res = LzmaDec_DecodeToBuf(&state,
		                          (unsigned char *)dst, &dstlen,
		                          &cp[LZMA_PROPS_SIZE], &srclen,
		                          LZMA_FINISH_ANY,
		                          &status);

		LzmaDec_Free(&state, &g_Alloc);
		if (res != SZ_OK) {
			printf("Error Decompressing eNVRAM\n");
			return -19;
		}
	} else {
		for (; i < nvram_header->len && i < MAX_NVRAM_SPACE; i += 4)
			*dst++ = ltoh32(*src++);
	}
	return 0;
}
Beispiel #10
0
PakEntry Pak::read(uint32_t tag) const
{
  int entryIndex = findEntry(tag);
  if(entryIndex < 0)
  {
    return PakEntry(NULL, 0, false);
  }

  const Header *header = reinterpret_cast<const Header*>(m_pakData);
  const Entry *entry = reinterpret_cast<const Entry*>(header + 1) + entryIndex;

  size_t entrySize = (entry+1)->offset - entry->offset;
  if(entry->offset>m_pakDataSize || entrySize>=4*1024*1024 || entry->offset+entrySize>m_pakDataSize)
  {
    ERROR("Pak::findEntry: invalid entry offset/size (tag=0x%08x index=%u offset=%u size=%u)", tag, entryIndex, entry->offset, entrySize);
    return PakEntry(NULL, 0, false);
  }

  const uint8_t *entryData = cast<uint8_t>(m_pakData, entry->offset);
  const LzmaHeader *lzmaHeader = cast<LzmaHeader>(entryData, 0);

  if(memcmp(lzmaHeader->magic, "lzma", 4) != 0)
  {
    DEBUG("Pak::findEntry: found uncompressed 0x%08x at %u size %zu", tag, entry->offset, entrySize);
    return PakEntry(entryData, entrySize, false);
  }

  if(lzmaHeader->decompressedSize<entrySize/2 || lzmaHeader->decompressedSize>=8*1024*1024)
  {
    ERROR("Pak::findEntry: invalid uncompressed size (tag=0x%08x size=%u decompressedsize=%u)", tag, entrySize, lzmaHeader->decompressedSize);
    return PakEntry(NULL, 0, false);
  }

  CLzmaDec dec;
  LzmaDec_Construct(&dec);
  LzmaDec_Init(&dec);
  SRes res = LzmaDec_Allocate(&dec, lzmaHeader->props, LZMA_PROPS_SIZE, &lzmaAllocFuncs);
  if(res != SZ_OK)
  {
    ERROR("Pak::findEntry: LzmaDec_Allocate failed: %d (tag=0x%08x)", res, tag);
    return PakEntry(NULL, 0, false);
  }

  void *decdata = malloc(lzmaHeader->decompressedSize);
  if(decdata == NULL)
  {
    ERROR("Pak::findEntry: LzmaDec_Allocate failed to allocate %u bytes", lzmaHeader->decompressedSize);
    LzmaDec_Free(&dec, &lzmaAllocFuncs);
    return PakEntry(NULL, 0, false);
  }

  size_t destSize = lzmaHeader->decompressedSize;
  size_t srcSize = entrySize - sizeof(lzmaHeader);
  ELzmaStatus status;
  res = LzmaDec_DecodeToBuf(&dec,
      (Byte*)decdata, &destSize,
      lzmaHeader->data, &srcSize,
      LZMA_FINISH_END, &status);

  if(res != SZ_OK)
  {
    ERROR("Pak::findEntry: LzmaDec_DecodeToBuf failed: %d (tag=0x%08x)", res, tag);
    LzmaDec_Free(&dec, &lzmaAllocFuncs);
    free(decdata);
    return PakEntry(NULL, 0, false);
  }

  if(!(status==LZMA_STATUS_FINISHED_WITH_MARK || (status==LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK && destSize!=lzmaHeader->decompressedSize)))
  {
    ERROR("Pak::findEntry: LzmaDec_DecodeToBuf ended with unexpected status: %d (tag=0x%08x)", status, tag);
    LzmaDec_Free(&dec, &lzmaAllocFuncs);
    free(decdata);
    return PakEntry(NULL, 0, false);
  }

  if(destSize != lzmaHeader->decompressedSize)
  {
    ERROR("Pak::findEntry: LzmaDec_DecodeToBuf failed to decompress whole buffer: %zu!=%u (tag=0x%08x)", destSize, lzmaHeader->decompressedSize, tag);
    LzmaDec_Free(&dec, &lzmaAllocFuncs);
    free(decdata);
    return PakEntry(NULL, 0, false);
  }

  LzmaDec_Free(&dec, &lzmaAllocFuncs);
  return PakEntry(decdata, lzmaHeader->decompressedSize, true);
}
Beispiel #11
0
static int Decode(FILE *inFile, FILE *outFile, char *rs)
{
  UInt64 unpackSize;
  int thereIsSize; /* = 1, if there is uncompressed size in headers */
  int i;
  int res = 0;
  
  CLzmaDec state;

  /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */
  unsigned char header[LZMA_PROPS_SIZE + 8];

  /* Read and parse header */

  if (!MyReadFileAndCheck(inFile, header, sizeof(header)))
    return PrintError(rs, kCantReadMessage);

  unpackSize = 0;
  thereIsSize = 0;
  for (i = 0; i < 8; i++)
  {
    unsigned char b = header[LZMA_PROPS_SIZE + i];
    if (b != 0xFF)
      thereIsSize = 1;
    unpackSize += (UInt64)b << (i * 8);
  }

  LzmaDec_Construct(&state);
  res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
  if (res != SZ_OK)
    return res;
  {
    Byte inBuf[IN_BUF_SIZE];
    Byte outBuf[OUT_BUF_SIZE];
    size_t inPos = 0, inSize = 0, outPos = 0;
    LzmaDec_Init(&state);
    for (;;)
    {
      if (inPos == inSize)
      {
        inSize = MyReadFile(inFile, inBuf, IN_BUF_SIZE);
        inPos = 0;
      }
      {
        SizeT inProcessed = inSize - inPos;
        SizeT outProcessed = OUT_BUF_SIZE - outPos;
        ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
        ELzmaStatus status;
        if (thereIsSize && outProcessed > unpackSize)
        {
          outProcessed = (SizeT)unpackSize;
          finishMode = LZMA_FINISH_END;
        }

        res = LzmaDec_DecodeToBuf(&state, outBuf + outPos, &outProcessed,
            inBuf + inPos, &inProcessed, finishMode, &status);
        inPos += (UInt32)inProcessed;
        outPos += outProcessed;
        unpackSize -= outProcessed;

        if (outFile != 0)
          MyWriteFile(outFile, outBuf, outPos);
        outPos = 0;

        if (res != SZ_OK || thereIsSize && unpackSize == 0)
          break;

        if (inProcessed == 0 && outProcessed == 0)
        {
          if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
            res = SZ_ERROR_DATA;
          break;
        }
      }
    }
  }

  LzmaDec_Free(&state, &g_Alloc);
  return res;
}
Beispiel #12
0
static int 
lzmafs_fileop_read(void *ref, uint8_t *buf, int len)
{
	lzmafs_file_t *file = (lzmafs_file_t *) ref;
	int res = 0;
	int err;
	int amtcopy;
	int ttlcopy = 0;
	unsigned int in_processed;
	ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
	ELzmaStatus status;

    if (len == 0) return 0;

    while (len) {

		/* Figure the amount to copy.  This is the min of what we
	       have left to do and what is available. */
	   amtcopy = len;
	   if (amtcopy > file->lzmafs_outlen) {
		   amtcopy = file->lzmafs_outlen;
	   }

	   /* Copy the data. */
	   if (buf) {
		   memcpy(buf, file->lzmafs_outptr, amtcopy);
		   buf += amtcopy;
	   }

	   /* Update the pointers. */
	   file->lzmafs_outptr += amtcopy;
	   file->lzmafs_outlen -= amtcopy;
	   len -= amtcopy;
	   ttlcopy += amtcopy;
	   file->lzmafs_unpackSize -= amtcopy;

	   if (file->lzmafs_unpackSize == 0) {
		   file->lzmafs_eofseen = 1;
	   }
	   /* If we've eaten all of the output, reset and call decode
	      again. */

	   if (file->lzmafs_outlen == 0) {
			/* If no input data to decompress, get some more if we can. */
			if (file->lzmafs_eofseen) 
				break;
			if (file->lzmafs_inlen == 0) {
				file->lzmafs_inlen = BDREAD(file->lzmafs_fsctx->lzmafsctx_subops,
							file->lzmafs_subfile,
							file->lzmafs_inbuf,
							LZMAFS_INBUFSIZE);
				/* If at EOF or error, get out. */
				if (file->lzmafs_inlen <= 0) 
					break;
				file->lzmafs_inptr = file->lzmafs_inbuf;
			}
			in_processed  = file->lzmafs_inlen;
			file->lzmafs_outlen = LZMAFS_OUTBUFSIZE;
			file->lzmafs_outptr = file->lzmafs_outbuf;
			
			if (file->lzmafs_outlen > file->lzmafs_unpackSize) {
				file->lzmafs_outlen = (SizeT)file->lzmafs_unpackSize;
				finishMode = LZMA_FINISH_END;
			}
			/* decompress the input data. */
			err = LzmaDec_DecodeToBuf(file->lzmafs_state, file->lzmafs_outbuf, (SizeT *)&file->lzmafs_outlen, 
						file->lzmafs_inptr, &in_processed, finishMode, &status);
			file->lzmafs_inptr += in_processed;
			file->lzmafs_inlen -= in_processed;
			if (err != SZ_OK) {
				res = CFE_ERR;
				break;
			}
	    }
	}

    file->lzmafs_fileoffset += ttlcopy;
    return (res < 0) ? res : ttlcopy;
}
static PyObject *
pylzma_decomp_decompress(CDecompressionObject *self, PyObject *args)
{
    PyObject *result=NULL;
    unsigned char *data;
    Byte *next_in, *next_out;
    int length, res, bufsize=BLOCK_SIZE;
    SizeT avail_in;
    SizeT inProcessed, outProcessed;
    ELzmaStatus status;
    
    if (!PyArg_ParseTuple(args, "s#|i", &data, &length, &bufsize)){
        return NULL;
    }

    if (bufsize <= 0) {
        PyErr_SetString(PyExc_ValueError, "bufsize must be greater than zero");
        return NULL;
    }
    
    if (self->unconsumed_length > 0) {
        self->unconsumed_tail = (unsigned char *) realloc(self->unconsumed_tail, self->unconsumed_length + length);
        next_in = (unsigned char *) self->unconsumed_tail;
        memcpy(next_in + self->unconsumed_length, data, length);
    } else {
        next_in = data;
    }
    
    if (self->need_properties) {
        if ((self->unconsumed_length + length) < LZMA_PROPS_SIZE) {
            // we need enough bytes to read the properties
            self->unconsumed_tail = (unsigned char *) realloc(self->unconsumed_tail, self->unconsumed_length + length);
            if (self->unconsumed_tail == NULL) {
                PyErr_NoMemory();
                return NULL;
            }
            memcpy(self->unconsumed_tail + self->unconsumed_length, data, length);
            self->unconsumed_length += length;
            return PyString_FromString("");
        }

        self->unconsumed_length += length;
        res = LzmaDec_Allocate(&self->state, next_in, LZMA_PROPS_SIZE, &allocator);
        if (res != SZ_OK) {
            PyErr_SetString(PyExc_TypeError, "Incorrect stream properties");
            return NULL;
        }
        
        next_in += LZMA_PROPS_SIZE;
        self->unconsumed_length -= LZMA_PROPS_SIZE;
        if (self->unconsumed_length > 0) {
            if (self->unconsumed_tail == NULL) {
                // No remaining data yet
                self->unconsumed_tail = (unsigned char *) malloc(self->unconsumed_length);
                if (self->unconsumed_tail == NULL) {
                    PyErr_NoMemory();
                    return NULL;
                }
                memcpy(self->unconsumed_tail, next_in, self->unconsumed_length);
                next_in = self->unconsumed_tail;
            } else {
                // Skip properties in remaining data
                memmove(self->unconsumed_tail, self->unconsumed_tail+LZMA_PROPS_SIZE, self->unconsumed_length);
                self->unconsumed_tail = next_in = (unsigned char *) realloc(self->unconsumed_tail, self->unconsumed_length);
                if (self->unconsumed_tail == NULL) {
                    PyErr_NoMemory();
                    return NULL;
                }
            }
        } else {
            FREE_AND_NULL(self->unconsumed_tail);
        }
        
        self->need_properties = 0;
        LzmaDec_Init(&self->state);
    } else {
        self->unconsumed_length += length;
    }
    avail_in = self->unconsumed_length;
    if (avail_in == 0) {
        // no more bytes to decompress
        return PyString_FromString("");
    }
    
    result = PyString_FromStringAndSize(NULL, bufsize);
    if (result == NULL) {
        PyErr_NoMemory();
        goto exit;
    }
    
    next_out = (unsigned char *) PyString_AS_STRING(result);
    Py_BEGIN_ALLOW_THREADS
    // Decompress until EOS marker is reached
    inProcessed = avail_in;
    outProcessed = bufsize;
    res = LzmaDec_DecodeToBuf(&self->state, next_out, &outProcessed,
                    next_in, &inProcessed, LZMA_FINISH_ANY, &status);
    Py_END_ALLOW_THREADS
    self->total_out += outProcessed;
    next_in += inProcessed;
    avail_in -= inProcessed;
    
    if (res != SZ_OK) {
        DEC_AND_NULL(result);
        PyErr_SetString(PyExc_ValueError, "data error during decompression");
        goto exit;
    }

    // Not all of the compressed data could be accomodated in the output buffer
    // of specified size. Return the unconsumed tail in an attribute.
    if (avail_in > 0) {
        if (self->unconsumed_tail == NULL) {
            // data are in "data"
            self->unconsumed_tail = (unsigned char *) malloc(avail_in);
            if (self->unconsumed_tail == NULL) {
                Py_DECREF(result);
                PyErr_NoMemory();
                goto exit;
            }
            memcpy(self->unconsumed_tail, next_in, avail_in);
        } else {
            memmove(self->unconsumed_tail, next_in, avail_in);
            self->unconsumed_tail = (unsigned char *) realloc(self->unconsumed_tail, avail_in);
        }
    } else {
        FREE_AND_NULL(self->unconsumed_tail);
    }
    
    self->unconsumed_length = avail_in;
    _PyString_Resize(&result, outProcessed);
    
exit:
    return result;
}
static PyObject *
pylzma_decomp_flush(CDecompressionObject *self, PyObject *args)
{
    PyObject *result=NULL;
    int res;
    SizeT avail_out, outsize;
    unsigned char *tmp;
    SizeT inProcessed, outProcessed;
    ELzmaStatus status;
    
    if (self->max_length != -1) {
        avail_out = self->max_length - self->total_out;
    } else {
        avail_out = BLOCK_SIZE;
    }
    
    if (avail_out == 0) {
        // no more remaining data
        return PyString_FromString("");
    }
    
    result = PyString_FromStringAndSize(NULL, avail_out);
    if (result == NULL) {
        return NULL;
    }
    
    tmp = (unsigned char *)PyString_AS_STRING(result);
    outsize = 0;
    while (1) {
        Py_BEGIN_ALLOW_THREADS
        if (self->unconsumed_length == 0) {
            // No remaining data
            inProcessed = 0;
            outProcessed = avail_out;
            res = LzmaDec_DecodeToBuf(&self->state, tmp, &outProcessed,
                            (Byte *) "", &inProcessed, LZMA_FINISH_ANY, &status);
        } else {
            // Decompress remaining data
            inProcessed = self->unconsumed_length;
            outProcessed = avail_out;
            res = LzmaDec_DecodeToBuf(&self->state, tmp, &outProcessed,
                            self->unconsumed_tail, &inProcessed, LZMA_FINISH_ANY, &status);
            self->unconsumed_length -= inProcessed;
            if (self->unconsumed_length > 0)
                memmove(self->unconsumed_tail, self->unconsumed_tail + inProcessed, self->unconsumed_length);
            else
                FREE_AND_NULL(self->unconsumed_tail);
        }
        Py_END_ALLOW_THREADS
        
        if (res != SZ_OK) {
            PyErr_SetString(PyExc_ValueError, "data error during decompression");
            DEC_AND_NULL(result);
            goto exit;
        }
        
        if (!outProcessed && self->max_length != -1 && self->total_out < self->max_length) {
            PyErr_SetString(PyExc_ValueError, "data error during decompression");
            DEC_AND_NULL(result);
            goto exit;
        }
        
        self->total_out += outProcessed;
        outsize += outProcessed;
        if (outProcessed < avail_out || (outProcessed == avail_out && self->max_length != -1)) {
            break;
        }
        
        if (self->max_length != -1) {
            PyErr_SetString(PyExc_ValueError, "not enough input data for decompression");
            DEC_AND_NULL(result);
            goto exit;
        }
        
        avail_out -= outProcessed;
        
        // Output buffer is full, might be more data for decompression
        if (_PyString_Resize(&result, outsize+BLOCK_SIZE) != 0) {
            goto exit;
        }
        
        avail_out += BLOCK_SIZE;
        tmp = (unsigned char *)PyString_AS_STRING(result) + outsize;
    }
    
    if (outsize != PyString_GET_SIZE(result)) {
        _PyString_Resize(&result, outsize);
    }
    
exit:
    return result;
}
int
elzma_decompress_run(elzma_decompress_handle hand,
                     elzma_read_callback inputStream, void * inputContext,
                     elzma_write_callback outputStream, void * outputContext,
                     elzma_file_format format)
{
    unsigned long long int totalRead = 0; /* total amount read from stream */
    unsigned int crc32 = CRC_INIT_VAL; /* running crc32 (lzip case) */     
    CLzmaDec dec;
    unsigned int errorCode = ELZMA_E_OK;
    struct elzma_format_handler formatHandler;
    struct elzma_file_header h;
    struct elzma_file_footer f;

    /* switch between supported formats */ 
    if (format == ELZMA_lzma) {
        initializeLZMAFormatHandler(&formatHandler);
    } else if (format == ELZMA_lzip) {
        CrcGenerateTable();        
        initializeLZIPFormatHandler(&formatHandler);
    } else {
        return ELZMA_E_BAD_PARAMS;        
    }

    /* initialize footer */
    f.crc32 = 0;
    f.uncompressedSize = 0;
    
    /* initialize decoder memory */
    memset((void *) &dec, 0, sizeof(dec));
    LzmaDec_Init(&dec);

    /* decode the header. */
    {
        unsigned char * hdr = 
            hand->allocStruct.Alloc(&(hand->allocStruct),
                                    formatHandler.header_size);

        size_t sz = formatHandler.header_size;

        formatHandler.init_header(&h);        

        if (inputStream(inputContext, hdr, &sz) != 0 ||
            sz != formatHandler.header_size)
        {
            hand->allocStruct.Free(&(hand->allocStruct), hdr);
            return ELZMA_E_INPUT_ERROR;
        }

        if (0 != formatHandler.parse_header(hdr, &h)) {
            hand->allocStruct.Free(&(hand->allocStruct), hdr);
            return ELZMA_E_CORRUPT_HEADER;
        }

        /* the LzmaDec_Allocate call requires 5 bytes which have
         * compression properties encoded in them.  In the case of
         * lzip, the header format does not already contain what
         * LzmaDec_Allocate expects, so we must craft it, silly */
        {
            unsigned char propsBuf[13];
            const unsigned char * propsPtr = hdr;            

            if (format == ELZMA_lzip) {
                struct elzma_format_handler lzmaHand;
                initializeLZMAFormatHandler(&lzmaHand);
                lzmaHand.serialize_header(propsBuf, &h);
                propsPtr = propsBuf;
            }

            /* now we're ready to allocate the decoder */
            LzmaDec_Allocate(&dec, propsPtr, 5,
                             (ISzAlloc *) &(hand->allocStruct));
        }
        
        hand->allocStruct.Free(&(hand->allocStruct), hdr);
    }

    /* perform the decoding */
    for (;;)
    {
        size_t dstLen = ELZMA_DECOMPRESS_OUTPUT_BUFSIZE;
        size_t srcLen = ELZMA_DECOMPRESS_INPUT_BUFSIZE;
        size_t amt = 0;
        size_t bufOff = 0;
		ELzmaStatus stat;

        if (0 != inputStream(inputContext, hand->inbuf, &srcLen))
        {
            errorCode = ELZMA_E_INPUT_ERROR;
            goto decompressEnd;                    
        }

        /* handle the case where the input prematurely finishes */
        if (srcLen == 0) {
            errorCode = ELZMA_E_INSUFFICIENT_INPUT;
            goto decompressEnd;
        }
        
        amt = srcLen;

        /* handle the case where a single read buffer of compressed bytes
         * will translate into multiple buffers of uncompressed bytes,
         * with this inner loop */
        stat = LZMA_STATUS_NOT_SPECIFIED;

        while (bufOff < srcLen) {
            SRes r = LzmaDec_DecodeToBuf(&dec, (Byte *) hand->outbuf, &dstLen,
                                         ((Byte *) hand->inbuf + bufOff), &amt,
                                         LZMA_FINISH_ANY, &stat);

            /* XXX deal with result code more granularly*/
            if (r != SZ_OK) {
                errorCode = ELZMA_E_DECOMPRESS_ERROR;
                goto decompressEnd;
            }
            
            /* write what we've read */
            {
                size_t wt;
                
                /* if decoding lzip, update our crc32 value */
                if (format == ELZMA_lzip && dstLen > 0) {
                    crc32 = CrcUpdate(crc32, hand->outbuf, dstLen);

                }
                totalRead += dstLen;
                
                wt = outputStream(outputContext, hand->outbuf, dstLen);
                if (wt != dstLen) {
                    errorCode = ELZMA_E_OUTPUT_ERROR;
                    goto decompressEnd;                    
                }
            }
            
            /* do we have more data on the input buffer? */
            bufOff += amt;
            assert( bufOff <= srcLen );
            if (bufOff >= srcLen) break;
            amt = srcLen - bufOff;

            /* with lzip, we will have the footer left on the buffer! */
            if (stat == LZMA_STATUS_FINISHED_WITH_MARK) {
                break;
            }
        }

        /* now check status */
        if (stat == LZMA_STATUS_FINISHED_WITH_MARK) {
            /* read a footer if one is expected and
             * present */ 
            if (formatHandler.footer_size > 0 &&
                amt >= formatHandler.footer_size &&
                formatHandler.parse_footer != NULL)
            {
                formatHandler.parse_footer(
                    (unsigned char *) hand->inbuf + bufOff, &f);
            }

            break;
        }
        /* for LZMA utils,  we don't always have a finished mark */
        if (!h.isStreamed && totalRead >= h.uncompressedSize) {
            break;
        }
    }

    /* finish the calculated crc32 */
    crc32 ^= 0xFFFFFFFF;

    /* if we have a footer, check that the calculated crc32 matches
     * the encoded crc32, and that the sizes match */
    if (formatHandler.footer_size)
    {
        if (f.crc32 != crc32) {
            errorCode = ELZMA_E_CRC32_MISMATCH;
        } else if (f.uncompressedSize != totalRead) {
            errorCode = ELZMA_E_SIZE_MISMATCH;            
        }
    }
    else if (!h.isStreamed)
    {
        /* if the format does not support a footer and has an uncompressed
         * size in the header, let's compare that with how much we actually
         * read */
        if (h.uncompressedSize != totalRead) {
            errorCode = ELZMA_E_SIZE_MISMATCH;
        }
    }

  decompressEnd:
    LzmaDec_Free(&dec, (ISzAlloc *) &(hand->allocStruct));

    return errorCode;
}