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

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

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