Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2162966

Browse files
committed
Use InputStreamReader for serial UTF8 decoder
The implementation is much more straightforward. It should also solve a JDK incompatiblity: java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer; at processing.app.Serial.serialEvent(Serial.java:185) at jssc.SerialPort$LinuxEventThread.run(SerialPort.java:1299) See #8903
1 parent 5adf408 commit 2162966

File tree

1 file changed

+30
-55
lines changed

1 file changed

+30
-55
lines changed

‎arduino-core/src/processing/app/Serial.java

Lines changed: 30 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,22 @@
2222

2323
package processing.app;
2424

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;
2927

3028
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;
3332
import java.nio.charset.Charset;
34-
import java.nio.charset.CharsetDecoder;
35-
import java.nio.charset.CodingErrorAction;
3633
import java.nio.charset.StandardCharsets;
3734
import java.util.Arrays;
3835
import java.util.List;
3936

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;
4241

4342
public class Serial implements SerialPortEventListener {
4443

@@ -53,11 +52,8 @@ public class Serial implements SerialPortEventListener {
5352

5453
private SerialPort port;
5554

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;
6157

6258
public Serial() throws SerialException {
6359
this(PreferencesData.get("serial.port"),
@@ -189,42 +185,18 @@ public synchronized void serialEvent(SerialPortEvent serialEvent) {
189185

190186
public void processSerialEvent(byte[] buf) {
191187
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();
228200
}
229201
}
230202

@@ -295,10 +267,13 @@ public void setRTS(boolean state) {
295267
* before they are handed as Strings to {@Link #message(char[], int)}.
296268
*/
297269
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+
}
302277
}
303278

304279
static public List<String> list() {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /