EXtremeZip 2025.1.28 → 2026.2.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/extremeunzip.zzaqsu.rb +203 -156
- metadata +4 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f227682a38c8df0687a850c2a05ad9d01a82dd7ec90cede09c4b1e65ff50fd1b
|
|
4
|
+
data.tar.gz: f196b85b110b359cb724f67f8d8d8068f4e9641baa77435f1412e56f82beb66b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2a77bafc6398bf03e73187288cf2d5b2bfbd78f6db2f046965697410d7a4dc7b42d75098e3abe27ea945abe2fd7317375eaedae4871fb9aab4da9485d893f8c8
|
|
7
|
+
data.tar.gz: afd5272df3f62c35a1dae6446282689020460e5fec46eb119ebecdfd70a9c318e526ebe8d573d5c5367e57a2372e524d6ebbaf508c5d50ceceb1d96957e2a148
|
data/lib/extremeunzip.zzaqsu.rb
CHANGED
|
@@ -1,156 +1,203 @@
|
|
|
1
|
-
require 'victoriafresh'
|
|
2
|
-
require 'cbor'
|
|
3
|
-
require 'lzma'
|
|
4
|
-
require 'get_process_mem'
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
1
|
+
require 'victoriafresh'
|
|
2
|
+
require 'cbor'
|
|
3
|
+
require 'lzma'
|
|
4
|
+
require 'get_process_mem'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def checkMemoryUsage(lineNumber)
|
|
8
|
+
mem = GetProcessMem.new
|
|
9
|
+
puts("#{lineNumber} , Memory: #{mem.mb}") # Debug
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class ExtremeUnZip
|
|
13
|
+
def initialize
|
|
14
|
+
# 移除 StreamDecoder 初始化,改为直接调用 LZMA.decompress
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def readVfsDataList(wholeCbor, currentBlockFile)
|
|
18
|
+
compressedVfsDataList = []
|
|
19
|
+
startIndix = wholeCbor['vfsDataListStart']
|
|
20
|
+
|
|
21
|
+
puts "list content: #{wholeCbor['vfsDataList']}" # Debug
|
|
22
|
+
|
|
23
|
+
expected_block_length = nil
|
|
24
|
+
|
|
25
|
+
# ✅ Release @wholeFileContent BEFORE the loop
|
|
26
|
+
@wholeFileContent = nil
|
|
27
|
+
GC.start
|
|
28
|
+
|
|
29
|
+
# Ensure temp dir exists
|
|
30
|
+
Dir.mkdir('/tmp/exz_blocks') rescue Errno::EEXIST
|
|
31
|
+
|
|
32
|
+
wholeCbor['vfsDataList'].each_with_index do |currentBlockInfo, index|
|
|
33
|
+
length = currentBlockInfo['length']
|
|
34
|
+
|
|
35
|
+
if expected_block_length.nil?
|
|
36
|
+
expected_block_length = length
|
|
37
|
+
elsif length != expected_block_length
|
|
38
|
+
puts "Warning: unexpected block length detected. Expected: #{expected_block_length}, got: #{length}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# ✅ Read directly from file on disk
|
|
42
|
+
currentBlockFile.seek(startIndix)
|
|
43
|
+
currentBlock = currentBlockFile.read(length)
|
|
44
|
+
|
|
45
|
+
# ✅ Write to persistent temp file (not Tempfile)
|
|
46
|
+
path = "/tmp/exz_blocks/block_#{Time.now.to_i}_#{rand(1000..9999)}.dat"
|
|
47
|
+
File.open(path, 'wb') do |f|
|
|
48
|
+
f.binmode
|
|
49
|
+
f.write(currentBlock)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Store path only
|
|
53
|
+
compressedVfsDataList << path
|
|
54
|
+
|
|
55
|
+
# ✅ Immediately release currentBlock
|
|
56
|
+
currentBlock = nil
|
|
57
|
+
|
|
58
|
+
# Optional: trigger GC periodically
|
|
59
|
+
GC.start if index % 5 == 0
|
|
60
|
+
|
|
61
|
+
startIndix += length
|
|
62
|
+
|
|
63
|
+
# ✅ Monitor memory after each block
|
|
64
|
+
checkMemoryUsage(200)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
compressedVfsDataList
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def extractVfsDataWithVersionExternalFile(wholeCbor, fileVersion, currentBlockFile)
|
|
71
|
+
dataFileName = 'victoriafreshdata.w'
|
|
72
|
+
expected_block_length = nil
|
|
73
|
+
|
|
74
|
+
if (fileVersion == 14)
|
|
75
|
+
compressedVfsData = wholeCbor['vfsData']
|
|
76
|
+
victoriaFreshData = LZMA.decompress(compressedVfsData)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
File.open(dataFileName, 'wb') do |dataFile|
|
|
80
|
+
dataFile.syswrite(victoriaFreshData)
|
|
81
|
+
puts "After writing initial block, raw data file size: #{File.size(dataFileName)}"
|
|
82
|
+
end
|
|
83
|
+
elsif (fileVersion >= 30)
|
|
84
|
+
compressedVfsDataList = wholeCbor['vfsDataList']
|
|
85
|
+
|
|
86
|
+
if (fileVersion >= 251)
|
|
87
|
+
# Returns list of temp file paths
|
|
88
|
+
compressedVfsDataList = readVfsDataList(wholeCbor, currentBlockFile)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
puts("data block amount: #{compressedVfsDataList.length}")
|
|
92
|
+
|
|
93
|
+
dataBlockCounter = 0
|
|
94
|
+
previous_block_length = nil
|
|
95
|
+
|
|
96
|
+
File.open(dataFileName, 'wb') do |dataFile|
|
|
97
|
+
begin
|
|
98
|
+
# Process one block at a time
|
|
99
|
+
compressedVfsDataList.each_with_index do |temp_path, index|
|
|
100
|
+
puts("data block counter: #{dataBlockCounter}")
|
|
101
|
+
checkMemoryUsage(30)
|
|
102
|
+
|
|
103
|
+
currentRawData = nil
|
|
104
|
+
|
|
105
|
+
begin
|
|
106
|
+
File.open(temp_path, 'rb') do |f|
|
|
107
|
+
compressedData = f.read
|
|
108
|
+
currentRawData = LZMA.decompress(compressedData)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if previous_block_length.nil?
|
|
112
|
+
previous_block_length = currentRawData.length
|
|
113
|
+
expected_block_length ||= previous_block_length
|
|
114
|
+
elsif currentRawData.length != previous_block_length || currentRawData.length == 0
|
|
115
|
+
if currentRawData.length == 0
|
|
116
|
+
puts "Warning: decompressed block length is zero at block #{index}. Generating fake data of expected length."
|
|
117
|
+
currentRawData = "\x00" * expected_block_length
|
|
118
|
+
else
|
|
119
|
+
puts "Warning: unexpected decompressed block length detected at block #{index}. Previous length: #{previous_block_length}, current length: #{currentRawData.length}"
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
dataFile.syswrite(currentRawData)
|
|
124
|
+
puts "After writing block #{index}, raw data file size: #{File.size(dataFileName)}"
|
|
125
|
+
rescue RuntimeError => e
|
|
126
|
+
puts "Warning: the exz file may be incomplete at block #{index}. Error: #{e.message}"
|
|
127
|
+
|
|
128
|
+
fake_data_block = "\x00" * expected_block_length
|
|
129
|
+
dataFile.syswrite(fake_data_block)
|
|
130
|
+
puts "After writing fake block #{index}, raw data file size: #{File.size(dataFileName)}"
|
|
131
|
+
next
|
|
132
|
+
ensure
|
|
133
|
+
# ✅ Delete after use
|
|
134
|
+
File.unlink(temp_path) rescue nil
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
dataBlockCounter += 1
|
|
138
|
+
checkMemoryUsage(70)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
dataFileName
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def exuz(rootPath)
|
|
148
|
+
result = true
|
|
149
|
+
|
|
150
|
+
begin
|
|
151
|
+
currentBlockFile = File.new(rootPath, 'rb')
|
|
152
|
+
@wholeFileContent = currentBlockFile.read
|
|
153
|
+
|
|
154
|
+
checkMemoryUsage(60)
|
|
155
|
+
|
|
156
|
+
wholeCborByteArray = @wholeFileContent[4..-1]
|
|
157
|
+
|
|
158
|
+
options = {:tolerant => true}
|
|
159
|
+
wholeCbor = CBOR.decode(wholeCborByteArray, options)
|
|
160
|
+
|
|
161
|
+
# ✅ Release wholeCborByteArray immediately after use
|
|
162
|
+
wholeCborByteArray = nil
|
|
163
|
+
GC.start
|
|
164
|
+
|
|
165
|
+
fileVersion = wholeCbor['version']
|
|
166
|
+
|
|
167
|
+
if (fileVersion < 14)
|
|
168
|
+
checkMemoryUsage(85)
|
|
169
|
+
puts 'file version too old'
|
|
170
|
+
else
|
|
171
|
+
compressedVfsMenu = wholeCbor['vfsMenu']
|
|
172
|
+
puts "compressed vfs menu size: #{compressedVfsMenu.size}"
|
|
173
|
+
|
|
174
|
+
checkMemoryUsage(90)
|
|
175
|
+
replyByteArray = LZMA.decompress(compressedVfsMenu)
|
|
176
|
+
|
|
177
|
+
checkMemoryUsage(95)
|
|
178
|
+
|
|
179
|
+
# ✅ Pass currentBlockFile all the way down
|
|
180
|
+
victoriaFreshDataFile = extractVfsDataWithVersionExternalFile(wholeCbor, fileVersion, currentBlockFile)
|
|
181
|
+
|
|
182
|
+
checkMemoryUsage(100)
|
|
183
|
+
$clipDownloader = VictoriaFresh.new
|
|
184
|
+
|
|
185
|
+
$clipDownloader.releaseFilesExternalDataFile(replyByteArray, victoriaFreshDataFile)
|
|
186
|
+
|
|
187
|
+
File.delete(victoriaFreshDataFile)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# ✅ Close file only after ALL operations
|
|
191
|
+
currentBlockFile.close
|
|
192
|
+
@wholeFileContent = nil
|
|
193
|
+
|
|
194
|
+
result = true
|
|
195
|
+
rescue EOFError => e
|
|
196
|
+
puts "Error: the exz file may be incomplete. Error: #{e.message}"
|
|
197
|
+
result = false
|
|
198
|
+
rescue => e
|
|
199
|
+
puts "Unexpected error: #{e.message}"
|
|
200
|
+
result = false
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: EXtremeZip
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2026.2.21
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hxcan Cai
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2026-02-21 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: cod
|
|
@@ -117,8 +116,8 @@ dependencies:
|
|
|
117
116
|
description: Extreme zip.
|
|
118
117
|
email: caihuosheng@gmail.com
|
|
119
118
|
executables:
|
|
120
|
-
- exz
|
|
121
119
|
- exuz
|
|
120
|
+
- exz
|
|
122
121
|
extensions: []
|
|
123
122
|
extra_rdoc_files: []
|
|
124
123
|
files:
|
|
@@ -130,7 +129,6 @@ homepage: http://rubygems.org/gems/EXtremeZip
|
|
|
130
129
|
licenses:
|
|
131
130
|
- MIT
|
|
132
131
|
metadata: {}
|
|
133
|
-
post_install_message:
|
|
134
132
|
rdoc_options: []
|
|
135
133
|
require_paths:
|
|
136
134
|
- lib
|
|
@@ -145,8 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
145
143
|
- !ruby/object:Gem::Version
|
|
146
144
|
version: '0'
|
|
147
145
|
requirements: []
|
|
148
|
-
rubygems_version: 3.
|
|
149
|
-
signing_key:
|
|
146
|
+
rubygems_version: 3.6.9
|
|
150
147
|
specification_version: 4
|
|
151
148
|
summary: EXtremeZip
|
|
152
149
|
test_files: []
|