/** * BlueCove - Java library for Bluetooth * Copyright (C) 2004 Intel Corporation * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * @version $Id$ */ package com.intel.bluetooth; import java.io.IOException; import java.io.InputStream; class BluetoothRFCommInputStream extends InputStream { volatile private BluetoothRFCommConnection conn; public BluetoothRFCommInputStream(BluetoothRFCommConnection conn) { this.conn = conn; } /* * returns the amount of data that can be read in a single call to the read function, * which may not be the same as the total amount of data queued on the socket. * */ public synchronized int available() throws IOException { if (conn == null) { throw new IOException("Stream closed"); } else { return conn.bluetoothStack.connectionRfReadAvailable(conn.handle); } } /* * Reads the next byte of data from the input stream. The value byte is * returned as an int in the range 0 to 255. If no byte is available because * the end of the stream has been reached, the value -1 is returned. This * method blocks until input data is available, the end of the stream is * detected, or an exception is thrown. A subclass must provide an * implementation of this method. * * Returns: the next byte of data, or -1 if the end of the stream is * reached. Throws: IOException - if an I/O error occurs. */ public int read() throws IOException { if (conn == null) { throw new IOException("Stream closed"); } else { try { return conn.bluetoothStack.connectionRfRead(conn.handle); } catch (IOException e) { if (isClosed()) { return -1; } else { throw e; } } } } /* * Reads up to len bytes of data from the input stream into an array of * bytes. An attempt is made to read as many as len bytes, but a smaller * number may be read, possibly zero. The number of bytes actually read is * returned as an integer. This method blocks until input data is available, * end of file is detected, or an exception is thrown. * * If b is null, a NullPointerException is thrown. * * If off is negative, or len is negative, or off+len is greater than the * length of the array b, then an IndexOutOfBoundsException is thrown. * * If len is zero, then no bytes are read and 0 is returned; otherwise, * there is an attempt to read at least one byte. If no byte is available * because the stream is at end of file, the value -1 is returned; * otherwise, at least one byte is read and stored into b. * * The first byte read is stored into element b[off], the next one into * b[off+1], and so on. The number of bytes read is, at most, equal to len. * Let k be the number of bytes actually read; these bytes will be stored in * elements b[off] through b[off+k-1], leaving elements b[off+k] through * b[off+len-1] unaffected. * * In every case, elements b[0] through b[off] and elements b[off+len] * through b[b.length-1] are unaffected. * * If the first byte cannot be read for any reason other than end of file, * then an IOException is thrown. In particular, an IOException is thrown if * the input stream has been closed. * * The read(b, off, len) method for class InputStream simply calls the * method read() repeatedly. If the first such call results in an * IOException, that exception is returned from the call to the read(b, off, * len) method. If any subsequent call to read() results in a IOException, * the exception is caught and treated as if it were end of file; the bytes * read up to that point are stored into b and the number of bytes read * before the exception occurred is returned. Subclasses are encouraged to * provide a more efficient implementation of this method. * * Parameters: b - the buffer into which the data is read. off - the start * offset in array b at which the data is written. len - the maximum number * of bytes to read. Returns: the total number of bytes read into the * buffer, or -1 if there is no more data because the end of the stream has * been reached. Throws: IOException - if an I/O error occurs. See Also: * read() */ public int read(byte[] b, int off, int len) throws IOException { if (off < 0 || len < 0 || off + len > b.length) { throw new IndexOutOfBoundsException(); } if (conn == null) { throw new IOException("Stream closed"); } else { if (len == 0) { // If the length of b is zero, then no bytes are read and 0 is returned return 0; } // otherwise, there is an attempt to read at least one byte. try { return conn.bluetoothStack.connectionRfRead(conn.handle, b, off, len); } catch (IOException e) { if (isClosed()) { return -1; } else { throw e; } } } } /** * Closes this input stream and releases any system resources associated with the stream. * <p> * The general contract of close is that it closes the stream. A * closed stream cannot perform output operations and cannot be reopened. * * @throws IOException * If an I/O error occurs */ public void close() throws IOException { // Function is not synchronized BluetoothRFCommConnection c = conn; if (c != null) { conn = null; c.streamClosed(); } } boolean isClosed() { return this.conn == null; } }