/******************************************************************************* * Copyright (c) 2014 Jeff Martin. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * Jeff Martin - initial API and implementation ******************************************************************************/ package cuchaz.enigma.mapping; import java.io.IOException; import java.io.StringReader; import java.util.List; import com.google.common.collect.Lists; public class SignatureUpdater { public interface ClassNameUpdater { String update( String className ); } public static String update( String signature, ClassNameUpdater updater ) { try { StringBuilder buf = new StringBuilder(); // read the signature character-by-character StringReader reader = new StringReader( signature ); int i = -1; while( ( i = reader.read() ) != -1 ) { char c = (char)i; // does this character start a class name? if( c == 'L' ) { // update the class name and add it to the buffer buf.append( 'L' ); String className = readClass( reader ); if( className == null ) { throw new IllegalArgumentException( "Malformed signature: " + signature ); } buf.append( updater.update( className ) ); buf.append( ';' ); } else { // copy the character into the buffer buf.append( c ); } } return buf.toString(); } catch( IOException ex ) { // I'm pretty sure a StringReader will never throw one of these throw new Error( ex ); } } private static String readClass( StringReader reader ) throws IOException { // read all the characters in the buffer until we hit a ';' StringBuilder buf = new StringBuilder(); int i = -1; while( ( i = reader.read() ) != -1 ) { char c = (char)i; if( c == ';' ) { return buf.toString(); } else { buf.append( c ); } } return null; } public static List getClasses( String signature ) { final List classNames = Lists.newArrayList(); update( signature, new ClassNameUpdater( ) { @Override public String update( String className ) { classNames.add( className ); return className; } } ); return classNames; } }