/******************************************************************************* * Copyright (c) 2014, 2016 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.r.scl.variable; import org.rosuda.REngine.REXP; import org.rosuda.REngine.REXPDouble; import org.rosuda.REngine.REXPFactor; import org.rosuda.REngine.REXPGenericVector; import org.rosuda.REngine.REXPInteger; import org.rosuda.REngine.REXPList; import org.rosuda.REngine.REXPLogical; import org.rosuda.REngine.REXPMismatchException; import org.rosuda.REngine.REXPNull; import org.rosuda.REngine.REXPRaw; import org.rosuda.REngine.REXPReference; import org.rosuda.REngine.REXPS4; import org.rosuda.REngine.REXPString; import org.rosuda.REngine.REXPSymbol; import org.rosuda.REngine.RList; import org.simantics.databoard.Bindings; import org.simantics.databoard.Datatypes; import org.simantics.databoard.binding.ArrayBinding; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.BooleanBinding; import org.simantics.databoard.binding.ByteBinding; import org.simantics.databoard.binding.DoubleBinding; import org.simantics.databoard.binding.IntegerBinding; import org.simantics.databoard.binding.NumberBinding; import org.simantics.databoard.binding.StringBinding; import org.simantics.databoard.binding.VariantBinding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.binding.impl.BooleanArrayBinding; import org.simantics.databoard.binding.impl.ByteArrayBinding; import org.simantics.databoard.binding.impl.DoubleArrayBinding; import org.simantics.databoard.binding.impl.IntArrayBinding; import org.simantics.databoard.binding.impl.StringArrayBinding; import org.simantics.databoard.type.Datatype; public class RDataboardConversion { public static Datatype getDatatype(REXP rexp) throws BindingException { if (rexp == null) return Datatypes.VOID; if(rexp instanceof REXPDouble) return Datatypes.DOUBLE_ARRAY; else if(rexp instanceof REXPInteger) return Datatypes.INTEGER_ARRAY; else if(rexp instanceof REXPString) return Datatypes.STRING_ARRAY; else if(rexp instanceof REXPLogical) return Datatypes.BOOLEAN_ARRAY; else if(rexp instanceof REXPSymbol) return Datatypes.STRING; else if(rexp instanceof REXPFactor) return Datatypes.STRING_ARRAY; else if(rexp instanceof REXPRaw) return Datatypes.BYTE_ARRAY; else if(rexp instanceof REXPReference) return getDatatype(((REXPReference)rexp).resolve()); else if(rexp instanceof REXPList || rexp instanceof REXPNull || rexp instanceof REXPGenericVector) return Datatypes.VARIANT_ARRAY; else if(rexp instanceof REXPS4) return Datatypes.VARIANT; else throw new BindingException("Cannot handle REXP of type " + rexp != null ? (rexp.getClass().getSimpleName() + ".") : "null"); } public static Object fromREXP(REXP value, Binding binding) throws BindingException { if (value == null) return binding.createDefault(); try { if(binding instanceof DoubleBinding) return ((DoubleBinding)binding).create(value.asDouble()); else if(binding instanceof IntegerBinding) return ((IntegerBinding)binding).create(value.asInteger()); else if(binding instanceof ByteBinding) return ((ByteBinding)binding).create(value.asInteger()); else if(binding instanceof StringBinding) return ((StringBinding)binding).create(value.asString()); else if(binding instanceof NumberBinding) return ((NumberBinding)binding).create(value.asDouble()); else if(binding instanceof BooleanBinding) return ((BooleanBinding)binding).create(value.asInteger() == 1); else if(binding instanceof VariantBinding) { Datatype dt = getDatatype(value); if (dt != null) { if (dt == Datatypes.VARIANT) return ((VariantBinding) binding).create(Bindings.OBJECT, value); else { Binding bd = Bindings.getBinding(dt); if (bd != null) { return ((VariantBinding)binding).create(bd, fromREXP(value, bd)); } } } } else if(binding instanceof ArrayBinding) { if(binding instanceof DoubleArrayBinding) return value.asDoubles(); else if(binding instanceof ByteArrayBinding) return value.asBytes(); else if(binding instanceof IntArrayBinding) return value.asIntegers(); else if(binding instanceof StringArrayBinding) return value.asStrings(); else if(binding instanceof BooleanArrayBinding) { int[] values = value.asIntegers(); boolean[] result = new boolean[values.length]; for (int i = 0; i < values.length; i++) result[i] = values[i] == 1; return result; } ArrayBinding arrayBinding = (ArrayBinding)binding; if(arrayBinding.componentBinding instanceof DoubleBinding) { DoubleBinding componentBinding = (DoubleBinding)arrayBinding.componentBinding; double[] vs = value.asDoubles(); Object[] components = new Object[vs.length]; for(int i=0;i