〜 ソフトウェア 〜
圧縮されたZipファイル内のファイル情報を取得 (要UNZIP32.DLL)

WindowsXPからは標準機能でzip書庫への追加や展開ができるようになりましたが、
ココでは昔ながらのアーカイバーで利用されていたZip書庫解凍用のUnZip32.dllを用いて
HSPでZipファイルを展開してみるサンプルを紹介します。
このUnZip32.dllがない場合は当モジュールを使用して正常に書庫を解凍できませんので、
統合アーカイバプロジェクト等から事前にダウンロードしておいてください。

今回はZip書庫ファイル内の情報取得について説明します。
その他のサンプル内で使用しているZip操作共通モジュールについては説明していません。
初期化やファイリスト取得についてはコチラの説明を参照してください。

それではモジュール命令の使い方を軽く説明します。
格納後のファイル名を取得するにはzip_getfilenameを使用しましょう。
この名称は、フォルダ内にある場合にフォルダ名も含んだ相対パスとなっています。

ファイルサイズを取得するにはzip_getfilesizeを使用してください。
zip_getfilesizezip_getfilenameと違って、格納前のファイルサイズとなります。
今回のサンプルではファイル名と共にファイル情報の表示しか行っておりませんが、
今後に紹介する「ファイル保存ではなくメモリ内に展開する際に変数の確保サイズ」として利用します。
	

zip_init
[パラメータなし]バージョンを取得するだけである為、パラメータは必要ない。
プログラム起動後に一度だけ実行する必要がある。

zip_wait
[パラメータなし]処理待ちするだけである為、パラメータは必要ない。
尚、処理可能状態になれば0が、処理できないままなら−1がstatに返る。

zip_getcount 受取先変数, 取得タイプ
受取先変数取得したカウント値(失敗:-1, 成功:アイテム数)の受取先とする数値型変数を指定する。
取得タイプ取得するタイプ(0:格納ファイル数, 1:ファイルリスト行数)を指定する。

zip_findfile 絞込条件
絞込条件ファイルリストに格納するファイル名の一部または拡張子とワイルドカードを指定する。
半角スペースを含むと複数の条件を指定したことになるので、
ファイル名の一部に半角スペースを含んでいるものを指定する時はダブルクォーテーションで囲む。
正常に指定したなら0が、失敗なら−1がstatに返る。

zip_sel zipファイル
zipファイル解凍対象となるzip書庫ファイルパスを指定する。
尚、内部でzip_findfileを使用している為、zip_selより前にzip_findfileを定義すること。
その際のファイルリスト絞込条件は「*」全ファイルである。
正常に指定したならファイルリストのバイト数が、失敗なら−1がstatに返る。

zip_getfilename 受取先変数, 番号
受取先変数ファイル名の受取先とする文字列型変数を指定する。
番号0から始まるファイルリストの行番号を指定する。

zip_getfilesize 受取先変数, 番号
受取先変数解凍後のファイルサイズ受取先とする数値型変数を指定する。
番号0から始まるファイルリストの行番号を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
	ll_libload unzip32, "UnZip32.dll"
	ll_getproc UnZipCloseArchive, "UnZipCloseArchive", unzip32
	ll_getproc UnZipFindFirst, "UnZipFindFirst", unzip32
	ll_getproc UnZipFindNext, "UnZipFindNext", unzip32
	ll_getproc UnZipGetFileCount, "UnZipGetFileCount", unzip32
	ll_getproc UnZipGetFileName, "UnZipGetFileName", unzip32
	ll_getproc UnZipGetOriginalSize, "UnZipGetOriginalSize", unzip32
	ll_getproc UnZipGetRunning, "UnZipGetRunning", unzip32
	ll_getproc UnZipGetVersion, "UnZipGetVersion", unzip32
	ll_getproc UnZipOpenArchive, "UnZipOpenArchive", unzip32

#module
#deffunc zip_init
	mref stt, 64
	zipver = 0
	if UnZipGetVersion@ {
		ll_callfnv UnZipGetVersion@ : ll_ret zipver
		poke zipver, 2
		stt = zipver ! 0
	}
	return

#deffunc zip_wait
	mref stt, 64
	repeat 0xFFFF
		ll_callfnv UnZipGetRunning@ : ll_ret prm
		if prm = 0 : stt = 1 : break
		wait 10
	loop
	stt = (stt ! 1) * -1
	return

#deffunc zip_getcount val, int
	mref count, 16 : mref type, 1
	mref stt, 64
	if zipver = 0 : stt = -1 : return : else : stt = 0
	if type {
		notesel filelist
		notemax count
	} else {
		ll_getptr zipfile : ll_ret prm
		ll_callfunc prm, 1, UnZipGetFileCount@ : ll_ret count
	}
	return

#deffunc zip_findfile str
	mref extension, 32
	mref stt, 64
	if zipver = 0 : stt = -1 : return
	zip_wait
	if stat : stt = -1 : return
	sdim s, 256
	zip_getcount prm
	if prm > 0 {
		sdim filelist, prm * 256
		dim sizelist, prm
	} else : stt = -1 : return
	prm = 0
	ll_getptr zipfile : ll_ret prm.1
	prm.2 = 0x02800000
	ll_callfunc prm, 2, UnZipOpenArchive@ : ll_ret harc
	notesel filelist
	j = 0
	repeat
		if cnt {
			ll_callfunc, harc, 1, UnZipFindNext@
		} else {
			prm = harc
			ll_getptr extension : ll_ret prm.1
			ll_callfunc, prm, 2, UnZipFindFirst@
		}
		ll_ret prm.3
		if prm.3 = -1 : break
		ll_getptr s : ll_ret prm.1
		prm.2 = 256
		ll_callfunc, prm, 3, UnZipGetFileName@
		ll_callfunc, prm, 1, UnZipGetOriginalSize@ : ll_ret prm.3
		if prm.3 > 0 : sizelist.j = prm.3 : noteadd s
	loop
	ll_callfunc, harc, 1, UnZipCloseArchive@
	notemax prm
	stt = ((prm ! 0) = 0) * -1
	return

#deffunc zip_sel str
	mref file, 32
	mref stt, 64
	if zipver = 0 : stt = -1 : return
	zipfile = file
	zip_findfile "*"
	if stat ! -1 : strlen stt, filelist
	return

#deffunc zip_getfilename val, int
	mref file, 24 : mref no, 1
	mref stt, 64 : mref rstr, 65
	notesel filelist
	notemax prm
	if prm <= no : stt = -1 : else : stt = 0 : noteget file, no
	return

#deffunc zip_getfilesize val, int
	mref size, 16 : mref no, 1
	mref stt, 64
	size = sizelist.no
	return
#global

	gosub *open
	objsize 100, 25
	button "選択", *change
	combox index, , item
	button "情報表示", *show
	stop

*open
	dialog "zip", 16, "zipファイル"
	if stat = 0 : end
	zip_init
	zip_sel refstr
	if stat = -1 : dialog "取得に失敗しました" : end
	zip_getcount i, 1
	sdim item, i * 4
	repeat i
		if cnt : item += "\n"
		item += "" + cnt
	loop
	return

*change
	gosub *open
	objprm 1, item
	objprm 1, 0
	stop

*show
	zip_getfilename filename, index
	zip_getfilesize filesize, index
	dialog "Item No. " + index + "\n\nFile Name\t" + filename + "\nFile Size\t" + filesize
	stop

zip_init
[パラメータなし]バージョンを取得するだけである為、パラメータは必要ない。
プログラム起動後に一度だけ実行する必要がある。

zip_wait
[パラメータなし]処理待ちするだけである為、パラメータは必要ない。
尚、処理可能状態になれば0が、処理できないままなら−1がstatに返る。

アイテム数 = zip_getcount(取得タイプ)
アイテム数カウント値(失敗:-1, 成功:アイテム数)の受取先を指定する。
取得タイプ取得するタイプ(0:格納ファイル数, 1:ファイルリスト行数)を指定する。

zip_findfile 絞込条件
絞込条件ファイルリストに格納するファイル名の一部または拡張子とワイルドカードを指定する。
半角スペースを含むと複数の条件を指定したことになるので、
ファイル名の一部に半角スペースを含んでいるものを指定する時はダブルクォーテーションで囲む。
正常に指定したなら0が、失敗なら−1がstatに返る。

zip_sel zipファイル
zipファイル解凍対象となるzip書庫ファイルパスを指定する。
尚、内部でzip_findfileを使用している為、zip_selより前にzip_findfileを定義すること。
その際のファイルリスト絞込条件は「*」全ファイルである。
正常に指定したならファイルリストのバイト数が、失敗なら−1がstatに返る。

ファイル名 = zip_getfilename(番号)
ファイル名ファイル名の受取先を指定する。
番号0から始まるファイルリストの行番号を指定する。

サイズ = zip_getfilesize(番号)
サイズ解凍後のファイルサイズ受取先を指定する。
番号0から始まるファイルリストの行番号を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#uselib "unzip32"
#func  global UnZipCloseArchive "UnZipCloseArchive" int
#func  global UnZipFindFirst "UnZipFindFirst" int, str, int
#func  global UnZipFindNext "UnZipFindNext" int, int
#cfunc global UnZipGetFileCount "UnZipGetFileCount" str
#func  global UnZipGetFileName "UnZipGetFileName" int, var, int
#cfunc global UnZipGetOriginalSize "UnZipGetOriginalSize" int
#func  global UnZipGetRunning "UnZipGetRunning"
#cfunc global UnZipGetVersion "UnZipGetVersion"
#cfunc global UnZipOpenArchive "UnZipOpenArchive" nullptr, str, int

#module
#deffunc zip_init
	zipver = 0
	if varptr(UnZipGetVersion) : zipver = UnZipGetVersion()
	poke zipver, 2
	return zipver ! 0

#deffunc zip_wait local i
	repeat 0xFFFF
		UnZipGetRunning
		if stat = 0 : i = 1 : break
		wait 10
	loop
	return (i = 0) * -1

#defcfunc zip_getcount int type, local i
	if zipver = 0 : return -1
	if type {
		notesel filelist
		i = notemax
		noteunsel
	} else : i = UnZipGetFileCount(zipfile)
	return i

#deffunc zip_findfile str extension, local i, local s
	if zipver = 0 : return -1
	zip_wait
	if stat : return -1
	sdim s, 256
	dim i, 3
	i = zip_getcount()
	if i <= 0 : return -1
	sdim filelist, i * 256
	dim sizelist, i
	i = UnZipOpenArchive(zipfile, 0x02800000)
	notesel filelist
	repeat
		if cnt = 0 : UnZipFindFirst i, extension : else : UnZipFindNext i
		if stat = -1 : break
		UnZipGetFileName i, s, 256
		sizelist(i.1) = UnZipGetOriginalSize(i)
		if stat > 0 : noteadd s : i.1++
	loop
	UnZipCloseArchive i
	noteunsel
	return 0

#deffunc zip_sel str file, local i
	if zipver = 0 : return -1
	zipfile = file
	zip_findfile "*"
	if stat = -1 : i = -1 : else : i = strlen(filelist)
	return i

#defcfunc zip_getfilename int no, local s
	notesel filelist
	if notemax <= no : return -1
	noteget s, no
	noteunsel
	return s

#defcfunc zip_getfilesize int no
	if length(sizelist) <= no : return -1
	return sizelist.no
#global

	gosub *open
	objsize 100, 25
	button gosub "ファイルを選択", *change
	combox index, , item
	button gosub "情報を表示", *show
	stop

*open
	dialog "zip", 16, "zipファイル"
	if stat = 0 : end
	zip_init
	zip_sel refstr
	if stat = -1 : dialog "取得に失敗しました" : end
	sdim item, zip_getcount(1) * 4
	repeat zip_getcount(1)
		if cnt : item += "\n"
		item += str(cnt)
	loop
	return

*change
	gosub *open
	objprm 1, item
	objprm 1, 0
	return

*show
	dialog strf("Item No. %d\n\nFile Name\t%s\nFile Size\t%d", index, zip_getfilename(index), zip_getfilesize(index))
	return