1 package org.simantics.r.scl.variable;
\r
3 import org.rosuda.REngine.REXP;
\r
4 import org.rosuda.REngine.REXPDouble;
\r
5 import org.rosuda.REngine.REXPFactor;
\r
6 import org.rosuda.REngine.REXPGenericVector;
\r
7 import org.rosuda.REngine.REXPInteger;
\r
8 import org.rosuda.REngine.REXPList;
\r
9 import org.rosuda.REngine.REXPLogical;
\r
10 import org.rosuda.REngine.REXPMismatchException;
\r
11 import org.rosuda.REngine.REXPNull;
\r
12 import org.rosuda.REngine.REXPRaw;
\r
13 import org.rosuda.REngine.REXPReference;
\r
14 import org.rosuda.REngine.REXPS4;
\r
15 import org.rosuda.REngine.REXPString;
\r
16 import org.rosuda.REngine.REXPSymbol;
\r
17 import org.rosuda.REngine.RList;
\r
18 import org.simantics.databoard.Bindings;
\r
19 import org.simantics.databoard.Datatypes;
\r
20 import org.simantics.databoard.binding.ArrayBinding;
\r
21 import org.simantics.databoard.binding.Binding;
\r
22 import org.simantics.databoard.binding.BooleanBinding;
\r
23 import org.simantics.databoard.binding.ByteBinding;
\r
24 import org.simantics.databoard.binding.DoubleBinding;
\r
25 import org.simantics.databoard.binding.IntegerBinding;
\r
26 import org.simantics.databoard.binding.NumberBinding;
\r
27 import org.simantics.databoard.binding.StringBinding;
\r
28 import org.simantics.databoard.binding.VariantBinding;
\r
29 import org.simantics.databoard.binding.error.BindingException;
\r
30 import org.simantics.databoard.binding.impl.BooleanArrayBinding;
\r
31 import org.simantics.databoard.binding.impl.ByteArrayBinding;
\r
32 import org.simantics.databoard.binding.impl.DoubleArrayBinding;
\r
33 import org.simantics.databoard.binding.impl.IntArrayBinding;
\r
34 import org.simantics.databoard.binding.impl.StringArrayBinding;
\r
35 import org.simantics.databoard.type.Datatype;
\r
37 public class RDataboardConversion {
\r
38 public static Datatype getDatatype(REXP rexp) throws BindingException {
\r
39 if (rexp == null) return Datatypes.VOID;
\r
41 if(rexp instanceof REXPDouble)
\r
42 return Datatypes.DOUBLE_ARRAY;
\r
43 else if(rexp instanceof REXPInteger)
\r
44 return Datatypes.INTEGER_ARRAY;
\r
45 else if(rexp instanceof REXPString)
\r
46 return Datatypes.STRING_ARRAY;
\r
47 else if(rexp instanceof REXPLogical)
\r
48 return Datatypes.BOOLEAN_ARRAY;
\r
49 else if(rexp instanceof REXPSymbol)
\r
50 return Datatypes.STRING;
\r
51 else if(rexp instanceof REXPFactor)
\r
52 return Datatypes.STRING_ARRAY;
\r
53 else if(rexp instanceof REXPRaw)
\r
54 return Datatypes.BYTE_ARRAY;
\r
55 else if(rexp instanceof REXPReference)
\r
56 return getDatatype(((REXPReference)rexp).resolve());
\r
57 else if(rexp instanceof REXPList || rexp instanceof REXPNull || rexp instanceof REXPGenericVector)
\r
58 return Datatypes.VARIANT_ARRAY;
\r
59 else if(rexp instanceof REXPS4)
\r
60 return Datatypes.VARIANT;
\r
62 throw new BindingException("Cannot handle REXP of type " + rexp != null ? (rexp.getClass().getSimpleName() + ".") : "null");
\r
65 public static Object fromREXP(REXP value, Binding binding) throws BindingException {
\r
67 return binding.createDefault();
\r
70 if(binding instanceof DoubleBinding)
\r
71 return ((DoubleBinding)binding).create(value.asDouble());
\r
72 else if(binding instanceof IntegerBinding)
\r
73 return ((IntegerBinding)binding).create(value.asInteger());
\r
74 else if(binding instanceof ByteBinding)
\r
75 return ((ByteBinding)binding).create(value.asInteger());
\r
76 else if(binding instanceof StringBinding)
\r
77 return ((StringBinding)binding).create(value.asString());
\r
78 else if(binding instanceof NumberBinding)
\r
79 return ((NumberBinding)binding).create(value.asDouble());
\r
80 else if(binding instanceof BooleanBinding)
\r
81 return ((BooleanBinding)binding).create(value.asInteger() == 1);
\r
82 else if(binding instanceof VariantBinding) {
\r
83 Datatype dt = getDatatype(value);
\r
85 if (dt == Datatypes.VARIANT)
\r
86 return ((VariantBinding) binding).create(Bindings.OBJECT, value);
\r
88 Binding bd = Bindings.getBinding(dt);
\r
90 return ((VariantBinding)binding).create(bd, fromREXP(value, bd));
\r
95 else if(binding instanceof ArrayBinding) {
\r
96 if(binding instanceof DoubleArrayBinding)
\r
97 return value.asDoubles();
\r
98 else if(binding instanceof ByteArrayBinding)
\r
99 return value.asBytes();
\r
100 else if(binding instanceof IntArrayBinding)
\r
101 return value.asIntegers();
\r
102 else if(binding instanceof StringArrayBinding)
\r
103 return value.asStrings();
\r
104 else if(binding instanceof BooleanArrayBinding) {
\r
105 int[] values = value.asIntegers();
\r
106 boolean[] result = new boolean[values.length];
\r
107 for (int i = 0; i < values.length; i++)
\r
108 result[i] = values[i] == 1;
\r
112 ArrayBinding arrayBinding = (ArrayBinding)binding;
\r
113 if(arrayBinding.componentBinding instanceof DoubleBinding) {
\r
114 DoubleBinding componentBinding = (DoubleBinding)arrayBinding.componentBinding;
\r
115 double[] vs = value.asDoubles();
\r
116 Object[] components = new Object[vs.length];
\r
117 for(int i=0;i<vs.length;++i)
\r
118 components[i] = componentBinding.create(vs[i]);
\r
119 return arrayBinding.create(components);
\r
121 else if(arrayBinding.componentBinding instanceof IntegerBinding) {
\r
122 IntegerBinding componentBinding = (IntegerBinding)arrayBinding.componentBinding;
\r
123 int[] vs = value.asIntegers();
\r
124 Object[] components = new Object[vs.length];
\r
125 for(int i=0;i<vs.length;++i)
\r
126 components[i] = componentBinding.create(vs[i]);
\r
127 return arrayBinding.create(components);
\r
129 else if(arrayBinding.componentBinding instanceof StringBinding) {
\r
130 StringBinding componentBinding = (StringBinding)arrayBinding.componentBinding;
\r
131 String[] vs = value.asStrings();
\r
132 Object[] components = new Object[vs.length];
\r
133 for(int i=0;i<vs.length;++i)
\r
134 components[i] = componentBinding.create(vs[i]);
\r
135 return arrayBinding.create(components);
\r
137 else if(arrayBinding.componentBinding instanceof NumberBinding) {
\r
138 NumberBinding componentBinding = (NumberBinding)arrayBinding.componentBinding;
\r
139 double[] vs = value.asDoubles();
\r
140 Object[] components = new Object[vs.length];
\r
141 for(int i=0;i<vs.length;++i)
\r
142 components[i] = componentBinding.create(vs[i]);
\r
143 return arrayBinding.create(components);
\r
145 else if(arrayBinding.componentBinding instanceof VariantBinding) {
\r
146 if (value instanceof REXPNull || value.length() == 0)
\r
147 return arrayBinding.create();
\r
149 VariantBinding componentBinding = (VariantBinding)arrayBinding.componentBinding;
\r
150 Object[] components = new Object[value.length()];
\r
151 if (value.isInteger()) {
\r
152 int[] vs = value.asIntegers();
\r
153 for (int i=0; i<vs.length; i++)
\r
154 components[i] = componentBinding.create(Bindings.INTEGER, vs[i]);
\r
156 else if (value.isNumeric()) {
\r
157 double[] vs = value.asDoubles();
\r
158 for (int i=0; i<vs.length; i++)
\r
159 components[i] = componentBinding.create(Bindings.DOUBLE, vs[i]);
\r
161 else if (value.isString()) {
\r
162 String[] vs = value.asStrings();
\r
163 for (int i=0; i<vs.length; i++)
\r
164 components[i] = componentBinding.create(Bindings.STRING, vs[i]);
\r
166 else if (value.isList()) {
\r
167 RList vs = value.asList();
\r
168 for (int i=0; i<vs.size(); i++)
\r
169 components[i] = fromREXP(vs.at(i), componentBinding);
\r
171 return arrayBinding.create(components);
\r
173 //TODO: Other bindings
\r
176 throw new BindingException("Couldn't handle binding " + binding + ".");
\r
177 } catch(REXPMismatchException e) {
\r
178 throw new BindingException(e);
\r
182 public static REXP toREXP(Object value, Binding binding) throws BindingException {
\r
183 if(binding instanceof DoubleBinding)
\r
184 return new REXPDouble(((DoubleBinding)binding).getValue_(value));
\r
185 else if(binding instanceof IntegerBinding)
\r
186 return new REXPInteger(((IntegerBinding)binding).getValue_(value));
\r
187 else if(binding instanceof StringBinding)
\r
188 return new REXPString(((StringBinding)binding).getValue(value));
\r
189 else if(binding instanceof NumberBinding)
\r
190 return new REXPDouble(((NumberBinding)binding).getValue(value).doubleValue());
\r
191 else if(binding instanceof ArrayBinding) {
\r
192 if(binding instanceof DoubleArrayBinding)
\r
193 return new REXPDouble((double[])value);
\r
194 else if(binding instanceof IntArrayBinding)
\r
195 return new REXPInteger((int[])value);
\r
196 else if(binding instanceof StringArrayBinding)
\r
197 return new REXPString((String[])value);
\r
198 ArrayBinding arrayBinding = (ArrayBinding)binding;
\r
199 if(arrayBinding.componentBinding instanceof DoubleBinding) {
\r
200 DoubleBinding componentBinding = (DoubleBinding)arrayBinding.componentBinding;
\r
201 double[] vs = new double[arrayBinding.size(value)];
\r
202 for(int i=0;i<vs.length;++i)
\r
203 vs[i] = componentBinding.getValue_(arrayBinding.get(value, i));
\r
204 return new REXPDouble(vs);
\r
206 if(arrayBinding.componentBinding instanceof IntegerBinding) {
\r
207 IntegerBinding componentBinding = (IntegerBinding)arrayBinding.componentBinding;
\r
208 int[] vs = new int[arrayBinding.size(value)];
\r
209 for(int i=0;i<vs.length;++i)
\r
210 vs[i] = componentBinding.getValue_(arrayBinding.get(value, i));
\r
211 return new REXPInteger(vs);
\r
213 if(arrayBinding.componentBinding instanceof StringBinding) {
\r
214 StringBinding componentBinding = (StringBinding)arrayBinding.componentBinding;
\r
215 String[] vs = new String[arrayBinding.size(value)];
\r
216 for(int i=0;i<vs.length;++i)
\r
217 vs[i] = componentBinding.getValue(arrayBinding.get(value, i));
\r
218 return new REXPString(vs);
\r
220 if(arrayBinding.componentBinding instanceof NumberBinding) {
\r
221 NumberBinding componentBinding = (NumberBinding)arrayBinding.componentBinding;
\r
222 double[] vs = new double[arrayBinding.size(value)];
\r
223 for(int i=0;i<vs.length;++i)
\r
224 vs[i] = componentBinding.getValue(arrayBinding.get(value, i)).doubleValue();
\r
225 return new REXPDouble(vs);
\r
229 throw new BindingException("Couldn't handle binding " + binding + ".");
\r