PageRenderTime 109ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/ApacheHttpClient/src/java/org/apache/commons/httpclient/ContentLengthInputStream.java

http://google-enterprise-connector-sharepoint.googlecode.com/
Java | 220 lines | 71 code | 21 blank | 128 comment | 9 complexity | 44ed253f1d9fa7adad5a8c3b3210dd9a MD5 | raw file
Possible License(s): LGPL-2.1, GPL-3.0, CPL-1.0, Apache-2.0, MPL-2.0-no-copyleft-exception, GPL-2.0
  1. /*
  2. * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/ContentLengthInputStream.java,v 1.12 2004/10/04 22:05:44 olegk Exp $
  3. * $Revision: 480424 $
  4. * $Date: 2006-11-29 11:26:49 +0530 (Wed, 29 Nov 2006) $
  5. *
  6. * ====================================================================
  7. *
  8. * Licensed to the Apache Software Foundation (ASF) under one or more
  9. * contributor license agreements. See the NOTICE file distributed with
  10. * this work for additional information regarding copyright ownership.
  11. * The ASF licenses this file to You under the Apache License, Version 2.0
  12. * (the "License"); you may not use this file except in compliance with
  13. * the License. You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. * ====================================================================
  23. *
  24. * This software consists of voluntary contributions made by many
  25. * individuals on behalf of the Apache Software Foundation. For more
  26. * information on the Apache Software Foundation, please see
  27. * <http://www.apache.org/>.
  28. *
  29. */
  30. package org.apache.commons.httpclient;
  31. import java.io.IOException;
  32. import java.io.InputStream;
  33. /**
  34. * Cuts the wrapped InputStream off after a specified number of bytes.
  35. *
  36. * <p>Implementation note: Choices abound. One approach would pass
  37. * through the {@link InputStream#mark} and {@link InputStream#reset} calls to
  38. * the underlying stream. That's tricky, though, because you then have to
  39. * start duplicating the work of keeping track of how much a reset rewinds.
  40. * Further, you have to watch out for the "readLimit", and since the semantics
  41. * for the readLimit leave room for differing implementations, you might get
  42. * into a lot of trouble.</p>
  43. *
  44. * <p>Alternatively, you could make this class extend {@link java.io.BufferedInputStream}
  45. * and then use the protected members of that class to avoid duplicated effort.
  46. * That solution has the side effect of adding yet another possible layer of
  47. * buffering.</p>
  48. *
  49. * <p>Then, there is the simple choice, which this takes - simply don't
  50. * support {@link InputStream#mark} and {@link InputStream#reset}. That choice
  51. * has the added benefit of keeping this class very simple.</p>
  52. *
  53. * @author Ortwin Glueck
  54. * @author Eric Johnson
  55. * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
  56. * @since 2.0
  57. */
  58. public class ContentLengthInputStream extends InputStream {
  59. /**
  60. * The maximum number of bytes that can be read from the stream. Subsequent
  61. * read operations will return -1.
  62. */
  63. private long contentLength;
  64. /** The current position */
  65. private long pos = 0;
  66. /** True if the stream is closed. */
  67. private boolean closed = false;
  68. /**
  69. * Wrapped input stream that all calls are delegated to.
  70. */
  71. private InputStream wrappedStream = null;
  72. /**
  73. * @deprecated use {@link #ContentLengthInputStream(InputStream, long)}
  74. *
  75. * Creates a new length limited stream
  76. *
  77. * @param in The stream to wrap
  78. * @param contentLength The maximum number of bytes that can be read from
  79. * the stream. Subsequent read operations will return -1.
  80. */
  81. public ContentLengthInputStream(InputStream in, int contentLength) {
  82. this(in, (long)contentLength);
  83. }
  84. /**
  85. * Creates a new length limited stream
  86. *
  87. * @param in The stream to wrap
  88. * @param contentLength The maximum number of bytes that can be read from
  89. * the stream. Subsequent read operations will return -1.
  90. *
  91. * @since 3.0
  92. */
  93. public ContentLengthInputStream(InputStream in, long contentLength) {
  94. super();
  95. this.wrappedStream = in;
  96. this.contentLength = contentLength;
  97. }
  98. /**
  99. * <p>Reads until the end of the known length of content.</p>
  100. *
  101. * <p>Does not close the underlying socket input, but instead leaves it
  102. * primed to parse the next response.</p>
  103. * @throws IOException If an IO problem occurs.
  104. */
  105. public void close() throws IOException {
  106. if (!closed) {
  107. try {
  108. ChunkedInputStream.exhaustInputStream(this);
  109. } finally {
  110. // close after above so that we don't throw an exception trying
  111. // to read after closed!
  112. closed = true;
  113. }
  114. }
  115. }
  116. /**
  117. * Read the next byte from the stream
  118. * @return The next byte or -1 if the end of stream has been reached.
  119. * @throws IOException If an IO problem occurs
  120. * @see java.io.InputStream#read()
  121. */
  122. public int read() throws IOException {
  123. if (closed) {
  124. throw new IOException("Attempted read from closed stream.");
  125. }
  126. if (pos >= contentLength) {
  127. return -1;
  128. }
  129. pos++;
  130. return this.wrappedStream.read();
  131. }
  132. /**
  133. * Does standard {@link InputStream#read(byte[], int, int)} behavior, but
  134. * also notifies the watcher when the contents have been consumed.
  135. *
  136. * @param b The byte array to fill.
  137. * @param off Start filling at this position.
  138. * @param len The number of bytes to attempt to read.
  139. * @return The number of bytes read, or -1 if the end of content has been
  140. * reached.
  141. *
  142. * @throws java.io.IOException Should an error occur on the wrapped stream.
  143. */
  144. public int read (byte[] b, int off, int len) throws java.io.IOException {
  145. if (closed) {
  146. throw new IOException("Attempted read from closed stream.");
  147. }
  148. if (pos >= contentLength) {
  149. return -1;
  150. }
  151. if (pos + len > contentLength) {
  152. len = (int) (contentLength - pos);
  153. }
  154. int count = this.wrappedStream.read(b, off, len);
  155. pos += count;
  156. return count;
  157. }
  158. /**
  159. * Read more bytes from the stream.
  160. * @param b The byte array to put the new data in.
  161. * @return The number of bytes read into the buffer.
  162. * @throws IOException If an IO problem occurs
  163. * @see java.io.InputStream#read(byte[])
  164. */
  165. public int read(byte[] b) throws IOException {
  166. return read(b, 0, b.length);
  167. }
  168. /**
  169. * Skips and discards a number of bytes from the input stream.
  170. * @param n The number of bytes to skip.
  171. * @return The actual number of bytes skipped. <= 0 if no bytes
  172. * are skipped.
  173. * @throws IOException If an error occurs while skipping bytes.
  174. * @see InputStream#skip(long)
  175. */
  176. public long skip(long n) throws IOException {
  177. // make sure we don't skip more bytes than are
  178. // still available
  179. long length = Math.min(n, contentLength - pos);
  180. // skip and keep track of the bytes actually skipped
  181. length = this.wrappedStream.skip(length);
  182. // only add the skipped bytes to the current position
  183. // if bytes were actually skipped
  184. if (length > 0) {
  185. pos += length;
  186. }
  187. return length;
  188. }
  189. public int available() throws IOException {
  190. if (this.closed) {
  191. return 0;
  192. }
  193. int avail = this.wrappedStream.available();
  194. if (this.pos + avail > this.contentLength ) {
  195. avail = (int)(this.contentLength - this.pos);
  196. }
  197. return avail;
  198. }
  199. }