66
77import static org .epics .gpclient .datasource .ca .CADataSource .log ;
88
9+ import static org .epics .util .array .UnsafeUnwrapper .wrappedArray ;
10+ import static org .epics .util .array .UnsafeUnwrapper .wrappedDoubleArray ;
11+
912import java .util .Arrays ;
13+ import java .util .LinkedList ;
1014import java .util .logging .Level ;
1115import java .util .regex .Pattern ;
1216
1317import org .epics .gpclient .ReadCollector ;
18+ import org .epics .gpclient .WriteCollector .WriteRequest ;
1419import org .epics .gpclient .datasource .MultiplexedChannelHandler ;
1520import 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 ;
1629
1730import gov .aps .jca .CAException ;
1831import gov .aps .jca .Channel ;
@@ -74,7 +87,8 @@ protected void connect() {
7487 channel = caDataSource .getContext ().createChannel (getChannelName (), connectionListener , (short ) (Channel .PRIORITY_MIN + 1 ));
7588 }
7689 } catch (CAException ex ) {
77- throw new RuntimeException ("JCA Connection failed" , ex );
90+ reportExceptionToAllReadersAndWriters (ex );
91+ log .log (Level .WARNING , "JCA Connection failed" , ex );
7892 }
7993 }
8094
@@ -89,7 +103,8 @@ protected void disconnect() {
89103 channel .destroy ();
90104 }
91105 } catch (CAException ex ) {
92- throw new RuntimeException ("JCA Disconnect fail" , ex );
106+ reportExceptionToAllReadersAndWriters (ex );
107+ log .log (Level .WARNING , "JCA Disconnect fail" , ex );
93108 } finally {
94109 channel = null ;
95110 processConnection (null );
@@ -265,6 +280,103 @@ public void monitorChanged(MonitorEvent ev) {
265280 }
266281 };
267282
283+ @ Override
284+ protected void write (Object newValue ) {
285+ // If it's a ListNumber, extract the array
286+ if (newValue instanceof ListNumber ) {
287+ ListNumber data = (ListNumber ) newValue ;
288+ Object wrappedArray = wrappedArray (data );
289+ if (wrappedArray == null ) {
290+ newValue = wrappedDoubleArray (data );
291+ } else {
292+ newValue = wrappedArray ;
293+ }
294+ }
295+ try {
296+ if (newValue instanceof Double []) {
297+ log .warning ("You are writing a Double[] to channel " + getChannelName ()
298+ + ": use org.epics.util.array.ListDouble instead" );
299+ final Double dbl [] = (Double []) newValue ;
300+ final double val [] = new double [dbl .length ];
301+ for (int i = 0 ; i < val .length ; ++i ) {
302+ val [i ] = dbl [i ].doubleValue ();
303+ }
304+ newValue = val ;
305+ }
306+ if (newValue instanceof Integer []) {
307+ log .warning ("You are writing a Integer[] to channel " + getChannelName ()
308+ + ": use org.epics.util.array.ListInt instead" );
309+ final Integer ival [] = (Integer []) newValue ;
310+ final int val [] = new int [ival .length ];
311+ for (int i = 0 ; i < val .length ; ++i ) {
312+ val [i ] = ival [i ].intValue ();
313+ }
314+ newValue = val ;
315+ }
316+
317+ if (newValue instanceof String ) {
318+ if (isLongString ()) {
319+ channel .put (toBytes (newValue .toString ()));
320+ } else {
321+ if (channel .getFieldType ().isBYTE () && channel .getElementCount () > 1 ) {
322+ log .warning ("You are writing the String " + newValue + " to BYTE channel " + getChannelName ()
323+ + ": use {\" longString\" :true} for support" );
324+ channel .put (toBytes (newValue .toString ()));
325+ } else {
326+ channel .put (newValue .toString ());
327+ }
328+ }
329+ } else if (newValue instanceof byte []) {
330+ channel .put ((byte []) newValue );
331+ } else if (newValue instanceof short []) {
332+ channel .put ((short []) newValue );
333+ } else if (newValue instanceof int []) {
334+ channel .put ((int []) newValue );
335+ } else if (newValue instanceof float []) {
336+ channel .put ((float []) newValue );
337+ } else if (newValue instanceof double []) {
338+ channel .put ((double []) newValue );
339+ } else if (newValue instanceof VByte ) {
340+ channel .put (((VByte ) newValue ).getValue ());
341+ } else if (newValue instanceof VShort ) {
342+ channel .put (((VShort ) newValue ).getValue ());
343+ } else if (newValue instanceof VInt ) {
344+ channel .put (((VInt )newValue ).getValue ());
345+ } else if (newValue instanceof VLong ) {
346+ // XXX: Channel access does not support 64 bit integers
347+ // If fits 32 bits, use int. Use double otherwise
348+ long value64 = ((VLong ) newValue ).getValue ();
349+ int value32 = (int ) value64 ;
350+ if (value32 == value64 ) {
351+ channel .put (value32 );
352+ } else {
353+ channel .put ((double ) value64 );
354+ }
355+ } else if (newValue instanceof VFloat ) {
356+ channel .put (((VFloat ) newValue ).getValue ());
357+ } else if (newValue instanceof VDouble ) {
358+ channel .put (((VDouble ) newValue ).getValue ());
359+ } else {
360+ // callback.channelWritten(new Exception(new RuntimeException("Unsupported type
361+ // for CA: " + newValue.getClass())));
362+ return ;
363+ }
364+ caDataSource .getContext ().flushIO ();
365+ } catch (Exception e ) {
366+ throw new RuntimeException (e );
367+ }
368+ }
369+
370+ @ Override
371+ protected void processWriteRequest (WriteRequest <?> request ) {
372+ try {
373+ write (request .getValue ());
374+ request .writeSuccessful ();
375+ } catch (Exception ex ) {
376+ request .writeFailed (ex );
377+ }
378+ }
379+
268380 protected int countFor (Channel channel ) {
269381 if (channel .getElementCount () == 1 )
270382 return 1 ;
0 commit comments