| 188 | } |
| 189 | |
| 190 | public void processSerialEvent(byte[] buf) { |
| 191 | int next = 0; |
| 192 | // This uses a CharsetDecoder to convert from bytes to UTF-8 in |
| 193 | // a streaming fashion (i.e. where characters might be split |
| 194 | // over multiple reads). This needs the data to be in a |
| 195 | // ByteBuffer (inFromSerial, which we also use to store leftover |
| 196 | // incomplete characters for the nexst run) and produces a |
| 197 | // CharBuffer (outToMessage), which we then convert to char[] to |
| 198 | // pass onwards. |
| 199 | // Note that these buffers switch from input to output mode |
| 200 | // using flip/compact/clear |
| 201 | while (next < buf.length || inFromSerial.position() > 0) { |
| 202 | do { |
| 203 | // This might be 0 when all data was already read from buf |
| 204 | // (but then there will be data in inFromSerial left to |
| 205 | // decode). |
| 206 | int copyNow = Math.min(buf.length - next, inFromSerial.remaining()); |
| 207 | inFromSerial.put(buf, next, copyNow); |
| 208 | next += copyNow; |
| 209 | |
| 210 | inFromSerial.flip(); |
| 211 | bytesToStrings.decode(inFromSerial, outToMessage, false); |
| 212 | inFromSerial.compact(); |
| 213 | |
| 214 | // When there are multi-byte characters, outToMessage might |
| 215 | // still have room, so add more bytes if we have any. |
| 216 | } while (next < buf.length && outToMessage.hasRemaining()); |
| 217 | |
| 218 | // If no output was produced, the input only contained |
| 219 | // incomplete characters, so we're done processing |
| 220 | if (outToMessage.position() == 0) |
| 221 | break; |
| 222 | |
| 223 | outToMessage.flip(); |
| 224 | char[] chars = new char[outToMessage.remaining()]; |
| 225 | outToMessage.get(chars); |
| 226 | message(chars, chars.length); |
| 227 | outToMessage.clear(); |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | /** |
| 232 | * This method is intented to be extended to receive messages |