/*
 * Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package javax.swing.text.rtf;

import java.io.*;
import java.lang.*;

/**
 * A generic superclass for streams which read and parse text
 * consisting of runs of characters interspersed with occasional
 * ``specials'' (formatting characters).
 *
 * <p> Most of the functionality
 * of this class would be redundant except that the
 * <code>ByteToChar</code> converters
 * are suddenly private API. Presumably this class will disappear
 * when the API is made public again. (sigh) That will also let us handle
 * multibyte character sets...
 *
 * <P> A subclass should override at least <code>write(char)</code>
 * and <code>writeSpecial(int)</code>. For efficiency's sake it's a
 * good idea to override <code>write(String)</code> as well. The subclass'
 * initializer may also install appropriate translation and specials tables.
 *
 * @see OutputStream
 */
abstract class AbstractFilter extends OutputStream
{
    /** A table mapping bytes to characters */
    protected char translationTable[];
    /** A table indicating which byte values should be interpreted as
     *  characters and which should be treated as formatting codes */
    protected boolean specialsTable[];

    /** A translation table which does ISO Latin-1 (trivial) */
    static final char latin1TranslationTable[];
    /** A specials table which indicates that no characters are special */
    static final boolean noSpecialsTable[];
    /** A specials table which indicates that all characters are special */
    static final boolean allSpecialsTable[];

    static {
      int i;

      noSpecialsTable = new boolean[256];
      for (i = 0; i < 256; i++)
        noSpecialsTable[i] = false;

      allSpecialsTable = new boolean[256];
      for (i = 0; i < 256; i++)
        allSpecialsTable[i] = true;

      latin1TranslationTable = new char[256];
      for (i = 0; i < 256; i++)
        latin1TranslationTable[i] = (char)i;
    }

    /**
     * A convenience method that reads text from a FileInputStream
     * and writes it to the receiver.
     * The format in which the file
     * is read is determined by the concrete subclass of
     * AbstractFilter to which this method is sent.
     * <p>This method does not close the receiver after reaching EOF on
     * the input stream.
     * The user must call <code>close()</code> to ensure that all
     * data are processed.
     *
     * @param in      An InputStream providing text.
     */
    public void readFromStream(InputStream in)
      throws IOException
    {
        byte buf[];
        int count;

        buf = new byte[16384];

        while(true) {
            count = in.read(buf);
            if (count < 0)
                break;

            this.write(buf, 0, count);
        }
    }

    public void readFromReader(Reader in)
      throws IOException
    {
        char buf[];
        int count;

        buf = new char[2048];

        while(true) {
            count = in.read(buf);
            if (count < 0)
                break;
            for (int i = 0; i < count; i++) {
              this.write(buf[i]);
            }
        }
    }

    public AbstractFilter()
    {
        translationTable = latin1TranslationTable;
        specialsTable = noSpecialsTable;
    }

    /**
     * Implements the abstract method of OutputStream, of which this class
     * is a subclass.
     */
    public void write(int b)
      throws IOException
    {
      if (b < 0)
        b += 256;
      if (specialsTable[b])
        writeSpecial(b);
      else {
        char ch = translationTable[b];
        if (ch != (char)0)
          write(ch);
      }
    }

    /**
     * Implements the buffer-at-a-time write method for greater
     * efficiency.
     *
     * <p> <strong>PENDING:</strong> Does <code>write(byte[])</code>
     * call <code>write(byte[], int, int)</code> or is it the other way
     * around?
     */
    public void write(byte[] buf, int off, int len)
      throws IOException
    {
      StringBuffer accumulator = null;
      while (len > 0) {
        short b = (short)buf[off];

        // stupid signed bytes
        if (b < 0)
            b += 256;

        if (specialsTable[b]) {
          if (accumulator != null) {
            write(accumulator.toString());
            accumulator = null;
          }
          writeSpecial(b);
        } else {
          char ch = translationTable[b];
          if (ch != (char)0) {
            if (accumulator == null)
              accumulator = new StringBuffer();
            accumulator.append(ch);
          }
        }

        len --;
        off ++;
      }

      if (accumulator != null)
        write(accumulator.toString());
    }

    /**
     * Hopefully, all subclasses will override this method to accept strings
     * of text, but if they don't, AbstractFilter's implementation
     * will spoon-feed them via <code>write(char)</code>.
     *
     * @param s The string of non-special characters written to the
     *          OutputStream.
     */
    public void write(String s)
      throws IOException
    {
      int index, length;

      length = s.length();
      for(index = 0; index < length; index ++) {
        write(s.charAt(index));
      }
    }

    /**
     * Subclasses must provide an implementation of this method which
     * accepts a single (non-special) character.
     *
     * @param ch The character written to the OutputStream.
     */
    protected abstract void write(char ch) throws IOException;

    /**
     * Subclasses must provide an implementation of this method which
     * accepts a single special byte. No translation is performed
     * on specials.
     *
     * @param b The byte written to the OutputStream.
     */
    protected abstract void writeSpecial(int b) throws IOException;
}
