MCPcopy
hub / github.com/Col-E/Recaf / writeArchive

Method writeArchive

src/main/java/me/coley/recaf/command/impl/Export.java:139–190  ·  view source on GitHub ↗

Writes a map to an archive. @param compress Enable zip compression. @param output File location of jar. @param content Contents to write to location. @throws IOException When the jar file cannot be written to.

(boolean compress, File output, Map<String, byte[]> content)

Source from the content-addressed store, hash-verified

137 * When the jar file cannot be written to.
138 */
139 public static void writeArchive(boolean compress, File output, Map<String, byte[]> content) throws IOException {
140 String extension = IOUtil.getExtension(output.toPath());
141 // Use buffered streams, reduce overall file write operations
142 OutputStream os = new BufferedOutputStream(Files.newOutputStream(output.toPath()), 1048576);
143 try (ZipOutputStream jos = ("zip".equals(extension)) ? new ZipOutputStream(os) :
144 /* Let's assume it's a jar */ new JarOutputStream(os)) {
145 VMUtil.patchZipOutput(jos);
146 PluginsManager pluginsManager = PluginsManager.getInstance();
147 Set<String> dirsVisited = new HashSet<>();
148 // Contents is iterated in sorted order (because 'archiveContent' is TreeMap).
149 // This allows us to insert directory entries before file entries of that directory occur.
150 CRC32 crc = new CRC32();
151 for (Map.Entry<String, byte[]> entry : content.entrySet()) {
152 String key = entry.getKey();
153 byte[] out = entry.getValue();
154 for (ExportInterceptorPlugin interceptor : pluginsManager.ofType(ExportInterceptorPlugin.class)) {
155 out = interceptor.intercept(key, out);
156 }
157 // Write directories for upcoming entries if necessary
158 // - Ugly, but does the job.
159 if (key.contains("/")) {
160 // Record directories
161 String parent = key;
162 List<String> toAdd = new ArrayList<>();
163 do {
164 parent = parent.substring(0, parent.lastIndexOf('/'));
165 if (dirsVisited.add(parent)) {
166 toAdd.add(0, parent + '/');
167 } else break;
168 } while (parent.contains("/"));
169 // Put directories in order of depth
170 for (String dir : toAdd) {
171 jos.putNextEntry(new JarEntry(dir));
172 jos.closeEntry();
173 }
174 }
175 // Write entry content
176 crc.reset();
177 crc.update(out, 0, out.length);
178 JarEntry outEntry = new JarEntry(key);
179 outEntry.setMethod(compress ? ZipEntry.DEFLATED : ZipEntry.STORED);
180 if (!compress) {
181 outEntry.setSize(out.length);
182 outEntry.setCompressedSize(out.length);
183 }
184 outEntry.setCrc(crc.getValue());
185 jos.putNextEntry(outEntry);
186 jos.write(out);
187 jos.closeEntry();
188 }
189 }
190 }
191
192 private void put(Map<String, byte[]> content, JavaResource res) {
193 content.putAll(res.getFiles());

Callers 1

callMethod · 0.95

Calls 13

getExtensionMethod · 0.95
patchZipOutputMethod · 0.95
getInstanceMethod · 0.95
ofTypeMethod · 0.95
toPathMethod · 0.80
entrySetMethod · 0.80
getKeyMethod · 0.80
interceptMethod · 0.65
equalsMethod · 0.45
getValueMethod · 0.45
containsMethod · 0.45
addMethod · 0.45

Tested by

no test coverage detected