EMMA Coverage Report (generated Wed Aug 16 18:51:55 GMT 2006)
[all classes][gnu.java.net.protocol.ftp]

COVERAGE SUMMARY FOR SOURCE FILE [CompressedOutputStream.java]

nameclass, %method, %block, %line, %
CompressedOutputStream.java0%   (0/1)0%   (0/9)0%   (0/345)0%   (0/81)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CompressedOutputStream0%   (0/1)0%   (0/9)0%   (0/345)0%   (0/81)
CompressedOutputStream (DTP, OutputStream): void 0%   (0/1)0%   (0/5)0%   (0/2)
close (): void 0%   (0/1)0%   (0/17)0%   (0/6)
compress (byte [], int, int): byte [] 0%   (0/1)0%   (0/199)0%   (0/43)
flush_compressed (byte [], int, int, byte): int 0%   (0/1)0%   (0/15)0%   (0/3)
flush_raw (byte [], int, byte [], int, int): int 0%   (0/1)0%   (0/16)0%   (0/3)
realloc (byte [], int): byte [] 0%   (0/1)0%   (0/15)0%   (0/3)
write (byte []): void 0%   (0/1)0%   (0/7)0%   (0/2)
write (byte [], int, int): void 0%   (0/1)0%   (0/40)0%   (0/9)
write (int): void 0%   (0/1)0%   (0/31)0%   (0/10)

1/* CompressedOutputStream.java --
2   Copyright (C) 2003, 2004  Free Software Foundation, Inc.
3 
4This file is part of GNU Classpath.
5 
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10 
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14General Public License for more details.
15 
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING.  If not, write to the
18Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1902110-1301 USA.
20 
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library.  Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25 
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module.  An independent module is a module which is not derived from
33or based on this library.  If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so.  If you do not wish to do so, delete this
36exception statement from your version. */
37 
38 
39package gnu.java.net.protocol.ftp;
40 
41import java.io.IOException;
42import java.io.OutputStream;
43 
44/**
45 * A DTP output stream that implements the FTP compressed transfer mode.
46 *
47 * @author Chris Burdess (dog@gnu.org)
48 */
49class CompressedOutputStream
50  extends DTPOutputStream
51{
52 
53  static final byte RECORD = -128;      // 0x80
54  static final byte EOF = 64;   // 0x40
55 
56  CompressedOutputStream(DTP dtp, OutputStream out)
57  {
58    super(dtp, out);
59  }
60  
61  /**
62   * Just one byte cannot be compressed.
63   * It takes 5 bytes to transmit - hardly very compressed!
64   */
65  public void write(int c)
66    throws IOException
67  {
68    if (transferComplete)
69      {
70        return;
71      }
72    byte[] buf = new byte[]
73      {
74        RECORD,                   /* record descriptor */
75        0x00, 0x01,             /* one byte */
76        0x01,                   /* one uncompressed byte */
77        (byte) c                /* the byte */
78      };
79    out.write(buf, 0, 5);
80  }
81 
82  public void write(byte[] b)
83    throws IOException
84  {
85    write(b, 0, b.length);
86  }
87 
88  /**
89   * The larger len is, the better.
90   */
91  public void write(byte[] b, int off, int len)
92    throws IOException
93  {
94    if (transferComplete)
95      {
96        return;
97      }
98    byte[] buf = compress(b, off, len);
99    len = buf.length;
100    buf[0] = RECORD;            /* record descriptor */
101    buf[1] = (byte) ((len & 0x00ff) >> 8);      /* high byte of bytecount */
102    buf[2] = (byte) (len & 0xff00);     /* low byte of bytecount */
103    out.write(buf, 0, len);
104  }
105 
106  /**
107   * Returns the compressed form of the given byte array.
108   * The first 3 bytes are left free for header information.
109   */
110  byte[] compress(byte[] b, int off, int len)
111  {
112    byte[] buf = new byte[len];
113    byte last = 0;
114    int pos = 0, raw_count = 0, rep_count = 1;
115    for (int i = off; i < len; i++)
116      {
117        byte c = b[i];
118        if (i > off && c == last) // compress
119          {
120            if (raw_count > 0)      // flush raw bytes to buf
121              {
122                // need to add raw_count+1 bytes
123                if (pos + (raw_count + 1) > buf.length)
124                  {
125                    buf = realloc(buf, len);
126                  }
127                pos = flush_raw(buf, pos, b, (i - raw_count) - 1,
128                                raw_count);
129                raw_count = 0;
130              }
131            rep_count++;            // keep looking for same byte
132          }
133        else
134          {
135            if (rep_count > 1)      // flush compressed bytes to buf
136              {
137                // need to add 2 bytes
138                if (pos + 2 > buf.length)
139                  {
140                    buf = realloc(buf, len);
141                  }
142                pos = flush_compressed(buf, pos, rep_count, last);
143                rep_count = 1;
144              }
145            raw_count++;            // keep looking for raw bytes
146          }
147        if (rep_count == 127)     // flush compressed bytes
148          {
149            // need to add 2 bytes
150            if (pos + 2 > buf.length)
151              {
152                buf = realloc(buf, len);
153              }
154            pos = flush_compressed(buf, pos, rep_count, last);
155            rep_count = 1;
156          }
157        if (raw_count == 127)     // flush raw bytes
158          {
159            // need to add raw_count+1 bytes
160            if (pos + (raw_count + 1) > buf.length)
161              {
162                buf = realloc(buf, len);
163              }
164            pos = flush_raw(buf, pos, b, (i - raw_count), raw_count);
165            raw_count = 0;
166          }
167        last = c;
168      }
169    if (rep_count > 1)          // flush compressed bytes
170      {
171        // need to add 2 bytes
172        if (pos + 2 > buf.length)
173          {
174            buf = realloc(buf, len);
175          }
176        pos = flush_compressed(buf, pos, rep_count, last);
177        rep_count = 1;
178      }
179    if (raw_count > 0)          // flush raw bytes
180      {
181        // need to add raw_count+1 bytes
182        if (pos + (raw_count + 1) > buf.length)
183          {
184            buf = realloc(buf, len);
185          }
186        pos = flush_raw(buf, pos, b, (len - raw_count), raw_count);
187        raw_count = 0;
188      }
189    byte[] ret = new byte[pos + 3];
190    System.arraycopy(buf, 0, ret, 3, pos);
191    return ret;
192  }
193  
194  int flush_compressed(byte[] buf, int pos, int count, byte c)
195  {
196    buf[pos++] = (byte) (0x80 | count);
197    buf[pos++] = c;
198    return pos;
199  }
200 
201  int flush_raw(byte[] buf, int pos, byte[] src, int off, int len)
202  {
203    buf[pos++] = (byte) len;
204    System.arraycopy(src, off, buf, pos, len);
205    return pos + len;
206  }
207 
208  byte[] realloc(byte[] buf, int len)
209  {
210    byte[] ret = new byte[buf.length + len];
211    System.arraycopy(buf, 0, ret, 0, buf.length);
212    return ret;
213  }
214 
215  public void close()
216    throws IOException
217  {
218    byte[] buf = new byte[]
219      {
220        EOF,                      /* eof descriptor */
221        0x00, 0x00              /* no bytes */
222      };
223    out.write(buf, 0, 3);
224    out.close();
225  }
226 
227}
228 

[all classes][gnu.java.net.protocol.ftp]
EMMA 2.0.6427 (unsupported private build) (C) Vladimir Roubtsov