Index: trunk/FACT++/src/InterpreterV8.cc
===================================================================
--- trunk/FACT++/src/InterpreterV8.cc	(revision 14622)
+++ trunk/FACT++/src/InterpreterV8.cc	(revision 14626)
@@ -427,4 +427,29 @@
 }
 
+Handle<Value> InterpreterV8::FuncFile(const Arguments& args)
+{
+    for (int i=0; i<1; i++)
+    {
+        const String::Utf8Value file(args[i]);
+        if (*file == NULL)
+            return ThrowException(String::New("File name missing"));
+
+        ifstream fin(*file);
+        if (!fin)
+            return ThrowException(String::New(("Error - Could not open file '"+string(*file)+"'").c_str()));
+
+        string buffer;
+        if (!getline(fin, buffer, '\0'))
+            return ThrowException(String::New(("Error - Could read file '"+string(*file)+"'").c_str()));
+
+        if (fin.fail())
+            return ThrowException(String::New(("Error - Could read file '"+string(*file)+"'").c_str()));
+
+        return String::New(buffer.c_str());
+
+    }
+    return Boolean::New(true);
+}
+
 Handle<Value> InterpreterV8::FuncVersion(const Arguments&)
 {
@@ -663,7 +688,6 @@
             ostringstream val;
             val << setprecision(7) << *reinterpret_cast<const float*>(ptr);
-            Handle<Value> v=Number::New(stod(val.str()));
-            ptr+=4;
-            return v;
+            ptr += 4;
+            return Number::New(stod(val.str()));
         }
     case 'D':  { Handle<Value> v=Number::New(*reinterpret_cast<const double*>(ptr)); ptr+=8; return v; }
@@ -709,5 +733,5 @@
     const vector<Description> vec = JsDescription(str);
 
-    Handle<Array> ret = Array::New();
+    Handle<Object> ret = Object::New();
     if (ret.IsEmpty())
         return Undefined();
@@ -719,9 +743,8 @@
     ret->Set(String::New("name"),    String::New(str),             ReadOnly);
     ret->Set(String::New("format"),  String::New(evt->GetFormat().c_str()), ReadOnly);
-    ret->Set(String::New("named"),   Boolean::New(vec.size()>0),    ReadOnly);
     ret->Set(String::New("qos"),     Integer::New(evt->GetQoS()),   ReadOnly);
     ret->Set(String::New("size"),    Integer::New(evt->GetSize()),  ReadOnly);
     ret->Set(String::New("counter"), Integer::New(counter),         ReadOnly);
-    ret->Set(String::New("time"), date, ReadOnly);
+    ret->Set(String::New("time"),    date,  ReadOnly);
 
     // If no event was received (usually a disconnection event in
@@ -730,6 +753,22 @@
         return ret;
 
+    // If names are available data will also be provided as an
+    // object. If an empty event was received, but names are available,
+    // the object will be empty. Otherwise 'obj' will be undefined.
+    // obj===undefined:               no data received
+    // obj!==undefined, length==0:    names for event available
+    // obj!==undefined, obj.length>0: names available, data received
+    Handle<Object> named = Object::New();
+    if (named.IsEmpty())
+        return Undefined();
+
+    if (vec.size()>0)
+        ret->Set(String::New("obj"), named, ReadOnly);
+
     // If valid data was received, but the size was zero, then
     // null is returned as data
+    // data===undefined: no data received
+    // data===null:      event received, but no data
+    // data.length>0:    event received, contains data
     if (evt->GetSize()==0 || evt->GetFormat().empty())
     {
@@ -743,6 +782,6 @@
     const vector<string> tok(tokenizer.begin(), tokenizer.end());
 
-    Handle<Array> obj = tok.size()>1 ? Array::New() : ret;
-    if (obj.IsEmpty())
+    Handle<Object> arr = tok.size()>1 ? Array::New() : ret;
+    if (arr.IsEmpty())
         return Undefined();
 
@@ -770,15 +809,12 @@
             const uint32_t cnt = it==tok.end() ? 1 : stoi(it->c_str());
 
+            Handle<Value> v;
             if (cnt==1)
             {
-                const Handle<Value> v = Convert(type, ptr);
-                if (tok.size()>1)
-                    obj->Set(pos-1, v);
-                if (!name.empty())
-                    obj->Set(String::New(name.c_str()), v);
+                v = Convert(type, ptr);
             }
             else
             {
-                Handle<Array> a = Array::New(cnt);
+                Handle<Object> a = Array::New(cnt);
                 if (a.IsEmpty())
                     return Undefined();
@@ -786,8 +822,15 @@
                 for (uint32_t i=0; i<cnt; i++)
                     a->Set(i, Convert(type, ptr));
-                if (tok.size()>1)
-                    obj->Set(pos-1, a);
-                if (!name.empty())
-                    obj->Set(String::New(name.c_str()), a);
+
+                v = a;
+            }
+
+            if (tok.size()>1)
+                arr->Set(pos-1, v);
+
+            if (!name.empty())
+            {
+                const Handle<String> n = String::New(name.c_str());
+                named->Set(n, v);
             }
 
@@ -797,5 +840,5 @@
 
         if (tok.size()>1)
-            ret->Set(String::New("data"), obj, ReadOnly);
+            ret->Set(String::New("data"), arr, ReadOnly);
 
         return ret;
@@ -828,14 +871,18 @@
 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."));
+    if (args.Length()>2)
+        return ThrowException(String::New("Number of arguments must not be greater than 2."));
+
+    if (args.Length()>=1 && !args[0]->IsInt32() && !args[0]->IsNull())
+        return ThrowException(String::New("Argument 1 not an uint32."));
+
+    if (args.Length()==2 && !args[1]->IsBoolean())
+        return ThrowException(String::New("Argument 2 not a boolean."));
 
     // 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;
+    const bool    null    = args.Length()>=1 && args[0]->IsNull();
+    const int32_t timeout = args.Length()>=1 ? args[0]->Int32Value() : 0;
+    const bool    named   = args.Length()<2 || args[1]->BooleanValue();
 
     HandleScope handle_scope;
@@ -845,6 +892,6 @@
         return Undefined();
 
-    const Handle<String> data  = String::New("data");
-    const Handle<String> named = String::New("named");
+    //const Handle<String> data   = String::New("data");
+    const Handle<String> object = String::New("obj");
 
     const String::Utf8Value name(args.Holder()->Get(String::New("name")));
@@ -867,7 +914,16 @@
             if (!val.IsEmpty() && val->IsObject())
             {
-                const Handle<Object> obj = val->ToObject();
-                if (obj->Has(data) && obj->Get(named)->ToBoolean()->Value())
+                if (!named)
                     return handle_scope.Close(val);
+
+                const Handle<Object> event = val->ToObject();
+                const Handle<Value>  obj   = event->Get(object);
+
+                if (!obj.IsEmpty() && obj->IsObject())
+                {
+                    // Has names and data was received?
+                    if (obj->ToObject()->GetOwnPropertyNames()->Length()>0)
+                        return handle_scope.Close(val);
+                }
             }
         }
@@ -888,5 +944,5 @@
         return exception.ReThrow();
 
-    if (timeout>=0)
+    if (timeout<0)
         return Undefined();
 
@@ -1429,7 +1485,14 @@
 Handle<Value> InterpreterV8::ExecuteInternal(const string &code)
 {
+    // Try/catch and re-throw hides our internal code from
+    // the displayed exception showing the origin and shows
+    // the user function instead.
     TryCatch exception;
+
     const Handle<Value> result = ExecuteCode(code);
-    return exception.HasCaught() ? exception.ReThrow() : result;
+    if (exception.HasCaught())
+        exception.ReThrow();
+
+    return result;
 }
 
@@ -1452,5 +1515,5 @@
     const Handle<Value> result = script->Run();
     if (result.IsEmpty())
-        return result;
+        return Handle<Value>();
 
     // If all went well and the result wasn't undefined then print
@@ -1548,4 +1611,7 @@
 bool InterpreterV8::JsRun(const string &filename, const map<string, string> &map)
 {
+    //const string argv = "--prof";
+    //V8::SetFlagsFromString(argv.c_str(), argv.size());
+
     const Locker locker;
     fThreadId = V8::GetCurrentThreadId();
@@ -1571,4 +1637,5 @@
     dim->Set(String::New("subscribe"), FunctionTemplate::New(WrapSubscribe), ReadOnly);
     dim->Set(String::New("database"),  FunctionTemplate::New(WrapDatabase),  ReadOnly);
+    //dim->Set(String::New("file"),      FunctionTemplate::New(WrapFile),      ReadOnly);
 
     Handle<ObjectTemplate> onchange = ObjectTemplate::New();
@@ -1611,4 +1678,6 @@
     fGlobalContext->Global()->Set(String::New("arg"), args, ReadOnly);
 
+    //V8::ResumeProfiler();
+
     AddFormatToGlobal();
 
@@ -1621,4 +1690,5 @@
     Locker::StartPreemption(10);
     bool rc = ExecuteFile(filename, true);
+
     Locker::StopPreemption();
 
@@ -1627,4 +1697,7 @@
     if (exception.HasCaught())
         rc = ReportException(&exception);
+
+    // IsProfilerPaused()
+    // V8::PauseProfiler();
 
     // -----
