Index: /trunk/FACT++/src/InterpreterV8.cc
===================================================================
--- /trunk/FACT++/src/InterpreterV8.cc	(revision 14567)
+++ /trunk/FACT++/src/InterpreterV8.cc	(revision 14568)
@@ -769,5 +769,5 @@
     // If valid data was received, but the size was zero, then
     // null is returned as data
-    if (evt->GetSize()==0)
+    if (evt->GetSize()==0 || evt->GetFormat().empty())
     {
         ret->Set(String::New("data"), Null(), ReadOnly);
@@ -780,15 +780,14 @@
     const vector<string> tok(tokenizer.begin(), tokenizer.end());
 
-    Handle<Array> obj = tok.size()==1 ? ret : Array::New();
+    Handle<Array> obj = tok.size()>1 ? Array::New() : ret;
 
     const char *ptr = evt->GetText();
+    const char *end = evt->GetText()+evt->GetSize();
+
     try
     {
         size_t pos = 1;
-        for (auto it=tok.begin(); it!=tok.end(); it++, pos++)
+        for (auto it=tok.begin(); it!=tok.end() && ptr<end; it++, pos++)
         {
-            if (ptr>=evt->GetText())
-                return ret;
-
             char type = (*it)[0];
             it++;
@@ -839,5 +838,5 @@
     }
 }
-
+/*
 Handle<Value> InterpreterV8::FuncGetData(const Arguments &args)
 {
@@ -858,4 +857,72 @@
     return ret->IsNativeError() ? ThrowException(ret) : handle_scope.Close(ret);
 }
+*/
+Handle<Value> InterpreterV8::FuncGetData(const Arguments &args)
+{
+    if (args.Length()>1)
+        return ThrowException(String::New("Number of arguments must not be greatr than 1."));
+
+    if (args.Length()==1 && !args[0]->IsInt32() && !args[0]->IsNull())
+        return ThrowException(String::New("Argument 1 not an int32."));
+
+    // Using a Javascript function has the advantage that it is fully
+    // interruptable without the need of C++ code
+    const bool    null    = args.Length()==1 && args[0]->IsNull();
+    const int32_t timeout = args.Length()==1 ? args[0]->Int32Value() : 0;
+
+    HandleScope handle_scope;
+
+    const Handle<Script> sleep = Script::Compile(String::New("dim.sleep();"));
+
+    const Handle<String> data  = String::New("data");
+    const Handle<String> named = String::New("named");
+
+    const String::Utf8Value name(args.Holder()->Get(String::New("name")));
+
+    TryCatch exception;
+
+    Time t;
+    while (!exception.HasCaught())
+    {
+        const pair<uint64_t, EventImp *> p = JsGetEvent(*name);
+
+        const EventImp *evt = p.second;
+        if (evt)
+        {
+            const Handle<Value> val = ConvertEvent(evt, p.first, *name);
+            if (val->IsNativeError())
+                return ThrowException(val);
+
+            // Protect against the return of an exception
+            if (!val.IsEmpty() && val->IsObject())
+            {
+                const Handle<Object> obj = val->ToObject();
+                if (obj->Has(data) && obj->Get(named)->ToBoolean()->Value())
+                    return handle_scope.Close(val);
+            }
+        }
+
+        if (args.Length()==0)
+            break;
+
+        if (!null && Time()-t>=boost::posix_time::milliseconds(abs(timeout)))
+            break;
+
+        // We cannot sleep directly because we have to give control back to
+        // JavaScript ever now and then. This also allows us to catch
+        // exceptions, either from the preemption or ConvertEvent
+        sleep->Run();
+    }
+
+    if (exception.HasCaught())
+        return exception.ReThrow();
+
+    if (timeout>=0)
+        return Undefined();
+
+    const string str = "Waiting for a valid event of "+string(*name)+" timed out.";
+    return ThrowException(String::New(str.c_str()));
+}
+
 
 // This is a callback from the RemoteControl piping event handling
@@ -1029,6 +1096,6 @@
 
     Handle<ObjectTemplate> tem = ObjectTemplate::New();
-    tem->Set(String::New("get"),    FunctionTemplate::New(WrapGetData), ReadOnly);
-    tem->Set(String::New("close"),  FunctionTemplate::New(WrapClose),   ReadOnly);
+    tem->Set(String::New("get"),    FunctionTemplate::New(WrapGetData),  ReadOnly);
+    tem->Set(String::New("close"),  FunctionTemplate::New(WrapClose),    ReadOnly);
     tem->Set(String::New("name"),   String::New(*str), ReadOnly);
     tem->Set(String::New("isOpen"), Boolean::New(true));
