001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026: package com.sun.kvem.jsr082.bluetooth;
027:
028: import java.io.IOException;
029: import java.util.Enumeration;
030: import java.util.Stack;
031: import javax.bluetooth.DataElement;
032: import javax.bluetooth.L2CAPConnection;
033: import javax.bluetooth.UUID;
034:
035: /**
036: * Logical Link Control and Adaptation Protocol connection reader/writer.
037: */
038: class DataL2CAPReaderWriter extends DataElementSerializer {
039:
040: /** The L2CAP connection to read from or write to. */
041: private L2CAPConnection con = null;
042:
043: /** Actual size of the read buffer. */
044: private long readSize = 0;
045:
046: /**
047: * Constructs reader-and-writer object for the given connection.
048: *
049: * @param con the L2CAP connection to create reader-writer for.
050: */
051: DataL2CAPReaderWriter(L2CAPConnection con) throws IOException {
052: this .con = con;
053: writeBuffer = new byte[con.getTransmitMTU()];
054: readBuffer = new byte[con.getReceiveMTU()];
055: }
056:
057: /**
058: * Writes 1-byte data to the connection.
059: *
060: * @param data byte value to write.
061: */
062: void writeByte(long data) throws IOException {
063: if ((writePos < 0) || (writePos >= writeBuffer.length)) {
064: throw new IndexOutOfBoundsException();
065: }
066: writeBuffer[(int) writePos] = (byte) data;
067: writePos++;
068: if (writePos == writeBuffer.length) {
069: con.send(writeBuffer);
070: writePos = 0;
071: }
072: }
073:
074: /**
075: * Writes given data to the connection.
076: *
077: * @param data bytes to write.
078: */
079: void writeBytes(byte[] data) throws IOException {
080: if ((writePos < 0) || (writePos >= writeBuffer.length)) {
081: throw new IndexOutOfBoundsException();
082: }
083: int dataPos = 0;
084:
085: while ((data.length - dataPos) >= ((writeBuffer.length - writePos))) {
086: int length = writeBuffer.length - ((int) writePos);
087: System.arraycopy(data, (int) dataPos, writeBuffer,
088: (int) writePos, (int) length);
089: con.send(writeBuffer);
090: writePos = 0;
091: dataPos += length;
092: }
093: int length = data.length - dataPos;
094:
095: if (length > 0) {
096: System.arraycopy(data, (int) dataPos, writeBuffer,
097: (int) writePos, (int) length);
098: }
099: writePos += length;
100: }
101:
102: /**
103: * Flushes write buffer to the conection.
104: */
105: void flush() throws IOException {
106: if ((writePos < 0) || (writePos >= writeBuffer.length)) {
107: throw new IndexOutOfBoundsException();
108: }
109: if (writePos == 0) {
110: return;
111: }
112: byte[] tempBuffer = new byte[(int) writePos];
113: System.arraycopy(writeBuffer, 0, tempBuffer, 0, (int) writePos);
114: con.send(tempBuffer);
115: writePos = 0;
116: }
117:
118: /**
119: * Reads 1-byte value from the connection.
120: *
121: * @return byte recieved.
122: */
123: byte readByte() throws IOException {
124: if ((readPos == 0) || (readPos == readSize)) {
125: if ((readSize = con.receive(readBuffer)) == 0) {
126: throw new IOException("Empty packet is received");
127: }
128: readPos = 0;
129: } else if ((readPos < 0) || (readPos > readSize)) {
130: throw new IndexOutOfBoundsException();
131: }
132:
133: if (readSize == -1) {
134: throw new IOException("Reached end of stream");
135: }
136:
137: byte data = readBuffer[(int) readPos];
138: readPos++;
139: return data;
140: }
141:
142: /**
143: * Reads given number of bytes from the connection.
144: *
145: * @param size number of bytes to read.
146: * @return array of bytes read.
147: */
148: byte[] readBytes(int size) throws IOException {
149: byte[] data = new byte[size];
150: int dataPos = 0;
151:
152: if ((readPos == 0) || (readPos == readSize)) {
153: readSize = con.receive(readBuffer);
154: readPos = 0;
155: } else if ((readPos < 0) || (readPos > readSize)) {
156: throw new IndexOutOfBoundsException();
157: }
158:
159: while ((data.length - dataPos) > (readSize - readPos)) {
160: int length = (int) (readSize - readPos);
161: System.arraycopy(readBuffer, (int) readPos, data,
162: (int) dataPos, length);
163: dataPos += length;
164: readSize = con.receive(readBuffer);
165: readPos = 0;
166: }
167: int length = data.length - dataPos;
168: System.arraycopy(readBuffer, (int) readPos, data,
169: (int) dataPos, length);
170: readPos += length;
171: return data;
172: }
173: }
|