cuchaz.enigma.mapping.io.reader.MappingsLegacyReader.java Source code

Java tutorial

Introduction

Here is the source code for cuchaz.enigma.mapping.io.reader.MappingsLegacyReader.java

Source

/*******************************************************************************
 * 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.io.reader;

import com.google.common.collect.Queues;
import cuchaz.enigma.mapping.type.ArgumentMapping;
import cuchaz.enigma.mapping.type.ClassMapping;
import cuchaz.enigma.mapping.type.FieldMapping;
import cuchaz.enigma.mapping.exception.MappingParseException;
import cuchaz.enigma.mapping.util.Mappings;
import cuchaz.enigma.mapping.type.MethodMapping;
import cuchaz.enigma.mapping.element.Signature;
import cuchaz.enigma.mapping.element.Type;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Deque;

public class MappingsLegacyReader implements IMappingsReader {

    @Override
    public Mappings read(Reader in) throws IOException, MappingParseException {
        return read(new BufferedReader(in));
    }

    @Override
    public Mappings read(BufferedReader in) throws IOException, MappingParseException {
        Mappings mappings = new Mappings();
        Deque<Object> mappingStack = Queues.newArrayDeque();

        int lineNumber = 0;
        String line = null;
        while ((line = in.readLine()) != null) {
            lineNumber++;

            // strip comments
            int commentPos = line.indexOf('#');
            if (commentPos >= 0) {
                line = line.substring(0, commentPos);
            }

            // skip blank lines
            if (line.trim().length() <= 0) {
                continue;
            }

            // get the indent of this line
            int indent = 0;
            for (int i = 0; i < line.length(); i++) {
                if (line.charAt(i) != '\t') {
                    break;
                }
                indent++;
            }

            // handle stack pops
            while (indent < mappingStack.size()) {
                mappingStack.pop();
            }

            String[] parts = line.trim().split("\\s");
            try {
                // read the first token
                String token = parts[0];

                if (token.equalsIgnoreCase("CLASS")) {
                    ClassMapping classMapping;
                    if (indent <= 0) {
                        // outer class
                        classMapping = readClass(parts, false);
                        mappings.addClassMapping(classMapping);
                    } else {

                        // inner class
                        if (!(mappingStack.peek() instanceof ClassMapping)) {
                            throw new MappingParseException(lineNumber, "Unexpected CLASS entry here!");
                        }

                        classMapping = readClass(parts, true);
                        ((ClassMapping) mappingStack.peek()).addInnerClassMapping(classMapping);
                    }
                    mappingStack.push(classMapping);
                } else if (token.equalsIgnoreCase("FIELD")) {
                    if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof ClassMapping)) {
                        throw new MappingParseException(lineNumber, "Unexpected FIELD entry here!");
                    }
                    ((ClassMapping) mappingStack.peek()).addFieldMapping(readField(parts));
                } else if (token.equalsIgnoreCase("METHOD")) {
                    if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof ClassMapping)) {
                        throw new MappingParseException(lineNumber, "Unexpected METHOD entry here!");
                    }
                    MethodMapping methodMapping = readMethod(parts);
                    ((ClassMapping) mappingStack.peek()).addMethodMapping(methodMapping);
                    mappingStack.push(methodMapping);
                } else if (token.equalsIgnoreCase("ARG")) {
                    if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof MethodMapping)) {
                        throw new MappingParseException(lineNumber, "Unexpected ARG entry here!");
                    }
                    ((MethodMapping) mappingStack.peek()).addArgumentMapping(readArgument(parts));
                }
            } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException ex) {
                throw new MappingParseException(lineNumber, "Malformed line:\n" + line);
            }
        }

        return mappings;
    }

    private ArgumentMapping readArgument(String[] parts) {
        return new ArgumentMapping(Integer.parseInt(parts[1]), parts[2]);
    }

    private ClassMapping readClass(String[] parts, boolean makeSimple) {
        if (parts.length == 2) {
            return new ClassMapping(parts[1]);
        } else {
            return new ClassMapping(parts[1], parts[2]);
        }
    }

    /* TEMP */
    protected FieldMapping readField(String[] parts) {
        return new FieldMapping(parts[1], new Type(parts[3]), parts[2]);
    }

    private MethodMapping readMethod(String[] parts) {
        if (parts.length == 3) {
            return new MethodMapping(parts[1], new Signature(parts[2]));
        } else {
            return new MethodMapping(parts[1], new Signature(parts[3]), parts[2]);
        }
    }
}