FileDocCategorySizeDatePackage
InputHelper.javaAPI DocExample4588Sat Mar 09 14:51:28 GMT 2002ora.ch6

InputHelper.java

package ora.ch6;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;

// A class that scans through an input
// stream for strins without reading the
// entire stream into a large string.
public class InputHelper {

    // Size of the input buffer
    private static final int BUFFER_SIZE = 1024;

    // The input buffer
    private final char[] buffer = new char[BUFFER_SIZE];

    // Number of characters left in the buffer
    private int charsLeft;

    // Index of the next character in the buffer
    private int nextChar;

    // InputStreamReader used to map to Unicode
    private InputStreamReader reader;

    // Constructs a helper to read a given stream
    public InputHelper(InputStream is) {
        reader = new InputStreamReader(is);
    }
    
    // Cleans up when no longer needed
    public void dispose() {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException ex) {
            }
            reader = null;
        }
    }

    // Looks for a given string in the input
    // stream and positions the stream so that the
    // next character read is one beyond the string.
    // Returns true if the string was found, false if
    // not (and the stream will have been completely read).
    public boolean moveAfterString(String str) throws IOException {
        char[] chars = str.toCharArray();
        int count = chars.length;
        char firstChar = chars[0];

        char c = (char)0;
        for (;;) {
            if (c != firstChar && !findNext(firstChar)) {
                // Reached the end of the input stream
                return false;
            }

            boolean mismatch = false;
            for (int i = 1; i < count; i++) {
                c = getNext();
                if (c != chars[i]) {
                    mismatch = true;
                    break;
                }
            }

            if (!mismatch) {
                return true;
            }

            // Mismatch. 'c' has the first mismatched
            // character - start the loop again with
            // that character. This is necessary because we
            // could have found "wweb" while looking for "web"
        }
    }
    
    // Gets the characters for a number, ignoring
    // the grouping separator. The number starts at the
    // current input position, but any leading non-numerics
    // are skipped.
    public String gatherNumber() throws IOException {
        StringBuffer sb = new StringBuffer();
        boolean gotNumeric = false;
        for (;;) {
            char c = getNext();
            
            // Skip until we find a digit.
            boolean isDigit = Character.isDigit(c);
            if (!gotNumeric && !isDigit) {
                continue;
            }
            gotNumeric = true;
            if (!isDigit) {
                if (c == '.' || c == ',') {
                    continue;
                }
                break;
            }
            sb.append(c);
        }
        return sb.toString();
    }
    
    // Gets the balance of the current line
    // and returns it as a StringBuffer
    public StringBuffer getRestOfLine() throws IOException {
    
        StringBuffer sb = new StringBuffer();
        char c;
        for (;;) {
            c = getNext();
            if (c == '\n' || c == (char)0) {
                break;
            }
            sb.append(c);
        }
        return sb;
    } 
    
    // Gets the next character from the stream,
    // returning (char)0 when all input has been read.
    private char getNext() throws IOException {
        if (charsLeft == 0) {
            charsLeft = reader.read(buffer, 0, BUFFER_SIZE);
            if (charsLeft < 0) {
                return (char)0;
            }
            nextChar = 0;
        }
        charsLeft--;
        return buffer[nextChar++];
    }
       
    // Finds the next instance of a given character in the
    // input stream. The input stream is positioned after
    // the located character. If EOF is reached without
    // finding the character, false is returned.
    private boolean findNext(char c) throws IOException {
        for (;;) {
            if (charsLeft == 0) {
                charsLeft = reader.read(buffer, 0, BUFFER_SIZE);
                if (charsLeft < 0) {
                    return false;
                }
                nextChar = 0;
            }
            charsLeft--;
            if (c == buffer[nextChar++]) {
                return true;
            }
        }
    }
}