summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2010-07-09 08:53:03 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2010-07-09 08:53:03 +0200
commit46c0f539112cd19628dc0305d3556111099a04da (patch)
treebe76abc7b3b402c635d09da39bbcdd6bdd750124
parent1b2562ed6503f3bb7c19514b5e9571c1fcb79360 (diff)
downloadeva-46c0f539112cd19628dc0305d3556111099a04da.tar
eva-46c0f539112cd19628dc0305d3556111099a04da.zip
Fixed unicode handling
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Term.vala68
-rw-r--r--src/Util.vala45
3 files changed, 100 insertions, 14 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index af9fafe..4e7f0b2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -5,6 +5,7 @@ link_directories(${GEE_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${ERL_LIBRARY_DIRS})
vala_precompile(EVA_C
PacketHandler.vala
Term.vala
+ Util.vala
PACKAGES
gee-1.0
gio-2.0
diff --git a/src/Term.vala b/src/Term.vala
index 7037e48..46c03b3 100644
--- a/src/Term.vala
+++ b/src/Term.vala
@@ -37,7 +37,7 @@ namespace Eva {
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));
+ return new Atom(array_to_string(value, size));
case Erl.TermType.SMALL_TUPLE:
case Erl.TermType.LARGE_TUPLE:
@@ -68,7 +68,7 @@ namespace Eva {
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));
+ return new String(array_to_string(value, size));
case Erl.TermType.BINARY:
char[] value = new char[size];
@@ -184,11 +184,33 @@ namespace Eva {
public string value {get; construct;}
public Atom(string v) {
+ assert(v.validate());
Object(value: v);
}
public string to_string() {
- return value.to_string();
+ if(value.length == 0)
+ return "''";
+
+ bool special = false;
+ unichar c = value.get_char();
+
+ if(!c.islower())
+ special = true;
+
+ for(unowned string rest = value.next_char(); rest.length != 0 && !special; rest = rest.next_char()) {
+ c = rest.get_char();
+
+ if(!(c == '_' || c.isalnum()))
+ special = true;
+ }
+
+ if(!special) {
+ return value;
+ }
+ else {
+ return "'" + value.replace("\\", "\\\\").replace("'", "\\'") + "'";
+ }
}
public bool equals(Term o) {
@@ -201,7 +223,9 @@ namespace Eva {
}
public void encode(Erl.Buffer buffer) {
- buffer.encode_atom(value.to_utf8());
+ char[]? array = string_to_array(value);
+ assert(array != null);
+ buffer.encode_atom(array);
}
}
@@ -312,23 +336,30 @@ namespace Eva {
string s = "";
foreach(Term t in list) {
+ unichar c;
+
if(t is Int) {
Int i = t as Int;
if(i.value < 0 || i.value > 255)
return false;
- s += i.value.to_string("%c");
+ c = (unichar)i.value;
}
else if(t is UInt) {
UInt i = t as UInt;
if(i.value > 255)
return false;
- s += i.value.to_string("%c");
+ c = (unichar)i.value;
}
else {
return false;
}
+
+ string buf = string.nfill(6, 0);
+ c.to_utf8(buf);
+
+ s += buf;
}
return (s == (o as String).value);
@@ -382,7 +413,7 @@ namespace Eva {
}
public string to_string() {
- return value.to_string();
+ return "\"" + value.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
}
public bool equals(Term o) {
@@ -398,7 +429,13 @@ namespace Eva {
}
public void encode(Erl.Buffer buffer) {
- buffer.encode_string(value.to_utf8());
+ char[]? array = string_to_array(value);
+ if(array != null) {
+ buffer.encode_string(array);
+ }
+ else {
+ string_to_list(value).encode(buffer);
+ }
}
}
@@ -442,7 +479,7 @@ namespace Eva {
public uint creation {get; construct;}
public Pid(Erl.Pid pid) {
- this.create(((string)pid.node).ndup(Erl.MAXATOMLEN), pid.num, pid.serial, pid.creation);
+ this.create(array_to_string(pid.node, Erl.MAXATOMLEN), pid.num, pid.serial, pid.creation);
}
private Pid.create(string node0, uint num0, uint serial0, uint creation0) {
@@ -464,7 +501,8 @@ namespace Eva {
public void encode(Erl.Buffer buffer) {
Erl.Pid pid = Erl.Pid();
- char[] nodedata = node.to_utf8();
+ char[]? nodedata = string_to_array(node);
+ assert(nodedata != null);
Memory.copy(pid.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length));
pid.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0;
@@ -483,7 +521,7 @@ namespace Eva {
public uint creation {get; construct;}
public Port(Erl.Port port) {
- this.create(((string)port.node).ndup(Erl.MAXATOMLEN), port.id, port.creation);
+ this.create(array_to_string(port.node, Erl.MAXATOMLEN), port.id, port.creation);
}
private Port.create(string node0, uint id0, uint creation0) {
@@ -505,7 +543,8 @@ namespace Eva {
public void encode(Erl.Buffer buffer) {
Erl.Port port = Erl.Port();
- char[] nodedata = node.to_utf8();
+ char[]? nodedata = string_to_array(node);
+ assert(nodedata != null);
Memory.copy(port.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length));
port.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0;
@@ -524,7 +563,7 @@ namespace Eva {
public uint creation {get; construct;}
public Ref(Erl.Ref reference) {
- this.create(((string)reference.node).ndup(Erl.MAXATOMLEN), reference.len, reference.n, reference.creation);
+ this.create(array_to_string(reference.node, Erl.MAXATOMLEN), reference.len, reference.n, reference.creation);
}
private Ref.create(string node0, int len0, uint* n0, uint creation0) {
@@ -560,7 +599,8 @@ namespace Eva {
public void encode(Erl.Buffer buffer) {
Erl.Ref reference = Erl.Ref();
- char[] nodedata = node.to_utf8();
+ char[]? nodedata = string_to_array(node);
+ assert(nodedata != null);
Memory.copy(reference.node, nodedata, int.min(Erl.MAXATOMLEN, nodedata.length));
reference.node[int.min(Erl.MAXATOMLEN, nodedata.length)] = 0;
diff --git a/src/Util.vala b/src/Util.vala
new file mode 100644
index 0000000..3666f96
--- /dev/null
+++ b/src/Util.vala
@@ -0,0 +1,45 @@
+namespace Eva {
+ private string array_to_string(uchar* array, ulong len) {
+ string ret = "";
+
+ for(ulong i = 0; i < len; ++i) {
+ if(array[i] == 0)
+ break;
+
+ string buf = string.nfill(6, 0);
+ ((unichar)array[i]).to_utf8(buf);
+
+ ret += buf;
+ }
+
+ return ret;
+ }
+
+ private char[]? string_to_array(string str) {
+ char[] ret = new char[str.len()];
+ int index = 0;
+
+ for(unowned string rest = str; rest.length > 0; rest = rest.next_char()) {
+ unichar c = rest.get_char();
+
+ if(c > 255)
+ return null;
+
+ ret[index++] = (char)c;
+ }
+
+ return ret;
+ }
+
+ private List string_to_list(string str) {
+ List ret = new List();
+
+ for(unowned string rest = str; rest.length > 0; rest = rest.next_char()) {
+ unichar c = rest.get_char();
+
+ ret.list.add(new UInt(c));
+ }
+
+ return ret;
+ }
+}