All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.serialpundit.serial.SerialComOutByteStream Maven / Gradle / Ivy

The newest version!
/*
 * This file is part of SerialPundit.
 * 
 * Copyright (C) 2014-2016, Rishi Gupta. All rights reserved.
 *
 * The SerialPundit is DUAL LICENSED. It is made available under the terms of the GNU Affero 
 * General Public License (AGPL) v3.0 for non-commercial use and under the terms of a commercial 
 * license for commercial use of this software. 
 * 
 * The SerialPundit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

package com.serialpundit.serial;

import java.io.IOException;
import java.io.OutputStream;

import com.serialpundit.core.SerialComException;
import com.serialpundit.serial.SerialComManager.SMODE;
import com.serialpundit.serial.internal.ISerialIOStream;
import com.serialpundit.serial.internal.SerialComPortHandleInfo;

/**
 * 

Represents an output stream of bytes that gets sent over to serial port for transmission.

* * @author Rishi Gupta */ public final class SerialComOutByteStream extends OutputStream implements ISerialIOStream { private final SerialComManager scm; private final SerialComPortHandleInfo portHandleInfo; private final long handle; private final Object lock; private final boolean isBlocking; private final long context; private boolean isOpened; /** *

Allocates a new SerialComOutByteStream object.

* * @param scm instance of SerialComManager class with which this stream will associate itself. * @param handle handle of the serial port on which to write data bytes. * @param streamMode indicates blocking or non-blocking behavior of stream. * @throws SerialComException if serial port can not be configured for specified write behavior. * @throws com.serialpundit.core.SerialComException */ public SerialComOutByteStream(SerialComManager scm, SerialComPortHandleInfo portHandleInfo, long handle, SMODE streamMode) throws SerialComException { this.scm = scm; this.portHandleInfo = portHandleInfo; this.handle = handle; lock = new Object(); if(streamMode.getValue() == 1) { context = scm.createBlockingIOContext(); isBlocking = true; }else { context = 0; isBlocking = false; } isOpened = true; } /** *

Writes the specified byte to this output stream (eight low-order bits of the argument data). * The 24 high-order bits of data are ignored.

* * @param data integer to be written to serial port. * @throws IOException if write fails or output stream has been closed. */ @Override public void write(int data) throws IOException { if(isOpened != true) { throw new IOException("The byte stream has been closed !"); } try { if(isBlocking == true) { synchronized(lock) { try { byte[] buffer = new byte[1]; buffer[0] = (byte)data; data = scm.writeBytesBlocking(handle, buffer, context); }catch (SerialComException e) { if(SerialComManager.EXP_UNBLOCKIO.equals(e.getExceptionMsg())) { // this exception message occurs when application has closed stream. // release lock so that blocking context can be destroyed. return; } // this is error other than expected, pass it to the application. throw new IOException(e.getExceptionMsg()); } } }else { int ret = scm.writeSingleByte(handle, (byte)data); if(ret == 0) { throw new IOException("Given data not sent to serial port. Please retry !"); } } } catch (SerialComException e) { throw new IOException(e.getExceptionMsg()); } } /** *

Writes data.length bytes from the specified byte array to this output stream.

* * @param data byte type array of data to be written to serial port. * @throws IOException if write fails or output stream has been closed. * @throws IllegalArgumentException if data is null or an empty array. */ @Override public void write(byte[] data) throws IOException { if(isOpened != true) { throw new IOException("The byte stream has been closed !"); } if((data == null) || (data.length == 0)) { throw new IllegalArgumentException("Argument data can not be null or an empty array !"); } try { if(isBlocking == true) { synchronized(lock) { try { int result = scm.writeBytesBlocking(handle, data, context); if(result == 0) { throw new IOException("Given data not sent to serial port. Please retry !"); } }catch (SerialComException e) { if(SerialComManager.EXP_UNBLOCKIO.equals(e.getExceptionMsg())) { return; } throw new IOException(e.getExceptionMsg()); } } }else { int ret = scm.writeBytes(handle, data, 0); if(ret == 0) { throw new IOException("Given data not sent to serial port. Please retry !"); } } } catch (SerialComException e) { throw new IOException(e.getExceptionMsg()); } } /** *

Writes len bytes from the specified byte array starting at offset off to this output stream.

*

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 data, * then an IndexOutOfBoundsException is thrown.

* * @param data byte type array of data to be written to serial port. * @param off offset from where to start sending data. * @param len length of data to be written. * @throws IOException if write fails or output stream has been closed. * @throws IllegalArgumentException if data is not a byte type array. * @throws NullPointerException if data is null. * @throws IndexOutOfBoundsException If off is negative, or len is negative, or off+len is greater * than the length of the array data. */ @Override public void write(byte[] data, final int off, final int len) throws IOException, IndexOutOfBoundsException { if(isOpened != true) { throw new IOException("The byte stream has been closed !"); } if((data == null) || (data.length == 0)) { throw new IllegalArgumentException("Argument data can not be null or an empty array !"); } if((off < 0) || (len < 0) || ((off+len) > data.length)) { throw new IndexOutOfBoundsException("Index violation detected in given data array !"); } int i = off; byte[] buf = new byte[len]; for(int x=0; xSCM always flushes data every time writeBytes() method is called. So do nothing just return.

* * @throws IOException if write fails or output stream has been closed. */ @Override public void flush() throws IOException { if(isOpened != true) { throw new IOException("The byte stream has been closed !"); } } /** *

This method releases the OutputStream object internally associated with the operating handle.

*

To actually close the port closeComPort() method should be used.

* * @throws IOException if write fails or output stream has been closed. */ @Override public void close() throws IOException { if(isOpened != true) { throw new IOException("The byte stream has been already closed !"); } if(isBlocking == true) { scm.unblockBlockingIOOperation(context); // if there was a blocked write operation, it will hold this lock. when it gets unblocked // it will release this lock and therefore this close method will acquire this lock. // once the lock is acquired it is safe to destroy context. synchronized(lock) { scm.destroyBlockingIOContext(context); } } isOpened = false; portHandleInfo.setSerialComOutByteStream(null); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy