/**
* This file is part of Erjang - A JVM-based Erlang VM
*
* Copyright (c) 2009 by Trifork
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package erjang.beam;
import java.util.HashMap;
import java.util.Map;
import com.ericsson.otp.erlang.OtpErlangAtom;
import com.ericsson.otp.erlang.OtpErlangBinary;
import com.ericsson.otp.erlang.OtpErlangBitstr;
import com.ericsson.otp.erlang.OtpErlangDouble;
import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangLong;
import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangString;
import com.ericsson.otp.erlang.OtpErlangTuple;
import erjang.EAtom;
import erjang.EBinary;
import erjang.EBitString;
import erjang.EObject;
import erjang.ERT;
import erjang.EString;
import erjang.ETuple;
abstract class Converter<T> {
abstract EObject conv(T obj);
}
/**
* Convert terms to/from jinterface's classes.
*
* Until I rewrite jinterface, this will have to do.
*
* @author krab
*/
public class OtpConverter {
static Map<? super Class<?>, ? super Converter<?>> conv = new HashMap<Class, Converter>();
static <T> void add(Class<T> c, Converter<T> co) {
conv.put(c, co);
}
static {
add(OtpErlangTuple.class, new Converter<OtpErlangTuple>() {
EObject conv(OtpErlangTuple obj) {
EObject[] vals = new EObject[obj.arity()];
for (int i = 0; i < obj.arity(); i++) {
vals[i] = convert(obj.elementAt(i));
}
return ETuple.make(vals);
}
});
add(OtpErlangList.class, new Converter<OtpErlangList>() {
@Override
EObject conv(OtpErlangList obj) {
EObject tail = obj.getLastTail() == null ? ERT.NIL
: convert(obj.getLastTail());
for (int i = obj.arity() - 1; i >= 0; i--) {
tail = ERT.cons(convert(obj.elementAt(i)), tail);
}
return tail;
}
});
add(OtpErlangAtom.class, new Converter<OtpErlangAtom>() {
EObject conv(OtpErlangAtom obj) {
return EAtom.intern(obj.atomValue());
}
});
add(OtpErlangLong.class, new Converter<OtpErlangLong>() {
EObject conv(OtpErlangLong obj) {
return (obj.isLong())
? ERT.box(obj.longValue())
: ERT.box(obj.bigIntegerValue());
}
});
add(OtpErlangString.class, new Converter<OtpErlangString>() {
EObject conv(OtpErlangString obj) {
return new EString(obj.stringValue());
}
});
add(OtpErlangDouble.class, new Converter<OtpErlangDouble>() {
EObject conv(OtpErlangDouble obj) {
return ERT.box(obj.doubleValue());
}
});
add(OtpErlangBinary.class, new Converter<OtpErlangBinary>() {
EObject conv(OtpErlangBinary obj) {
return new EBinary(obj.binaryValue());
}
});
add(OtpErlangBitstr.class, new Converter<OtpErlangBitstr>() {
EObject conv(OtpErlangBitstr obj) {
return EBitString.make(obj.binaryValue(), 0, obj.size(), obj.pad_bits() );
}
});
}
public static EObject convert(OtpErlangObject value) {
Class<? extends OtpErlangObject> c = value.getClass();
Converter<OtpErlangObject> cc = (Converter<OtpErlangObject>) conv.get(c);
if (cc == null) {
throw new Error("cannot convert " + c);
} else {
return cc.conv(value);
}
}
}