From c4970cc4addedd4565cf8c3ed9ea92b6a4487e0c Mon Sep 17 00:00:00 2001 From: Thomas Guillemard Date: Fri, 12 Aug 2016 19:23:54 +0200 Subject: Implement Enigma directory format (#1) Others changes: ~ Rework File menu ~ Force UTF-8 for all I/O operations ~ Enigma now detect the original file format and use the correct one when you save a mapping--- .../enigma/mapping/MappingsEnigmaWriter.java | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java (limited to 'src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java') diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java new file mode 100644 index 0000000..a3b0616 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.mapping; + +import com.google.common.base.Charsets; + +import java.io.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class MappingsEnigmaWriter { + + public void write(File out, Mappings mappings, boolean isDirectoryFormat) throws IOException { + if (!isDirectoryFormat) + { + PrintWriter outputWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(out), Charsets.UTF_8)); + write(outputWriter, mappings); + outputWriter.close(); + } + else + writeAsDirectory(out, mappings); + } + + public void writeAsDirectory(File target, Mappings mappings) throws IOException { + if (!target.exists() && !target.mkdirs()) + throw new IOException("Cannot create mapping directory!"); + + for (ClassMapping classMapping : sorted(mappings.classes())) { + File obFile = new File(target, classMapping.getObfFullName() + ".mapping"); + File result; + if (classMapping.getDeobfName() == null) + result = obFile; + else + { + // Make sure that old version of the file doesn't exist + if (obFile.exists()) + obFile.delete(); + result = new File(target, classMapping.getDeobfName() + ".mapping"); + } + + if (!result.getParentFile().exists()) + result.getParentFile().mkdirs(); + result.createNewFile(); + PrintWriter outputWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(result), Charsets.UTF_8)); + write(outputWriter, classMapping, 0); + outputWriter.close(); + } + + // Remove empty directories + File[] fileList = target.listFiles(); + if (fileList != null) + { + for (File file : fileList) + { + if (file.isDirectory()) + { + File[] childFiles = file.listFiles(); + if (childFiles != null && childFiles.length == 0) + file.delete(); + } + } + } + + } + + public void write(PrintWriter out, Mappings mappings) throws IOException { + for (ClassMapping classMapping : sorted(mappings.classes())) { + write(out, classMapping, 0); + } + } + + private void write(PrintWriter out, ClassMapping classMapping, int depth) throws IOException { + if (classMapping.getDeobfName() == null) { + out.format("%sCLASS %s\n", getIndent(depth), classMapping.getObfFullName()); + } else { + out.format("%sCLASS %s %s\n", getIndent(depth), classMapping.getObfFullName(), classMapping.getDeobfName()); + } + + for (ClassMapping innerClassMapping : sorted(classMapping.innerClasses())) { + write(out, innerClassMapping, depth + 1); + } + + for (FieldMapping fieldMapping : sorted(classMapping.fields())) { + write(out, fieldMapping, depth + 1); + } + + for (MethodMapping methodMapping : sorted(classMapping.methods())) { + write(out, methodMapping, depth + 1); + } + } + + private void write(PrintWriter out, FieldMapping fieldMapping, int depth) throws IOException { + out.format("%sFIELD %s %s %s\n", getIndent(depth), fieldMapping.getObfName(), fieldMapping.getDeobfName(), fieldMapping.getObfType().toString()); + } + + private void write(PrintWriter out, MethodMapping methodMapping, int depth) throws IOException { + if (methodMapping.getDeobfName() == null) { + out.format("%sMETHOD %s %s\n", getIndent(depth), methodMapping.getObfName(), methodMapping.getObfSignature()); + } else { + out.format("%sMETHOD %s %s %s\n", getIndent(depth), methodMapping.getObfName(), methodMapping.getDeobfName(), methodMapping.getObfSignature()); + } + + for (ArgumentMapping argumentMapping : sorted(methodMapping.arguments())) { + write(out, argumentMapping, depth + 1); + } + } + + private void write(PrintWriter out, ArgumentMapping argumentMapping, int depth) throws IOException { + out.format("%sARG %d %s\n", getIndent(depth), argumentMapping.getIndex(), argumentMapping.getName()); + } + + private > List sorted(Iterable classes) { + List out = new ArrayList(); + for (T t : classes) { + out.add(t); + } + Collections.sort(out); + return out; + } + + private String getIndent(int depth) { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < depth; i++) { + buf.append("\t"); + } + return buf.toString(); + } +} -- cgit v1.2.3