/*	
 *	clipunz.c
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2003 Naoyuki Sawa
 *
 *	* Wed Feb 27 19:37:00 JST 2003 Naoyuki Sawa
 *	- 新規作成。
 *	  my_unzip()だけをclipzlib.cから移してきました。
 *	  clipzlib.cにはmy_compress()が入っていて、my_unzip()もclipzlib.cに入れると、
 *	  my_unzip()を使っただけで、zlib圧縮ルーチンまでリンクされてしまうからです。
 *	* Sun Jul 13 18:48:00 JST 2003 Naoyuki Sawa
 *	- my_unzip(..., buffer=0, ...) で、ロードせずにサイズを取得できるようにしました。
 *	* Thu Nov 27 06:00:00 JST 2003 Naoyuki Sawa
 *	- my_unzip()にufi_out引数を追加。
 */
#include "clip.h"

/****************************************************************************
 *	zip展開
 ****************************************************************************/

int
my_unzip(const char* zip_fname, const char* item_name, void* buffer, int max_size, unz_file_info* ufi_out)
{
	int retval, len;
	unzFile uf;
	unz_file_info ufi;

	/* ZIPファイルを開きます。 */
	uf = unzOpen(zip_fname);
	if(uf == NULL) return 0;

	/* 目的のアイテムへシークします。 */
	retval = unzLocateFile(uf, item_name, 0);
	if(retval != 0) { unzClose(uf); return 0; }

	/* アイテムの情報を取得します。 */
	retval = unzGetCurrentFileInfo(uf, &ufi, NULL, 0, NULL, 0, NULL, 0);
	if(retval != 0) { unzClose(uf); return 0; }

	/* アイテムサイズを取得します。 */
	len = ufi.uncompressed_size;

	/* 読み込み要求ありなら... */
	if(buffer != NULL) {
		/* バッファサイズよりも大きければ、読み込めません。 */
		if(len > max_size) { unzClose(uf); return 0; }

		/* アイテムを開きます。 */
		retval = unzOpenCurrentFile(uf);
		if(retval != 0) { unzClose(uf); return 0; }

		/* アイテムを読み込みます。 */
		retval = unzReadCurrentFile(uf, buffer, len);
		if(retval != len) { unzClose(uf); return 0; }

		/* アイテムを閉じ、正しく読み込めたことを確認します。（CRC） */
		retval = unzCloseCurrentFile(uf);
		if(retval != 0) { unzClose(uf); return 0; }
	}

	/* ZIPファイルを閉じます。 */
	unzClose(uf);

	/* アイテム情報が要求されていたら、格納します。 */
	if(ufi_out) memcpy(ufi_out, &ufi, sizeof(unz_file_info));

	/* アイテムサイズを返します。 */
	return len;
}

