/* CompressedOutputStream.java --
   Copyright (C) 2003, 2004  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.net.protocol.ftp;

import java.io.IOException;
import java.io.OutputStream;

/**
 * A DTP output stream that implements the FTP compressed transfer mode.
 *
 * @author Chris Burdess (dog@gnu.org)
 */
class CompressedOutputStream
  extends DTPOutputStream
{

  static final byte RECORD = -128;      // 0x80
  static final byte EOF = 64;   // 0x40

  CompressedOutputStream(DTP dtp, OutputStream out)
  {
    super(dtp, out);
  }

  /**
   * Just one byte cannot be compressed.
   * It takes 5 bytes to transmit - hardly very compressed!
   */
  public void write(int c)
    throws IOException
  {
    if (transferComplete)
      {
        return;
      }
    byte[] buf = new byte[]
      {
        RECORD,                   /* record descriptor */
        0x00, 0x01,             /* one byte */
        0x01,                   /* one uncompressed byte */
        (byte) c                /* the byte */
      };
    out.write(buf, 0, 5);
  }

  public void write(byte[] b)
    throws IOException
  {
    write(b, 0, b.length);
  }

  /**
   * The larger len is, the better.
   */
  public void write(byte[] b, int off, int len)
    throws IOException
  {
    if (transferComplete)
      {
        return;
      }
    byte[] buf = compress(b, off, len);
    len = buf.length;
    buf[0] = RECORD;            /* record descriptor */
    buf[1] = (byte) ((len & 0x00ff) >> 8);      /* high byte of bytecount */
    buf[2] = (byte) (len & 0xff00);     /* low byte of bytecount */
    out.write(buf, 0, len);
  }

  /**
   * Returns the compressed form of the given byte array.
   * The first 3 bytes are left free for header information.
   */
  byte[] compress(byte[] b, int off, int len)
  {
    byte[] buf = new byte[len];
    byte last = 0;
    int pos = 0, raw_count = 0, rep_count = 1;
    for (int i = off; i < len; i++)
      {
        byte c = b[i];
        if (i > off && c == last) // compress
          {
            if (raw_count > 0)      // flush raw bytes to buf
              {
                // need to add raw_count+1 bytes
                if (pos + (raw_count + 1) > buf.length)
                  {
                    buf = realloc(buf, len);
                  }
                pos = flush_raw(buf, pos, b, (i - raw_count) - 1,
                                raw_count);
                raw_count = 0;
              }
            rep_count++;            // keep looking for same byte
          }
        else
          {
            if (rep_count > 1)      // flush compressed bytes to buf
              {
                // need to add 2 bytes
                if (pos + 2 > buf.length)
                  {
                    buf = realloc(buf, len);
                  }
                pos = flush_compressed(buf, pos, rep_count, last);
                rep_count = 1;
              }
            raw_count++;            // keep looking for raw bytes
          }
        if (rep_count == 127)     // flush compressed bytes
          {
            // need to add 2 bytes
            if (pos + 2 > buf.length)
              {
                buf = realloc(buf, len);
              }
            pos = flush_compressed(buf, pos, rep_count, last);
            rep_count = 1;
          }
        if (raw_count == 127)     // flush raw bytes
          {
            // need to add raw_count+1 bytes
            if (pos + (raw_count + 1) > buf.length)
              {
                buf = realloc(buf, len);
              }
            pos = flush_raw(buf, pos, b, (i - raw_count), raw_count);
            raw_count = 0;
          }
        last = c;
      }
    if (rep_count > 1)          // flush compressed bytes
      {
        // need to add 2 bytes
        if (pos + 2 > buf.length)
          {
            buf = realloc(buf, len);
          }
        pos = flush_compressed(buf, pos, rep_count, last);
        rep_count = 1;
      }
    if (raw_count > 0)          // flush raw bytes
      {
        // need to add raw_count+1 bytes
        if (pos + (raw_count + 1) > buf.length)
          {
            buf = realloc(buf, len);
          }
        pos = flush_raw(buf, pos, b, (len - raw_count), raw_count);
        raw_count = 0;
      }
    byte[] ret = new byte[pos + 3];
    System.arraycopy(buf, 0, ret, 3, pos);
    return ret;
  }

  int flush_compressed(byte[] buf, int pos, int count, byte c)
  {
    buf[pos++] = (byte) (0x80 | count);
    buf[pos++] = c;
    return pos;
  }

  int flush_raw(byte[] buf, int pos, byte[] src, int off, int len)
  {
    buf[pos++] = (byte) len;
    System.arraycopy(src, off, buf, pos, len);
    return pos + len;
  }

  byte[] realloc(byte[] buf, int len)
  {
    byte[] ret = new byte[buf.length + len];
    System.arraycopy(buf, 0, ret, 0, buf.length);
    return ret;
  }

  public void close()
    throws IOException
  {
    byte[] buf = new byte[]
      {
        EOF,                      /* eof descriptor */
        0x00, 0x00              /* no bytes */
      };
    out.write(buf, 0, 3);
    out.close();
  }

}
