Source code: org/apache/http/io/ContentLengthOutputStream.java
1 /*
2 * $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpcore/tags/4.0-alpha2/src/java/org/apache/http/io/ContentLengthOutputStream.java $
3 * $Revision: 390883 $
4 * $Date: 2006-04-02 20:39:50 +0200 (Sun, 02 Apr 2006) $
5 *
6 * ====================================================================
7 *
8 * Copyright 1999-2006 The Apache Software Foundation
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 * ====================================================================
22 *
23 * This software consists of voluntary contributions made by many
24 * individuals on behalf of the Apache Software Foundation. For more
25 * information on the Apache Software Foundation, please see
26 * <http://www.apache.org/>.
27 *
28 */
29
30 package org.apache.http.io;
31
32 import java.io.IOException;
33 import java.io.OutputStream;
34
35 /**
36 * A stream wrapper that closes itself after a defined number of bytes.
37 *
38 * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
39 *
40 * @version $Revision: 390883 $
41 *
42 * @since 4.0
43 */
44 public class ContentLengthOutputStream extends OutputStream {
45
46 /**
47 * Wrapped data transmitter that all calls are delegated to.
48 */
49 private final HttpDataTransmitter out;
50
51 /**
52 * The maximum number of bytes that can be written the stream. Subsequent
53 * write operations will be ignored.
54 */
55 private final long contentLength;
56
57 /** Total bytes written */
58 private long total = 0;
59
60 /** True if the stream is closed. */
61 private boolean closed = false;
62
63 /**
64 * Creates a new length limited stream
65 *
66 * @param out The data transmitter to wrap
67 * @param contentLength The maximum number of bytes that can be written to
68 * the stream. Subsequent write operations will be ignored.
69 *
70 * @since 4.0
71 */
72 public ContentLengthOutputStream(final HttpDataTransmitter out, long contentLength) {
73 super();
74 if (out == null) {
75 throw new IllegalArgumentException("HTTP data transmitter may not be null");
76 }
77 if (contentLength < 0) {
78 throw new IllegalArgumentException("Content length may not be negative");
79 }
80 this.out = out;
81 this.contentLength = contentLength;
82 }
83
84 /**
85 * <p>Does not close the underlying socket output.</p>
86 *
87 * @throws IOException If an I/O problem occurs.
88 */
89 public void close() throws IOException {
90 if (!this.closed) {
91 this.closed = true;
92 this.out.flush();
93 }
94 }
95
96 public void flush() throws IOException {
97 this.out.flush();
98 }
99
100 public void write(byte[] b, int off, int len) throws IOException {
101 if (this.closed) {
102 throw new IOException("Attempted write to closed stream.");
103 }
104 if (this.total < this.contentLength) {
105 long max = this.contentLength - this.total;
106 if (len > max) {
107 len = (int) max;
108 }
109 this.out.write(b, off, len);
110 this.total += len;
111 }
112 }
113
114 public void write(byte[] b) throws IOException {
115 write(b, 0, b.length);
116 }
117
118 public void write(int b) throws IOException {
119 if (this.closed) {
120 throw new IOException("Attempted write to closed stream.");
121 }
122 if (this.total < this.contentLength) {
123 this.out.write(b);
124 this.total++;
125 }
126 }
127
128 }