Ejemplo n.º 1
0
	source_result::status drive(bool flush = false)
	{
		if (empty())
			return source_result::eos;
			
		int deflate_flags = flush ? MZ_SYNC_FLUSH : MZ_NO_FLUSH;

		while (true)
		{
			if (str.avail_in == 0 && pull)
			{
				cur_ = end_;
				auto s = next_piece_();
				if (s == source_result::ok)
				{
					str.avail_in = (unsigned int)buf_left();
					sassert(str.avail_in > 0);
					str.next_in = (unsigned char*)cur_;
				}
				else if (s != source_result::eos)
				{
					return s;
				}
			}

			if (str.avail_out == 0)
			{
				cur_out->size_ = str.next_out - cur_out->data;
				
				return source_result::ok;
			}

			int ret;
			
			if (compress)
				ret = mz_deflate(&str, deflate_flags);
			else
				ret = mz_inflate(&str, deflate_flags);

			if (ret == MZ_STREAM_END)
			{
				cur_out->size_ = str.next_out - cur_out->data;

				close();
				return source_result::ok;
			}
			else if (ret != MZ_OK)
			{
				throw std::runtime_error("Error while deflating");
			}
			else if (deflate_flags == MZ_SYNC_FLUSH && str.avail_in == 0)
			{
				cur_out->size_ = str.next_out - cur_out->data;
				
				return source_result::ok;
			}
		}
	}
Ejemplo n.º 2
0
DataBuffer ZLibCompression::compress(const DataBuffer &data, bool raw, int compression_level, CompressionMode mode)
{
	const int window_bits = 15;

	DataBuffer zbuffer(1024*1024);
	IODevice_Memory output;

	int strategy = MZ_DEFAULT_STRATEGY;
	switch (mode)
	{
	case default_strategy: strategy = MZ_DEFAULT_STRATEGY; break;
	case filtered: strategy = MZ_FILTERED; break;
	case huffman_only: strategy = MZ_HUFFMAN_ONLY; break;
	case rle: strategy = MZ_RLE; break;
	case fixed: strategy = MZ_FIXED; break;
	}

	mz_stream zs = { nullptr };
	int result = mz_deflateInit2(&zs, compression_level, MZ_DEFLATED, raw ? -window_bits : window_bits, 8, strategy); // Undocumented: if wbits is negative, zlib skips header check
	if (result != MZ_OK)
		throw Exception("Zlib deflateInit failed");

	try
	{
		zs.next_in = (unsigned char *) data.get_data();
		zs.avail_in = data.get_size();
		while (true)
		{
			zs.next_out = (unsigned char *) zbuffer.get_data();
			zs.avail_out = zbuffer.get_size();

			int result = mz_deflate(&zs, MZ_FINISH);
			if (result == MZ_NEED_DICT) throw Exception("Zlib deflate wants a dictionary!");
			if (result == MZ_DATA_ERROR) throw Exception("Zip data stream is corrupted");
			if (result == MZ_STREAM_ERROR) throw Exception("Zip stream structure was inconsistent!");
			if (result == MZ_MEM_ERROR) throw Exception("Zlib did not have enough memory to compress file!");
			if (result == MZ_BUF_ERROR) throw Exception("Not enough data in buffer when Z_FINISH was used");
			if (result != MZ_OK && result != MZ_STREAM_END) throw Exception("Zlib deflate failed while compressing zip file!");
			int zsize = zbuffer.get_size() - zs.avail_out;
			if (zsize == 0)
				break;
			output.write(zbuffer.get_data(), zsize);
			if (result == MZ_STREAM_END)
				break;
		}
		mz_deflateEnd(&zs);
	}
	catch (...)
	{
		mz_deflateEnd(&zs);
		throw;
	}

	return output.get_data();
}
Ejemplo n.º 3
0
	void ZipWriter::end_file()
	{
		if (!impl->file_begun)
			return;

		if (impl->compress)
		{
			impl->zs.next_in = nullptr;
			impl->zs.avail_in = 0;

			while (true)
			{
				impl->zs.next_out = (unsigned char *)impl->zbuffer;
				impl->zs.avail_out = 16 * 1024;
				int result = mz_deflate(&impl->zs, MZ_FINISH);
				if (result == MZ_NEED_DICT) throw Exception("Zlib deflate wants a dictionary!");
				if (result == MZ_DATA_ERROR) throw Exception("Zip data stream is corrupted");
				if (result == MZ_STREAM_ERROR) throw Exception("Zip stream structure was inconsistent!");
				if (result == MZ_MEM_ERROR) throw Exception("Zlib did not have enough memory to compress file!");
				if (result == MZ_BUF_ERROR) throw Exception("Not enough data in buffer when Z_FINISH was used");
				if (result != MZ_OK && result != MZ_STREAM_END) throw Exception("Zlib deflate failed while compressing zip file!");
				int64_t zsize = 16 * 1024 - impl->zs.avail_out;
				if (zsize == 0)
					break;
				impl->output.write(impl->zbuffer, zsize);
				impl->compressed_length += zsize;

				if (result == MZ_STREAM_END)
					break;
			}

			mz_deflateEnd(&impl->zs);
			impl->compress = false;
		}

		impl->local_header.uncompressed_size = impl->uncompressed_length;
		impl->local_header.compressed_size = impl->compressed_length;
		impl->local_header.crc32 = ZipArchive_Impl::calc_crc32(nullptr, 0, impl->crc32, true);

		int64_t current_offset = impl->output.get_position();
		impl->output.seek(impl->local_header_offset);
		impl->local_header.save(impl->output);
		impl->output.seek(current_offset);

		ZipWriter_Impl::FileEntry file_entry;
		file_entry.local_header = impl->local_header;
		file_entry.local_header_offset = impl->local_header_offset;
		impl->written_files.push_back(file_entry);

		impl->file_begun = false;
	}
Ejemplo n.º 4
0
static int lmz_inflator_deflator_impl(lua_State* L, lmz_stream_t* stream) {
  mz_streamp miniz_stream = &(stream->stream);
  size_t data_size;
  const char* data = luaL_checklstring(L, 2, &data_size);
  int flush = luaL_checkoption(L, 3, "no", flush_types);
  miniz_stream->avail_in = data_size;
  miniz_stream->next_in = (const unsigned char*)data;
  luaL_Buffer buf;
  luaL_buffinit(L, &buf);
  while (1) {
    char* buffer = luaL_prepbuffer(&buf);
    memset(buffer, 0, LUAL_BUFFERSIZE);
    miniz_stream->avail_out = LUAL_BUFFERSIZE;
    miniz_stream->next_out = (unsigned char*)buffer;
    size_t before = miniz_stream->total_out;
    int status;
    if (stream->mode) {
      status = mz_inflate(miniz_stream, flush);
    } else {
      status = mz_deflate(miniz_stream, flush);
    }
    size_t added = miniz_stream->total_out - before;
    luaL_addsize(&buf, added);
    switch (status) {
      case MZ_OK:
      case MZ_STREAM_END:
        luaL_pushresult(&buf);
        return 1;
      case MZ_STREAM_ERROR:
      case MZ_DATA_ERROR:
      case MZ_PARAM_ERROR:
        luaL_pushresult(&buf);
        lua_pushnil(L);
        lua_insert(L, -2);
        lua_pushstring(L, mz_error(status));
        lua_insert(L, -2);
        return 3;
      case MZ_BUF_ERROR:
        if (stream->mode) {
        // not enough input
        luaL_pushresult(&buf);
        lua_pushnil(L);
        lua_insert(L, -2);
        lua_pushstring(L, "Not enough input data");
        lua_insert(L, -2);
        return 3;
        }
        break;
    }
  }
}
Ejemplo n.º 5
0
Archivo: gzip.c Proyecto: strake/gzip
St go (int level /* Zip level; 0 to mean unzip */, int ifd, int ofd) {
	uint8_t x[chunkSize], y[chunkSize];
	z_stream s;
	
	memset (&s, 0, sizeof (z_stream));
	int windowBits = -MZ_DEFAULT_WINDOW_BITS;
	if (level == 0 ? inflateInit2 (&s,                     windowBits)
	               : deflateInit2 (&s, level, MZ_DEFLATED, windowBits, 6, MZ_DEFAULT_STRATEGY)) {
		errx (-1, "failed");
	}
	
	for (;;) {
		int n, fin = 0;
		n = read (ifd, x + s.avail_in, chunkSize - s.avail_in);
		if (n < 0) err (n, "failed to read");
		s.next_in   = x;
		s.next_out  = y;
		s.avail_in += n;
		s.avail_out = chunkSize;
retry:
		switch (level == 0 ? mz_inflate (&s, MZ_SYNC_FLUSH) : mz_deflate (&s, n > 0 ? MZ_FINISH : MZ_SYNC_FLUSH)) {
		int n;
		case MZ_STREAM_END:
			fin = 1;
		case MZ_OK:
			write (ofd, y, chunkSize - s.avail_out);
			s.avail_in = 0;
			if (fin) return (St) { .l = level == 0 ? s.total_out : s.total_in, .crc32 = s.crc32 };
			break;
		case MZ_BUF_ERROR:
			continue;
		case MZ_DATA_ERROR:
			errx (-1, "not flated data");
		case MZ_PARAM_ERROR:
			errx (-1, "failed");
		}
	}
}

ssize_t readn (int fd, void *x, size_t n) {
	int n0 = n;
	while (n > 0) {
		int m = read (fd, x, n);
		if (m < 0) return m;
		n -= m;
		x = (uint8_t *)x + m;
	}
	return n0;
}
Ejemplo n.º 6
0
	void ZipWriter::write_file_data(const void *data, int64_t size)
	{
		if (!impl->file_begun)
			throw Exception("ZipWriter::begin_file not called prior ZipWriter::write_file_data");

		impl->uncompressed_length += size;

		if (impl->compress)
		{
			impl->zs.next_in = (unsigned char *)data;
			impl->zs.avail_in = size;

			while (impl->zs.avail_in > 0)
			{
				impl->zs.next_out = (unsigned char *)impl->zbuffer;
				impl->zs.avail_out = 16 * 1024;
				int result = mz_deflate(&impl->zs, MZ_NO_FLUSH);
				if (result == MZ_NEED_DICT) throw Exception("Zlib deflate wants a dictionary!");
				if (result == MZ_DATA_ERROR) throw Exception("Zip data stream is corrupted");
				if (result == MZ_STREAM_ERROR) throw Exception("Zip stream structure was inconsistent!");
				if (result == MZ_MEM_ERROR) throw Exception("Zlib did not have enough memory to compress file!");
				if (result == MZ_BUF_ERROR) throw Exception("Not enough data in buffer when Z_FINISH was used");
				if (result != MZ_OK) throw Exception("Zlib deflate failed while compressing zip file!");

				int64_t zsize = 16 * 1024 - impl->zs.avail_out;
				if (zsize > 0)
				{
					impl->compressed_length += zsize;
					impl->output.write(impl->zbuffer, zsize);
				}
			}
		}
		else
		{
			impl->compressed_length += size;
			impl->output.write(data, size);
		}

		impl->crc32 = ZipArchive_Impl::calc_crc32(data, size, impl->crc32, false);
	}