// zlib.java zilla // modified // apr02 min/max integer // mar01 bull // feb01 scruff // jan01 bull // oct00 bull // jun00 scruff // may00 scruff // apr00 scruff // jan99 doom // jan97 doom: created // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library 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 // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this library; if not, write to the // Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // contact info: zilla@computer.org package zlib; import java.io.*; import java.util.*; import javax.swing.*; import java.awt.*; /** * zlib - misc utilities * * @author jplewis */ final public class zlib { /** * write string bytes on a stream */ public static void writeString(BufferedOutputStream f, String s) throws IOException { //s.getBytes(0, s.length(), buf, 0); //deprecated byte[] buf = s.getBytes(); f.write(buf, 0, s.length()); } //writeString /** * read the whole input stream into a string (beware) */ public static String InputStreamToString(BufferedReader fr) throws IOException { StringBuffer s = new StringBuffer(); String line = fr.readLine(); while( line != null ) { s.append(line); line = fr.readLine(); } fr.close(); return s.toString(); } /** * read the input stream through the next newline, then stop. */ public static void InputStreamEatLine(InputStream f) throws IOException { int cc; do { cc = f.read(); } while( cc != '\n' ); } //InputStreamEatLine /** * Provide a readline method for an input stream. * (BufferedReader has a readLine method.) * Useful for reading binary ppm files - read the header in * a line-oriented way, then read binary bytes. * This method allocates a byte[] array each time. Beware. */ public static String InputStreamReadLine(InputStream f) throws IOException { byte[] buf = new byte[2048]; // TODO: garbage int cc; int i = 0; do { cc = f.read(); if (cc != '\n') { buf[i] = (byte)cc; i++; if (i == 2048) break; } } while( cc != '\n' ); return new String(buf, 0, i); } //InputStreamReadLine /** * read a token, stop at newline, tab, space */ public static String InputStreamReadToken(InputStream f, String whitechars) throws IOException { byte[] buf = new byte[2048]; // TODO: garbage int cc; int i = 0; boolean iswhite = false; do { cc = f.read(); if (cc == -1) break; iswhite = (whitechars.indexOf(cc) >= 0); if (!iswhite) { buf[i] = (byte)cc; i++; if (i == 2048) break; } } while(!iswhite); return new String(buf, 0, i); } //InputStreamReadToken /** * read the next token, skipping comment line * this is primarly for ppm parsing * NOT DEBUGGED */ public static String InputStreamReadTokenComment(InputStream f, String whitechars, char commentchar) throws IOException { byte[] buf = new byte[2048]; // TODO: garbage int cc; int i = 0; boolean iswhite = false; do { cc = f.read(); if (cc == commentchar) { while( (cc != '\n') && (cc != '\r') && (cc != -1) ) { cc = f.read(); } if (i > 0) // token already started break; else { if (cc != -1) cc = f.read(); } } if (cc == -1) break; iswhite = (whitechars.indexOf(cc) >= 0); if (!iswhite) { buf[i] = (byte)cc; i++; if (i == 2048) break; } } while(!iswhite); return new String(buf, 0, i); } //InputStreamReadToken //---------------------------------------------------------------- /**
  state table for streamtokenizer:

  Input                   Action                  New state 
  ----------------
  State=idle 
  ----------------
  word character          push back character     accumulate 

  ordinary character      return character        idle 

  whitespace character    consume character       idle 

  ----------------
  State=accumulate 
  ----------------
  word character          add to current word     accumulate 

  ordinary character      return current word     idle 
			  push back character 

  whitespace character    return current word     idle 
			  consume character 
 
  for jdk1.4.2:
  TT_EOF = -1
  TT_EOL = -10
  TT_WRD = -3
  TT_NUM = -2
  and ordinary (non word) characters are returned as their numberic value
  */

  /**
   * handy setup a streamtokenizer
   */
  public static StreamTokenizer getParsingStream(String file,
				   String whitechars, String wordchars,
				   String commentchars, String breakchars,
				   boolean eolIsSignificant,
				   boolean lowercase)
    throws IOException
  {
    return getParsingStream(file,
			    whitechars,wordchars,
			    commentchars,breakchars,
			    eolIsSignificant,lowercase,
			    false);
  }


  /**
   * I think breakchars are things like ; that should be returned
   * as separate tokens.
   * Typical call:
   
      StreamTokenizer st = zlib.getParsingStream(cmdline[0],
						 " \t\r\n", "'",
						 "", "",
						 false,true,
						 false);
   */
  public static StreamTokenizer getParsingStream(String file,
				   String whitechars, String wordchars,
				   String commentchars, String breakchars,
			  	   boolean eolIsSignificant, boolean lowercase,
 		 	 	   boolean doNumbers)

    throws IOException
  {
    BufferedReader br = new BufferedReader(new FileReader(file));
    StreamTokenizer st = new StreamTokenizer(br);
    st.resetSyntax();

    if (doNumbers) st.parseNumbers();

    st.wordChars((int)'A',(int)'Z');
    st.wordChars((int)'a',(int)'z');

    //st.whitespaceChars((int)'\u0000',(int)'\u0020');
    char[] arr = whitechars.toCharArray();
    for( int i = 0; i < arr.length; i++ )
      st.whitespaceChars(arr[i],arr[i]);

    arr = wordchars.toCharArray();
    for( int i = 0; i < arr.length; i++ )
      st.wordChars(arr[i],arr[i]);

    arr = commentchars.toCharArray();
    for( int i = 0; i < arr.length; i++ )
      st.commentChar(arr[i]);

    arr = breakchars.toCharArray();
    for( int i = 0; i < arr.length; i++ )
      // note 'ordinary' as opposed to 'word'
      st.ordinaryChars(arr[i],arr[i]);

    st.eolIsSignificant(eolIsSignificant);
    //System.out.println("eolIsSignificant = "+eolIsSignificant);
    st.lowerCaseMode(lowercase);

    return st;
  } //getParsingStream


  /**
   * print the current StreamTokenizer token
   */
  public static void printToken(StreamTokenizer st)
  {
    switch(st.ttype) {
    case StreamTokenizer.TT_WORD:
      System.out.print(st.sval);
      break;
    case StreamTokenizer.TT_NUMBER:
      System.out.print(st.nval);
      break;
    case StreamTokenizer.TT_EOL:
      System.out.print("");
      break;
    case StreamTokenizer.TT_EOF:
      System.out.print("");
      break;
    default:
      System.out.print("character("+st.ttype+")");
    }
  } //printToken


  /**
   * read the next token from st,
   * call parseError if it is not 'desired'
   */
  public static void parseToken(StreamTokenizer st,
				String desired,
				String file)
    throws IOException
  {
    int val = st.nextToken();
    if (val != StreamTokenizer.TT_WORD) zliberror.parseError(st, file);
    if (!st.sval.equals(desired)) zliberror.parseError(st, file);
  } //parseToken


  /**
   * read the next token from st,
   * call parseError if it is not a string, else return it.
   * (jul05 added) exception: if EOF return null
   */
  public static String parseString(StreamTokenizer st,
				   String file)
    throws IOException
  {
    int val = st.nextToken();
    //System.out.println("val = "+val);
    if (val == StreamTokenizer.TT_EOF) return null;
    if (val != StreamTokenizer.TT_WORD) zliberror.parseError(st, file);
    return st.sval;
  } //parseString



  /**
   * Debugging version of parseString -
   * prints out all the internal variables.
   */
  public static String parseStringDebug(StreamTokenizer st,
					String file)
    throws IOException
  {
    int val = st.nextToken();
    System.out.println("parseStringDebug val = " + val);
    System.out.println("   TT_WORD = " + StreamTokenizer.TT_WORD);
    System.out.println("   TT_NUMBER = " + StreamTokenizer.TT_NUMBER);
    System.out.println("   TT_EOL = " + StreamTokenizer.TT_EOL);
    System.out.println("   TT_EOF = " + StreamTokenizer.TT_EOF);
    System.out.println("   nval = " + st.nval);
    System.out.println("   sval = " + st.sval);
    if (val != StreamTokenizer.TT_WORD) zliberror.parseError(st, file);
    return st.sval;
  } //parseStringDebug


  /**
   * read the next token from st,
   * call parseError if it is not a double, else return it
   * Beware: if the input has E notation numbers, this wont
   * work, it is necessary to do:
   * 
   * st.resetSyntax();
   * st.eolIsSignificant(false);
   * st.whitespaceChars((int)'\u0000',(int)'\u0020');
   * st.wordChars((int)'0',(int)'9');
   * st.wordChars((int)'.',(int)'.');
   * st.wordChars((int)'E',(int)'E');
   * st.wordChars((int)'-',(int)'-');
   * st.wordChars((int)'+',(int)'+');
   * //st.commentChar('#');
   * 
*/ public static double parseDouble(StreamTokenizer st, String file) throws IOException { int val = st.nextToken(); if (val != StreamTokenizer.TT_NUMBER) zliberror.parseError(st, file); return st.nval; } //parseDouble //---------------------------------------------------------------- /** */ public static String getFilename(String path) { File f = new File(path); return f.getName(); } /** */ public static String getDirectory(String path) { File f = new File(path); return f.getParent(); } /** * return the root part of a pathname (excluding the period). * null if no such. */ public static String getRoot(String path) { int i = path.lastIndexOf('.'); if (i == -1) return path; return path.substring(0,i); } /** * return the .ext part of a pathname (including the period). * null if no such. */ public static String getExtension(String path) { int i = path.lastIndexOf('.'); if (i == -1) return null; return path.substring(i); } /** * if path has no extension, add the given one; * ext should include the period. * TODO this does not work properly if the path is abc.0120 */ public static String addExtensionIfMissing(String path, String ext) { String hasext = getExtension(path); if (hasext == null) path = path + ext; return path; } /** * Java link detection: *

* For a link that actually points to something (either a file or * a directory), the absolute path is the path through the link, * whereas the canonical path is the path the link references. *

* Dangling links appear as files of size zero - * no way to distinguish dangling links from non-existent files * other than by consulting the parent directory. */ public static boolean isLink(File file) { try { if (!file.exists()) return true; else { String cnnpath = file.getCanonicalPath(); String abspath = file.getAbsolutePath(); //System.out.println(abspath+" <-> "+cnnpath); return !abspath.equals(cnnpath); } } catch (java.io.FileNotFoundException ex) { return true; // a dangling link. } catch (IOException ex) { /*ignore other errors*/ } return false; } //isLink /** * launch JFileChooser to select a file */ public static String chooseFile(Component parent) { String wdir = System.getProperty("user.dir"); JFileChooser chooser = new JFileChooser(wdir); int retval = chooser.showOpenDialog(parent); if (retval != JFileChooser.APPROVE_OPTION) return null; File f = chooser.getSelectedFile(); if (f == null || f.isDirectory()) return null; return f.getPath(); } /** * launch JFileChooser to select a directory */ public static String chooseDir(Component parent) { String wdir = System.getProperty("user.dir"); JFileChooser chooser = new JFileChooser(wdir); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int retval = chooser.showOpenDialog(parent); if (retval != JFileChooser.APPROVE_OPTION) return null; File f = chooser.getSelectedFile(); if (f == null) return null; return f.getPath(); } //chooseDir /** pop up a GUI to ask the user to pick one of a couple choices * choces are passed like: Object[] values = { "draw mode", "paint mode" }; */ public static Object getUIInput(Object[] values) { Object selected = JOptionPane.showInputDialog(null, "Choose one", "Input", JOptionPane.INFORMATION_MESSAGE, null, values, values[0]); return selected; } //getUIInput //---------------------------------------------------------------- /** * load properties from file */ public static java.util.Properties readProps(String path) throws IOException { java.util.Properties props = new java.util.Properties(); InputStream f = new FileInputStream(path); props.load(f); f.close(); return props; } //readProps /** * go over cmdline, for any arg that looks like an -option, * add the next arg as its value unless it too begins with a hypen, * in that case add True as its value. */ public static void addCmdlineProps(java.util.Properties props, String[] cmdline) { for( int i=0; i < cmdline.length; i++ ) { if (cmdline[i].startsWith("-")) { String key = cmdline[i]; Object val = Boolean.TRUE; if (i < (cmdline.length-1) && !cmdline[i+1].startsWith("-")) val = cmdline[i+1]; props.put(key, val); // relying on the fact that props is a hashtable } } } //addCmdlineProps //---------------------------------------------------------------- /** * return a string with any characters c removed */ public static String stripchar(String tok, char c) { if (tok.indexOf(c) < 0) return tok; StringBuffer sb = new StringBuffer(); int len = tok.length(); for( int i = 0; i < len; i++ ) { char c1 = tok.charAt(i); if (c1 != c) sb.append(c1); } return sb.toString(); } //stripchars /** */ public static void sleepfor(int msecs) { //System.out.println("sleeping for " + msecs); System.out.print("."); try { Thread.sleep(msecs); } catch(Exception x) {} } /** * Print --more--, wait for user to hit enter to continue. */ public static void more() { //if (verbose == 0) return; System.out.println("--more--"); try { System.in.read(); } catch(Exception x) {} } /** * substitute becomes for was in str, return new string */ public static String stringsubst(String str, String was, String becomes) { int idx = str.indexOf(was); if (idx < 0) return str; String start = str.substring(0, idx); String end = str.substring(idx+was.length(), str.length()); return start + becomes + end; } /** * Split string at delimiters, like python string.split. * NOTE There is a jdk1.4 String.split routine * TODO: could probably speed this up by coding without the stringtokenizer */ public static ArrayList stringSplit(String s, String delim) { ArrayList l = null; StringTokenizer st = new StringTokenizer(s, delim, false); while( st.hasMoreTokens() ) { String tok = st.nextToken(); if (l == null) l = new ArrayList(5); l.add(tok); } return l; } //stringSplit //---------------------------------------------------------------- /** * full clone of a 2d int array * @deprecated moved to zlib.array */ public static int[][] cloneArray(int[][] arr) { int[][] rarr = (int[][])arr.clone(); int nr = arr.length; for( int r=0; r < nr; r++ ) { rarr[r] = (int[])(arr[r]).clone(); } return rarr; } //cloneArray /** * full clone of a 2d float array * @deprecated moved to zlib.array */ public static float[][] cloneArray(float[][] arr) { float[][] rarr = (float[][])arr.clone(); int nr = arr.length; for( int r=0; r < nr; r++ ) { rarr[r] = (float[])(arr[r]).clone(); } return rarr; } //cloneArray /** * full clone of a 2d double array * @deprecated moved to zlib.array */ public static double[][] cloneArray(double[][] arr) { double[][] rarr = (double[][])arr.clone(); int nr = arr.length; for( int r=0; r < nr; r++ ) { rarr[r] = (double[])(arr[r]).clone(); } return rarr; } //cloneArray //---------------------------------------------------------------- /** * copy float[][] to double[][] */ public static double[] toDouble(float[] arr) { int len = arr.length; double[] d = new double[len]; for( int i=0; i < len; i++ ) { d[i] = arr[i]; } return d; } //toDouble /** * copy float[][] to double[][] * @deprecated moved to zlib.array */ public static double[][] toDouble(float[][] arr) { int nr = arr.length; int nc = arr[0].length; double[][] darr = new double[nr][nc]; for( int r=0; r < nr; r++ ) { for( int c=0; c < nc; c++ ) { darr[r][c] = arr[r][c]; } } return darr; } //toDouble /** * copy double[][] to float[][] * @deprecated moved to zlib.array */ public static float[] toFloat(double[] arr) { int len = arr.length; float[] d = new float[len]; for( int i=0; i < len; i++ ) { d[i] = (float)arr[i]; } return d; } //toFloat /** * copy double[][] to float[][] * @deprecated moved to zlib.array */ public static float[][] toFloat(double[][] arr) { int nr = arr.length; int nc = arr[0].length; float[][] farr = new float[nr][nc]; for( int r=0; r < nr; r++ ) { // TODO: row access to speed up for( int c=0; c < nc; c++ ) { farr[r][c] = (float)arr[r][c]; } } return farr; } //toFloat //---------------------------------------------------------------- /** * this is in java.util.Arrays * @deprecated */ public static boolean equals(double[] arr1, double[] arr2) { int len = arr1.length; if (len != arr2.length) return false; for( int i=0; i < len; i++ ) { if (arr1[i] != arr2[i]) return false; } return true; } //equals(double[],double[]) /** * this is in java.util.Arrays * @deprecated */ public static boolean equals(float[] arr1, float[] arr2) { int len = arr1.length; if (len != arr2.length) return false; for( int i=0; i < len; i++ ) { if (arr1[i] != arr2[i]) return false; } return true; } //equals(float[],float[]) //---------------------------------------------------------------- /** * @deprecated moved to zlib.array */ public static int max(int[] arr) { int len = arr.length; int max = Integer.MIN_VALUE; for( int i=0; i < len; i++ ) { if (arr[i] > max) max = arr[i]; } return max; } //max /** * @deprecated moved to zlib.array */ public static int min(int[] arr) { int len = arr.length; int min = Integer.MAX_VALUE; for( int i=0; i < len; i++ ) { if (arr[i] < min) min = arr[i]; } return min; } //min /** * @deprecated moved to zlib.array */ public static float max(float[] arr) { int len = arr.length; float max = Float.NEGATIVE_INFINITY; for( int i=0; i < len; i++ ) { if (arr[i] > max) max = arr[i]; } return max; } //max /** * @deprecated moved to zlib.array */ public static float min(float[] arr) { int len = arr.length; float min = Float.POSITIVE_INFINITY; for( int i=0; i < len; i++ ) { if (arr[i] < min) min = arr[i]; } return min; } //min //---------------------------------------------------------------- public static int atoi(String s) { return Integer.parseInt(s); } public static double atof(String s) { return Double.valueOf(s).doubleValue(); } //---------------------------------------------------------------- /** test the InputStreamReadLine */ public static void main(String[] args) { try { InputStream f = new FileInputStream("zlib/zlib.java"); String s = InputStreamReadLine(f); System.out.println("line :"+s+":"); f.close(); } catch(Exception ex) { System.err.println(ex); } } } //zlib