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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* ChunkedInputStream.java --
2
   Copyright (C) 2004, 2006 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.http;
40
 
41
import gnu.java.lang.CPStringBuilder;
42
 
43
import java.io.IOException;
44
import java.io.InputStream;
45
import java.net.ProtocolException;
46
 
47
 
48
//
49
// Note that we rely on the implemtation of skip() in the super class
50
// (InputStream) calling our read methods to account for chunk headers
51
// while skipping.
52
//
53
 
54
 
55
/**
56
 * Input stream wrapper for the "chunked" transfer-coding.
57
 *
58
 * @author Chris Burdess (dog@gnu.org)
59
 */
60
public class ChunkedInputStream
61
  extends InputStream
62
{
63
  Headers headers;
64
 
65
  /** The underlying stream. */
66
  private InputStream in;
67
 
68
  /** Size of the chunk we're reading.  */
69
  int size;
70
  /** Number of bytes we've read in this chunk.  */
71
  int count;
72
  /**
73
   * True when we should read meta-information, false when we should
74
   * read data.
75
   */
76
  boolean meta;
77
  /** True when we've hit EOF.  */
78
  boolean eof;
79
 
80
  /**
81
   * Constructor.
82
   * @param in the response socket input stream
83
   * @param headers the headers to receive additional header lines
84
   */
85
  public ChunkedInputStream(InputStream in, Headers headers)
86
  {
87
    this.in = in;
88
    this.headers = headers;
89
    size = -1;
90
    count = 0;
91
    meta = true;
92
  }
93
 
94
  public int read()
95
    throws IOException
96
  {
97
    byte[] buf = new byte[1];
98
    int len = read(buf, 0, 1);
99
    if (len == -1)
100
      {
101
        return -1;
102
      }
103
    return 0xff & buf[0];
104
  }
105
 
106
  public synchronized int read(byte[] buffer, int offset, int length)
107
    throws IOException
108
  {
109
    if (eof)
110
      {
111
        return -1;
112
      }
113
    if (meta)
114
      {
115
        // Read chunk header
116
        int c, last = 0;
117
        boolean seenSemi = false;
118
        CPStringBuilder buf = new CPStringBuilder();
119
        do
120
          {
121
            c = in.read();
122
            if (c == 0x3b) // ;
123
              {
124
                seenSemi = true;
125
              }
126
            else if (c == 0x0a && last == 0x0d) // CRLF
127
              {
128
                try
129
                  {
130
                    size = Integer.parseInt(buf.toString(), 16);
131
                  }
132
                catch (NumberFormatException nfe)
133
                  {
134
                    IOException ioe = new IOException("Bad chunk header");
135
                    ioe.initCause(nfe);
136
                    // Unrecoverable.  Don't try to read more.
137
                    in.close();
138
                    throw ioe;
139
                  }
140
                break;
141
              }
142
            else if (!seenSemi && c >= 0x30)
143
              {
144
                buf.append ((char) c);
145
              }
146
            last = c;
147
          }
148
        while(c != -1);
149
        count = 0;
150
        meta = false;
151
      }
152
    if (size == 0)
153
      {
154
        // Read trailer
155
        headers.parse(in);
156
        eof = true;
157
        return -1;
158
      }
159
    else
160
      {
161
        int canRead = Math.min(size - count, length);
162
        int len = in.read(buffer, offset, canRead);
163
        if (len == -1)
164
          {
165
            // This is an error condition but it isn't clear what we
166
            // should do with it.
167
            eof = true;
168
            return -1;
169
          }
170
        count += len;
171
        if (count == size)
172
          {
173
            // Read CRLF
174
            int c1 = in.read();
175
            int c2 = in.read();
176
            if (c1 == -1 || c2 == -1)
177
              {
178
                // EOF before CRLF: bad, but ignore
179
                eof = true;
180
                return -1;
181
              }
182
            if (c1 != 0x0d || c2 != 0x0a)
183
              {
184
                throw new ProtocolException("expecting CRLF: " + c1 + "," + c2);
185
              }
186
            meta = true;
187
          }
188
        return len;
189
      }
190
  }
191
 
192
  /**
193
   * This method returns the number of bytes that can be read from
194
   * this stream before a read might block.  Even if the underlying
195
   * InputStream has data available past the end of the current chunk,
196
   * we have no way of knowing how large the next chunk header will
197
   * be. So we cannot report available data past the current chunk.
198
   *
199
   * @return The number of bytes that can be read before a read might
200
   * block
201
   *
202
   * @exception IOException If an error occurs
203
   */
204
  public int available() throws IOException
205
  {
206
    if (meta)
207
      return 0;
208
 
209
    return Math.min(in.available(), size - count);
210
  }
211
 
212
  /**
213
   * This method closes the ChunkedInputStream by closing the underlying
214
   * InputStream.
215
   *
216
   * @exception IOException If an error occurs
217
   */
218
  public void close() throws IOException
219
  {
220
    in.close();
221
  }
222
 
223
}

powered by: WebSVN 2.1.0

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