Index: /trunk/FACT++/src/InterpreterV8.cc
===================================================================
--- /trunk/FACT++/src/InterpreterV8.cc	(revision 14092)
+++ /trunk/FACT++/src/InterpreterV8.cc	(revision 14093)
@@ -1,3 +1,5 @@
 #include "InterpreterV8.h"
+
+#include <boost/tokenizer.hpp>
 
 InterpreterV8 *InterpreterV8::This = 0;
@@ -213,6 +215,9 @@
 
     Handle<ObjectTemplate> obj = ObjectTemplate::New();
-    obj->Set(String::New("index"), rc.first <=-256?Undefined():Integer::New(rc.first),          ReadOnly);
-    obj->Set(String::New("name"),  rc.first <=-256?Undefined():String::New (rc.second.c_str()), ReadOnly);
+
+
+    obj->Set(String::New("index"), rc.first<=-256?Undefined():Integer::New(rc.first),         ReadOnly);
+    obj->Set(String::New("name"),  rc.first<=-256?Undefined():String::New(rc.second.c_str()), ReadOnly);
+    //obj->Set(String::New("toString"),  String::New(("[Object state "+string(*str)+"]").c_str()), ReadOnly);
  
     return handle_scope.Close(obj->NewInstance());
@@ -275,4 +280,158 @@
 {
     return String::New(V8::GetVersion());
+}
+
+Handle<Value> Convert(char type, const char* &ptr)
+{
+    switch (type)
+    {
+    case 'F':  { Handle<Value> v=Number::New(*reinterpret_cast<const float*>(ptr));    ptr+=4; return v; }
+    case 'D':  { Handle<Value> v=Number::New(*reinterpret_cast<const double*>(ptr));   ptr+=8; return v; }
+    case 'I':  {
+    case 'L':    Handle<Value> v=Integer::New(*reinterpret_cast<const uint32_t*>(ptr)); ptr += 4; return v; }
+    case 'X':  { Handle<Value> v=Integer::New(*reinterpret_cast<const uint64_t*>(ptr)); ptr += 8; return v; }
+    case 'S':  { Handle<Value> v=Integer::New(*reinterpret_cast<const uint16_t*>(ptr)); ptr += 2; return v; }
+    case 'C':  { Handle<Value> v=Integer::New((uint16_t)*reinterpret_cast<const uint8_t*>(ptr));  ptr += 1; return v; }
+    case ':':  { Handle<Value> v=String::New(ptr); return v; }
+    }
+    return Undefined();
+}
+
+
+Handle<Value> InterpreterV8::FuncClose(const Arguments &args)
+{
+    HandleScope handle_scope;
+
+    const String::Utf8Value str(args.Holder()->Get(String::New("name")));
+    return Boolean::New(JsUnsubscribe(*str));
+}
+
+Handle<Value> InterpreterV8::FuncGetData(const Arguments &args)
+{
+    HandleScope handle_scope;
+
+    const String::Utf8Value str(args.Holder()->Get(String::New("name")));
+
+    const pair<uint64_t, EventImp *> p = JsGetEvent(*str);
+
+    const EventImp *evt = p.second;
+    if (!evt)
+        return Undefined();
+
+    //if (counter==cnt)
+    //    return info.Holder();//Holder()->Get(String::New("data"));
+    //cout << counter << " " << cnt << endl;
+
+    //const void *ppp = Local<External>::Cast(info.This()->GetInternalField(0))->Value();
+    //info.This()->SetInternalField(0, External::New((void*)evt));
+    //cout << info.This().
+
+    const vector<Description> vec = JsDescription(*str);
+
+    Handle<Array> ret = Array::New();
+    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("counter"), Integer::New(p.first), ReadOnly);
+    ret->Set(String::New("time"),    Date::New(evt->GetJavaDate()), ReadOnly);
+
+    typedef boost::char_separator<char> separator;
+    const boost::tokenizer<separator> tokenizer(evt->GetFormat(), separator(";:"));
+
+    const vector<string> tok(tokenizer.begin(), tokenizer.end());
+
+    Handle<Array> obj = tok.size()==1 ? ret : Array::New();
+
+    const char *ptr = evt->GetText();
+    try
+    {
+        size_t pos = 1;
+        for (auto it=tok.begin(); it!=tok.end(); it++, pos++)
+        {
+            char type = (*it)[0];
+            it++;
+
+            if (it==tok.end() && type=='C')
+                type = ':';
+
+            if (it==tok.end() && type!=':')
+                return ThrowException(String::New(("Format string invalid '"+evt->GetFormat()+"'").c_str()));
+
+            string name = pos<vec.size() ? vec[pos].name : "";
+            if (tok.size()==1)
+                name = "data";
+
+            const uint32_t cnt = it==tok.end() ? 1 : stoi(it->c_str());
+
+            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);
+            }
+            else
+            {
+                Handle<Array> a = Array::New(cnt);
+                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);
+            }
+
+            if (it==tok.end())
+                break;
+        }
+
+        if (tok.size()>1)
+            ret->Set(String::New("data"), obj, ReadOnly);
+
+        return handle_scope.Close(ret);
+    }
+    catch (...)
+    {
+        return ThrowException(String::New(("Format string conversion '"+evt->GetFormat()+"' failed.").c_str()));
+    }
+}
+
+/*
+void Cleanup( Persistent<Value> object, void *parameter )
+{
+    cout << "======================> RemoveMyObj()" << endl;
+}*/
+
+Handle<Value> InterpreterV8::FuncOpen(const Arguments &args)
+{
+    if (args.Length()!=1)
+        return ThrowException(String::New("Number of arguments must be exactly 1."));
+
+    if (!args[0]->IsString())
+        return ThrowException(String::New("Argument 1 must be a string."));
+
+    //if (!args.IsConstructCall())
+    //    return ThrowException(String::New("Must be used as constructor."));
+
+    HandleScope handle_scope;
+
+    const String::Utf8Value str(args[0]);
+
+    JsSubscribe(*str);
+
+    //args.This()->SetInternalField(0, External::New((void*)test));
+    //obj->SetInternalFieldCount(1);
+
+    Handle<ObjectTemplate> obj = ObjectTemplate::New();
+    obj->Set(String::New("get"),   FunctionTemplate::New(WrapGetData), ReadOnly);
+    obj->Set(String::New("close"), FunctionTemplate::New(WrapClose),   ReadOnly);
+    obj->Set(String::New("name"),  String::New(*str), ReadOnly);
+    //obj->Set(String::New("toString"), String::New(("[object Dim "+string(*str)+"]").c_str()), ReadOnly);
+
+    return obj->NewInstance();
+
+    // Persistent<Object> p = Persistent<Object>::New(obj->NewInstance());
+    // obj.MakeWeak((void*)1, Cleanup);
+    // return obj;
 }
 
@@ -293,4 +452,5 @@
     dim->Set(String::New("state"),   FunctionTemplate::New(WrapState),   ReadOnly);
     dim->Set(String::New("sleep"),   FunctionTemplate::New(WrapSleep),   ReadOnly);
+    dim->Set(String::New("open"),    FunctionTemplate::New(WrapOpen), ReadOnly);
 
     Handle<ObjectTemplate> global = ObjectTemplate::New();
@@ -326,4 +486,5 @@
     //context.Dispose();
 
+    cout << "JsEnd" << endl;
     JsEnd(filename);
 
Index: /trunk/FACT++/src/InterpreterV8.h
===================================================================
--- /trunk/FACT++/src/InterpreterV8.h	(revision 14092)
+++ /trunk/FACT++/src/InterpreterV8.h	(revision 14093)
@@ -8,4 +8,7 @@
 #include <v8.h>
 #endif
+
+#include "Description.h"
+#include "EventImp.h"
 
 class InterpreterV8
@@ -29,5 +32,7 @@
     v8::Handle<v8::Value> FuncExit(const v8::Arguments& args);
     v8::Handle<v8::Value> FuncState(const v8::Arguments& args);
-    v8::Handle<v8::Value> FuncInfo(const v8::Arguments& args);
+    v8::Handle<v8::Value> FuncOpen(const v8::Arguments& args);
+    v8::Handle<v8::Value> FuncGetData(const v8::Arguments &args);
+    v8::Handle<v8::Value> FuncClose(const v8::Arguments &args);
 
     static v8::Handle<v8::Value> FuncVersion(const v8::Arguments&);
@@ -39,5 +44,7 @@
     static v8::Handle<v8::Value> WrapExit(const v8::Arguments &args)    { if (This) return This->FuncExit(args);    else return v8::Undefined(); }
     static v8::Handle<v8::Value> WrapState(const v8::Arguments &args)   { if (This) return This->FuncState(args);   else return v8::Undefined(); }
-    static v8::Handle<v8::Value> WrapInfo(const v8::Arguments &args)    { if (This) return This->FuncInfo(args);    else return v8::Undefined(); }
+    static v8::Handle<v8::Value> WrapOpen(const v8::Arguments &args)    { if (This) return This->FuncOpen(args);    else return v8::Undefined(); }
+    static v8::Handle<v8::Value> WrapGetData(const v8::Arguments &args) { if (This) return This->FuncGetData(args); else return v8::Undefined(); }
+    static v8::Handle<v8::Value> WrapClose(const v8::Arguments &args)   { if (This) return This->FuncClose(args);   else return v8::Undefined(); }
 #endif
 
@@ -64,4 +71,7 @@
     virtual std::pair<int32_t, std::string>  JsState(const std::string &) { return std::make_pair(-256, ""); };
     virtual void *JsSubscribe(const std::string &) { return 0; };
+    virtual bool JsUnsubscribe(const std::string &) { return false; };
+    virtual std::vector<Description> JsDescription(const std::string &) { return std::vector<Description>(); };
+    virtual std::pair<uint64_t, EventImp *> JsGetEvent(const std::string &) { return std::make_pair(0, (EventImp*)0); };
 
     bool JsRun(const std::string &, const std::map<std::string,std::string> & = std::map<std::string,std::string>());
