Java tutorial
/* * Copyright (c) 2015, Minecrell <https://github.com/Minecrell> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package net.minecrell.workbench.tools.mapping.format; import static net.minecrell.workbench.tools.mapping.name.Name.Type.FIELD; import static net.minecrell.workbench.tools.mapping.name.Name.Type.METHOD; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableMap; import net.minecrell.workbench.tools.mapping.BaseMappings; import net.minecrell.workbench.tools.mapping.name.BaseName; import net.minecrell.workbench.tools.mapping.name.Name; import java.io.BufferedReader; import java.io.IOException; import java.util.Iterator; import java.util.function.Consumer; public final class McpMappingFormat { private McpMappingFormat() { } private static final Splitter CSV_SPLITTER = Splitter.on(',').limit(4); private static final char QUOTE_CHAR = '"'; private static final String QUOTE = "\"\"\""; private static final char ESCAPE_CHAR = '\\'; private static final char ESCAPED_NEWLINE = 'n'; private static final char NEWLINE = '\n'; public static BaseMappings.Builder read(BufferedReader reader, BaseMappings.Builder builder, Name.Type type) throws IOException { switch (type) { case FIELD: read(reader, builder.getFields(), FIELD); break; case METHOD: read(reader, builder.getMethods(), METHOD); break; case PARAMETER: readCsv(reader, parts -> builder.addParameter(parts.next(), parts.next())); break; } return builder; } private static void read(BufferedReader reader, ImmutableMap.Builder<String, BaseName> builder, Name.Type type) throws IOException { readCsv(reader, parts -> { String srg = parts.next(); String mcp = parts.next(); parts.next(); // Skip side String javadoc = parseJavadoc(parts.next()); builder.put(srg, new BaseName(type, mcp, javadoc)); }); } private static void readCsv(BufferedReader reader, Consumer<Iterator<String>> consumer) throws IOException { String line; boolean first = true; while ((line = reader.readLine()) != null) { if ((line = line.trim()).isEmpty() || line.charAt(0) == '#') { continue; } else if (first) { first = false; continue; } consumer.accept(CSV_SPLITTER.split(line).iterator()); } } private static String parseJavadoc(String javadoc) { if (javadoc.isEmpty()) { return ""; } int len = javadoc.length(); int start = 0; int end = len; if (javadoc.startsWith(QUOTE) && javadoc.endsWith(QUOTE)) { start = 3; end -= 3; } else if (javadoc.charAt(0) == QUOTE_CHAR && javadoc.charAt(len - 1) == QUOTE_CHAR) { start = 1; end -= 1; } int next = javadoc.indexOf(ESCAPE_CHAR); if (next == -1) { return javadoc.substring(start, end); } StringBuilder result = new StringBuilder(len); int pos = start; do { if (javadoc.charAt(next + 1) == ESCAPED_NEWLINE) { result.append(javadoc, pos, next); result.append(NEWLINE); pos = ++next + 1; } next = javadoc.indexOf(ESCAPE_CHAR, next + 1); } while (next != -1); if (pos < end) { result.append(javadoc, pos, end); } return result.toString(); } }