/** * BlueCove - Java library for Bluetooth * Copyright (C) 2007-2009 Vlad Skarzhevskyy * * 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.obex; import java.io.IOException; import java.io.OutputStream; class OBEXOperationOutputStream extends OutputStream { private final OBEXOperationDelivery operation; private byte[] buffer; private int bufferLength; private Object lock = new Object(); private boolean isClosed = false; OBEXOperationOutputStream(int mtu, OBEXOperationDelivery op) { this.operation = op; buffer = new byte[mtu - OBEXOperationCodes.OBEX_MTU_HEADER_RESERVE]; bufferLength = 0; } public void write(int i) throws IOException { write(new byte[] { (byte) i }, 0, 1); } public void write(byte b[], int off, int len) throws IOException { if (this.operation.isClosed() || isClosed) { throw new IOException("stream closed"); } if (b == null) { throw new NullPointerException(); } else if ((off < 0) || (len < 0) || ((off + len) > b.length)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return; } synchronized (lock) { int written = 0; while (written < len) { int available = (buffer.length - bufferLength); if ((len - written) < available) { available = len - written; } System.arraycopy(b, off + written, buffer, bufferLength, available); bufferLength += available; written += available; if (bufferLength == buffer.length) { this.operation.deliverPacket(false, buffer); bufferLength = 0; } } } } public void flush() throws IOException { if (bufferLength > 0) { deliverBuffer(false); } } void deliverBuffer(boolean finalPacket) throws IOException { synchronized (lock) { byte[] b = new byte[bufferLength]; System.arraycopy(buffer, 0, b, 0, bufferLength); this.operation.deliverPacket(finalPacket, b); bufferLength = 0; } } void abort() { synchronized (lock) { isClosed = true; } } public void close() throws IOException { if (!isClosed) { synchronized (lock) { isClosed = true; if (!operation.isClosed()) { deliverBuffer(true); } } } } }