summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Term.vala172
-rw-r--r--test/Test.vala2
2 files changed, 158 insertions, 16 deletions
diff --git a/src/Term.vala b/src/Term.vala
index 3a75931..a32ea1f 100644
--- a/src/Term.vala
+++ b/src/Term.vala
@@ -53,14 +53,13 @@ namespace Eva {
case Erl.TermType.LIST:
List term = new List();
- while(true) {
- assert(Erl.decode_list_header(buffer, ref index, out size) == 0);
- if(size == 0)
- break;
-
+ assert(Erl.decode_list_header(buffer, ref index, out size) == 0);
+ if(size != 0) {
for(int i = 0; i < size; ++i) {
- term.value.add(do_decode(buffer, ref index));
+ term.list.add(do_decode(buffer, ref index));
}
+
+ term.tail = do_decode(buffer, ref index);
}
return term;
@@ -72,11 +71,26 @@ namespace Eva {
case Erl.TermType.BINARY:
char[] value = new char[size];
- stdout.printf("Size: %i\n", size);
long l;
assert(Erl.decode_binary(buffer, ref index, value, out l) == 0);
return new Binary(value);
+ case Erl.TermType.PID:
+ Erl.Pid value;
+ assert(Erl.decode_pid(buffer, ref index, out value) == 0);
+ return new Pid(value);
+
+ case Erl.TermType.PORT:
+ Erl.Port value;
+ assert(Erl.decode_port(buffer, ref index, out value) == 0);
+ return new Port(value);
+
+ case Erl.TermType.REFERENCE:
+ case Erl.TermType.NEW_REFERENCE:
+ Erl.Ref value;
+ assert(Erl.decode_ref(buffer, ref index, out value) == 0);
+ return new Ref(value);
+
default:
assert_not_reached();
}
@@ -182,18 +196,37 @@ namespace Eva {
}
public class List : Object, Term {
- public Gee.List<Term?> value {get; construct;}
+ private Term? _tail;
+
+ public Gee.List<Term?> list {get; construct;}
+ public Term? tail {
+ get {
+ return _tail;
+ }
+ set {
+ if(value is List) {
+ List l = value as List;
+
+ list.add_all(l.list);
+ _tail = l._tail;
+ }
+ else {
+ _tail = value;
+ }
+ }
+ }
public List() {
- Gee.List<Term?> list = new Gee.LinkedList<Term?>();
- Object(value: list);
+ Gee.List<Term?> list0 = new Gee.LinkedList<Term?>();
+ Object(list: list0);
+ tail = null;
}
public string to_string() {
string ret = "[";
bool first = true;
- foreach(Term term in value) {
+ foreach(Term term in list) {
if(first) {
first = false;
ret += term.to_string();
@@ -203,14 +236,17 @@ namespace Eva {
}
}
+ if(tail != null)
+ ret += "|" + tail.to_string();
+
return ret + "]";
}
public void encode(Erl.Buffer buffer) {
- if(!value.is_empty) {
- buffer.encode_list_header(value.size);
+ if(!list.is_empty) {
+ buffer.encode_list_header(list.size);
- foreach(Term term in value) {
+ foreach(Term term in list) {
term.encode(buffer);
}
}
@@ -245,11 +281,117 @@ namespace Eva {
}
public string to_string() {
- return "[[Binary]]";
+ return "#Bin";
}
public void encode(Erl.Buffer buffer) {
buffer.encode_binary((char*)value, len);
}
}
+
+ public class Pid : Object, Term {
+ public string node {get; construct;}
+ public uint num {get; construct;}
+ public uint serial {get; construct;}
+ public uint creation {get; construct;}
+
+ public Pid(Erl.Pid pid) {
+ this.create(((string)pid.node).ndup(Erl.MAXATOMLEN), pid.num, pid.serial, pid.creation);
+ }
+
+ private Pid.create(string node0, uint num0, uint serial0, uint creation0) {
+ Object(node: node0, num: num0, serial: serial0, creation: creation0);
+ }
+
+ public string to_string() {
+ return "<" + node + "." + num.to_string() + "." + serial.to_string() + ">";
+ }
+
+ public void encode(Erl.Buffer buffer) {
+ Erl.Pid pid = Erl.Pid();
+ char[] nodedata = node.to_utf8();
+
+ Memory.copy(pid.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length));
+ pid.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0;
+
+ pid.num = num;
+ pid.serial = serial;
+ pid.creation = creation;
+
+ buffer.encode_pid(pid);
+ }
+ }
+
+ public class Port : Object, Term {
+ public string node {get; construct;}
+ public uint id {get; construct;}
+ public uint creation {get; construct;}
+
+ public Port(Erl.Port port) {
+ this.create(((string)port.node).ndup(Erl.MAXATOMLEN), port.id, port.creation);
+ }
+
+ private Port.create(string node0, uint id0, uint creation0) {
+ Object(node: node0, id: id0, creation: creation0);
+ }
+
+ public string to_string() {
+ return "#Port";
+ }
+
+ public void encode(Erl.Buffer buffer) {
+ Erl.Port port = Erl.Port();
+ char[] nodedata = node.to_utf8();
+
+ Memory.copy(port.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length));
+ port.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0;
+
+ port.id = id;
+ port.creation = creation;
+
+ buffer.encode_port(port);
+ }
+ }
+
+ public class Ref : Object, Term {
+ public string node {get; construct;}
+ public int len {get; construct;}
+ public uint[] n {get; private set;}
+ public uint creation {get; construct;}
+
+ public Ref(Erl.Ref reference) {
+ this.create(((string)reference.node).ndup(Erl.MAXATOMLEN), reference.len, reference.n, reference.creation);
+ }
+
+ private Ref.create(string node0, int len0, uint* n0, uint creation0) {
+ Object(node: node0, len: len0, creation: creation0);
+
+ n = new uint[len];
+ for(int i = 0; i < len; ++i) {
+ n[i] = n0[i];
+ }
+ }
+
+ public string to_string() {
+ return "#Ref";
+ }
+
+ public void encode(Erl.Buffer buffer) {
+ Erl.Ref reference = Erl.Ref();
+ char[] nodedata = node.to_utf8();
+
+ Memory.copy(reference.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length));
+ reference.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0;
+
+ reference.len = len;
+
+ for(int i = 0; i < len; ++i) {
+ reference.n[i] = n[i];
+ }
+
+ reference.creation = creation;
+
+ buffer.encode_ref(reference);
+ }
+ }
}
diff --git a/test/Test.vala b/test/Test.vala
index 5d71095..86907ea 100644
--- a/test/Test.vala
+++ b/test/Test.vala
@@ -4,7 +4,7 @@ namespace Eva {
MainLoop main = new MainLoop();
Eva.PacketHandler handler = new Eva.PacketHandler(new UnixInputStream(3, true), new UnixOutputStream(4, true), 4);
- handler.received_term.connect((term) => {stdout.printf("%s\n", term.to_string()); handler.send(term); main.quit();});
+ handler.received_term.connect((term) => {stdout.printf("Received term %s\n", term.to_string()); handler.send(term); main.quit();});
handler.start();
main.run();