/** * Copyright (C) 2002-2012 The FreeCol Team * * This file is part of FreeCol. * * FreeCol is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * FreeCol is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FreeCol. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.freecol.tools; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.GZIPInputStream; /** * Class for converting FreeCol Savegames (fsg-files). * * @see #getFSGConverter() */ public class FSGConverter { /** * A singleton object of this class. * @see #getFSGConverter() */ private static FSGConverter singleton; /** * Creates an instance of <code>FSGConverter</code> */ private FSGConverter() { // Nothing to initialize; } /** * Gets an object for converting FreeCol Savegames. * @return The singleton object. */ public static FSGConverter getFSGConverter() { // Using lazy initialization: if (singleton == null) { singleton = new FSGConverter(); } return singleton; } /** * Converts the given input file to an uncompressed and * indented XML-file. * * <br><br> * * Savegame compression is automatically detected, so using * this method on an uncompressed savegame creates an * indented version of that savegame. * * @param in The input file. * @param out The output file. This file will be overwritten * if it already exists. * @throws FileNotFoundException if the given input file could not be found. * @throws IOException if thrown while reading or writing the files. */ public void convertToXML(File in, File out) throws FileNotFoundException, IOException { convertToXML(new FileInputStream(in), new FileOutputStream(out)); } /** * Converts the data from the given input stream to an * uncompressed and indented text to the output stream. * Both streams are closed by this method. * * <br><br> * * Savegame compression is automatically detected, so using * this method on an uncompressed savegame creates an * indented version of that savegame. * * @param in The input stream. * @param out The output stream. * * @throws IOException if thrown while reading or writing the streams. */ public void convertToXML(InputStream in, OutputStream out) throws IOException { try { in = new BufferedInputStream(in); out = new BufferedOutputStream(out); // Automatically detect savegame compression: in.mark(10); byte[] buf = new byte[5]; in.read(buf, 0, 5); in.reset(); if (!(new String(buf)).equals("<?xml")) { in = new BufferedInputStream(new GZIPInputStream(in)); } // Support for XML comments has not been added: int indent = 0; int i; while ((i = in.read()) != -1) { char c = (char) i; if (c == '<') { i = in.read(); char b = (char) i; if (b == '/') { indent -= 4; } for (int h=0; h<indent; h++) { out.write(' '); } out.write(c); if (b != '\n' && b != '\r') { out.write(b); } if (b != '/' && b != '?') { indent += 4; } } else if (c == '/') { out.write(c); i = in.read(); c = (char) i; if (c == '>') { indent -= 4; out.write(c); out.write('\n'); } } else if (c == '>') { out.write(c); out.write('\n'); } else if (c != '\n' && c != '\r') { out.write(c); } } } finally { in.close(); out.close(); } } /** * Prints the usage of this program to standard out. */ private static void printUsage() { System.out.println("A program for converting FreeCol Savegames."); System.out.println(); System.out.println("Usage: java -cp FreeCol.jar net.sf.freecol.tools.FSGConverter [-][-]output:xml FSG_FILE [OUTPUT_FILE]"); System.out.println(); System.out.println("output:xml \tThe output will be indented XML."); System.out.println(); System.out.println("The output file will get the same name as FSG_FILE if not specified (with \".fsg\" replaced with \".xml\")."); } /** * An entry point for converting FreeCol Savegames. * * @param args The command-line parameters. */ public static void main(String[] args) { if (args.length >= 2 && args[0].endsWith("output:xml")) { File in = new File(args[1]); if (!in.exists()) { printUsage(); System.exit(1); } File out; if (args.length >= 3) { out = new File(args[2]); } else { String filename = in.getName().replaceAll(".fsg", ".xml"); if (filename.equals(in.getName())) { filename += ".xml"; } out = new File(filename); } try { FSGConverter fsgc = FSGConverter.getFSGConverter(); fsgc.convertToXML(in, out); } catch (IOException e) { System.out.println("An error occured while converting the file."); e.printStackTrace(); System.exit(1); } } else { printUsage(); System.exit(1); } } }