java/ch/wlkl/wsh/Buf.java

package ch.wlkl.wsh;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * Stores the input received by {@link #write(Object)} and it and returns it by {@link #read()}
 * 
 * @author walter keller
 *
 * @param <T>
 */
public class Buf<T> extends Top implements Read<T>, Write<T> {

    public final Collection<T> contents;
    Collection<T> adder = null;
    Iterator<T> it = null;

    /**
     * instanciate a Buf with an existing list as contents.
     * @param li the list to use
     */
    public Buf (Collection<T> li) {
        contents = li;
    }

    /**
     * instanciate a Buf with a new List
     */
    public Buf () {
        this(new ArrayList<T>());
    }

    /**
     * instanciate a Buf and initialise contents with the given values.
     * @param args the initial contents
     */
    public Buf (T... args) {
        this();
        if (args.length == 1 && args[0] instanceof Collection)
            fail("constructor mismatch");
        add(args);
    }
    
    @SuppressWarnings("unchecked")
    public void reset(Object... args) {
        close();
        contents.clear();
        add((T[]) args);        
    }

    public Buf<T> add(T... args) {
        if (it != null || adder != null)
            fail("add but not closed");
        Ut.addAll(contents, args);
        return this;
    }
    /**
     * open the receiver in read or write mode, after closing it if necessary.
     * @param opt at most one argument as follows:
     * <ul>
     * <li>"r": open for reading
     * <li>"w": open for writing, clear existing contents 
     * <li>"a": open for writing, append to existing contents 
     * </ul>
     * {@inheritDoc} shTwo.OpenClose#open(java.lang.String[])
     */
    public void open(String opt) {
        close();
        if (opt.indexOf('r') >= 0) {
            it = contents.iterator();
        } else if (opt.indexOf('w') >= 0) {
            contents.clear();
            adder = contents;
        } else if (opt.indexOf('a') >= 0) {
            adder = contents;
        } else {
            fail("open(" + opt + ") bad opt");
        }
    }

    public void close() {
        it = null;
        adder = null;
    }

    /**
     * add arg to contents.
     * <br>
     * fail (currently with null pointer exception, but not specified) if not opened for write
     */
    public void write(T arg) {
        adder.add(arg);
    }

    public     void writeAll(String opt, Read<T> r) {
        Cat.writeAll(this, opt, r);
    }

    /**
     * return next value from contents or null if at end.
     * <br>
     * fail (currently with null pointer exception, but not specified) if not opened for read
     */
    public T read() {
        return it.hasNext() ? it.next() : null;
    }    
}