001package com.pi4j.io.serial.impl; 002 003/* 004 * #%L 005 * ********************************************************************** 006 * ORGANIZATION : Pi4J 007 * PROJECT : Pi4J :: Java Library (Core) 008 * FILENAME : AbstractSerialDataWriter.java 009 * 010 * This file is part of the Pi4J project. More information about 011 * this project can be found here: https://www.pi4j.com/ 012 * ********************************************************************** 013 * %% 014 * Copyright (C) 2012 - 2021 Pi4J 015 * %% 016 * This program is free software: you can redistribute it and/or modify 017 * it under the terms of the GNU Lesser General Public License as 018 * published by the Free Software Foundation, either version 3 of the 019 * License, or (at your option) any later version. 020 * 021 * This program is distributed in the hope that it will be useful, 022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 024 * GNU General Lesser Public License for more details. 025 * 026 * You should have received a copy of the GNU General Lesser Public 027 * License along with this program. If not, see 028 * <http://www.gnu.org/licenses/lgpl-3.0.html>. 029 * #L% 030 */ 031 032import com.pi4j.io.serial.SerialDataWriter; 033 034import java.io.ByteArrayOutputStream; 035import java.io.IOException; 036import java.io.InputStream; 037import java.nio.ByteBuffer; 038import java.nio.CharBuffer; 039import java.nio.charset.Charset; 040import java.nio.charset.StandardCharsets; 041import java.util.Collection; 042 043public abstract class AbstractSerialDataWriter implements SerialDataWriter { 044 045 // ---------------------------------------- 046 // WRITE OPERATIONS 047 // ---------------------------------------- 048 049 /** 050 * <p>Sends an array of bytes to the serial port/device identified by the given file descriptor.</p> 051 * 052 * @param data 053 * A ByteBuffer of data to be transmitted. 054 * @param offset 055 * The starting index (inclusive) in the array to send from. 056 * @param length 057 * The number of bytes from the byte array to transmit to the serial port. 058 */ 059 public abstract void write(byte[] data, int offset, int length) throws IllegalStateException, IOException; 060 061 /** 062 * <p>Sends one of more bytes to the serial device identified by the given file descriptor.</p> 063 * 064 * @param data 065 * One or more bytes (or an array) of data to be transmitted. (variable-length-argument) 066 */ 067 public void write(byte ... data) throws IllegalStateException, IOException{ 068 write(data, 0, data.length); 069 } 070 071 /** 072 * <p>Sends one of more bytes arrays to the serial device identified by the given file descriptor.</p> 073 * 074 * @param data 075 * One or more byte arrays of data to be transmitted. (variable-length-argument) 076 */ 077 public void write(byte[] ... data) throws IllegalStateException, IOException{ 078 for(byte[] single : data) { 079 write(single); 080 } 081 } 082 083 /** 084 * Read the content of byte buffer and write the data to the serial port transmit buffer. 085 * (The buffer is read from the current position up to the 'limit' value, not the 'capacity'. You may need to 086 * rewind() or flip() the byte buffer if you have just written to it.) 087 * 088 * @param data 089 * A ByteBuffer of data to be transmitted. 090 */ 091 public void write(ByteBuffer... data) throws IllegalStateException, IOException{ 092 // write each byte buffer to the serial port 093 for(ByteBuffer single : data) { 094 095 // read the byte buffer from the current position up to the limit 096 byte[] payload = new byte[single.remaining()]; 097 single.get(payload); 098 099 write(payload); 100 } 101 } 102 103 /** 104 * Read content from an input stream of data and write it to the serial port transmit buffer. 105 * 106 * @param input 107 * An InputStream of data to be transmitted 108 */ 109 public void write(InputStream input) throws IllegalStateException, IOException{ 110 // ensure bytes are available 111 if(input.available() <= 0){ 112 throw new IOException("No available bytes in input stream to write to serial port."); 113 } 114 115 ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 116 int length; 117 byte[] data = new byte[1024]; 118 while ((length = input.read(data, 0, data.length)) != -1) { 119 buffer.write(data, 0, length); 120 } 121 buffer.flush(); 122 123 write(buffer.toByteArray()); 124 } 125 126 /** 127 * <p>Sends an array of characters to the serial port/device identified by the given file descriptor.</p> 128 * 129 * @param charset 130 * The character set to use for encoding/decoding bytes to/from text characters 131 * @param data 132 * An array of chars to be decoded into bytes and transmitted. 133 * @param offset 134 * The starting index (inclusive) in the array to send from. 135 * @param length 136 * The number of characters from the char array to transmit to the serial port. 137 */ 138 public void write(Charset charset, char[] data, int offset, int length) throws IllegalStateException, IOException{ 139 write(charset, CharBuffer.wrap(data, offset, length)); 140 } 141 142 /** 143 * <p>Sends an array of characters to the serial port/device identified by the given file descriptor.</p> 144 * 145 * @param charset 146 * The character set to use for encoding/decoding bytes to/from text characters 147 * @param data 148 * One or more characters (or an array) of data to be transmitted. (variable-length-argument) 149 */ 150 public void write(Charset charset, char ... data) throws IllegalStateException, IOException{ 151 write(charset, CharBuffer.wrap(data)); 152 } 153 154 /** 155 * <p>Sends an array of ASCII characters to the serial port/device identified by the given file descriptor.</p> 156 * 157 * @param data 158 * One or more ASCII characters (or an array) of data to be transmitted. (variable-length-argument) 159 */ 160 public void write(char ... data) throws IllegalStateException, IOException{ 161 write(StandardCharsets.US_ASCII, CharBuffer.wrap(data)); 162 } 163 164 /** 165 * <p>Sends one or more CharBuffers to the serial port/device identified by the given file descriptor.</p> 166 * 167 * @param charset 168 * The character set to use for encoding/decoding bytes to/from text characters 169 * @param data 170 * One or more CharBuffers (or an array) of data to be transmitted. (variable-length-argument) 171 */ 172 public void write(Charset charset, CharBuffer... data) throws IllegalStateException, IOException{ 173 for(CharBuffer single : data) { 174 write(charset.encode(single)); 175 } 176 } 177 178 /** 179 * <p>Sends one or more ASCII CharBuffers to the serial port/device identified by the given file descriptor.</p> 180 * 181 * @param data 182 * One or more ASCII CharBuffers (or an array) of data to be transmitted. (variable-length-argument) 183 */ 184 public void write(CharBuffer ... data) throws IllegalStateException, IOException{ 185 write(StandardCharsets.US_ASCII, data); 186 } 187 188 /** 189 * <p>Sends one or more string objects to the serial port/device identified by the given file descriptor.</p> 190 * 191 * @param charset 192 * The character set to use for encoding/decoding bytes to/from text characters 193 * @param data 194 * One or more string objects (or an array) of data to be transmitted. (variable-length-argument) 195 */ 196 public void write(Charset charset, CharSequence ... data) throws IllegalStateException, IOException{ 197 for(CharSequence single : data) { 198 write(charset.encode(CharBuffer.wrap(single))); 199 } 200 } 201 202 /** 203 * <p>Sends one or more ASCII string objects to the serial port/device identified by the given file descriptor.</p> 204 * 205 * @param data 206 * One or more ASCII string objects (or an array) of data to be transmitted. (variable-length-argument) 207 */ 208 public void write(CharSequence ... data) throws IllegalStateException, IOException{ 209 write(StandardCharsets.US_ASCII, data); 210 } 211 212 /** 213 * <p>Sends a collection of string objects to the serial port/device identified by the given file descriptor.</p> 214 * 215 * @param charset 216 * The character set to use for encoding/decoding bytes to/from text characters 217 * @param data 218 * A collection of string objects (or an array) of data to be transmitted. (variable-length-argument) 219 */ 220 public void write(Charset charset, Collection<? extends CharSequence> data) throws IllegalStateException, IOException{ 221 for(CharSequence single : data) { 222 write(charset.encode(CharBuffer.wrap(single))); 223 } 224 } 225 226 /** 227 * <p>Sends a collection of ASCII string objects to the serial port/device identified by the given file descriptor.</p> 228 * 229 * @param data 230 * A collection of string objects (or an array) of data to be transmitted. (variable-length-argument) 231 */ 232 public void write(Collection<? extends CharSequence> data) throws IllegalStateException, IOException{ 233 write(StandardCharsets.US_ASCII, data); 234 } 235 236 protected CharSequence appendNewLine(CharSequence data){ 237 String separator = System.getProperty("line.separator"); 238 return data + separator; 239 } 240 241 /** 242 * <p>Sends one or more string objects each appended with a line terminator (CR+LF) to the serial port/device.</p> 243 * 244 * @param charset 245 * The character set to use for encoding/decoding bytes to/from text characters 246 * @param data 247 * One or more string objects (or an array) of data to be transmitted. (variable-length-argument) 248 */ 249 public void writeln(Charset charset, CharSequence ... data) throws IllegalStateException, IOException{ 250 for(CharSequence single : data) { 251 write(charset.encode(CharBuffer.wrap(appendNewLine(single)))); 252 } 253 } 254 255 /** 256 * <p>Sends one or more ASCII string objects each appended with a line terminator (CR+LF) to the serial port/device.</p> 257 * 258 * @param data 259 * One or more ASCII string objects (or an array) of data to be transmitted. (variable-length-argument) 260 */ 261 public void writeln(CharSequence ... data) throws IllegalStateException, IOException{ 262 writeln(StandardCharsets.US_ASCII, data); 263 } 264 265 /** 266 * <p>Sends a collection of string objects each appended with a line terminator (CR+LF) to the serial port/device.</p> 267 * 268 * @param charset 269 * The character set to use for encoding/decoding bytes to/from text characters 270 * @param data 271 * A collection of string objects (or an array) of data to be transmitted. (variable-length-argument) 272 */ 273 public void writeln(Charset charset, Collection<? extends CharSequence> data) throws IllegalStateException, IOException{ 274 for(CharSequence single : data) { 275 write(charset.encode(CharBuffer.wrap(appendNewLine(single)))); 276 } 277 } 278 279 /** 280 * <p>Sends a collection of ASCII string objects each appended with a line terminator (CR+LF) to the serial port/device.</p> 281 * 282 * @param data 283 * A collection of ASCII string objects (or an array) of data to be transmitted. (variable-length-argument) 284 */ 285 public void writeln(Collection<? extends CharSequence> data) throws IllegalStateException, IOException{ 286 writeln(StandardCharsets.US_ASCII, data); 287 } 288 289}