22
22
23
23
package processing .app ;
24
24
25
- import jssc .SerialPort ;
26
- import jssc .SerialPortEvent ;
27
- import jssc .SerialPortEventListener ;
28
- import jssc .SerialPortException ;
25
+ import static processing .app .I18n .format ;
26
+ import static processing .app .I18n .tr ;
29
27
30
28
import java .io .IOException ;
31
- import java .nio .ByteBuffer ;
32
- import java .nio .CharBuffer ;
29
+ import java .io .InputStreamReader ;
30
+ import java .io .PipedInputStream ;
31
+ import java .io .PipedOutputStream ;
33
32
import java .nio .charset .Charset ;
34
- import java .nio .charset .CharsetDecoder ;
35
- import java .nio .charset .CodingErrorAction ;
36
33
import java .nio .charset .StandardCharsets ;
37
34
import java .util .Arrays ;
38
35
import java .util .List ;
39
36
40
- import static processing .app .I18n .format ;
41
- import static processing .app .I18n .tr ;
37
+ import jssc .SerialPort ;
38
+ import jssc .SerialPortEvent ;
39
+ import jssc .SerialPortEventListener ;
40
+ import jssc .SerialPortException ;
42
41
43
42
public class Serial implements SerialPortEventListener {
44
43
@@ -53,11 +52,8 @@ public class Serial implements SerialPortEventListener {
53
52
54
53
private SerialPort port ;
55
54
56
- private CharsetDecoder bytesToStrings ;
57
- private static final int IN_BUFFER_CAPACITY = 128 ;
58
- private static final int OUT_BUFFER_CAPACITY = 128 ;
59
- private ByteBuffer inFromSerial = ByteBuffer .allocate (IN_BUFFER_CAPACITY );
60
- private CharBuffer outToMessage = CharBuffer .allocate (OUT_BUFFER_CAPACITY );
55
+ private PipedOutputStream decoderInRaw ;
56
+ private InputStreamReader decoderOutputUTF8 ;
61
57
62
58
public Serial () throws SerialException {
63
59
this (PreferencesData .get ("serial.port" ),
@@ -189,42 +185,18 @@ public synchronized void serialEvent(SerialPortEvent serialEvent) {
189
185
190
186
public void processSerialEvent (byte [] buf ) {
191
187
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 ();
188
+ int max = buf .length ;
189
+ char chars [] = new char [512 ];
190
+ try {
191
+ while (next < max ) {
192
+ int w = Integer .min (max - next , 128 );
193
+ decoderInRaw .write (buf , next , w );
194
+ next += w ;
195
+ int n = decoderOutputUTF8 .read (chars );
196
+ message (chars , n );
197
+ }
198
+ } catch (IOException e ) {
199
+ e .printStackTrace ();
228
200
}
229
201
}
230
202
@@ -295,10 +267,13 @@ public void setRTS(boolean state) {
295
267
* before they are handed as Strings to {@Link #message(char[], int)}.
296
268
*/
297
269
public synchronized void resetDecoding (Charset charset ) {
298
- bytesToStrings = charset .newDecoder ()
299
- .onMalformedInput (CodingErrorAction .REPLACE )
300
- .onUnmappableCharacter (CodingErrorAction .REPLACE )
301
- .replaceWith ("\u2e2e " );
270
+ try {
271
+ decoderInRaw = new PipedOutputStream ();
272
+ decoderOutputUTF8 = new InputStreamReader (new PipedInputStream (decoderInRaw ), charset );
273
+ } catch (IOException e ) {
274
+ // Should never happen...
275
+ e .printStackTrace ();
276
+ }
302
277
}
303
278
304
279
static public List <String > list () {
0 commit comments