001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0-beta1/module-main/src/main/java/org/apache/http/impl/io/ContentLengthOutputStream.java $
003: * $Revision: 560343 $
004: * $Date: 2007-07-27 20:18:19 +0200 (Fri, 27 Jul 2007) $
005: *
006: * ====================================================================
007: * Licensed to the Apache Software Foundation (ASF) under one
008: * or more contributor license agreements. See the NOTICE file
009: * distributed with this work for additional information
010: * regarding copyright ownership. The ASF licenses this file
011: * to you under the Apache License, Version 2.0 (the
012: * "License"); you may not use this file except in compliance
013: * with the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing,
018: * software distributed under the License is distributed on an
019: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
020: * KIND, either express or implied. See the License for the
021: * specific language governing permissions and limitations
022: * under the License.
023: * ====================================================================
024: *
025: * This software consists of voluntary contributions made by many
026: * individuals on behalf of the Apache Software Foundation. For more
027: * information on the Apache Software Foundation, please see
028: * <http://www.apache.org/>.
029: *
030: */
031:
032: package org.apache.http.impl.io;
033:
034: import java.io.IOException;
035: import java.io.OutputStream;
036:
037: import org.apache.http.io.SessionOutputBuffer;
038:
039: /**
040: * A stream wrapper that closes itself after a defined number of bytes.
041: *
042: * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
043: *
044: * @version $Revision: 560343 $
045: *
046: * @since 4.0
047: */
048: public class ContentLengthOutputStream extends OutputStream {
049:
050: /**
051: * Wrapped session outbut buffer.
052: */
053: private final SessionOutputBuffer out;
054:
055: /**
056: * The maximum number of bytes that can be written the stream. Subsequent
057: * write operations will be ignored.
058: */
059: private final long contentLength;
060:
061: /** Total bytes written */
062: private long total = 0;
063:
064: /** True if the stream is closed. */
065: private boolean closed = false;
066:
067: /**
068: * Creates a new length limited stream
069: *
070: * @param out The data transmitter to wrap
071: * @param contentLength The maximum number of bytes that can be written to
072: * the stream. Subsequent write operations will be ignored.
073: *
074: * @since 4.0
075: */
076: public ContentLengthOutputStream(final SessionOutputBuffer out,
077: long contentLength) {
078: super ();
079: if (out == null) {
080: throw new IllegalArgumentException(
081: "Session output buffer may not be null");
082: }
083: if (contentLength < 0) {
084: throw new IllegalArgumentException(
085: "Content length may not be negative");
086: }
087: this .out = out;
088: this .contentLength = contentLength;
089: }
090:
091: /**
092: * <p>Does not close the underlying socket output.</p>
093: *
094: * @throws IOException If an I/O problem occurs.
095: */
096: public void close() throws IOException {
097: if (!this .closed) {
098: this .closed = true;
099: this .out.flush();
100: }
101: }
102:
103: public void flush() throws IOException {
104: this .out.flush();
105: }
106:
107: public void write(byte[] b, int off, int len) throws IOException {
108: if (this .closed) {
109: throw new IOException("Attempted write to closed stream.");
110: }
111: if (this .total < this .contentLength) {
112: long max = this .contentLength - this .total;
113: if (len > max) {
114: len = (int) max;
115: }
116: this .out.write(b, off, len);
117: this .total += len;
118: }
119: }
120:
121: public void write(byte[] b) throws IOException {
122: write(b, 0, b.length);
123: }
124:
125: public void write(int b) throws IOException {
126: if (this .closed) {
127: throw new IOException("Attempted write to closed stream.");
128: }
129: if (this.total < this.contentLength) {
130: this.out.write(b);
131: this.total++;
132: }
133: }
134:
135: }
|