OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [net/] [protocol/] [ftp/] [CompressedOutputStream.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* CompressedOutputStream.java --
2
   Copyright (C) 2003, 2004  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package gnu.java.net.protocol.ftp;
40
 
41
import java.io.IOException;
42
import 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
 */
49
class 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.