diff options
Diffstat (limited to 'src/Term.vala')
-rw-r--r-- | src/Term.vala | 192 |
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); + } + } } |