⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 block.c

📁 zzip-zzlib-src.zip. A new archiver that uses a BWT algorithm to achieve superior compression. The
💻 C
📖 第 1 页 / 共 3 页
字号:
		|| size > 20*1024*1024)
	{
		last_error = BAD_PARAMETER;
		return -1;
	}

	session = (session_param_s*)MyMalloc(sizeof(session_param_s));
	if (last_error != OK) return -1;

	block.type = NO_TYPE;
	session->multimedia_test = multimedia_test;
	session->compression_mode = compression_mode;

	len = CompressBlock(0, buffer, size);

	session = MyFree(session);

	return len;
}

DLL_EXPORT int ZzUncompressBlock(unsigned char *buffer)
{
	int len;

	last_error = OK;

	if (buffer == NULL)
	{
		last_error = BAD_PARAMETER;
		return -1;
	}

	session = (session_param_s*)MyMalloc(sizeof(session_param_s));
	if (last_error != OK) return -1;

	len = UncompressBlock(UNCOMPRESS, 0, buffer);

	session = MyFree(session);

	return len;
}

#endif /* ZZLIB */

/*---------------------------------------------*/

#ifdef ZZLIB
DLL_EXPORT
#endif /* ZZLIB */
int OpenArchive(actions action, 
				 char    *filename, 
				 info_s  *info)
{
	sint r = 0;

	last_error = OK;

	session = (session_param_s*)MyMalloc(sizeof(session_param_s));
	if (last_error != OK) return -1;

#ifdef ZZLIB
	if (filename == NULL)
	{
		last_error = BAD_PARAMETER;
		return -1;
	}

	while (session_tab[r] != NULL) r++;
	if (r == NB_MAX_SESSION)
	{ 
		last_error = TOO_MANY_SESSION; 
		return -1; 
	}
	session_tab[r] = session;
#endif /* ZZLIB */

    session->action = action;
	session->input_total = 0;
	session->output_total = 0;
	session->output_filename = NULL;
	session->output_file = NULL;
	session->input_filename = NULL;
	session->input_file = NULL;
	session->head_file.name = NULL;

	switch (action)
	{

#ifndef SFX
	case DELETE:
	case UPDATE:
		session->output_filename = strdup(filename);
		if ((session->output_file = fopen(session->output_filename, "r+b")) == NULL) 
		{ 
			last_error = CANNOT_OPEN_OUTPUT_FILE; 
			return -1;
		}
		session->input_file = session->output_file;
		
		FSEEK_O(0, SEEK_SET);

		Read_Header_Arc();

		FSEEK_I(0, SEEK_END);

		if (last_error != OK) return -1;

		break;
	case CREATE:
		session->head_arc.nb_of_file = 0;
		session->head_arc.magic[0] = 'Z';
		session->head_arc.magic[1] = 'Z';
		session->head_arc.version_number = VERSION_NUMBER;

		session->output_filename = strdup(filename);
		if ((session->output_file = fopen(session->output_filename, "wb")) == NULL) 
		{ 
			last_error = CANNOT_OPEN_OUTPUT_FILE; 
			return -1;
		}

		Write_Header_Arc();
		if (last_error != OK) return -1;

		break;
#endif /* !SFX */
	case TEST:
	case LIST:
	case EXTRACT:
		session->input_filename = strdup(filename);

		if ((session->input_file = fopen(session->input_filename, "rb")) == NULL)
		{ 
			last_error = CANNOT_OPEN_INPUT_FILE; 
			return -1;
		}

#ifdef SFX
		VERBOSE printf("\n  Checking archive CRC...");

		Crc32_File(session->input_file);
		if (last_error != OK) return -1;

		FSEEK_I(START_OFFSET, SEEK_SET);
		if (last_error != OK) return -1;

		VERBOSE printf(" OK\n");
#endif /* SFX */

		Read_Header_Arc();
		if (last_error != OK) return -1;

		break;
	default:
		last_error = BAD_PARAMETER;
		return -1;
	}

	if (info != NULL)
	{
		info->nb_of_file = session->head_arc.nb_of_file;
	}

	return r;
}

/*---------------------------------------------*/

#ifdef ZZLIB
DLL_EXPORT void CloseArchive(sint   handle, 
							 info_s *info)
#else  /* ZZLIB */
void CloseArchive(info_s *info)
#endif /* ZZLIB */
{
#ifdef ZZLIB
	if (session_tab[handle] == NULL)
	{
		last_error = BAD_PARAMETER;
		return;
	}
	session = session_tab[handle];
#else  /* ZZLIB */
	if (session == NULL) return;
#endif /* ZZLIB */


#ifndef SFX
	if (session->action == CREATE || session->action == UPDATE || session->action == DELETE)
	{
		FSEEK_O(0, SEEK_SET);
		Write_Header_Arc();
	}

	if (last_error != OK) return;

	if (session->action == DELETE)
	{
		slong filesize;
		ListAllFile(
#ifdef ZZLIB
			handle,
#endif /* ZZLIB */
			NULL);
		FTELL_I(filesize);

#ifdef WIN32
		if (chsize(fileno(session->input_file), filesize) != 0) IO_ERROR();
#else
		if (ftruncate(fileno(session->input_file), filesize) != 0) IO_ERROR();
#endif /* WIN32 */
	}
#endif /* !SFX */

	if (session->input_file != NULL) 
		if (fclose(session->input_file) != 0) last_error = CANNOT_CLOSE_INPUT_FILE;

	if (session->output_file != NULL && session->output_file != session->input_file) 
		if (fclose(session->output_file) != 0) last_error = CANNOT_CLOSE_OUTPUT_FILE;

	session->input_file = NULL;
	session->output_file = NULL;

	if (last_error != OK && session->output_filename != NULL) remove(session->output_filename); 

	free(session->input_filename);
	free(session->output_filename);

	if (info != NULL)
	{
		info->input_size = session->input_total;
		info->output_size = session->output_total;
		info->nb_of_file = session->head_arc.nb_of_file;
	}

	session = MyFree(session);
#ifdef ZZLIB
	session_tab[handle] = NULL;
#endif /* ZZLIB */
}

/*---------------------------------------------*/

#ifdef ZZLIB
DLL_EXPORT void ListNextFile(sint   handle, 
							 info_s *info)
#else  /* ZZLIB */
void ListNextFile(info_s *info)
#endif /* ZZLIB */
{
	slong pos1, pos2;

	last_error = OK;

#ifdef ZZLIB
	if (session_tab[handle] == NULL)
	{
		last_error = BAD_PARAMETER;
		return;
	}
	session = session_tab[handle];
#endif /* ZZLIB */

	FTELL_I(pos1);

	Read_Header_File();

	FSEEK_I((sint32)session->head_file.packed_size, SEEK_CUR);

	FTELL_I(pos2);

	if (last_error != OK) return;

	if (info != NULL)
	{
		info->filename = session->head_file.name;
		info->input_size = session->head_file.original_size;
		info->output_size = (uint32)(pos2 - pos1);
		info->filetime = session->head_file.time;
	}
}

/*---------------------------------------------*/

#ifdef ZZLIB
DLL_EXPORT void ListAllFile(sint   handle, 
							info_s **info)
#else  /* ZZLIB */
void ListAllFile(info_s **info)
#endif /* ZZLIB */
{
	uint  i, nb;

	last_error = OK;

#ifdef ZZLIB
	if (session_tab[handle] == NULL)
	{
		last_error = BAD_PARAMETER;
		return;
	}
	session = session_tab[handle];
#endif /* ZZLIB */

	FSEEK_I(START_OFFSET, SEEK_SET);
	if (last_error != OK) return;

	nb = session->head_arc.nb_of_file;
	Read_Header_Arc();
	if (last_error != OK) return;
	session->head_arc.nb_of_file = nb;

	for (i = 0; i < session->head_arc.nb_of_file; ++i)
	{
		if (info != NULL && info[i] != NULL) 
		{ 
			ListNextFile(
#ifdef ZZLIB
				handle,
#endif /* ZZLIB */
				info[i]);
			if (last_error != OK) return;
			info[i]->filename = strdup(info[i]->filename);
			session->input_total += info[i]->input_size;
			session->output_total += info[i]->output_size;
		}
		else
		{
			ListNextFile(
#ifdef ZZLIB
				handle,
#endif /* ZZLIB */
				NULL);
			if (last_error != OK) return;
		}
	}
}

/*---------------------------------------------*/

#ifdef ZZLIB
DLL_EXPORT void SetArchivePointer(sint   handle, 
								  char   *filename, 
								  info_s *info)
#else  /* ZZLIB */
void SetArchivePointer(char   *filename, 
					   info_s *info)
#endif /* ZZLIB */
{
	uint  i, nb;
	bool  ok = false;

	last_error = OK;

#ifdef ZZLIB
	if (session_tab[handle] == NULL)
	{
		last_error = BAD_PARAMETER;
		return;
	}
	session = session_tab[handle];
#endif /* ZZLIB */

	FSEEK_I(START_OFFSET, SEEK_SET);
	if (last_error != OK) return;

	nb = session->head_arc.nb_of_file;
	Read_Header_Arc();
	if (last_error != OK) return;
	session->head_arc.nb_of_file = nb;

	if (filename == NULL) 
	{
		session->input_total = 0;
		session->output_total = 0;
		return;
	}

	if (info == NULL)
	{
		info = (info_s*)MyMalloc(sizeof(info_s));
		if (last_error != OK) return;
	}

	for (i = 0; i < session->head_arc.nb_of_file; ++i)
	{
		ListNextFile(
#ifdef ZZLIB
			handle,
#endif
			info);
		if (last_error != OK) return;
		if (strcmp(info->filename, filename) == 0)
		{
			ok = true;
			break;
		}
	}

	if (ok == false)
	{
		last_error = FILE_NOT_FOUND;
		return;
	}

	FSEEK_I(-((slong)(info->output_size)), SEEK_CUR);
	if (last_error != OK) return;
}

/*---------------------------------------------*/

#ifndef SFX

#ifdef ZZLIB
DLL_EXPORT void AddFile(sint   handle, 
						char   *filename, 
						uint   compression_mode, 
						uint   multimedia_test, 
						uint   block_size, 
						info_s *info)
#else  /* ZZLIB */
void AddFile(char   *filename, 
			 uint   compression_mode, 
			 uint   multimedia_test, 
			 uint   block_size, 
			 info_s *info)
#endif /* ZZLIB */
{
	last_error = OK;

#ifdef ZZLIB
	if (session_tab[handle] == NULL
		|| filename == NULL
		|| (session->action != CREATE && session->action != UPDATE))
	{
		last_error = BAD_PARAMETER;
		return;
	}
	session = session_tab[handle];
#endif /* ZZLIB */

	block_size = MIN(block_size, 15*1024*1024);	/* max block size of 15Mb (1<<24 plus margin, cf. bwt.c) */
	block_size = MAX(block_size, 64*1024);		/* min block size of 64kb */

	session->compression_mode = compression_mode;
	session->type = NO_TYPE;
	session->block_size = block_size;
	session->head_arc.nb_of_file++;
	session->multimedia_test = multimedia_test;
	session->input_filename = filename;

	Compress();
	if (last_error != OK) return;

	if (info != NULL)
	{
		info->filename = session->output_filename;
		info->filetime = session->head_file.time;
		info->input_size = session->head_file.original_size;
		info->output_size = session->head_file.packed_size;
	}

	session->input_filename = NULL;
}

#endif /* !SFX */

/*---------------------------------------------*/

#ifdef ZZLIB
DLL_EXPORT void TestNextFile(sint   handle, 
							 info_s *info)
#else  /* ZZLIB */
void TestNextFile(info_s *info)
#endif /* ZZLIB*/
{
	last_error = OK;

#ifdef ZZLIB
	if (session_tab[handle] == NULL	|| session->action != TEST)
	{
		last_error = BAD_PARAMETER;
		return;
	}
	session = session_tab[handle];
#endif /* ZZLIB */

	session->with_path = false;
	session->output_filename = NULL;

	Uncompress(TEST_CRC);
	if (last_error != OK) return;

	if (info != NULL)
	{
		info->filename = session->output_filename;
		info->filetime = session->head_file.time;
		info->input_size = session->head_file.packed_size;
		info->output_size = session->head_file.original_size;
	}

	session->output_filename = NULL;
}

/*---------------------------------------------*/

#ifndef SFX

#define BSIZE (2 * 1024 * 1024)

#ifdef ZZLIB
DLL_EXPORT void DeleteNextFile(sint handle)
#else  /* ZZLIB */
void DeleteNextFile()
#endif /* ZZLIB */
{
	uint32 len;
	slong  rpointer, wpointer;
	uint8  *fileblock = NULL;

	last_error = OK;

#ifdef ZZLIB
	if (session_tab[handle] == NULL || session->action != DELETE)
	{
		last_error = BAD_PARAMETER;
		return;
	}
	session = session_tab[handle];
#endif /* ZZLIB */

	fileblock = (uint8*)MyMalloc(sizeof(uint8) * BSIZE);
	if (last_error != OK) return;
				
	FTELL_I(wpointer);
	if (last_error != OK) return;

	ListNextFile(
#ifdef ZZLIB
		handle,
#endif /* ZZLIB */
		NULL);
	if (last_error != OK) return;

	FTELL_I(rpointer);
	if (last_error != OK) return;
				
	do
	{
		FSEEK_I(rpointer, SEEK_SET);
		if (last_error != OK) return;
		len = READ_F(fileblock, sizeof(uint8) * BSIZE);
		if (last_error == UNEXPECTED_EOF) last_error = OK;
		if (last_error != OK) return;
		rpointer += len;
		
		FSEEK_I(wpointer, SEEK_SET);
		if (last_error != OK) return;
		WRITE_F(fileblock, sizeof(uint8) * len);
		CHECK_IO_W();
		if (last_error != OK) return;
		wpointer += len;
	}
	while (len == BSIZE);

	session->head_arc.nb_of_file--;
				
	fileblock = MyFree(fileblock);
}

#endif /* !SFX */

/*---------------------------------------------*/

#ifdef ZZLIB
DLL_EXPORT void ExtractNextFile(sint   handle, 
								char   *filename, 
								uint   with_path, 
								info_s *info)
#else  /* ZZLIB */
void ExtractNextFile(char   *filename, 
					 uint   with_path, 
					 info_s *info)
#endif /* ZZLIB */
{
	last_error = OK;

#ifdef ZZLIB
	if (session_tab[handle] == NULL	|| session->action != EXTRACT)
	{
		last_error = BAD_PARAMETER;
		return;
	}
	session = session_tab[handle];
#endif /* ZZLIB */

	session->with_path = with_path;
	session->output_filename = filename;

	Uncompress(UNCOMPRESS);
	if (last_error != OK) return;

	if (info != NULL)
	{
		info->filename = session->output_filename;
		info->filetime = session->head_file.time;
		info->input_size = session->head_file.packed_size;
		info->output_size = session->head_file.original_size;
	}
	session->output_filename = NULL;
}

/*---------------------------------------------*/
/* end                                 block.c */
/*---------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -