summaryrefslogtreecommitdiffstats
path: root/src/Term.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/Term.vala')
-rw-r--r--src/Term.vala192
1 files changed, 188 insertions, 4 deletions
diff --git a/src/Term.vala b/src/Term.vala
index 2a9cca8..3a75931 100644
--- a/src/Term.vala
+++ b/src/Term.vala
@@ -3,12 +3,90 @@ namespace Eva {
public abstract string to_string();
public abstract void encode(Erl.Buffer buffer);
+
+ public static Term decode(void *buffer) {
+ int index = 0;
+ int version;
+
+ Erl.decode_version(buffer, ref index, out version);
+
+ return do_decode(buffer, ref index);
+ }
+
+ private static Term do_decode(void *buffer, ref int index) {
+ int type, size;
+ assert(Erl.get_type(buffer, ref index, out type, out size) == 0);
+
+ switch(type) {
+ case Erl.TermType.SMALL_INTEGER:
+ char value;
+ assert(Erl.decode_char(buffer, ref index, out value) == 0);
+ return new Int((uchar)value);
+
+ case Erl.TermType.INTEGER:
+ long value;
+ assert(Erl.decode_long(buffer, ref index, out value) == 0);
+ return new Int(value);
+
+ case Erl.TermType.FLOAT:
+ double value;
+ assert(Erl.decode_double(buffer, ref index, out value) == 0);
+ return new Double(value);
+
+ case Erl.TermType.ATOM:
+ char[] value = new char[size+1];
+ assert(Erl.decode_atom(buffer, ref index, value) == 0);
+ return new Atom(((string)value).ndup(size));
+
+ case Erl.TermType.SMALL_TUPLE:
+ case Erl.TermType.LARGE_TUPLE:
+ assert(Erl.decode_tuple_header(buffer, ref index, out size) == 0);
+ Tuple term = new Tuple();
+
+ for(int i = 0; i < size; ++i) {
+ term.value.add(do_decode(buffer, ref index));
+ }
+
+ return term;
+
+ case Erl.TermType.NIL:
+ 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;
+
+ for(int i = 0; i < size; ++i) {
+ term.value.add(do_decode(buffer, ref index));
+ }
+ }
+
+ return term;
+
+ case Erl.TermType.STRING:
+ char[] value = new char[size+1];
+ assert(Erl.decode_string(buffer, ref index, value) == 0);
+ return new String(((string)value).ndup(size));
+
+ 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);
+
+ default:
+ assert_not_reached();
+ }
+ }
}
- public class Long : Object, Term {
+ public class Int : Object, Term {
public long value {get; construct;}
- public Long(long v) {
+ public Int(long v) {
Object(value: v);
}
@@ -21,10 +99,10 @@ namespace Eva {
}
}
- public class ULong : Object, Term {
+ public class UInt : Object, Term {
public ulong value {get; construct;}
- public ULong(ulong v) {
+ public UInt(ulong v) {
Object(value: v);
}
@@ -68,4 +146,110 @@ namespace Eva {
buffer.encode_atom(value.to_utf8());
}
}
+
+ public class Tuple : Object, Term {
+ public Gee.List<Term?> value {get; construct;}
+
+ public Tuple() {
+ Gee.List<Term?> list = new Gee.ArrayList<Term?>();
+ Object(value: list);
+ }
+
+ public string to_string() {
+ string ret = "{";
+ bool first = true;
+
+ foreach(Term term in value) {
+ if(first) {
+ first = false;
+ ret += term.to_string();
+ }
+ else {
+ ret += "," + term.to_string();
+ }
+ }
+
+ return ret + "}";
+ }
+
+ public void encode(Erl.Buffer buffer) {
+ buffer.encode_tuple_header(value.size);
+
+ foreach(Term term in value) {
+ term.encode(buffer);
+ }
+ }
+ }
+
+ public class List : Object, Term {
+ public Gee.List<Term?> value {get; construct;}
+
+ public List() {
+ Gee.List<Term?> list = new Gee.LinkedList<Term?>();
+ Object(value: list);
+ }
+
+ public string to_string() {
+ string ret = "[";
+ bool first = true;
+
+ foreach(Term term in value) {
+ if(first) {
+ first = false;
+ ret += term.to_string();
+ }
+ else {
+ ret += "," + term.to_string();
+ }
+ }
+
+ return ret + "]";
+ }
+
+ public void encode(Erl.Buffer buffer) {
+ if(!value.is_empty) {
+ buffer.encode_list_header(value.size);
+
+ foreach(Term term in value) {
+ term.encode(buffer);
+ }
+ }
+
+ buffer.encode_empty_list();
+ }
+ }
+
+ public class String : Object, Term {
+ public string value {get; construct;}
+
+ public String(string v) {
+ Object(value: v);
+ }
+
+ public string to_string() {
+ return value.to_string();
+ }
+
+ public void encode(Erl.Buffer buffer) {
+ buffer.encode_string(value.to_utf8());
+ }
+ }
+
+ public class Binary : Object, Term {
+ public void* value {get; private set;}
+ public long len {get; private set;}
+
+ public Binary(char[] v) {
+ value = Memory.dup(v, (uint)(sizeof(char)*v.length));
+ len = v.length;
+ }
+
+ public string to_string() {
+ return "[[Binary]]";
+ }
+
+ public void encode(Erl.Buffer buffer) {
+ buffer.encode_binary((char*)value, len);
+ }
+ }
}