@@ -176,22 +176,41 @@ public synchronized void serialEvent(SerialPortEvent serialEvent) {
176176 try {
177177 byte [] buf = port .readBytes (serialEvent .getEventValue ());
178178 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 ());
183194 inFromSerial .put (buf , next , copyNow );
184195 next += copyNow ;
196+
185197 inFromSerial .flip ();
186198 bytesToStrings .decode (inFromSerial , outToMessage , false );
187199 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+
189210 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 );
195214 outToMessage .clear ();
196215 }
197216 } catch (SerialPortException e ) {
0 commit comments