package prefuse.data.io; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import prefuse.util.io.IOLib; /** * Helper class that stores character length counts for each column in * a fixed width text table. This class is needed for reading and writing * fixed width data tables. A schema definition can either be created * manually using the {@link #addColumn(String, int)} method or loaded from * a tab-delimited text file using the {@link #load(String)} method. * * @author <a href="http://jheer.org">jeffrey heer</a> */ public class FixedWidthTextTableSchema { private String[] names = new String[0]; private int[] cols = new int[1]; /** * Creates a new, initially empty FixedWidthTextTableSchema. */ public FixedWidthTextTableSchema() { } private void ensureCapacity(int cap) { String[] nnames = new String[names.length+1]; System.arraycopy(names, 0, nnames, 0, names.length); names = nnames; int[] ncols = new int[cols.length+1]; System.arraycopy(cols, 0, ncols, 0, cols.length); cols = ncols; } /** * Adds a column to this schema description. * @param name the name of this column * @param length the length, in text characters, of this column in a data file */ public void addColumn(String name, int length) { int idx = names.length; ensureCapacity(idx+1); names[idx] = name; cols[idx+1] = cols[idx]+length; } /** * Returns the number of columns in this schema. * @return the numner of columns */ public int getColumnCount() { return names.length; } /** * Gets the name of the requested column * @param idx the index of the column * @return the name of the column */ public String getColumnName(int idx) { return names[idx]; } /** * Gets the character length of the given column * @param idx the index of the column * @return the character length of the column in the fixed-width format */ public int getColumnLength(int idx) { return cols[idx+1]-cols[idx]; } /** * Gets the starting character number for the given column index * @param idx the index of the column * @return the text character position at which this column starts on a * line */ public int getColumnStart(int idx) { return cols[idx]; } /** * Sets the ending character number for the given column index. This value * is one greater than the last character position for the column. * @param idx the index of the column * @return one greater than the last text character position at which this * column ends on a line */ public int getColumnEnd(int idx) { return cols[idx+1]; } /** * Writes this schema description to a file with the given name. * @param filename the name of the file * @throws DataIOException if an IO exception occurs */ public void write(String filename) throws DataIOException { try { write(new FileOutputStream(filename)); } catch ( FileNotFoundException e ) { throw new DataIOException(e); } } /** * Writes this schema description to the given output stream. * @param os the output stream * @throws DataIOException if an IO exception occurs */ public void write(OutputStream os) throws DataIOException { try { PrintStream out = new PrintStream(new BufferedOutputStream(os)); for (int i = 0; i < names.length; ++i) { out.print(names[i]); out.print('\t'); out.print(cols[i+1]-cols[i]); out.println(); } } catch ( Exception e ) { throw new DataIOException(e); } } /** * Loads a schema description from the given location. * @param loc a location string representing a filename, URL, or resource locator * @return the loaded schema description * @throws DataIOException if an IO exception occurs */ public static FixedWidthTextTableSchema load(String loc) throws DataIOException { try { InputStream is = IOLib.streamFromString(loc); if (is == null) return null; FixedWidthTextTableSchema fws = new FixedWidthTextTableSchema(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; while ((line=br.readLine()) != null) { String[] tok = line.split("\t"); fws.addColumn(tok[0], Integer.parseInt(tok[1])); } return fws; } catch ( Exception e ) { throw new DataIOException(e); } } } // end of class FixedWidthTextTableReader