OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / obex / javax / obex / PrivateOutputStream.java
1 /*
2  * Copyright (c) 2008-2009, Motorola, Inc.
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * - Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * - Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * - Neither the name of the Motorola, Inc. nor the names of its contributors
17  * may be used to endorse or promote products derived from this software
18  * without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 package javax.obex;
34
35 import java.io.IOException;
36 import java.io.OutputStream;
37 import java.io.ByteArrayOutputStream;
38
39 /**
40  * This object provides an output stream to the Operation objects used in this
41  * package.
42  * @hide
43  */
44 public final class PrivateOutputStream extends OutputStream {
45
46     private BaseStream mParent;
47
48     private ByteArrayOutputStream mArray;
49
50     private boolean mOpen;
51
52     private int mMaxPacketSize;
53
54     /**
55      * Creates an empty <code>PrivateOutputStream</code> to write to.
56      * @param p the connection that this stream runs over
57      */
58     public PrivateOutputStream(BaseStream p, int maxSize) {
59         mParent = p;
60         mArray = new ByteArrayOutputStream();
61         mMaxPacketSize = maxSize;
62         mOpen = true;
63     }
64
65     /**
66      * Determines how many bytes have been written to the output stream.
67      * @return the number of bytes written to the output stream
68      */
69     public int size() {
70         return mArray.size();
71     }
72
73     /**
74      * Writes the specified byte to this output stream. The general contract for
75      * write is that one byte is written to the output stream. The byte to be
76      * written is the eight low-order bits of the argument b. The 24 high-order
77      * bits of b are ignored.
78      * @param b the byte to write
79      * @throws IOException if an I/O error occurs
80      */
81     @Override
82     public synchronized void write(int b) throws IOException {
83         ensureOpen();
84         mParent.ensureNotDone();
85         mArray.write(b);
86         if (mArray.size() == mMaxPacketSize) {
87             mParent.continueOperation(true, false);
88         }
89     }
90
91     @Override
92     public void write(byte[] buffer) throws IOException {
93         write(buffer, 0, buffer.length);
94     }
95
96     @Override
97     public synchronized void write(byte[] buffer, int offset, int count) throws IOException {
98         int offset1 = offset;
99         int remainLength = count;
100
101         if (buffer == null) {
102             throw new IOException("buffer is null");
103         }
104         if ((offset | count) < 0 || count > buffer.length - offset) {
105             throw new IndexOutOfBoundsException("index outof bound");
106         }
107
108         ensureOpen();
109         mParent.ensureNotDone();
110         if (count < mMaxPacketSize) {
111             mArray.write(buffer, offset, count);
112         } else {
113             while (remainLength >= mMaxPacketSize) {
114                 mArray.write(buffer, offset1, mMaxPacketSize);
115                 offset1 += mMaxPacketSize;
116                 remainLength = count - offset1;
117                 mParent.continueOperation(true, false);
118             }
119             if (remainLength > 0) {
120                 mArray.write(buffer, offset1, remainLength);
121             }
122         }
123     }
124
125     /**
126      * Reads the bytes that have been written to this stream.
127      * @param size the size of the array to return
128      * @return the byte array that is written
129      */
130     public synchronized byte[] readBytes(int size) {
131         if (mArray.size() > 0) {
132             byte[] temp = mArray.toByteArray();
133             mArray.reset();
134             byte[] result = new byte[size];
135             System.arraycopy(temp, 0, result, 0, size);
136             if (temp.length != size) {
137                 mArray.write(temp, size, temp.length - size);
138             }
139             return result;
140         } else {
141             return null;
142         }
143     }
144
145     /**
146      * Verifies that this stream is open
147      * @throws IOException if the stream is not open
148      */
149     private void ensureOpen() throws IOException {
150         mParent.ensureOpen();
151         if (!mOpen) {
152             throw new IOException("Output stream is closed");
153         }
154     }
155
156     /**
157      * Closes the output stream. If the input stream is already closed, do
158      * nothing.
159      * @throws IOException this will never happen
160      */
161     @Override
162     public void close() throws IOException {
163         mOpen = false;
164         mParent.streamClosed(false);
165     }
166
167     /**
168      * Determines if the connection is closed
169      * @return <code>true</code> if the connection is closed; <code>false</code>
170      *         if the connection is open
171      */
172     public boolean isClosed() {
173         return !mOpen;
174     }
175 }