1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/*
2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/io/AbstractSessionInputBuffer.java $
3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Revision: 576077 $
4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Date: 2007-09-16 04:50:22 -0700 (Sun, 16 Sep 2007) $
5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ====================================================================
7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one
8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * or more contributor license agreements.  See the NOTICE file
9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * distributed with this work for additional information
10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * regarding copyright ownership.  The ASF licenses this file
11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to you under the Apache License, Version 2.0 (the
12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * "License"); you may not use this file except in compliance
13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * with the License.  You may obtain a copy of the License at
14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *   http://www.apache.org/licenses/LICENSE-2.0
16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Unless required by applicable law or agreed to in writing,
18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * software distributed under the License is distributed on an
19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * KIND, either express or implied.  See the License for the
21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * specific language governing permissions and limitations
22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * under the License.
23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ====================================================================
24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This software consists of voluntary contributions made by many
26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * individuals on behalf of the Apache Software Foundation.  For more
27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * information on the Apache Software Foundation, please see
28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <http://www.apache.org/>.
29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpackage org.apache.http.impl.io;
33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.IOException;
35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.InputStream;
36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.io.SessionInputBuffer;
38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.io.HttpTransportMetrics;
39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.params.CoreConnectionPNames;
40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.params.HttpParams;
41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.params.HttpProtocolParams;
42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.protocol.HTTP;
43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.util.ByteArrayBuffer;
44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.util.CharArrayBuffer;
45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/**
47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Abstract base class for session input buffers that stream data
48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * from a {@link InputStream}.
49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
52d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *
53d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * @deprecated Please use {@link java.net.URL#openConnection} instead.
54d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
55d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *     for further details.
56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
57d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath@Deprecated
58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic abstract class AbstractSessionInputBuffer implements SessionInputBuffer {
59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private InputStream instream;
61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private byte[] buffer;
62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int bufferpos;
63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int bufferlen;
64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private ByteArrayBuffer linebuffer = null;
66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private String charset = HTTP.US_ASCII;
68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private boolean ascii = true;
69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int maxLineLen = -1;
70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private HttpTransportMetricsImpl metrics;
72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected void init(final InputStream instream, int buffersize, final HttpParams params) {
74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (instream == null) {
75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalArgumentException("Input stream may not be null");
76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (buffersize <= 0) {
78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalArgumentException("Buffer size may not be negative or zero");
79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (params == null) {
81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalArgumentException("HTTP parameters may not be null");
82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.instream = instream;
84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.buffer = new byte[buffersize];
85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.bufferpos = 0;
86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.bufferlen = 0;
87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.linebuffer = new ByteArrayBuffer(buffersize);
88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.charset = HttpProtocolParams.getHttpElementCharset(params);
89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.ascii = this.charset.equalsIgnoreCase(HTTP.US_ASCII)
90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                     || this.charset.equalsIgnoreCase(HTTP.ASCII);
91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.maxLineLen = params.getIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, -1);
92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.metrics = new HttpTransportMetricsImpl();
93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected int fillBuffer() throws IOException {
96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // compact the buffer if necessary
97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (this.bufferpos > 0) {
98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            int len = this.bufferlen - this.bufferpos;
99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (len > 0) {
100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                System.arraycopy(this.buffer, this.bufferpos, this.buffer, 0, len);
101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            this.bufferpos = 0;
103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            this.bufferlen = len;
104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int l;
106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int off = this.bufferlen;
107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int len = this.buffer.length - off;
108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        l = this.instream.read(this.buffer, off, len);
109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (l == -1) {
110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return -1;
111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            this.bufferlen = off + l;
113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            this.metrics.incrementBytesTransferred(l);
114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return l;
115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected boolean hasBufferedData() {
119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return this.bufferpos < this.bufferlen;
120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public int read() throws IOException {
123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int noRead = 0;
124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        while (!hasBufferedData()) {
125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            noRead = fillBuffer();
126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (noRead == -1) {
127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                return -1;
128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return this.buffer[this.bufferpos++] & 0xff;
131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public int read(final byte[] b, int off, int len) throws IOException {
134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (b == null) {
135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return 0;
136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int noRead = 0;
138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        while (!hasBufferedData()) {
139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            noRead = fillBuffer();
140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (noRead == -1) {
141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                return -1;
142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int chunk = this.bufferlen - this.bufferpos;
145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (chunk > len) {
146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            chunk = len;
147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        System.arraycopy(this.buffer, this.bufferpos, b, off, chunk);
149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.bufferpos += chunk;
150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return chunk;
151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public int read(final byte[] b) throws IOException {
154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (b == null) {
155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return 0;
156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return read(b, 0, b.length);
158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int locateLF() {
161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        for (int i = this.bufferpos; i < this.bufferlen; i++) {
162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (this.buffer[i] == HTTP.LF) {
163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                return i;
164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return -1;
167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public int readLine(final CharArrayBuffer charbuffer) throws IOException {
170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (charbuffer == null) {
171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalArgumentException("Char array buffer may not be null");
172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.linebuffer.clear();
174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int noRead = 0;
175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        boolean retry = true;
176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        while (retry) {
177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // attempt to find end of line (LF)
178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            int i = locateLF();
179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (i != -1) {
180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // end of line found.
181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (this.linebuffer.isEmpty()) {
182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    // the entire line is preset in the read buffer
183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    return lineFromReadBuffer(charbuffer, i);
184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                retry = false;
186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                int len = i + 1 - this.bufferpos;
187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                this.linebuffer.append(this.buffer, this.bufferpos, len);
188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                this.bufferpos = i + 1;
189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // end of line not found
191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (hasBufferedData()) {
192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    int len = this.bufferlen - this.bufferpos;
193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    this.linebuffer.append(this.buffer, this.bufferpos, len);
194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    this.bufferpos = this.bufferlen;
195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                noRead = fillBuffer();
197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (noRead == -1) {
198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    retry = false;
199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (this.maxLineLen > 0 && this.linebuffer.length() >= this.maxLineLen) {
202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                throw new IOException("Maximum line length limit exceeded");
203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (noRead == -1 && this.linebuffer.isEmpty()) {
206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // indicate the end of stream
207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return -1;
208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return lineFromLineBuffer(charbuffer);
210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int lineFromLineBuffer(final CharArrayBuffer charbuffer)
213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throws IOException {
214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // discard LF if found
215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int l = this.linebuffer.length();
216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (l > 0) {
217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (this.linebuffer.byteAt(l - 1) == HTTP.LF) {
218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                l--;
219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                this.linebuffer.setLength(l);
220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // discard CR if found
222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (l > 0) {
223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (this.linebuffer.byteAt(l - 1) == HTTP.CR) {
224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    l--;
225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    this.linebuffer.setLength(l);
226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        l = this.linebuffer.length();
230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (this.ascii) {
231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            charbuffer.append(this.linebuffer, 0, l);
232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // This is VERY memory inefficient, BUT since non-ASCII charsets are
234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // NOT meant to be used anyway, there's no point optimizing it
235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            String s = new String(this.linebuffer.buffer(), 0, l, this.charset);
236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            charbuffer.append(s);
237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return l;
239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int lineFromReadBuffer(final CharArrayBuffer charbuffer, int pos)
242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throws IOException {
243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int off = this.bufferpos;
244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int len;
245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.bufferpos = pos + 1;
246633bc1a8d332166c7fca3e4f6fa8e5603f1618beDan Bornstein        // BEGIN android-changed
247633bc1a8d332166c7fca3e4f6fa8e5603f1618beDan Bornstein        // The first test below was fixed to not try to skip beyond the
248633bc1a8d332166c7fca3e4f6fa8e5603f1618beDan Bornstein        // start of the live part of the buffer.
249633bc1a8d332166c7fca3e4f6fa8e5603f1618beDan Bornstein        if (pos > off && this.buffer[pos - 1] == HTTP.CR) {
250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // skip CR if found
251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            pos--;
252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
253633bc1a8d332166c7fca3e4f6fa8e5603f1618beDan Bornstein        // END android-changed
254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        len = pos - off;
255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (this.ascii) {
256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            charbuffer.append(this.buffer, off, len);
257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // This is VERY memory inefficient, BUT since non-ASCII charsets are
259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // NOT meant to be used anyway, there's no point optimizing it
260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            String s = new String(this.buffer, off, len, this.charset);
261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            charbuffer.append(s);
262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return len;
264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public String readLine() throws IOException {
267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        CharArrayBuffer charbuffer = new CharArrayBuffer(64);
268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int l = readLine(charbuffer);
269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (l != -1) {
270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return charbuffer.toString();
271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public HttpTransportMetrics getMetrics() {
277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return this.metrics;
278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project}
281