Ejemplo n.º 1
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.º 2
0
		~ZipWriter_Impl()
		{
			if (file_begun && compress)
			{
				mz_deflateEnd(&zs);
			}
		}
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_deflator_gc(lua_State* L) {
  lmz_stream_t* stream = luaL_checkudata(L, 1, "miniz_deflator");
  mz_deflateEnd(&(stream->stream));
  return 0;
}