Skip to content

Commit 9929c51

Browse files
authored
Merge pull request #76 from epics-base/Issue_72
Issue 72 Support additional types in CAChannelHandler.write()
2 parents e6d03db + 728e499 commit 9929c51

File tree

3 files changed

+294
-26
lines changed

3 files changed

+294
-26
lines changed

gpclient/gpclient-ca/src/main/java/org/epics/gpclient/datasource/ca/CAChannelHandler.java

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,6 @@
44
*/
55
package org.epics.gpclient.datasource.ca;
66

7-
import static org.epics.gpclient.datasource.ca.CADataSource.log;
8-
9-
import static org.epics.util.array.UnsafeUnwrapper.wrappedArray;
10-
import static org.epics.util.array.UnsafeUnwrapper.wrappedDoubleArray;
11-
12-
import java.util.Arrays;
13-
import java.util.LinkedList;
14-
import java.util.logging.Level;
15-
import java.util.regex.Pattern;
16-
17-
import org.epics.gpclient.ReadCollector;
18-
import org.epics.gpclient.WriteCollector.WriteRequest;
19-
import org.epics.gpclient.datasource.MultiplexedChannelHandler;
20-
import org.epics.gpclient.datasource.ca.types.CATypeAdapter;
21-
import org.epics.util.array.CollectionNumbers;
22-
import org.epics.util.array.ListNumber;
23-
import org.epics.vtype.VByte;
24-
import org.epics.vtype.VDouble;
25-
import org.epics.vtype.VFloat;
26-
import org.epics.vtype.VInt;
27-
import org.epics.vtype.VLong;
28-
import org.epics.vtype.VShort;
29-
307
import gov.aps.jca.CAException;
318
import gov.aps.jca.Channel;
329
import gov.aps.jca.Monitor;
@@ -48,6 +25,27 @@
4825
import gov.aps.jca.event.ConnectionListener;
4926
import gov.aps.jca.event.MonitorEvent;
5027
import gov.aps.jca.event.MonitorListener;
28+
import org.epics.gpclient.ReadCollector;
29+
import org.epics.gpclient.WriteCollector.WriteRequest;
30+
import org.epics.gpclient.datasource.MultiplexedChannelHandler;
31+
import org.epics.gpclient.datasource.ca.types.CATypeAdapter;
32+
import org.epics.util.array.ListNumber;
33+
import org.epics.vtype.VByte;
34+
import org.epics.vtype.VDouble;
35+
import org.epics.vtype.VEnum;
36+
import org.epics.vtype.VFloat;
37+
import org.epics.vtype.VInt;
38+
import org.epics.vtype.VLong;
39+
import org.epics.vtype.VShort;
40+
41+
import java.math.BigInteger;
42+
import java.util.Arrays;
43+
import java.util.logging.Level;
44+
import java.util.regex.Pattern;
45+
46+
import static org.epics.gpclient.datasource.ca.CADataSource.log;
47+
import static org.epics.util.array.UnsafeUnwrapper.wrappedArray;
48+
import static org.epics.util.array.UnsafeUnwrapper.wrappedDoubleArray;
5149

5250
public class CAChannelHandler extends MultiplexedChannelHandler<CAConnectionPayload, CAMessagePayload> {
5351

@@ -294,6 +292,7 @@ protected void write(Object newValue) {
294292
}
295293
try {
296294
if (newValue instanceof Double[]) {
295+
297296
log.warning("You are writing a Double[] to channel " + getChannelName()
298297
+ ": use org.epics.util.array.ListDouble instead");
299298
final Double dbl[] = (Double[]) newValue;
@@ -302,8 +301,10 @@ protected void write(Object newValue) {
302301
val[i] = dbl[i].doubleValue();
303302
}
304303
newValue = val;
304+
channel.put((double[])newValue);
305+
305306
}
306-
if (newValue instanceof Integer[]) {
307+
else if (newValue instanceof Integer[]) {
307308
log.warning("You are writing a Integer[] to channel " + getChannelName()
308309
+ ": use org.epics.util.array.ListInt instead");
309310
final Integer ival[] = (Integer[]) newValue;
@@ -312,9 +313,28 @@ protected void write(Object newValue) {
312313
val[i] = ival[i].intValue();
313314
}
314315
newValue = val;
316+
channel.put((int[])newValue);
315317
}
316318

317-
if (newValue instanceof String) {
319+
else if(newValue instanceof Double){
320+
channel.put(((Double) newValue).doubleValue());
321+
}
322+
else if(newValue instanceof Integer){
323+
channel.put(((Integer) newValue).intValue());
324+
}
325+
else if(newValue instanceof BigInteger){
326+
channel.put(((BigInteger) newValue).intValue());
327+
}
328+
else if(newValue instanceof Short){
329+
channel.put(((Short) newValue).shortValue());
330+
}
331+
else if(newValue instanceof Float){
332+
channel.put(((Float) newValue).floatValue());
333+
}
334+
else if(newValue instanceof Byte){
335+
channel.put(((Byte) newValue).byteValue());
336+
}
337+
else if (newValue instanceof String) {
318338
if (isLongString()) {
319339
channel.put(toBytes(newValue.toString()));
320340
} else {
@@ -336,6 +356,13 @@ protected void write(Object newValue) {
336356
channel.put((float[]) newValue);
337357
} else if (newValue instanceof double[]) {
338358
channel.put((double[]) newValue);
359+
} else if (newValue instanceof long[]) {
360+
long[] longs = (long[])newValue;
361+
double[] value = new double[longs.length];
362+
for(int i = 0; i < longs.length; i++){
363+
value[i] = (double)longs[i];
364+
}
365+
channel.put(value);
339366
} else if (newValue instanceof VByte) {
340367
channel.put(((VByte) newValue).getValue());
341368
} else if (newValue instanceof VShort) {
@@ -356,7 +383,10 @@ protected void write(Object newValue) {
356383
channel.put(((VFloat) newValue).getValue());
357384
} else if (newValue instanceof VDouble) {
358385
channel.put(((VDouble) newValue).getValue());
359-
} else {
386+
} else if(newValue instanceof VEnum){
387+
channel.put(((VEnum) newValue).getValue());
388+
}
389+
else {
360390
// callback.channelWritten(new Exception(new RuntimeException("Unsupported type
361391
// for CA: " + newValue.getClass())));
362392
return;
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
package org.epics.gpclient.datasource.ca;
2+
3+
import gov.aps.jca.Channel;
4+
import gov.aps.jca.Context;
5+
import gov.aps.jca.dbr.DBRType;
6+
import gov.aps.jca.event.ConnectionListener;
7+
import org.epics.util.array.ArrayDouble;
8+
import org.epics.util.array.ListNumber;
9+
import org.epics.vtype.Alarm;
10+
import org.epics.vtype.Display;
11+
import org.epics.vtype.EnumDisplay;
12+
import org.epics.vtype.Time;
13+
import org.epics.vtype.VByte;
14+
import org.epics.vtype.VDouble;
15+
import org.epics.vtype.VEnum;
16+
import org.epics.vtype.VFloat;
17+
import org.epics.vtype.VInt;
18+
import org.epics.vtype.VLong;
19+
import org.epics.vtype.VShort;
20+
import org.junit.Before;
21+
import org.junit.Ignore;
22+
import org.junit.Test;
23+
import org.mockito.Mockito;
24+
25+
import java.math.BigInteger;
26+
27+
import static org.mockito.Mockito.*;
28+
29+
public class CAChannelHandlerTest {
30+
31+
private CADataSource caDataSource;
32+
private Channel channel;
33+
private Context context;
34+
private CAChannelHandler caChannelHandler;
35+
36+
@Before
37+
public void init() throws Exception{
38+
caDataSource = Mockito.mock(CADataSource.class);
39+
channel = Mockito.mock(Channel.class);
40+
context = Mockito.mock(Context.class);
41+
caChannelHandler = new CAChannelHandler("test", caDataSource);
42+
43+
when(context.createChannel(anyString(), Mockito.any(ConnectionListener.class), anyShort())).thenReturn(channel);
44+
when(caDataSource.getContext()).thenReturn(context);
45+
caChannelHandler.connect();
46+
}
47+
48+
/**
49+
* This is deliberately disabled. It should be fine, but the logic
50+
* handling {@link ListNumber}s is broken as type information is lost
51+
* in the transformations happening in other classes.
52+
* @throws Exception
53+
*/
54+
@Test
55+
@Ignore
56+
public void testWriteListNumberDouble() throws Exception{
57+
58+
ListNumber doubles = ArrayDouble.of(Double.valueOf(1.1d), Double.valueOf(2.2d));
59+
caChannelHandler.write(doubles);
60+
verify(channel).put(new double[]{1.1d, 2.2d});
61+
}
62+
63+
@Test
64+
public void testWriteDouble() throws Exception{
65+
Double value = Double.valueOf(7.7d);
66+
caChannelHandler.write(value);
67+
verify(channel).put(7.7d);
68+
}
69+
70+
@Test
71+
public void testWriteInteger() throws Exception{
72+
Integer value = Integer.valueOf(7);
73+
caChannelHandler.write(value);
74+
verify(channel).put(7);
75+
}
76+
77+
@Test
78+
public void testWriteFloat() throws Exception{
79+
Float value = Float.valueOf(7.8f);
80+
caChannelHandler.write(value);
81+
verify(channel).put(7.8f);
82+
}
83+
84+
@Test
85+
public void testWriteShort() throws Exception{
86+
Short value = Short.valueOf((short)7);
87+
caChannelHandler.write(value);
88+
verify(channel).put((short)7);
89+
}
90+
91+
@Test
92+
public void testWriteBigInteger() throws Exception{
93+
BigInteger value = BigInteger.valueOf(7);
94+
caChannelHandler.write(value);
95+
verify(channel).put(7);
96+
}
97+
98+
@Test
99+
public void testWriteByte() throws Exception{
100+
Byte value = Byte.valueOf((byte)7);
101+
caChannelHandler.write(value);
102+
verify(channel).put((byte)7);
103+
}
104+
105+
@Test
106+
public void testWriteDoubleArray() throws Exception{
107+
Double[] value = new Double[]{1.1d, 2.2d};
108+
caChannelHandler.write(value);
109+
verify(channel).put(new double[]{1.1d, 2.2d});
110+
}
111+
112+
@Test
113+
public void testWriteIntegerArray() throws Exception{
114+
Integer[] value =
115+
new Integer[]{1, 2};
116+
caChannelHandler.write(value);
117+
verify(channel).put(new int[]{1, 2});
118+
}
119+
120+
@Test
121+
public void testWriteString() throws Exception{
122+
String value = "ABC";
123+
when(channel.getFieldType()).thenReturn(DBRType.STRING);
124+
when(channel.getElementCount()).thenReturn(value.length());
125+
caChannelHandler.write(value);
126+
verify(channel).put("ABC");
127+
}
128+
129+
@Test
130+
public void testWriteStringAsBytes() throws Exception{
131+
String value = "ABC";
132+
when(channel.getFieldType()).thenReturn(DBRType.BYTE);
133+
when(channel.getElementCount()).thenReturn(value.length());
134+
caChannelHandler.write(value);
135+
verify(channel).put(new byte[]{0x41, 0x42, 0x43, 0x0});
136+
}
137+
138+
@Test
139+
public void testWriteByteArray() throws Exception{
140+
byte[] value = new byte[]{0x1, 0x2, 0x3};
141+
caChannelHandler.write(value);
142+
verify(channel).put(value);
143+
}
144+
145+
@Test
146+
public void testWriteShortArray() throws Exception{
147+
short[] value = new short[]{(short)1, (short)2, (short)3};
148+
caChannelHandler.write(value);
149+
verify(channel).put(value);
150+
}
151+
152+
@Test
153+
public void testWriteIntArray() throws Exception{
154+
int[] value = new int[]{1, 2, 3};
155+
caChannelHandler.write(value);
156+
verify(channel).put(value);
157+
}
158+
159+
@Test
160+
public void testWriteFloatArray() throws Exception{
161+
float[] value = new float[]{1.1f, 2.2f, 3.3f};
162+
caChannelHandler.write(value);
163+
verify(channel).put(value);
164+
}
165+
166+
@Test
167+
public void testWriteLongArray() throws Exception{
168+
long[] value = new long[]{1L, 2L, 3L};
169+
caChannelHandler.write(value);
170+
verify(channel).put(new double[]{1, 2, 3});
171+
}
172+
173+
@Test
174+
public void testWriteDoubleAsPrimitiveArray() throws Exception{
175+
double[] value = new double[]{1.1d, 2.2d, 3.3d};
176+
caChannelHandler.write(value);
177+
verify(channel).put(value);
178+
}
179+
180+
@Test
181+
public void testWriteVByte() throws Exception{
182+
VByte value = VByte.of(Byte.valueOf((byte)1), Alarm.none(), Time.now(), Display.none());
183+
caChannelHandler.write(value);
184+
verify(channel).put((byte)1);
185+
}
186+
187+
@Test
188+
public void testWriteVShort() throws Exception{
189+
VShort value = VShort.of(Short.valueOf((short)1), Alarm.none(), Time.now(), Display.none());
190+
caChannelHandler.write(value);
191+
verify(channel).put((short)1);
192+
}
193+
194+
@Test
195+
public void testWriteVInt() throws Exception{
196+
VInt value = VInt.of(Integer.valueOf(1), Alarm.none(), Time.now(), Display.none());
197+
caChannelHandler.write(value);
198+
verify(channel).put(1);
199+
}
200+
201+
@Test
202+
public void testWriteVLong() throws Exception{
203+
VLong value = VLong.of(Long.valueOf(1), Alarm.none(), Time.now(), Display.none());
204+
caChannelHandler.write(value);
205+
verify(channel).put(1);
206+
207+
double doubleValue = Math.pow(2, 33);
208+
value = VLong.of(Long.valueOf((long)doubleValue), Alarm.none(), Time.now(), Display.none());
209+
caChannelHandler.write(value);
210+
verify(channel).put(doubleValue);
211+
}
212+
213+
@Test
214+
public void testWriteVFloat() throws Exception{
215+
VFloat value = VFloat.of(Float.valueOf(1.1f), Alarm.none(), Time.now(), Display.none());
216+
caChannelHandler.write(value);
217+
verify(channel).put(1.1f);
218+
}
219+
220+
@Test
221+
public void testWriteVDouble() throws Exception{
222+
VDouble value = VDouble.of(Double.valueOf(1.1d), Alarm.none(), Time.now(), Display.none());
223+
caChannelHandler.write(value);
224+
verify(channel).put(1.1d);
225+
}
226+
227+
@Test
228+
public void testWriteVEnum() throws Exception{
229+
VEnum value = VEnum.of(1, EnumDisplay.of("A", "b", "c"), Alarm.none(), Time.now());
230+
caChannelHandler.write(value);
231+
verify(channel).put("b");
232+
}
233+
}

gpclient/gpclient-sample/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
<artifactId>gpclient-pva</artifactId>
3232
<version>${project.version}</version>
3333
</dependency>
34+
<dependency>
35+
<groupId>${project.groupId}</groupId>
36+
<artifactId>gpclient-ca</artifactId>
37+
<version>${project.version}</version>
38+
</dependency>
3439
<dependency>
3540
<groupId>${project.groupId}</groupId>
3641
<artifactId>gpclient-loc</artifactId>

0 commit comments

Comments
 (0)