/[classpath]/inetlib/source/gnu/inet/ftp/CompressedOutputStream.java
ViewVC logotype

Diff of /inetlib/source/gnu/inet/ftp/CompressedOutputStream.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by dog, Sun Oct 19 08:51:37 2003 UTC revision 1.2 by dog, Sun Oct 19 16:16:49 2003 UTC
# Line 40  import java.io.OutputStream; Line 40  import java.io.OutputStream;
40  class CompressedOutputStream extends DTPOutputStream  class CompressedOutputStream extends DTPOutputStream
41  {  {
42    
43          static final byte RECORD = -128; // 0x80    static final byte RECORD = -128;      // 0x80
44          static final byte EOF = 64; // 0x40    static final byte EOF = 64;   // 0x40
45    
46          CompressedOutputStream(DTP dtp, OutputStream out)      CompressedOutputStream(DTP dtp, OutputStream out)
47          {    {
48                  super(dtp, out);      super(dtp, out);
49          }    }
50    
51          /**          /**
52           * Just one byte cannot be compressed.           * Just one byte cannot be compressed.
53           * It takes 5 bytes to transmit - hardly very compressed!           * It takes 5 bytes to transmit - hardly very compressed!
54           */           */
55          public void write(int c)    public void write(int c) throws IOException
56                  throws IOException    {
57          {      if (transferComplete)
58                  if (transferComplete)        return;
59                          return;      byte[] buf = new byte[]
60                  byte[] buf = new byte[] {      {
61                          RECORD, /* record descriptor */        RECORD,                   /* record descriptor */
62                          0x00,          0x00, 0x01,             /* one byte */
63                          0x01, /* one byte */          0x01,                   /* one uncompressed byte */
64                          0x01, /* one uncompressed byte */          (byte) c                /* the byte */
65                          (byte)c /* the byte */      };
66                  };      super.write(buf, 0, 5);
67                  super.write(buf, 0, 5);    }
68          }  
69      public void write(byte[]b) throws IOException
70          public void write(byte[] b)    {
71                  throws IOException      write(b, 0, b.length);
72          {    }
                 write(b, 0, b.length);  
         }  
73    
74          /**          /**
75           * The larger len is, the better.           * The larger len is, the better.
76           */           */
77          public void write(byte[] b, int off, int len)    public void write(byte[]b, int off, int len) throws IOException
78                  throws IOException    {
79          {      if (transferComplete)
80                  if (transferComplete)        return;
81                          return;      byte[] buf = compress(b, off, len);
82                  byte[] buf = compress(b, off, len);      len = buf.length;
83                  len = buf.length;      buf[0] = RECORD;            /* record descriptor */
84                  buf[0] = RECORD; /* record descriptor */      buf[1] = (byte) ((len & 0x00ff) >> 8);      /* high byte of bytecount */
85                  buf[1] = (byte)((len & 0x00ff) >> 8); /* high byte of bytecount */      buf[2] = (byte) (len & 0xff00);     /* low byte of bytecount */
86                  buf[2] = (byte)(len & 0xff00); /* low byte of bytecount */      super.write(buf, 0, len);
87                  super.write(buf, 0, len);    }
         }  
88    
89          /**          /**
90           * Returns the compressed form of the given byte array.           * Returns the compressed form of the given byte array.
91           * The first 3 bytes are left free for header information.           * The first 3 bytes are left free for header information.
92           */           */
93          byte[] compress(byte[] b, int off, int len)    byte[] compress(byte[]b, int off, int len)
94          {    {
95                  byte[] buf = new byte[len];      byte[]buf = new byte[len];
96                  byte last = 0;      byte last = 0;
97                  int pos = 0, raw_count = 0, rep_count = 1;      int pos = 0, raw_count = 0, rep_count = 1;
98                  for (int i=off; i<len; i++)      for (int i = off; i < len; i++)
99                  {      {
100                          byte c = b[i];        byte c = b[i];
101                          if (i>off && c==last) // compress        if (i > off && c == last) // compress
102                          {        {
103                                  if (raw_count>0) // flush raw bytes to buf          if (raw_count > 0)      // flush raw bytes to buf
104                                  {          {
105                                          // need to add raw_count+1 bytes            // need to add raw_count+1 bytes
106                                          if (pos+(raw_count+1)>buf.length)            if (pos + (raw_count + 1) > buf.length)
107                                                  buf = realloc(buf, len);              buf = realloc(buf, len);
108                                          pos = flush_raw(buf, pos, b, (i-raw_count)-1, raw_count);            pos = flush_raw(buf, pos, b, (i - raw_count) - 1, raw_count);
109                                          raw_count = 0;            raw_count = 0;
110                                  }          }
111                                  rep_count++; // keep looking for same byte          rep_count++;            // keep looking for same byte
112                          }        }
113                          else        else
114                          {        {
115                                  if (rep_count>1) // flush compressed bytes to buf          if (rep_count > 1)      // flush compressed bytes to buf
116                                  {          {
117                                          // need to add 2 bytes            // need to add 2 bytes
118                                          if (pos+2>buf.length)            if (pos + 2 > buf.length)
119                                                  buf = realloc(buf, len);              buf = realloc(buf, len);
120                                          pos = flush_compressed(buf, pos, rep_count, last);            pos = flush_compressed(buf, pos, rep_count, last);
121                                          rep_count = 1;            rep_count = 1;
122                                  }          }
123                                  raw_count++; // keep looking for raw bytes          raw_count++;            // keep looking for raw bytes
124                          }        }
125                          if (rep_count==127) // flush compressed bytes        if (rep_count == 127)     // flush compressed bytes
126                          {        {
127                                  // need to add 2 bytes          // need to add 2 bytes
128                                  if (pos+2>buf.length)          if (pos + 2 > buf.length)
129                                                  buf = realloc(buf, len);            buf = realloc(buf, len);
130                                  pos = flush_compressed(buf, pos, rep_count, last);          pos = flush_compressed(buf, pos, rep_count, last);
131                                  rep_count = 1;          rep_count = 1;
132                          }        }
133                          if (raw_count==127) // flush raw bytes        if (raw_count == 127)     // flush raw bytes
134                          {        {
135                                  // need to add raw_count+1 bytes          // need to add raw_count+1 bytes
136                                  if (pos+(raw_count+1)>buf.length)          if (pos + (raw_count + 1) > buf.length)
137                                          buf = realloc(buf, len);            buf = realloc(buf, len);
138                                  pos = flush_raw(buf, pos, b, (i-raw_count), raw_count);          pos = flush_raw(buf, pos, b, (i - raw_count), raw_count);
139                                  raw_count = 0;          raw_count = 0;
140                          }        }
141                          last = c;        last = c;
142                  }      }
143                  if (rep_count>1) // flush compressed bytes      if (rep_count > 1)          // flush compressed bytes
144                  {      {
145                          // need to add 2 bytes        // need to add 2 bytes
146                          if (pos+2>buf.length)        if (pos + 2 > buf.length)
147                                  buf = realloc(buf, len);          buf = realloc(buf, len);
148                          pos = flush_compressed(buf, pos, rep_count, last);        pos = flush_compressed(buf, pos, rep_count, last);
149                          rep_count = 1;        rep_count = 1;
150                  }      }
151                  if (raw_count>0) // flush raw bytes      if (raw_count > 0)          // flush raw bytes
152                  {      {
153                          // need to add raw_count+1 bytes        // need to add raw_count+1 bytes
154                          if (pos+(raw_count+1)>buf.length)        if (pos + (raw_count + 1) > buf.length)
155                                  buf = realloc(buf, len);          buf = realloc(buf, len);
156                          pos = flush_raw(buf, pos, b, (len-raw_count), raw_count);        pos = flush_raw(buf, pos, b, (len - raw_count), raw_count);
157                          raw_count = 0;        raw_count = 0;
158                  }      }
159                  byte[] ret = new byte[pos+3];      byte[]ret = new byte[pos + 3];
160                  System.arraycopy(buf, 0, ret, 3, pos);      System.arraycopy(buf, 0, ret, 3, pos);
161                  return ret;      return ret;
162          }    }
163    
164          int flush_compressed(byte[] buf, int pos, int count, byte c)    int flush_compressed(byte[]buf, int pos, int count, byte c)
165          {    {
166                  buf[pos++] = (byte)(0x80 | count);      buf[pos++] = (byte) (0x80 | count);
167                  buf[pos++] = c;      buf[pos++] = c;
168                  return pos;      return pos;
169          }    }
170    
171          int flush_raw(byte[] buf, int pos, byte[] src, int off, int len)    int flush_raw(byte[]buf, int pos, byte[]src, int off, int len)
172          {    {
173                  buf[pos++] = (byte)len;      buf[pos++] = (byte) len;
174                  System.arraycopy(src, off, buf, pos, len);      System.arraycopy(src, off, buf, pos, len);
175                  return pos + len;      return pos + len;
176          }    }
177    
178          byte[] realloc(byte[] buf, int len)    byte[]realloc(byte[]buf, int len)
179          {    {
180                  byte[] ret = new byte[buf.length+len];      byte[]ret = new byte[buf.length + len];
181                  System.arraycopy(buf, 0, ret, 0, buf.length);      System.arraycopy(buf, 0, ret, 0, buf.length);
182                  return ret;      return ret;
183          }    }
184    
185          public void close()    public void close() throws IOException
186                  throws IOException    {
187          {      byte[] buf = new byte[]
188                  byte[] buf = new byte[] {      {
189                          EOF, /* eof descriptor */        EOF,                      /* eof descriptor */
190                          0x00,          0x00, 0x00              /* no bytes */
191                          0x00 /* no bytes */      };
192                  };      super.write(buf, 0, 3);
193                  super.write(buf, 0, 3);      super.close();
194                  super.close();    }
         }  
195    
196  }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26