ベータ版移行版。作業部屋IDの綴り修正
リビジョン | aa12c6dd891fb715293df6a261a4353f8d3f0e5f (tree) |
---|---|
日時 | 2015-07-16 21:13:30 |
作者 | MirrgieRiana Kurilab |
コミッター | MirrgieRiana Kurilab |
project(workspace/cf-serial-framework -> workspace/mirrg.serial.fluorine); groupId(jp.ac.kisarazu.j.kurilab -> mirrg); artifactId(cf-serial-framework -> mirrg.serial.fluorine)
@@ -3,6 +3,6 @@ | ||
3 | 3 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> |
4 | 4 | <classpathentry kind="src" path="ants.tunnelserialtoieee1888"/> |
5 | 5 | <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> |
6 | - <classpathentry combineaccessrules="false" kind="src" path="/cf-serial-framework"/> | |
6 | + <classpathentry combineaccessrules="false" kind="src" path="/mirrg.serial.fluorine"/> | |
7 | 7 | <classpathentry kind="output" path="bin"/> |
8 | 8 | </classpath> |
@@ -4,8 +4,8 @@ | ||
4 | 4 | |
5 | 5 | import java.time.LocalDateTime; |
6 | 6 | |
7 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode.AcsCallMethod; | |
8 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode.EncoderAcsCallMethod; | |
7 | +import mirrg.serial.fluorine.encode.AcsCallMethod; | |
8 | +import mirrg.serial.fluorine.encode.EncoderAcsCallMethod; | |
9 | 9 | |
10 | 10 | import org.junit.Test; |
11 | 11 |
@@ -1,26 +0,0 @@ | ||
1 | -<?xml version="1.0" encoding="UTF-8"?> | |
2 | -<classpath> | |
3 | - <classpathentry kind="src" output="target/classes" path="src/main/java"> | |
4 | - <attributes> | |
5 | - <attribute name="optional" value="true"/> | |
6 | - <attribute name="maven.pomderived" value="true"/> | |
7 | - </attributes> | |
8 | - </classpathentry> | |
9 | - <classpathentry kind="src" output="target/test-classes" path="src/test/java"> | |
10 | - <attributes> | |
11 | - <attribute name="optional" value="true"/> | |
12 | - <attribute name="maven.pomderived" value="true"/> | |
13 | - </attributes> | |
14 | - </classpathentry> | |
15 | - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> | |
16 | - <attributes> | |
17 | - <attribute name="maven.pomderived" value="true"/> | |
18 | - </attributes> | |
19 | - </classpathentry> | |
20 | - <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | |
21 | - <attributes> | |
22 | - <attribute name="maven.pomderived" value="true"/> | |
23 | - </attributes> | |
24 | - </classpathentry> | |
25 | - <classpathentry kind="output" path="target/classes"/> | |
26 | -</classpath> |
@@ -1,23 +0,0 @@ | ||
1 | -<?xml version="1.0" encoding="UTF-8"?> | |
2 | -<projectDescription> | |
3 | - <name>cf-serial-framework</name> | |
4 | - <comment></comment> | |
5 | - <projects> | |
6 | - </projects> | |
7 | - <buildSpec> | |
8 | - <buildCommand> | |
9 | - <name>org.eclipse.jdt.core.javabuilder</name> | |
10 | - <arguments> | |
11 | - </arguments> | |
12 | - </buildCommand> | |
13 | - <buildCommand> | |
14 | - <name>org.eclipse.m2e.core.maven2Builder</name> | |
15 | - <arguments> | |
16 | - </arguments> | |
17 | - </buildCommand> | |
18 | - </buildSpec> | |
19 | - <natures> | |
20 | - <nature>org.eclipse.jdt.core.javanature</nature> | |
21 | - <nature>org.eclipse.m2e.core.maven2Nature</nature> | |
22 | - </natures> | |
23 | -</projectDescription> |
@@ -1,25 +0,0 @@ | ||
1 | -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
2 | - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
3 | - <modelVersion>4.0.0</modelVersion> | |
4 | - | |
5 | - <groupId>jp.ac.kisarazu.j.kurilab</groupId> | |
6 | - <artifactId>cf-serial-framework</artifactId> | |
7 | - <version>0.0.1-SNAPSHOT</version> | |
8 | - <packaging>jar</packaging> | |
9 | - | |
10 | - <name>cf-serial-framework</name> | |
11 | - <url>http://maven.apache.org</url> | |
12 | - | |
13 | - <properties> | |
14 | - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
15 | - </properties> | |
16 | - | |
17 | - <dependencies> | |
18 | - <dependency> | |
19 | - <groupId>junit</groupId> | |
20 | - <artifactId>junit</artifactId> | |
21 | - <version>4.12</version> | |
22 | - <scope>test</scope> | |
23 | - </dependency> | |
24 | - </dependencies> | |
25 | -</project> |
@@ -1,20 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection; | |
2 | - | |
3 | -import java.util.ArrayList; | |
4 | - | |
5 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection.InputChlorofilSender.EnumTypeMessage; | |
6 | - | |
7 | -public interface IListenerInputChlorofilSender | |
8 | -{ | |
9 | - | |
10 | - public void setAcceptedChars(int acceptedChars); | |
11 | - | |
12 | - public void onMessage(EnumTypeMessage typeMessage, String message); | |
13 | - | |
14 | - public void onMessageBlock(ArrayList<String> messageBlock); | |
15 | - | |
16 | - public void onInternalException(Exception exception); | |
17 | - | |
18 | - public void onClosed(); | |
19 | - | |
20 | -} |
@@ -1,8 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection; | |
2 | - | |
3 | -public interface IListenerOutputChlorofilSender | |
4 | -{ | |
5 | - | |
6 | - public void onSent(String string); | |
7 | - | |
8 | -} |
@@ -1,113 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection; | |
2 | - | |
3 | -import java.io.InputStream; | |
4 | -import java.util.ArrayList; | |
5 | -import java.util.function.Consumer; | |
6 | - | |
7 | -/** | |
8 | - * 入力ストリームを監視してメッセージを分解してハンドラに通知する。 | |
9 | - */ | |
10 | -public class InputChlorofilSender extends UTF8SerialStreamReader | |
11 | -{ | |
12 | - | |
13 | - public InputChlorofilSender(InputStream in) | |
14 | - { | |
15 | - super(in, false); | |
16 | - } | |
17 | - | |
18 | - public InputChlorofilSender(InputStream in, boolean blocking) | |
19 | - { | |
20 | - super(in, blocking); | |
21 | - } | |
22 | - | |
23 | - /** | |
24 | - * 複数行メッセージの処理中のメッセージ。 | |
25 | - */ | |
26 | - protected ArrayList<String> messageBlockBuffer; | |
27 | - | |
28 | - /** | |
29 | - * 複数行メッセージの終端記号。 | |
30 | - * nullの場合は現在複数行メッセージの処理中ではない。 | |
31 | - */ | |
32 | - protected String messageBlockSentinel = null; | |
33 | - | |
34 | - public void forEach(IListenerInputChlorofilSender listener) | |
35 | - { | |
36 | - forEach((Consumer<String>) line -> { | |
37 | - | |
38 | - // 現在複数行メッセージの処理中であるならば、 | |
39 | - if (messageBlockSentinel != null) { | |
40 | - | |
41 | - // 来た行が終端記号なら、 | |
42 | - if (line.equals(messageBlockSentinel)) { | |
43 | - | |
44 | - // 複数行メッセージの処理中でなくして、 | |
45 | - messageBlockSentinel = null; | |
46 | - | |
47 | - // リスナを起動する。 | |
48 | - listener.onMessageBlock(messageBlockBuffer); | |
49 | - | |
50 | - } else { // 終端記号でないなら、 | |
51 | - | |
52 | - // バッファに追加する。 | |
53 | - messageBlockBuffer.add(line); | |
54 | - | |
55 | - } | |
56 | - | |
57 | - } else { | |
58 | - String res; | |
59 | - | |
60 | - // 受け付けた | |
61 | - if ((res = getProperty(line, "C")) != null) { | |
62 | - int i; | |
63 | - try { | |
64 | - i = Integer.parseInt(res, 10); | |
65 | - } catch (NumberFormatException e) { | |
66 | - listener.onInternalException(e); | |
67 | - return; | |
68 | - } | |
69 | - listener.setAcceptedChars(i); | |
70 | - return; | |
71 | - } | |
72 | - if ((res = getProperty(line, "M")) != null) { | |
73 | - listener.onMessage(EnumTypeMessage.MESSAGE, res); | |
74 | - return; | |
75 | - } | |
76 | - if ((res = getProperty(line, "E")) != null) { | |
77 | - listener.onMessage(EnumTypeMessage.ERROR, res); | |
78 | - return; | |
79 | - } | |
80 | - if ((res = getProperty(line, "W")) != null) { | |
81 | - listener.onMessage(EnumTypeMessage.WARNINGS, res); | |
82 | - return; | |
83 | - } | |
84 | - if ((res = getProperty(line, "MB")) != null) { | |
85 | - messageBlockSentinel = res; | |
86 | - messageBlockBuffer = new ArrayList<>(); | |
87 | - return; | |
88 | - } | |
89 | - | |
90 | - } | |
91 | - | |
92 | - }, () -> { | |
93 | - listener.onClosed(); | |
94 | - }); | |
95 | - } | |
96 | - | |
97 | - protected String getProperty(String string, String prefix) | |
98 | - { | |
99 | - prefix += ":"; | |
100 | - | |
101 | - if (string.startsWith(prefix)) { | |
102 | - return string.substring(prefix.length()); | |
103 | - } else { | |
104 | - return null; | |
105 | - } | |
106 | - } | |
107 | - | |
108 | - public static enum EnumTypeMessage | |
109 | - { | |
110 | - MESSAGE, ERROR, WARNINGS, | |
111 | - } | |
112 | - | |
113 | -} |
@@ -1,103 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection; | |
2 | - | |
3 | -import java.io.OutputStream; | |
4 | -import java.io.PrintStream; | |
5 | -import java.io.UnsupportedEncodingException; | |
6 | -import java.util.Iterator; | |
7 | -import java.util.LinkedList; | |
8 | - | |
9 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode.EncoderAcsOperator; | |
10 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode.IAcsElement; | |
11 | - | |
12 | -public class OutputChlorofilSender | |
13 | -{ | |
14 | - | |
15 | - protected static final int ARDUINO_MAX_BUFFER = 63; | |
16 | - | |
17 | - protected PrintStream out; | |
18 | - | |
19 | - public OutputChlorofilSender(OutputStream outputStream) | |
20 | - { | |
21 | - try { | |
22 | - out = new PrintStream(outputStream, false, "UTF-8"); | |
23 | - } catch (UnsupportedEncodingException e) { | |
24 | - throw new RuntimeException(e); | |
25 | - } | |
26 | - } | |
27 | - | |
28 | - protected int sentChars = 0; | |
29 | - protected transient int acceptedChars = 0; | |
30 | - | |
31 | - public void setAcceptedChars(int acceptedChars) | |
32 | - { | |
33 | - this.acceptedChars = acceptedChars; | |
34 | - } | |
35 | - | |
36 | - public void send(IAcsElement acsElement) | |
37 | - { | |
38 | - synchronized (sendingAcsElements) { | |
39 | - sendingAcsElements.add(acsElement); | |
40 | - } | |
41 | - } | |
42 | - | |
43 | - protected LinkedList<IAcsElement> sendingAcsElements = new LinkedList<>(); | |
44 | - | |
45 | - public void run(IListenerOutputChlorofilSender listener) | |
46 | - { | |
47 | - try { | |
48 | - while (true) { | |
49 | - | |
50 | - synchronized (sendingAcsElements) { | |
51 | - Iterator<IAcsElement> iterator = sendingAcsElements.iterator(); | |
52 | - while (iterator.hasNext()) { | |
53 | - IAcsElement acsElement = iterator.next(); | |
54 | - sendImpl(acsElement.get(), listener); | |
55 | - iterator.remove(); | |
56 | - } | |
57 | - } | |
58 | - | |
59 | - Thread.sleep(5); | |
60 | - } | |
61 | - } catch (InterruptedException e) {} | |
62 | - } | |
63 | - | |
64 | - protected void sendImpl(String string, IListenerOutputChlorofilSender listener) throws InterruptedException | |
65 | - { | |
66 | - do { | |
67 | - int bufferedChars = sentChars - acceptedChars; | |
68 | - int bufferSpace = ARDUINO_MAX_BUFFER - bufferedChars; | |
69 | - int sendingChars = Math.min(string.length(), bufferSpace); | |
70 | - | |
71 | - if (sendingChars > 0) { | |
72 | - | |
73 | - String send = string.substring(0, sendingChars); | |
74 | - sendImpl2(send); | |
75 | - listener.onSent(send); | |
76 | - string = string.substring(sendingChars); | |
77 | - | |
78 | - if (string.isEmpty()) break; | |
79 | - } | |
80 | - | |
81 | - Thread.sleep(5); | |
82 | - | |
83 | - } while (true); | |
84 | - } | |
85 | - | |
86 | - protected void sendImpl2(String string) | |
87 | - { | |
88 | - sentChars += string.length(); | |
89 | - out.print(string); | |
90 | - out.flush(); | |
91 | - } | |
92 | - | |
93 | - /** | |
94 | - * 初期化の命令を送信し、内部変数を初期設定で同期する。 | |
95 | - */ | |
96 | - public void synchronize() | |
97 | - { | |
98 | - send(EncoderAcsOperator.reset()); | |
99 | - acceptedChars = 0; | |
100 | - sentChars = 0; | |
101 | - } | |
102 | - | |
103 | -} |
@@ -1,97 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection; | |
2 | - | |
3 | -import java.io.BufferedReader; | |
4 | -import java.io.IOException; | |
5 | -import java.io.InputStream; | |
6 | -import java.nio.ByteBuffer; | |
7 | -import java.nio.charset.Charset; | |
8 | -import java.util.ArrayList; | |
9 | -import java.util.function.Consumer; | |
10 | - | |
11 | -/** | |
12 | - * {@link BufferedReader#lines()}との違いは、 | |
13 | - * こちらはシリアル通信前提で文字コードが固定であり、 | |
14 | - * バッファリングも最小限なため謎挙動が少ない。 | |
15 | - */ | |
16 | -public class UTF8SerialStreamReader | |
17 | -{ | |
18 | - | |
19 | - protected static final Charset charset = Charset.forName("UTF-8"); | |
20 | - protected InputStream in; | |
21 | - protected boolean blocking; | |
22 | - | |
23 | - public UTF8SerialStreamReader(InputStream in, boolean blocking) | |
24 | - { | |
25 | - this.in = in; | |
26 | - this.blocking = blocking; | |
27 | - } | |
28 | - | |
29 | - /** | |
30 | - * {@link ByteBuffer}は固定長だから面倒。 | |
31 | - */ | |
32 | - protected ArrayList<Byte> buffer = new ArrayList<>(); | |
33 | - | |
34 | - public void forEach(Consumer<String> consumer, Runnable onClosed) | |
35 | - { | |
36 | - boolean r = false; | |
37 | - | |
38 | - while (true) { | |
39 | - int b; | |
40 | - try { | |
41 | - | |
42 | - // blocking == false | |
43 | - // -1が帰ると、データの受信待ち。 | |
44 | - // 例外が発生すると、通信が途切れた。 | |
45 | - // blocking == true | |
46 | - // -1が帰ると、通信が途切れた。 | |
47 | - b = in.read(); | |
48 | - | |
49 | - } catch (IOException e) { | |
50 | - onClosed.run(); | |
51 | - return; | |
52 | - } | |
53 | - if (b < 0) { | |
54 | - if (blocking) { | |
55 | - flush(consumer); | |
56 | - break; | |
57 | - } | |
58 | - } else if ((char) b == '\r') { | |
59 | - r = true; | |
60 | - flush(consumer); | |
61 | - continue; | |
62 | - } else if ((char) b == '\n') { | |
63 | - if (r) { | |
64 | - | |
65 | - } else { | |
66 | - flush(consumer); | |
67 | - } | |
68 | - continue; | |
69 | - } else { | |
70 | - buffer.add((byte) b); | |
71 | - continue; | |
72 | - } | |
73 | - | |
74 | - try { | |
75 | - Thread.sleep(1); | |
76 | - } catch (InterruptedException e) { | |
77 | - break; | |
78 | - } | |
79 | - } | |
80 | - } | |
81 | - | |
82 | - protected void flush(Consumer<String> consumer) | |
83 | - { | |
84 | - byte[] buffer2 = new byte[buffer.size()]; | |
85 | - for (int i = 0; i < buffer2.length; i++) { | |
86 | - buffer2[i] = buffer.get(i); | |
87 | - } | |
88 | - consumer.accept(new String(buffer2, charset)); | |
89 | - buffer.clear(); | |
90 | - } | |
91 | - | |
92 | - public void close() throws IOException | |
93 | - { | |
94 | - in.close(); | |
95 | - } | |
96 | - | |
97 | -} |
@@ -1,33 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode; | |
2 | - | |
3 | -/** | |
4 | - * immutable | |
5 | - */ | |
6 | -public class AcsCallMethod implements IAcsElement | |
7 | -{ | |
8 | - | |
9 | - private String string; | |
10 | - | |
11 | - public AcsCallMethod(Iterable<AcsOperator> acsOperators, boolean newLine) | |
12 | - { | |
13 | - StringBuffer stringBuffer = new StringBuffer(); | |
14 | - for (AcsOperator acsOperator : acsOperators) { | |
15 | - stringBuffer.append(acsOperator); | |
16 | - } | |
17 | - if (newLine) stringBuffer.append("\n"); | |
18 | - string = stringBuffer.toString(); | |
19 | - } | |
20 | - | |
21 | - @Override | |
22 | - public String toString() | |
23 | - { | |
24 | - return string; | |
25 | - } | |
26 | - | |
27 | - @Override | |
28 | - public String get() | |
29 | - { | |
30 | - return string; | |
31 | - } | |
32 | - | |
33 | -} |
@@ -1,32 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode; | |
2 | - | |
3 | -/** | |
4 | - * immutable | |
5 | - */ | |
6 | -public class AcsCallMethodChain implements IAcsElement | |
7 | -{ | |
8 | - | |
9 | - private String string; | |
10 | - | |
11 | - public AcsCallMethodChain(Iterable<AcsCallMethod> listAcsCallMethod) | |
12 | - { | |
13 | - StringBuffer stringBuffer = new StringBuffer(); | |
14 | - for (AcsCallMethod acsCallMethod : listAcsCallMethod) { | |
15 | - stringBuffer.append(acsCallMethod); | |
16 | - } | |
17 | - string = stringBuffer.toString(); | |
18 | - } | |
19 | - | |
20 | - @Override | |
21 | - public String toString() | |
22 | - { | |
23 | - return string; | |
24 | - } | |
25 | - | |
26 | - @Override | |
27 | - public String get() | |
28 | - { | |
29 | - return string; | |
30 | - } | |
31 | - | |
32 | -} |
@@ -1,28 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode; | |
2 | - | |
3 | -/** | |
4 | - * immutable | |
5 | - */ | |
6 | -public class AcsOperator implements IAcsElement | |
7 | -{ | |
8 | - | |
9 | - private String string; | |
10 | - | |
11 | - public AcsOperator(String string) | |
12 | - { | |
13 | - this.string = string; | |
14 | - } | |
15 | - | |
16 | - @Override | |
17 | - public String toString() | |
18 | - { | |
19 | - return string; | |
20 | - } | |
21 | - | |
22 | - @Override | |
23 | - public String get() | |
24 | - { | |
25 | - return string; | |
26 | - } | |
27 | - | |
28 | -} |
@@ -1,94 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode; | |
2 | - | |
3 | -import static org.junit.Assert.*; | |
4 | - | |
5 | -import java.util.ArrayList; | |
6 | -import java.util.function.Consumer; | |
7 | - | |
8 | -import org.junit.Test; | |
9 | - | |
10 | -public class EncoderAcsCallMethod | |
11 | -{ | |
12 | - | |
13 | - public static AcsCallMethodChain callMethods(Consumer<Consumer<AcsCallMethod>> arguments) | |
14 | - { | |
15 | - ArrayList<AcsCallMethod> acsCallMethods = new ArrayList<>(); | |
16 | - arguments.accept(acsCallMethods::add); | |
17 | - return new AcsCallMethodChain(acsCallMethods); | |
18 | - } | |
19 | - | |
20 | - public static AcsCallMethod callMethod(String name, Consumer<IConsumerArgument> arguments) | |
21 | - { | |
22 | - ArrayList<AcsOperator> acsOperators = new ArrayList<>(); | |
23 | - | |
24 | - acsOperators.add(EncoderAcsOperator.clear()); | |
25 | - IConsumerArgument consumerArgument = new IConsumerArgument() { | |
26 | - | |
27 | - @Override | |
28 | - public void acceptInteger(int argument) | |
29 | - { | |
30 | - acsOperators.add(EncoderAcsOperator.pushInteger(argument)); | |
31 | - } | |
32 | - | |
33 | - @Override | |
34 | - public void acceptDouble(double argument) | |
35 | - { | |
36 | - acsOperators.add(EncoderAcsOperator.pushDouble(argument)); | |
37 | - } | |
38 | - | |
39 | - @Override | |
40 | - public void acceptString(String argument) | |
41 | - { | |
42 | - acsOperators.add(EncoderAcsOperator.pushString(argument)); | |
43 | - } | |
44 | - | |
45 | - }; | |
46 | - consumerArgument.acceptString(name); | |
47 | - arguments.accept(consumerArgument); | |
48 | - acsOperators.add(EncoderAcsOperator.method()); | |
49 | - | |
50 | - return new AcsCallMethod(acsOperators, true); | |
51 | - } | |
52 | - | |
53 | - @Test | |
54 | - public void test1() | |
55 | - { | |
56 | - assertEquals( | |
57 | - "C;SMeth;D4.5;I79;D0.0;I0;S68;S;S/f4b[@\\\\4,].5o@s,\\;4e\\\n0o;M;\n", | |
58 | - EncoderAcsCallMethod.callMethod("Meth", consumer -> { | |
59 | - consumer.acceptDouble(4.5); | |
60 | - consumer.acceptInteger(79); | |
61 | - consumer.acceptDouble(0.0); | |
62 | - consumer.acceptInteger(0); | |
63 | - consumer.acceptString("68"); | |
64 | - consumer.acceptString(""); | |
65 | - consumer.acceptString("/f4b[@\\4,].5o@s,;4e\n0o"); | |
66 | - }).toString()); | |
67 | - } | |
68 | - | |
69 | - @Test | |
70 | - public void test2() | |
71 | - { | |
72 | - assertEquals("C;SMethodName;M;\n", | |
73 | - callMethod("MethodName", consumerArgument -> { | |
74 | - | |
75 | - }).toString()); | |
76 | - assertEquals("C;SMethodName;I45;Sgh;M;\n", | |
77 | - callMethod("MethodName", consumerArgument -> { | |
78 | - consumerArgument.acceptInteger(45); | |
79 | - consumerArgument.acceptString("gh"); | |
80 | - }).toString()); | |
81 | - } | |
82 | - | |
83 | - public interface IConsumerArgument | |
84 | - { | |
85 | - | |
86 | - public void acceptInteger(int argument); | |
87 | - | |
88 | - public void acceptDouble(double argument); | |
89 | - | |
90 | - public void acceptString(String argument); | |
91 | - | |
92 | - } | |
93 | - | |
94 | -} |
@@ -1,80 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode; | |
2 | - | |
3 | -import static org.junit.Assert.*; | |
4 | - | |
5 | -import java.util.regex.Matcher; | |
6 | -import java.util.regex.Pattern; | |
7 | - | |
8 | -import org.junit.Test; | |
9 | - | |
10 | -public class EncoderAcsOperator | |
11 | -{ | |
12 | - | |
13 | - public static AcsOperator pushInteger(int value) | |
14 | - { | |
15 | - return build(EnumAcsOperator.INTEGER, Integer.toString(value)); | |
16 | - } | |
17 | - | |
18 | - public static AcsOperator pushDouble(double value) | |
19 | - { | |
20 | - return build(EnumAcsOperator.DOUBLE, Double.toString(value)); | |
21 | - } | |
22 | - | |
23 | - private static final Pattern patternOperatorBreak = | |
24 | - Pattern.compile("([\\n;\\\\])"); | |
25 | - | |
26 | - public static AcsOperator pushString(String value) | |
27 | - { | |
28 | - Matcher matcher = patternOperatorBreak.matcher(value); | |
29 | - return build(EnumAcsOperator.STRING, matcher.replaceAll("\\\\$1")); | |
30 | - } | |
31 | - | |
32 | - private static final AcsOperator reset = build(EnumAcsOperator.RESET); | |
33 | - private static final AcsOperator clear = build(EnumAcsOperator.CLEAR); | |
34 | - private static final AcsOperator method = build(EnumAcsOperator.METHOD); | |
35 | - | |
36 | - public static AcsOperator reset() | |
37 | - { | |
38 | - return reset; | |
39 | - } | |
40 | - | |
41 | - public static AcsOperator clear() | |
42 | - { | |
43 | - return clear; | |
44 | - } | |
45 | - | |
46 | - public static AcsOperator method() | |
47 | - { | |
48 | - return method; | |
49 | - } | |
50 | - | |
51 | - public static AcsOperator build(EnumAcsOperator acsOperator) | |
52 | - { | |
53 | - return new AcsOperator(acsOperator.ch + ";"); | |
54 | - } | |
55 | - | |
56 | - public static AcsOperator build(EnumAcsOperator acsOperator, String argument) | |
57 | - { | |
58 | - return new AcsOperator(acsOperator.ch + argument + ";"); | |
59 | - } | |
60 | - | |
61 | - @Test | |
62 | - public void test() | |
63 | - { | |
64 | - assertEquals("C;", clear().toString()); | |
65 | - assertEquals("R;", reset().toString()); | |
66 | - assertEquals("M;", method().toString()); | |
67 | - assertEquals("I24;", pushInteger(24).toString()); | |
68 | - assertEquals("I-7;", pushInteger(-7).toString()); | |
69 | - assertEquals("I0;", pushInteger(0).toString()); | |
70 | - assertEquals("I99999;", pushInteger(99999).toString()); | |
71 | - assertEquals("D" + 1.5 + ";", pushDouble(1.5).toString()); | |
72 | - assertEquals("D" + -1.5 + ";", pushDouble(-1.5).toString()); | |
73 | - assertEquals("Sabc;", pushString("abc").toString()); | |
74 | - assertEquals("S;", pushString("").toString()); | |
75 | - assertEquals("S\\;;", pushString(";").toString()); | |
76 | - assertEquals("S\\\n;", pushString("\n").toString()); | |
77 | - assertEquals("S\\;\\\n;", pushString(";\n").toString()); | |
78 | - } | |
79 | - | |
80 | -} |
@@ -1,21 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode; | |
2 | - | |
3 | -public enum EnumAcsOperator | |
4 | -{ | |
5 | - RESET('R', false), | |
6 | - CLEAR('C', false), | |
7 | - METHOD('M', false), | |
8 | - INTEGER('I', true), | |
9 | - DOUBLE('D', true), | |
10 | - STRING('S', true), ; | |
11 | - | |
12 | - public final char ch; | |
13 | - public final boolean canArgument; | |
14 | - | |
15 | - private EnumAcsOperator(char ch, boolean canArgument) | |
16 | - { | |
17 | - this.ch = ch; | |
18 | - this.canArgument = canArgument; | |
19 | - } | |
20 | - | |
21 | -} |
@@ -1,8 +0,0 @@ | ||
1 | -package jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode; | |
2 | - | |
3 | -public interface IAcsElement | |
4 | -{ | |
5 | - | |
6 | - public String get(); | |
7 | - | |
8 | -} |
@@ -27,6 +27,6 @@ | ||
27 | 27 | <classpathentry combineaccessrules="false" kind="src" path="/mirrg.swing.helium"/> |
28 | 28 | <classpathentry kind="lib" path="mirrg.struct.hydrogen-20150715.jar"/> |
29 | 29 | <classpathentry kind="lib" path="RXTXcomm.jar"/> |
30 | - <classpathentry combineaccessrules="false" kind="src" path="/cf-serial-framework"/> | |
30 | + <classpathentry combineaccessrules="false" kind="src" path="/mirrg.serial.fluorine"/> | |
31 | 31 | <classpathentry kind="output" path="target/classes"/> |
32 | 32 | </classpath> |
@@ -6,12 +6,12 @@ | ||
6 | 6 | import java.io.OutputStream; |
7 | 7 | import java.util.ArrayList; |
8 | 8 | |
9 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection.IListenerInputChlorofilSender; | |
10 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection.IListenerOutputChlorofilSender; | |
11 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection.InputChlorofilSender; | |
12 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection.OutputChlorofilSender; | |
13 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.connection.InputChlorofilSender.EnumTypeMessage; | |
14 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode.IAcsElement; | |
9 | +import mirrg.serial.fluorine.connection.IListenerInputChlorofilSender; | |
10 | +import mirrg.serial.fluorine.connection.IListenerOutputChlorofilSender; | |
11 | +import mirrg.serial.fluorine.connection.InputChlorofilSender; | |
12 | +import mirrg.serial.fluorine.connection.OutputChlorofilSender; | |
13 | +import mirrg.serial.fluorine.connection.InputChlorofilSender.EnumTypeMessage; | |
14 | +import mirrg.serial.fluorine.encode.IAcsElement; | |
15 | 15 | import mirrg.swing.helium.FrameMirrg; |
16 | 16 | import mirrg.swing.helium.logging.HLog; |
17 | 17 | import ants.tunnelserialtoieee1888.BuilderTunnelSerialToIEEE1888; |
@@ -5,8 +5,8 @@ | ||
5 | 5 | import java.time.LocalDateTime; |
6 | 6 | import java.util.List; |
7 | 7 | |
8 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode.AcsCallMethodChain; | |
9 | -import jp.ac.kisarazu.j.kurilab.cf.serial.framework.encode.EncoderAcsCallMethod; | |
8 | +import mirrg.serial.fluorine.encode.AcsCallMethodChain; | |
9 | +import mirrg.serial.fluorine.encode.EncoderAcsCallMethod; | |
10 | 10 | |
11 | 11 | public class PacketChlorofilSender |
12 | 12 | { |
@@ -0,0 +1,26 @@ | ||
1 | +<?xml version="1.0" encoding="UTF-8"?> | |
2 | +<classpath> | |
3 | + <classpathentry kind="src" output="target/classes" path="src/main/java"> | |
4 | + <attributes> | |
5 | + <attribute name="optional" value="true"/> | |
6 | + <attribute name="maven.pomderived" value="true"/> | |
7 | + </attributes> | |
8 | + </classpathentry> | |
9 | + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> | |
10 | + <attributes> | |
11 | + <attribute name="optional" value="true"/> | |
12 | + <attribute name="maven.pomderived" value="true"/> | |
13 | + </attributes> | |
14 | + </classpathentry> | |
15 | + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> | |
16 | + <attributes> | |
17 | + <attribute name="maven.pomderived" value="true"/> | |
18 | + </attributes> | |
19 | + </classpathentry> | |
20 | + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | |
21 | + <attributes> | |
22 | + <attribute name="maven.pomderived" value="true"/> | |
23 | + </attributes> | |
24 | + </classpathentry> | |
25 | + <classpathentry kind="output" path="target/classes"/> | |
26 | +</classpath> |
@@ -0,0 +1,23 @@ | ||
1 | +<?xml version="1.0" encoding="UTF-8"?> | |
2 | +<projectDescription> | |
3 | + <name>mirrg.serial.fluorine</name> | |
4 | + <comment></comment> | |
5 | + <projects> | |
6 | + </projects> | |
7 | + <buildSpec> | |
8 | + <buildCommand> | |
9 | + <name>org.eclipse.jdt.core.javabuilder</name> | |
10 | + <arguments> | |
11 | + </arguments> | |
12 | + </buildCommand> | |
13 | + <buildCommand> | |
14 | + <name>org.eclipse.m2e.core.maven2Builder</name> | |
15 | + <arguments> | |
16 | + </arguments> | |
17 | + </buildCommand> | |
18 | + </buildSpec> | |
19 | + <natures> | |
20 | + <nature>org.eclipse.jdt.core.javanature</nature> | |
21 | + <nature>org.eclipse.m2e.core.maven2Nature</nature> | |
22 | + </natures> | |
23 | +</projectDescription> |
@@ -0,0 +1,25 @@ | ||
1 | +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
2 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
3 | + <modelVersion>4.0.0</modelVersion> | |
4 | + | |
5 | + <groupId>mirrg</groupId> | |
6 | + <artifactId>mirrg.serial.fluorine</artifactId> | |
7 | + <version>0.0.1-SNAPSHOT</version> | |
8 | + <packaging>jar</packaging> | |
9 | + | |
10 | + <name>cf-serial-framework</name> | |
11 | + <url>http://maven.apache.org</url> | |
12 | + | |
13 | + <properties> | |
14 | + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
15 | + </properties> | |
16 | + | |
17 | + <dependencies> | |
18 | + <dependency> | |
19 | + <groupId>junit</groupId> | |
20 | + <artifactId>junit</artifactId> | |
21 | + <version>4.12</version> | |
22 | + <scope>test</scope> | |
23 | + </dependency> | |
24 | + </dependencies> | |
25 | +</project> |
@@ -0,0 +1,20 @@ | ||
1 | +package mirrg.serial.fluorine.connection; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | + | |
5 | +import mirrg.serial.fluorine.connection.InputChlorofilSender.EnumTypeMessage; | |
6 | + | |
7 | +public interface IListenerInputChlorofilSender | |
8 | +{ | |
9 | + | |
10 | + public void setAcceptedChars(int acceptedChars); | |
11 | + | |
12 | + public void onMessage(EnumTypeMessage typeMessage, String message); | |
13 | + | |
14 | + public void onMessageBlock(ArrayList<String> messageBlock); | |
15 | + | |
16 | + public void onInternalException(Exception exception); | |
17 | + | |
18 | + public void onClosed(); | |
19 | + | |
20 | +} |
@@ -0,0 +1,8 @@ | ||
1 | +package mirrg.serial.fluorine.connection; | |
2 | + | |
3 | +public interface IListenerOutputChlorofilSender | |
4 | +{ | |
5 | + | |
6 | + public void onSent(String string); | |
7 | + | |
8 | +} |
@@ -0,0 +1,113 @@ | ||
1 | +package mirrg.serial.fluorine.connection; | |
2 | + | |
3 | +import java.io.InputStream; | |
4 | +import java.util.ArrayList; | |
5 | +import java.util.function.Consumer; | |
6 | + | |
7 | +/** | |
8 | + * 入力ストリームを監視してメッセージを分解してハンドラに通知する。 | |
9 | + */ | |
10 | +public class InputChlorofilSender extends UTF8SerialStreamReader | |
11 | +{ | |
12 | + | |
13 | + public InputChlorofilSender(InputStream in) | |
14 | + { | |
15 | + super(in, false); | |
16 | + } | |
17 | + | |
18 | + public InputChlorofilSender(InputStream in, boolean blocking) | |
19 | + { | |
20 | + super(in, blocking); | |
21 | + } | |
22 | + | |
23 | + /** | |
24 | + * 複数行メッセージの処理中のメッセージ。 | |
25 | + */ | |
26 | + protected ArrayList<String> messageBlockBuffer; | |
27 | + | |
28 | + /** | |
29 | + * 複数行メッセージの終端記号。 | |
30 | + * nullの場合は現在複数行メッセージの処理中ではない。 | |
31 | + */ | |
32 | + protected String messageBlockSentinel = null; | |
33 | + | |
34 | + public void forEach(IListenerInputChlorofilSender listener) | |
35 | + { | |
36 | + forEach((Consumer<String>) line -> { | |
37 | + | |
38 | + // 現在複数行メッセージの処理中であるならば、 | |
39 | + if (messageBlockSentinel != null) { | |
40 | + | |
41 | + // 来た行が終端記号なら、 | |
42 | + if (line.equals(messageBlockSentinel)) { | |
43 | + | |
44 | + // 複数行メッセージの処理中でなくして、 | |
45 | + messageBlockSentinel = null; | |
46 | + | |
47 | + // リスナを起動する。 | |
48 | + listener.onMessageBlock(messageBlockBuffer); | |
49 | + | |
50 | + } else { // 終端記号でないなら、 | |
51 | + | |
52 | + // バッファに追加する。 | |
53 | + messageBlockBuffer.add(line); | |
54 | + | |
55 | + } | |
56 | + | |
57 | + } else { | |
58 | + String res; | |
59 | + | |
60 | + // 受け付けた | |
61 | + if ((res = getProperty(line, "C")) != null) { | |
62 | + int i; | |
63 | + try { | |
64 | + i = Integer.parseInt(res, 10); | |
65 | + } catch (NumberFormatException e) { | |
66 | + listener.onInternalException(e); | |
67 | + return; | |
68 | + } | |
69 | + listener.setAcceptedChars(i); | |
70 | + return; | |
71 | + } | |
72 | + if ((res = getProperty(line, "M")) != null) { | |
73 | + listener.onMessage(EnumTypeMessage.MESSAGE, res); | |
74 | + return; | |
75 | + } | |
76 | + if ((res = getProperty(line, "E")) != null) { | |
77 | + listener.onMessage(EnumTypeMessage.ERROR, res); | |
78 | + return; | |
79 | + } | |
80 | + if ((res = getProperty(line, "W")) != null) { | |
81 | + listener.onMessage(EnumTypeMessage.WARNINGS, res); | |
82 | + return; | |
83 | + } | |
84 | + if ((res = getProperty(line, "MB")) != null) { | |
85 | + messageBlockSentinel = res; | |
86 | + messageBlockBuffer = new ArrayList<>(); | |
87 | + return; | |
88 | + } | |
89 | + | |
90 | + } | |
91 | + | |
92 | + }, () -> { | |
93 | + listener.onClosed(); | |
94 | + }); | |
95 | + } | |
96 | + | |
97 | + protected String getProperty(String string, String prefix) | |
98 | + { | |
99 | + prefix += ":"; | |
100 | + | |
101 | + if (string.startsWith(prefix)) { | |
102 | + return string.substring(prefix.length()); | |
103 | + } else { | |
104 | + return null; | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + public static enum EnumTypeMessage | |
109 | + { | |
110 | + MESSAGE, ERROR, WARNINGS, | |
111 | + } | |
112 | + | |
113 | +} |
@@ -0,0 +1,103 @@ | ||
1 | +package mirrg.serial.fluorine.connection; | |
2 | + | |
3 | +import java.io.OutputStream; | |
4 | +import java.io.PrintStream; | |
5 | +import java.io.UnsupportedEncodingException; | |
6 | +import java.util.Iterator; | |
7 | +import java.util.LinkedList; | |
8 | + | |
9 | +import mirrg.serial.fluorine.encode.EncoderAcsOperator; | |
10 | +import mirrg.serial.fluorine.encode.IAcsElement; | |
11 | + | |
12 | +public class OutputChlorofilSender | |
13 | +{ | |
14 | + | |
15 | + protected static final int ARDUINO_MAX_BUFFER = 63; | |
16 | + | |
17 | + protected PrintStream out; | |
18 | + | |
19 | + public OutputChlorofilSender(OutputStream outputStream) | |
20 | + { | |
21 | + try { | |
22 | + out = new PrintStream(outputStream, false, "UTF-8"); | |
23 | + } catch (UnsupportedEncodingException e) { | |
24 | + throw new RuntimeException(e); | |
25 | + } | |
26 | + } | |
27 | + | |
28 | + protected int sentChars = 0; | |
29 | + protected transient int acceptedChars = 0; | |
30 | + | |
31 | + public void setAcceptedChars(int acceptedChars) | |
32 | + { | |
33 | + this.acceptedChars = acceptedChars; | |
34 | + } | |
35 | + | |
36 | + public void send(IAcsElement acsElement) | |
37 | + { | |
38 | + synchronized (sendingAcsElements) { | |
39 | + sendingAcsElements.add(acsElement); | |
40 | + } | |
41 | + } | |
42 | + | |
43 | + protected LinkedList<IAcsElement> sendingAcsElements = new LinkedList<>(); | |
44 | + | |
45 | + public void run(IListenerOutputChlorofilSender listener) | |
46 | + { | |
47 | + try { | |
48 | + while (true) { | |
49 | + | |
50 | + synchronized (sendingAcsElements) { | |
51 | + Iterator<IAcsElement> iterator = sendingAcsElements.iterator(); | |
52 | + while (iterator.hasNext()) { | |
53 | + IAcsElement acsElement = iterator.next(); | |
54 | + sendImpl(acsElement.get(), listener); | |
55 | + iterator.remove(); | |
56 | + } | |
57 | + } | |
58 | + | |
59 | + Thread.sleep(5); | |
60 | + } | |
61 | + } catch (InterruptedException e) {} | |
62 | + } | |
63 | + | |
64 | + protected void sendImpl(String string, IListenerOutputChlorofilSender listener) throws InterruptedException | |
65 | + { | |
66 | + do { | |
67 | + int bufferedChars = sentChars - acceptedChars; | |
68 | + int bufferSpace = ARDUINO_MAX_BUFFER - bufferedChars; | |
69 | + int sendingChars = Math.min(string.length(), bufferSpace); | |
70 | + | |
71 | + if (sendingChars > 0) { | |
72 | + | |
73 | + String send = string.substring(0, sendingChars); | |
74 | + sendImpl2(send); | |
75 | + listener.onSent(send); | |
76 | + string = string.substring(sendingChars); | |
77 | + | |
78 | + if (string.isEmpty()) break; | |
79 | + } | |
80 | + | |
81 | + Thread.sleep(5); | |
82 | + | |
83 | + } while (true); | |
84 | + } | |
85 | + | |
86 | + protected void sendImpl2(String string) | |
87 | + { | |
88 | + sentChars += string.length(); | |
89 | + out.print(string); | |
90 | + out.flush(); | |
91 | + } | |
92 | + | |
93 | + /** | |
94 | + * 初期化の命令を送信し、内部変数を初期設定で同期する。 | |
95 | + */ | |
96 | + public void synchronize() | |
97 | + { | |
98 | + send(EncoderAcsOperator.reset()); | |
99 | + acceptedChars = 0; | |
100 | + sentChars = 0; | |
101 | + } | |
102 | + | |
103 | +} |
@@ -0,0 +1,97 @@ | ||
1 | +package mirrg.serial.fluorine.connection; | |
2 | + | |
3 | +import java.io.BufferedReader; | |
4 | +import java.io.IOException; | |
5 | +import java.io.InputStream; | |
6 | +import java.nio.ByteBuffer; | |
7 | +import java.nio.charset.Charset; | |
8 | +import java.util.ArrayList; | |
9 | +import java.util.function.Consumer; | |
10 | + | |
11 | +/** | |
12 | + * {@link BufferedReader#lines()}との違いは、 | |
13 | + * こちらはシリアル通信前提で文字コードが固定であり、 | |
14 | + * バッファリングも最小限なため謎挙動が少ない。 | |
15 | + */ | |
16 | +public class UTF8SerialStreamReader | |
17 | +{ | |
18 | + | |
19 | + protected static final Charset charset = Charset.forName("UTF-8"); | |
20 | + protected InputStream in; | |
21 | + protected boolean blocking; | |
22 | + | |
23 | + public UTF8SerialStreamReader(InputStream in, boolean blocking) | |
24 | + { | |
25 | + this.in = in; | |
26 | + this.blocking = blocking; | |
27 | + } | |
28 | + | |
29 | + /** | |
30 | + * {@link ByteBuffer}は固定長だから面倒。 | |
31 | + */ | |
32 | + protected ArrayList<Byte> buffer = new ArrayList<>(); | |
33 | + | |
34 | + public void forEach(Consumer<String> consumer, Runnable onClosed) | |
35 | + { | |
36 | + boolean r = false; | |
37 | + | |
38 | + while (true) { | |
39 | + int b; | |
40 | + try { | |
41 | + | |
42 | + // blocking == false | |
43 | + // -1が帰ると、データの受信待ち。 | |
44 | + // 例外が発生すると、通信が途切れた。 | |
45 | + // blocking == true | |
46 | + // -1が帰ると、通信が途切れた。 | |
47 | + b = in.read(); | |
48 | + | |
49 | + } catch (IOException e) { | |
50 | + onClosed.run(); | |
51 | + return; | |
52 | + } | |
53 | + if (b < 0) { | |
54 | + if (blocking) { | |
55 | + flush(consumer); | |
56 | + break; | |
57 | + } | |
58 | + } else if ((char) b == '\r') { | |
59 | + r = true; | |
60 | + flush(consumer); | |
61 | + continue; | |
62 | + } else if ((char) b == '\n') { | |
63 | + if (r) { | |
64 | + | |
65 | + } else { | |
66 | + flush(consumer); | |
67 | + } | |
68 | + continue; | |
69 | + } else { | |
70 | + buffer.add((byte) b); | |
71 | + continue; | |
72 | + } | |
73 | + | |
74 | + try { | |
75 | + Thread.sleep(1); | |
76 | + } catch (InterruptedException e) { | |
77 | + break; | |
78 | + } | |
79 | + } | |
80 | + } | |
81 | + | |
82 | + protected void flush(Consumer<String> consumer) | |
83 | + { | |
84 | + byte[] buffer2 = new byte[buffer.size()]; | |
85 | + for (int i = 0; i < buffer2.length; i++) { | |
86 | + buffer2[i] = buffer.get(i); | |
87 | + } | |
88 | + consumer.accept(new String(buffer2, charset)); | |
89 | + buffer.clear(); | |
90 | + } | |
91 | + | |
92 | + public void close() throws IOException | |
93 | + { | |
94 | + in.close(); | |
95 | + } | |
96 | + | |
97 | +} |
@@ -0,0 +1,33 @@ | ||
1 | +package mirrg.serial.fluorine.encode; | |
2 | + | |
3 | +/** | |
4 | + * immutable | |
5 | + */ | |
6 | +public class AcsCallMethod implements IAcsElement | |
7 | +{ | |
8 | + | |
9 | + private String string; | |
10 | + | |
11 | + public AcsCallMethod(Iterable<AcsOperator> acsOperators, boolean newLine) | |
12 | + { | |
13 | + StringBuffer stringBuffer = new StringBuffer(); | |
14 | + for (AcsOperator acsOperator : acsOperators) { | |
15 | + stringBuffer.append(acsOperator); | |
16 | + } | |
17 | + if (newLine) stringBuffer.append("\n"); | |
18 | + string = stringBuffer.toString(); | |
19 | + } | |
20 | + | |
21 | + @Override | |
22 | + public String toString() | |
23 | + { | |
24 | + return string; | |
25 | + } | |
26 | + | |
27 | + @Override | |
28 | + public String get() | |
29 | + { | |
30 | + return string; | |
31 | + } | |
32 | + | |
33 | +} |
@@ -0,0 +1,32 @@ | ||
1 | +package mirrg.serial.fluorine.encode; | |
2 | + | |
3 | +/** | |
4 | + * immutable | |
5 | + */ | |
6 | +public class AcsCallMethodChain implements IAcsElement | |
7 | +{ | |
8 | + | |
9 | + private String string; | |
10 | + | |
11 | + public AcsCallMethodChain(Iterable<AcsCallMethod> listAcsCallMethod) | |
12 | + { | |
13 | + StringBuffer stringBuffer = new StringBuffer(); | |
14 | + for (AcsCallMethod acsCallMethod : listAcsCallMethod) { | |
15 | + stringBuffer.append(acsCallMethod); | |
16 | + } | |
17 | + string = stringBuffer.toString(); | |
18 | + } | |
19 | + | |
20 | + @Override | |
21 | + public String toString() | |
22 | + { | |
23 | + return string; | |
24 | + } | |
25 | + | |
26 | + @Override | |
27 | + public String get() | |
28 | + { | |
29 | + return string; | |
30 | + } | |
31 | + | |
32 | +} |
@@ -0,0 +1,28 @@ | ||
1 | +package mirrg.serial.fluorine.encode; | |
2 | + | |
3 | +/** | |
4 | + * immutable | |
5 | + */ | |
6 | +public class AcsOperator implements IAcsElement | |
7 | +{ | |
8 | + | |
9 | + private String string; | |
10 | + | |
11 | + public AcsOperator(String string) | |
12 | + { | |
13 | + this.string = string; | |
14 | + } | |
15 | + | |
16 | + @Override | |
17 | + public String toString() | |
18 | + { | |
19 | + return string; | |
20 | + } | |
21 | + | |
22 | + @Override | |
23 | + public String get() | |
24 | + { | |
25 | + return string; | |
26 | + } | |
27 | + | |
28 | +} |
@@ -0,0 +1,94 @@ | ||
1 | +package mirrg.serial.fluorine.encode; | |
2 | + | |
3 | +import static org.junit.Assert.*; | |
4 | + | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.function.Consumer; | |
7 | + | |
8 | +import org.junit.Test; | |
9 | + | |
10 | +public class EncoderAcsCallMethod | |
11 | +{ | |
12 | + | |
13 | + public static AcsCallMethodChain callMethods(Consumer<Consumer<AcsCallMethod>> arguments) | |
14 | + { | |
15 | + ArrayList<AcsCallMethod> acsCallMethods = new ArrayList<>(); | |
16 | + arguments.accept(acsCallMethods::add); | |
17 | + return new AcsCallMethodChain(acsCallMethods); | |
18 | + } | |
19 | + | |
20 | + public static AcsCallMethod callMethod(String name, Consumer<IConsumerArgument> arguments) | |
21 | + { | |
22 | + ArrayList<AcsOperator> acsOperators = new ArrayList<>(); | |
23 | + | |
24 | + acsOperators.add(EncoderAcsOperator.clear()); | |
25 | + IConsumerArgument consumerArgument = new IConsumerArgument() { | |
26 | + | |
27 | + @Override | |
28 | + public void acceptInteger(int argument) | |
29 | + { | |
30 | + acsOperators.add(EncoderAcsOperator.pushInteger(argument)); | |
31 | + } | |
32 | + | |
33 | + @Override | |
34 | + public void acceptDouble(double argument) | |
35 | + { | |
36 | + acsOperators.add(EncoderAcsOperator.pushDouble(argument)); | |
37 | + } | |
38 | + | |
39 | + @Override | |
40 | + public void acceptString(String argument) | |
41 | + { | |
42 | + acsOperators.add(EncoderAcsOperator.pushString(argument)); | |
43 | + } | |
44 | + | |
45 | + }; | |
46 | + consumerArgument.acceptString(name); | |
47 | + arguments.accept(consumerArgument); | |
48 | + acsOperators.add(EncoderAcsOperator.method()); | |
49 | + | |
50 | + return new AcsCallMethod(acsOperators, true); | |
51 | + } | |
52 | + | |
53 | + @Test | |
54 | + public void test1() | |
55 | + { | |
56 | + assertEquals( | |
57 | + "C;SMeth;D4.5;I79;D0.0;I0;S68;S;S/f4b[@\\\\4,].5o@s,\\;4e\\\n0o;M;\n", | |
58 | + EncoderAcsCallMethod.callMethod("Meth", consumer -> { | |
59 | + consumer.acceptDouble(4.5); | |
60 | + consumer.acceptInteger(79); | |
61 | + consumer.acceptDouble(0.0); | |
62 | + consumer.acceptInteger(0); | |
63 | + consumer.acceptString("68"); | |
64 | + consumer.acceptString(""); | |
65 | + consumer.acceptString("/f4b[@\\4,].5o@s,;4e\n0o"); | |
66 | + }).toString()); | |
67 | + } | |
68 | + | |
69 | + @Test | |
70 | + public void test2() | |
71 | + { | |
72 | + assertEquals("C;SMethodName;M;\n", | |
73 | + callMethod("MethodName", consumerArgument -> { | |
74 | + | |
75 | + }).toString()); | |
76 | + assertEquals("C;SMethodName;I45;Sgh;M;\n", | |
77 | + callMethod("MethodName", consumerArgument -> { | |
78 | + consumerArgument.acceptInteger(45); | |
79 | + consumerArgument.acceptString("gh"); | |
80 | + }).toString()); | |
81 | + } | |
82 | + | |
83 | + public interface IConsumerArgument | |
84 | + { | |
85 | + | |
86 | + public void acceptInteger(int argument); | |
87 | + | |
88 | + public void acceptDouble(double argument); | |
89 | + | |
90 | + public void acceptString(String argument); | |
91 | + | |
92 | + } | |
93 | + | |
94 | +} |
@@ -0,0 +1,80 @@ | ||
1 | +package mirrg.serial.fluorine.encode; | |
2 | + | |
3 | +import static org.junit.Assert.*; | |
4 | + | |
5 | +import java.util.regex.Matcher; | |
6 | +import java.util.regex.Pattern; | |
7 | + | |
8 | +import org.junit.Test; | |
9 | + | |
10 | +public class EncoderAcsOperator | |
11 | +{ | |
12 | + | |
13 | + public static AcsOperator pushInteger(int value) | |
14 | + { | |
15 | + return build(EnumAcsOperator.INTEGER, Integer.toString(value)); | |
16 | + } | |
17 | + | |
18 | + public static AcsOperator pushDouble(double value) | |
19 | + { | |
20 | + return build(EnumAcsOperator.DOUBLE, Double.toString(value)); | |
21 | + } | |
22 | + | |
23 | + private static final Pattern patternOperatorBreak = | |
24 | + Pattern.compile("([\\n;\\\\])"); | |
25 | + | |
26 | + public static AcsOperator pushString(String value) | |
27 | + { | |
28 | + Matcher matcher = patternOperatorBreak.matcher(value); | |
29 | + return build(EnumAcsOperator.STRING, matcher.replaceAll("\\\\$1")); | |
30 | + } | |
31 | + | |
32 | + private static final AcsOperator reset = build(EnumAcsOperator.RESET); | |
33 | + private static final AcsOperator clear = build(EnumAcsOperator.CLEAR); | |
34 | + private static final AcsOperator method = build(EnumAcsOperator.METHOD); | |
35 | + | |
36 | + public static AcsOperator reset() | |
37 | + { | |
38 | + return reset; | |
39 | + } | |
40 | + | |
41 | + public static AcsOperator clear() | |
42 | + { | |
43 | + return clear; | |
44 | + } | |
45 | + | |
46 | + public static AcsOperator method() | |
47 | + { | |
48 | + return method; | |
49 | + } | |
50 | + | |
51 | + public static AcsOperator build(EnumAcsOperator acsOperator) | |
52 | + { | |
53 | + return new AcsOperator(acsOperator.ch + ";"); | |
54 | + } | |
55 | + | |
56 | + public static AcsOperator build(EnumAcsOperator acsOperator, String argument) | |
57 | + { | |
58 | + return new AcsOperator(acsOperator.ch + argument + ";"); | |
59 | + } | |
60 | + | |
61 | + @Test | |
62 | + public void test() | |
63 | + { | |
64 | + assertEquals("C;", clear().toString()); | |
65 | + assertEquals("R;", reset().toString()); | |
66 | + assertEquals("M;", method().toString()); | |
67 | + assertEquals("I24;", pushInteger(24).toString()); | |
68 | + assertEquals("I-7;", pushInteger(-7).toString()); | |
69 | + assertEquals("I0;", pushInteger(0).toString()); | |
70 | + assertEquals("I99999;", pushInteger(99999).toString()); | |
71 | + assertEquals("D" + 1.5 + ";", pushDouble(1.5).toString()); | |
72 | + assertEquals("D" + -1.5 + ";", pushDouble(-1.5).toString()); | |
73 | + assertEquals("Sabc;", pushString("abc").toString()); | |
74 | + assertEquals("S;", pushString("").toString()); | |
75 | + assertEquals("S\\;;", pushString(";").toString()); | |
76 | + assertEquals("S\\\n;", pushString("\n").toString()); | |
77 | + assertEquals("S\\;\\\n;", pushString(";\n").toString()); | |
78 | + } | |
79 | + | |
80 | +} |
@@ -0,0 +1,21 @@ | ||
1 | +package mirrg.serial.fluorine.encode; | |
2 | + | |
3 | +public enum EnumAcsOperator | |
4 | +{ | |
5 | + RESET('R', false), | |
6 | + CLEAR('C', false), | |
7 | + METHOD('M', false), | |
8 | + INTEGER('I', true), | |
9 | + DOUBLE('D', true), | |
10 | + STRING('S', true), ; | |
11 | + | |
12 | + public final char ch; | |
13 | + public final boolean canArgument; | |
14 | + | |
15 | + private EnumAcsOperator(char ch, boolean canArgument) | |
16 | + { | |
17 | + this.ch = ch; | |
18 | + this.canArgument = canArgument; | |
19 | + } | |
20 | + | |
21 | +} |
@@ -0,0 +1,8 @@ | ||
1 | +package mirrg.serial.fluorine.encode; | |
2 | + | |
3 | +public interface IAcsElement | |
4 | +{ | |
5 | + | |
6 | + public String get(); | |
7 | + | |
8 | +} |