@@ -176,22 +176,41 @@ public synchronized void serialEvent(SerialPortEvent serialEvent) {
176
176
try {
177
177
byte [] buf = port .readBytes (serialEvent .getEventValue ());
178
178
int next = 0 ;
179
- while (next < buf .length ) {
180
- while (next < buf .length && outToMessage .hasRemaining ()) {
181
- int spaceInIn = inFromSerial .remaining ();
182
- int copyNow = buf .length - next < spaceInIn ? buf .length - next : spaceInIn ;
179
+ // This uses a CharsetDecoder to convert from bytes to UTF-8 in
180
+ // a streaming fashion (i.e. where characters might be split
181
+ // over multiple reads). This needs the data to be in a
182
+ // ByteBuffer (inFromSerial, which we also use to store leftover
183
+ // incomplete characters for the nexst run) and produces a
184
+ // CharBuffer (outToMessage), which we then convert to char[] to
185
+ // pass onwards.
186
+ // Note that these buffers switch from input to output mode
187
+ // using flip/compact/clear
188
+ while (next < buf .length || inFromSerial .position () > 0 ) {
189
+ do {
190
+ // This might be 0 when all data was already read from buf
191
+ // (but then there will be data in inFromSerial left to
192
+ // decode).
193
+ int copyNow = Math .min (buf .length - next , inFromSerial .remaining ());
183
194
inFromSerial .put (buf , next , copyNow );
184
195
next += copyNow ;
196
+
185
197
inFromSerial .flip ();
186
198
bytesToStrings .decode (inFromSerial , outToMessage , false );
187
199
inFromSerial .compact ();
188
- }
200
+
201
+ // When there are multi-byte characters, outToMessage might
202
+ // still have room, so add more bytes if we have any.
203
+ } while (next < buf .length && outToMessage .hasRemaining ());
204
+
205
+ // If no output was produced, the input only contained
206
+ // incomplete characters, so we're done processing
207
+ if (outToMessage .position () == 0 )
208
+ break ;
209
+
189
210
outToMessage .flip ();
190
- if (outToMessage .hasRemaining ()) {
191
- char [] chars = new char [outToMessage .remaining ()];
192
- outToMessage .get (chars );
193
- message (chars , chars .length );
194
- }
211
+ char [] chars = new char [outToMessage .remaining ()];
212
+ outToMessage .get (chars );
213
+ message (chars , chars .length );
195
214
outToMessage .clear ();
196
215
}
197
216
} catch (SerialPortException e ) {
0 commit comments