]> gerrit.simantics Code Review - simantics/r.git/blob - org.simantics.r.scl/src/org/rosuda/REngine/REXPWrapper.java
(refs #6833) Test RExp inheritance in SCL
[simantics/r.git] / org.simantics.r.scl / src / org / rosuda / REngine / REXPWrapper.java
1 package org.rosuda.REngine ;
2
3 /**
4  * Utility class to wrap an Object into a REXP object. 
5  *
6  * This facilitates wrapping native java objects and arrays 
7  * into REXP objects that can be pushed to R
8  *
9  * @author Romain Francois <francoisromain@free.fr>
10  */
11 public class REXPWrapper {
12
13         /* various classes */
14         private static Class byte_ARRAY ;
15         private static Class short_ARRAY ;
16         private static Class int_ARRAY ;
17         private static Class long_ARRAY ;
18         private static Class float_ARRAY ;
19         private static Class double_ARRAY ;
20         private static Class boolean_ARRAY ;
21         
22         private static Class String_ARRAY ;
23         
24         private static Class Byte_ARRAY ;
25         private static Class Short_ARRAY;
26         private static Class Integer_ARRAY ;
27         private static Class Long_ARRAY ;
28         private static Class Float_ARRAY ;
29         private static Class Double_ARRAY ;
30         private static Class Boolean_ARRAY ;
31                 
32         static{
33                 try{
34                         byte_ARRAY     = Class.forName("[B") ;
35                         short_ARRAY    = Class.forName("[S" ); 
36                         int_ARRAY      = Class.forName("[I" ); 
37                         long_ARRAY     = (new long[1]).getClass() ; /* FIXME */
38                         float_ARRAY    = Class.forName("[F" ) ;
39                         double_ARRAY   = Class.forName("[D" );
40                         boolean_ARRAY  = Class.forName("[Z" ) ;
41                         
42                         String_ARRAY   = Class.forName( "[Ljava.lang.String;") ;
43                         
44                         Byte_ARRAY     = Class.forName( "[Ljava.lang.Byte;" ) ;
45                         Short_ARRAY    = Class.forName( "[Ljava.lang.Short;" ) ;
46                         Integer_ARRAY  = Class.forName( "[Ljava.lang.Integer;" ) ;
47                         Long_ARRAY     = Class.forName( "[Ljava.lang.Long;" ) ;
48                         Float_ARRAY    = Class.forName( "[Ljava.lang.Float;" ) ;
49                         Double_ARRAY   = Class.forName( "[Ljava.lang.Double;" ) ;
50                         Boolean_ARRAY  = Class.forName( "[Ljava.lang.Boolean;" ) ;
51                         
52                         
53                 } catch( Exception e){
54                         // should never happen
55                         e.printStackTrace(); 
56                         System.err.println( "problem while initiating the classes" ) ;
57                 }
58         }
59         
60         /**
61          * Wraps an Object into a REXP
62          *
63          * <p>Conversion :</p>
64          *
65          * <ul>
66          * <li>Byte (byte) : REXPRaw </li>
67          * <li>Short (short) : REXPInteger </li>
68          * <li>Integer (int) : REXPInteger </li>
69          * <li>Long (long) : REXPInteger</li>
70          * <li>Float (float) : REXPDouble</li>
71          * <li>Double (double) : REXPDouble </li>
72          * <li>Boolean (boolean) : REXPLogical</li>
73          * <li>--</li>
74          * <li>String : REXPString </li>
75          * <li>String[] : REXPString </li>
76          * <li>--</li>
77          * <li>byte[] or Byte[] : REXPRaw</li>
78          * <li>short[] or Short[] : REXPInteger</li>
79          * <li>int[] or Integer[] : REXPInteger</li>
80          * <li>long[] or Long[] : REXPInteger</li>
81          * <li>float[] or Float[] : REXPDouble</li>
82          * <li>double[] or Double[] : REXPDouble </li>
83          * <li>boolean[] or Boolean[]: REXPLogical</li>
84          * <li>--</li>
85          * <li>null for anything else</li>
86          * </ul>
87          * 
88          * @param o object to wrap
89          * @return REXP object that represents o or null if the conversion is not possible
90          */
91         public static REXP wrap( Object o ) {
92                 
93                 /* nothing to do in that case */
94                 if( o instanceof REXP){
95                         return (REXP)o; 
96                 } 
97                 
98                 Class clazz = o.getClass() ;
99                 
100                 /* primitives */
101                 
102                 if( clazz == Byte.class ){
103                         byte[] load = new byte[1]; 
104                         load[0] = ((Byte)o).byteValue() ;
105                         return new REXPRaw( load ); 
106                 } 
107                 
108                 if( clazz == Short.class ){
109                         return new REXPInteger( ((Short)o).intValue() ) ;
110                 } 
111                 
112                 if( clazz == Integer.class ){
113                         return new REXPInteger( ((Integer)o).intValue() ) ;
114                 } 
115                 
116                 if( clazz == Long.class ){
117                         return new REXPInteger( ((Long)o).intValue() ) ;
118                 } 
119                 
120                 if( clazz == Float.class ){
121                         return new REXPDouble( ((Float)o).doubleValue() ) ;
122                 }
123                 
124                 if( clazz == Double.class ){
125                         return new REXPDouble( ((Double)o).doubleValue() ) ;
126                 }
127                 
128                 if( clazz == Boolean.class ){
129                         return new REXPLogical( ((Boolean)o).booleanValue() ) ;
130                 }
131                 
132                 
133                 /* Strings -> REXPString */
134                 
135                 if( clazz == String.class ){
136                         return new REXPString( (String)o ) ;
137                 } 
138                 
139                 if( clazz == String_ARRAY ){ /* String[] */
140                         return new REXPString( (String[])o ); 
141                 } 
142                 
143                 /* array of byte or Bytes -> REXPRaw */
144                 
145                 if( clazz == byte_ARRAY ){ /* byte[] */
146                         return new REXPRaw( (byte[])o ) ; 
147                 } 
148                 
149                 if( clazz == Byte_ARRAY ){ /* Byte[] */
150                         Byte[] b = (Byte[])o;
151                         int n = b.length ;
152                         byte[] bytes = new byte[b.length];
153                         for( int i=0; i<n; i++){
154                                 bytes[i] = b[i].byteValue() ;
155                         }
156                         return new REXPRaw( bytes ); 
157                 }
158                 
159                 /* arrays of short or Short  -> REXPInteger */ 
160                 
161                 if( clazz == short_ARRAY ){ /* short[] */
162                         short[] shorts = (short[])o ;
163                         int[] ints = new int[ shorts.length ];
164                         int n = ints.length; 
165                         for( int i=0; i<n; i++ ){
166                                 ints[i] = shorts[i]; 
167                         }
168                         return new REXPInteger( ints ) ;
169                 }
170                 
171                 if( clazz == Short_ARRAY ){ /* Short[] */
172                         Short[] shorts = (Short[])o;
173                         int n = shorts.length ;
174                         int[] ints = new int[shorts.length];
175                         for( int i=0; i<n; i++){
176                                 ints[i] = shorts[i].intValue() ;
177                         }
178                         return new REXPInteger( ints ); 
179                 } 
180                 
181                 
182                 /* arrays of int or Integer ->  REXPInteger */
183                 
184                 if( clazz == int_ARRAY ){ /* int[] */
185                         return new REXPInteger( (int[])o ) ; 
186                 } 
187                 
188                 if( clazz == Integer_ARRAY ){ /* Integer[] */
189                         Integer[] integers = (Integer[])o;
190                         int n = integers.length ;
191                         int[] ints = new int[integers.length];
192                         for( int i=0; i<n; i++){
193                                 ints[i] = integers[i].intValue() ;
194                         }
195                         return new REXPInteger( ints ); 
196                 } 
197                 
198                 /* arrays of long or Long -> REXPInteger */
199                 
200                 if( clazz == long_ARRAY ){ /* long[] */
201                         long[] longs = (long[])o;
202                         int n = longs.length ;
203                         int[] ints = new int[longs.length];
204                         for( int i=0; i<n; i++){
205                                 ints[i] = (int)longs[i] ;
206                         }
207                         return new REXPInteger( ints ); 
208                 } 
209                 
210                 if( clazz == Long_ARRAY ){ /* Long[] */
211                         Long[] longs = (Long[])o;
212                         int n = longs.length ;
213                         int[] ints = new int[longs.length];
214                         for( int i=0; i<n; i++){
215                                 ints[i] = longs[i].intValue() ;
216                         }
217                         return new REXPInteger( ints ); 
218                 } 
219                 
220                 /* float or Float arrays -> REXPDouble */
221                 
222                 if( clazz == float_ARRAY ){ /* float[] */
223                         float[] floats = (float[])o;
224                         int n = floats.length ;
225                         double[] doubles = new double[floats.length];
226                         for( int i=0; i<n; i++){
227                                 doubles[i] = (double)floats[i] ;
228                         }
229                         return new REXPDouble( doubles ); 
230                 } 
231                 
232                 if( clazz == Float_ARRAY ){ /* Float[] */
233                         Float[] floats = (Float[])o;
234                         int n = floats.length ;
235                         double[] doubles = new double[floats.length];
236                         for( int i=0; i<n; i++){
237                                 doubles[i] = floats[i].doubleValue() ;
238                         }
239                         return new REXPDouble( doubles ); 
240                 }
241                 
242                 
243                 /* double or Double arrays -> REXPDouble */
244                 
245                 if(clazz == double_ARRAY ) { /* double[] */
246                         return new REXPDouble( (double[])o ) ;
247                 }
248                 
249                 if( clazz == Double_ARRAY ){ /* Double[] */
250                         Double[] doubles = (Double[])o;
251                         double n = doubles.length ;
252                         double[] d = new double[doubles.length];
253                         for( int i=0; i<n; i++){
254                                 d[i] = doubles[i].doubleValue() ;
255                         }
256                         return new REXPDouble( d ); 
257                 } 
258                 
259                 
260                 /* boolean arrays -> REXPLogical */
261                 
262                 if( clazz == boolean_ARRAY ){ /* boolean[] */
263                         return new REXPLogical( (boolean[])o ) ; 
264                 } 
265                 
266                 if( clazz == Boolean_ARRAY ){ /* Boolean[] */
267                         Boolean[] booleans = (Boolean[])o;
268                         int n = booleans.length ;
269                         boolean[] b = new boolean[booleans.length];
270                         for( int i=0; i<n; i++){
271                                 b[i] = booleans[i].booleanValue() ;
272                         }
273                         return new REXPLogical( b ); 
274                 } 
275                 
276                 /* give up and return null */
277                 
278                 return null ; 
279         }
280         
281 }
282