19439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/* 29439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Copyright (c) 2008-2009, Motorola, Inc. 39439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 49439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * All rights reserved. 59439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 69439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Redistribution and use in source and binary forms, with or without 79439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * modification, are permitted provided that the following conditions are met: 89439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 99439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Redistributions of source code must retain the above copyright notice, 109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this list of conditions and the following disclaimer. 119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Redistributions in binary form must reproduce the above copyright notice, 139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this list of conditions and the following disclaimer in the documentation 149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * and/or other materials provided with the distribution. 159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Neither the name of the Motorola, Inc. nor the names of its contributors 179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * may be used to endorse or promote products derived from this software 189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * without specific prior written permission. 199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * POSSIBILITY OF SUCH DAMAGE. 319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellypackage javax.obex; 349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 352e0da96e757a977154063f980d3f4e1abd41cf09Nick Pellyimport java.io.InputStream; 362e0da96e757a977154063f980d3f4e1abd41cf09Nick Pellyimport java.io.IOException; 379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/** 399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * This object provides an input stream to the Operation objects used in this 409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * package. 412e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @hide 429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 433998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejunpublic final class PrivateInputStream extends InputStream { 449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 453998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private BaseStream mParent; 469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private byte[] mData; 489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 493998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private int mIndex; 509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 513998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mOpen; 529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Creates an input stream for the <code>Operation</code> to read from 559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param p the connection this input stream is for 569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public PrivateInputStream(BaseStream p) { 583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent = p; 593998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mData = new byte[0]; 603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mIndex = 0; 613998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOpen = true; 629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the number of bytes that can be read (or skipped over) from this 669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * input stream without blocking by the next caller of a method for this 679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * input stream. The next caller might be the same thread or or another 689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * thread. 699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the number of bytes that can be read from this input stream 7005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * without blocking 712e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly @Override 749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized int available() throws IOException { 759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 763998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mData.length - mIndex; 779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Reads the next byte of data from the input stream. The value byte is 8105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * returned as an int in the range 0 to 255. If no byte is available because 8205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * the end of the stream has been reached, the value -1 is returned. This 8305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * method blocks until input data is available, the end of the stream is 8405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * detected, or an exception is thrown. 8505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @return the byte read from the input stream or -1 if it reaches the end of 8605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * stream 872e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly @Override 909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized int read() throws IOException { 919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while (mData.length == mIndex) { 933998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mParent.continueOperation(true, true)) { 949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return -1; 959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 973998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return (mData[mIndex++] & 0xFF); 989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly @Override 1019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public int read(byte[] b) throws IOException { 1029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return read(b, 0, b.length); 1039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly @Override 1069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized int read(byte[] b, int offset, int length) throws IOException { 1079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (b == null) { 1093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throw new IOException("buffer is null"); 1109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((offset | length) < 0 || length > b.length - offset) { 1129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new ArrayIndexOutOfBoundsException("index outof bound"); 1139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 1159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1163998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int currentDataLength = mData.length - mIndex; 1179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int remainReadLength = length; 1189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int offset1 = offset; 1199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int result = 0; 1209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (currentDataLength <= remainReadLength) { 1223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(mData, mIndex, b, offset1, currentDataLength); 1233998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mIndex += currentDataLength; 1249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly offset1 += currentDataLength; 1259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly result += currentDataLength; 1269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly remainReadLength -= currentDataLength; 1279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1283998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mParent.continueOperation(true, true)) { 1299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return result == 0 ? -1 : result; 1309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1313998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun currentDataLength = mData.length - mIndex; 1329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (remainReadLength > 0) { 1343998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(mData, mIndex, b, offset1, remainReadLength); 1353998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mIndex += remainReadLength; 1369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly result += remainReadLength; 1379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return result; 1399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 1429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Allows the <code>OperationImpl</code> thread to add body data to the 1439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * input stream. 1449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param body the data to add to the stream 1459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param start the start of the body to array to copy 1469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized void writeBytes(byte[] body, int start) { 1489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1493998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int length = (body.length - start) + (mData.length - mIndex); 1509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] temp = new byte[length]; 1519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(mData, mIndex, temp, 0, mData.length - mIndex); 1533998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(body, start, temp, mData.length - mIndex, body.length - start); 1549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1553998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mData = temp; 1563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mIndex = 0; 1579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly notifyAll(); 1589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 1619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Verifies that this stream is open 1622e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if the stream is not open 1639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private void ensureOpen() throws IOException { 1653998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.ensureOpen(); 1663998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mOpen) { 1679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Input stream is closed"); 1689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 17205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Closes the input stream. If the input stream is already closed, do 1739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * nothing. 1742e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException this will never happen 1759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly @Override 1779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void close() throws IOException { 1783998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOpen = false; 1793998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.streamClosed(true); 1809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly} 182