/
OtpConverter.java
127 lines (109 loc) · 3.25 KB
/
OtpConverter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**
* 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.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.EDouble;
import erjang.EInteger;
import erjang.EList;
import erjang.ERT;
import erjang.EString;
import erjang.ETerm;
import erjang.ETuple;
abstract class Converter<T> {
abstract ETerm 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<Class, 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>() {
ETerm conv(OtpErlangTuple obj) {
ETerm[] vals = new ETerm[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
ETerm conv(OtpErlangList obj) {
ETerm tail = obj.getLastTail() == null ? EList.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>() {
ETerm conv(OtpErlangAtom obj) {
return EAtom.intern(obj.atomValue());
}
});
add(OtpErlangLong.class, new Converter<OtpErlangLong>() {
ETerm conv(OtpErlangLong obj) {
return EInteger.parseInt(obj.toString());
}
});
add(OtpErlangString.class, new Converter<OtpErlangString>() {
ETerm conv(OtpErlangString obj) {
return new EString(obj.stringValue());
}
});
add(OtpErlangDouble.class, new Converter<OtpErlangDouble>() {
ETerm conv(OtpErlangDouble obj) {
return new EDouble(obj.doubleValue());
}
});
add(OtpErlangBinary.class, new Converter<OtpErlangBinary>() {
ETerm conv(OtpErlangBinary obj) {
return new EBinary(obj.binaryValue());
}
});
}
public static ETerm convert(OtpErlangObject value) {
Class<? extends OtpErlangObject> c = value.getClass();
Converter cc = conv.get(c);
if (cc == null) {
throw new Error("cannot convert " + c);
} else {
return cc.conv(value);
}
}
}