Subversion Repositories HomeAutomation

Rev

Rev 1008 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1008 Rev 1010
1
/***************************************************************************
1
/***************************************************************************
2
 *   Copyright (C) December 10, 2008 by Mattias Runge                             *
2
 *   Copyright (C) December 10, 2008 by Mattias Runge                             *
3
 *   mattias@runge.se                                                      *
3
 *   mattias@runge.se                                                      *
4
 *   virtualmachine.cpp                                            *
4
 *   virtualmachine.cpp                                            *
5
 *                                                                         *
5
 *                                                                         *
6
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   This program is free software; you can redistribute it and/or modify  *
7
 *   it under the terms of the GNU General Public License as published by  *
7
 *   it under the terms of the GNU General Public License as published by  *
8
 *   the Free Software Foundation; either version 2 of the License, or     *
8
 *   the Free Software Foundation; either version 2 of the License, or     *
9
 *   (at your option) any later version.                                   *
9
 *   (at your option) any later version.                                   *
10
 *                                                                         *
10
 *                                                                         *
11
 *   This program is distributed in the hope that it will be useful,       *
11
 *   This program is distributed in the hope that it will be useful,       *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU General Public License for more details.                          *
14
 *   GNU General Public License for more details.                          *
15
 *                                                                         *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU General Public License     *
16
 *   You should have received a copy of the GNU General Public License     *
17
 *   along with this program; if not, write to the                         *
17
 *   along with this program; if not, write to the                         *
18
 *   Free Software Foundation, Inc.,                                       *
18
 *   Free Software Foundation, Inc.,                                       *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20
 ***************************************************************************/
20
 ***************************************************************************/
21
 
21
 
22
#include "virtualmachine.h"
22
#include "virtualmachine.h"
23
 
23
 
24
VirtualMachine* VirtualMachine::myInstance = NULL;
24
VirtualMachine* VirtualMachine::myInstance = NULL;
25
 
25
 
26
VirtualMachine& VirtualMachine::getInstance()
26
VirtualMachine& VirtualMachine::getInstance()
27
{
27
{
28
    if (myInstance == NULL)
28
    if (myInstance == NULL)
29
    {
29
    {
30
        myInstance = new VirtualMachine();
30
        myInstance = new VirtualMachine();
31
    }
31
    }
32
 
32
 
33
    return *myInstance;
33
    return *myInstance;
34
}
34
}
35
 
35
 
36
void VirtualMachine::deleteInstance()
36
void VirtualMachine::deleteInstance()
37
{
37
{
38
    if (myInstance != NULL)
38
    if (myInstance != NULL)
39
    {
39
    {
40
        delete myInstance;
40
        delete myInstance;
41
        myInstance = NULL;
41
        myInstance = NULL;
42
    }
42
    }
43
}
43
}
44
 
44
 
45
VirtualMachine::VirtualMachine()
45
VirtualMachine::VirtualMachine()
46
{
46
{
47
}
47
}
48
 
48
 
49
VirtualMachine::~VirtualMachine()
49
VirtualMachine::~VirtualMachine()
50
{
50
{
51
    stop();
51
    stop();
52
 
52
 
53
    myCommandThread.stop();
53
    myCommandThread.stop();
54
 
54
 
55
    ///FIXME: Verify that this works and does not cause segfaults
55
    ///FIXME: Verify that this works and does not cause segfaults
56
    for (map<int, SocketThread*>::iterator iter = mySocketThreads.begin(); iter != mySocketThreads.end(); iter++)
56
    for (map<int, SocketThread*>::iterator iter = mySocketThreads.begin(); iter != mySocketThreads.end(); iter++)
57
    {
57
    {
58
        iter->second->stop();
58
        iter->second->stop();
59
        delete iter->second;
59
        delete iter->second;
60
        //mySocketThreads.erase(iter);
60
        //mySocketThreads.erase(iter);
61
    }
61
    }
62
 
62
 
63
    mySocketThreads.clear();
63
    mySocketThreads.clear();
64
 
64
 
65
    for (map<int, IntervalThread*>::iterator iter = myIntervalThreads.begin(); iter != myIntervalThreads.end(); iter++)
65
    for (map<int, IntervalThread*>::iterator iter = myIntervalThreads.begin(); iter != myIntervalThreads.end(); iter++)
66
    {
66
    {
67
        iter->second->stop();
67
        iter->second->stop();
68
        delete iter->second;
68
        delete iter->second;
69
        //myIntervalThreads.erase(iter);
69
        //myIntervalThreads.erase(iter);
70
    }
70
    }
71
 
71
 
72
    myIntervalThreads.clear();
72
    myIntervalThreads.clear();
73
}
73
}
74
 
74
 
75
void VirtualMachine::run()
75
void VirtualMachine::run()
76
{
76
{
77
    myGlobal = ObjectTemplate::New();
77
    myGlobal = ObjectTemplate::New();
78
    myGlobal->Set(String::New("_quit"), FunctionTemplate::New(VirtualMachine::_quit));
78
    myGlobal->Set(String::New("_quit"), FunctionTemplate::New(VirtualMachine::_quit));
79
    myGlobal->Set(String::New("_print"), FunctionTemplate::New(VirtualMachine::_print));
79
    myGlobal->Set(String::New("_print"), FunctionTemplate::New(VirtualMachine::_print));
80
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine::_log));
80
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine::_log));
81
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine::_sendCanMessage));
81
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine::_sendCanMessage));
82
    myGlobal->Set(String::New("sendCanNMTMessage"), FunctionTemplate::New(VirtualMachine::_sendCanNMTMessage));
82
    myGlobal->Set(String::New("sendCanNMTMessage"), FunctionTemplate::New(VirtualMachine::_sendCanNMTMessage));
83
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine::_loadScript));
83
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine::_loadScript));
84
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine::_startIntervalThread));
84
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine::_startIntervalThread));
85
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine::_stopIntervalThread));
85
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine::_stopIntervalThread));
86
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine::_startSocketThread));
86
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine::_startSocketThread));
87
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine::_stopSocketThread));
87
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine::_stopSocketThread));
88
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine::_sendToSocketThread));
88
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine::_sendToSocketThread));
89
    myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine::_uint2hex));
89
    myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine::_uint2hex));
90
    myGlobal->Set(String::New("loadDataStore"), FunctionTemplate::New(VirtualMachine::_loadDataStore));
90
    myGlobal->Set(String::New("loadDataStore"), FunctionTemplate::New(VirtualMachine::_loadDataStore));
91
    myGlobal->Set(String::New("getFileContents"), FunctionTemplate::New(VirtualMachine::_getFileContents));
91
    myGlobal->Set(String::New("getFileContents"), FunctionTemplate::New(VirtualMachine::_getFileContents));
92
    myContext = Context::New(NULL, myGlobal);
92
    myContext = Context::New(NULL, myGlobal);
93
 
93
 
94
 
94
 
95
    if (loadScript("System/Base.js"))
95
    if (loadScript("System/Base.js"))
96
    {
96
    {
97
        loadScript("System/Startup.js");
97
        loadScript("System/Startup.js");
98
 
98
 
99
        loadScript("Autostart.js");
99
        loadScript("Autostart.js");
100
 
100
 
101
        Context::Scope contextScope(myContext);
101
        Context::Scope contextScope(myContext);
102
 
102
 
103
        myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
103
        myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
104
    }
104
    }
105
    else
105
    else
106
    {
106
    {
107
        ///FIXME: We should probably exit the application here
107
        ///FIXME: We should probably exit the application here
108
        return;
108
        return;
109
    }
109
    }
110
 
110
 
111
    const int argc = 0;
111
    const int argc = 0;
112
    Handle<Value> argv[argc] = { };
112
    Handle<Value> argv[argc] = { };
113
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv);
113
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv);
114
 
114
 
115
 
115
 
116
    string commandPort = Settings::get("CommandPort");
116
    string commandPort = Settings::get("CommandPort");
117
    if (commandPort != "")
117
    if (commandPort != "")
118
    {
118
    {
119
        myCommandThread.setSettings(stoi(commandPort), "Command console");
119
        myCommandThread.setSettings(stoi(commandPort), "Command console");
120
        myCommandThread.start();
120
        myCommandThread.start();
121
    }
121
    }
122
    else
122
    else
123
    {
123
    {
124
        SyslogStream &slog = SyslogStream::getInstance();
124
        SyslogStream &slog = SyslogStream::getInstance();
125
        slog << "CommandPort is not defined, can not start Command console socket\n";
125
        slog << "CommandPort is not defined, can not start Command console socket\n";
126
    }
126
    }
127
 
127
 
128
 
128
 
129
    mySemaphore.lock();
129
    mySemaphore.lock();
130
 
130
 
131
    while (true)
131
    while (true)
132
    {
132
    {
133
        while (myExpressions.size() > 0)
133
        while (myExpressions.size() > 0)
134
        {
134
        {
135
            runExpression(myExpressions.pop());
135
            runExpression(myExpressions.pop());
136
        }
136
        }
137
 
137
 
138
        mySemaphore.wait();
138
        mySemaphore.wait();
139
    }
139
    }
140
 
140
 
141
    mySemaphore.unlock();
141
    mySemaphore.unlock();
142
}
142
}
143
 
143
 
144
void VirtualMachine::queueExpression(Expression expression)
144
void VirtualMachine::queueExpression(Expression expression)
145
{
145
{
146
    myExpressions.push(expression);
146
    myExpressions.push(expression);
147
    mySemaphore.broadcast();
147
    mySemaphore.broadcast();
148
}
148
}
149
 
149
 
150
string VirtualMachine::formatException(TryCatch* tryCatch)
150
string VirtualMachine::formatException(TryCatch* tryCatch)
151
{
151
{
152
    string result;
152
    string result;
153
 
153
 
154
    HandleScope handleScope;
154
    HandleScope handleScope;
155
    String::Utf8Value exception(tryCatch->Exception());
155
    String::Utf8Value exception(tryCatch->Exception());
156
    Handle<v8::Message> message = tryCatch->Message();
156
    Handle<v8::Message> message = tryCatch->Message();
157
 
157
 
158
    string strException = *exception;
158
    string strException = *exception;
159
 
159
 
160
    if (message.IsEmpty())
160
    if (message.IsEmpty())
161
    {
161
    {
162
        result += strException + "\n";
162
        result += strException + "\n";
163
    }
163
    }
164
    else
164
    else
165
    {
165
    {
166
        String::Utf8Value filename(message->GetScriptResourceName());
166
        String::Utf8Value filename(message->GetScriptResourceName());
167
        string strFilename = *filename;
167
        string strFilename = *filename;
168
 
168
 
169
        result += strFilename + ":" + itos(message->GetLineNumber()) + ": " + strException + "\n";
169
        result += strFilename + ":" + itos(message->GetLineNumber()) + ": " + strException + "\n";
170
 
170
 
171
        String::Utf8Value sourceline(message->GetSourceLine());
171
        String::Utf8Value sourceline(message->GetSourceLine());
172
        string strSourceline = *sourceline;
172
        string strSourceline = *sourceline;
173
 
173
 
174
        result += strSourceline + "\n";
174
        result += strSourceline + "\n";
175
 
175
 
176
        string underline = rpad("", message->GetStartColumn(), ' ');
176
        string underline = rpad("", message->GetStartColumn(), ' ');
177
        underline = rpad(underline, message->GetEndColumn(), '^');
177
        underline = rpad(underline, message->GetEndColumn(), '^');
178
 
178
 
179
        result += underline + "\n";
179
        result += underline + "\n";
180
    }
180
    }
181
 
181
 
182
    return result;
182
    return result;
183
}
183
}
184
 
184
 
185
bool VirtualMachine::loadDataStore(string storeName)
185
bool VirtualMachine::loadDataStore(string storeName)
186
{
186
{
187
    SyslogStream &slog = SyslogStream::getInstance();
187
    SyslogStream &slog = SyslogStream::getInstance();
188
 
188
 
189
    string basePath = Settings::get("BasePath") + "Services/DataStores/";
189
    string basePath = Settings::get("BasePath") + "Services/DataStores/";
190
    string scriptFileName = basePath + storeName + ".js";
190
    string scriptFileName = basePath + storeName + ".js";
191
 
191
 
192
    if (!file_exists(scriptFileName))
192
    if (!file_exists(scriptFileName))
193
    {
193
    {
194
        slog << "Failed to load datastore " + scriptFileName + ", file does not exist.\n";
194
        slog << "Failed to load datastore " + scriptFileName + ", file does not exist.\n";
195
        return false;
195
        return false;
196
    }
196
    }
197
 
197
 
198
    string scriptSource = file_get_contents(scriptFileName);
198
    string scriptSource = file_get_contents(scriptFileName);
199
 
199
 
200
    scriptSource = "DataStore.addStore('" + storeName + "', " + str_replace("\n", "", scriptSource) + ");";
200
    scriptSource = "DataStore.addStore('" + storeName + "', " + str_replace("\n", "", scriptSource) + ");";
201
 
201
 
202
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
202
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
203
    Handle<String> name = String::New(scriptFileName.c_str(), scriptFileName.length());
203
    Handle<String> name = String::New(scriptFileName.c_str(), scriptFileName.length());
204
 
204
 
205
    Context::Scope contextScope(myContext);
205
    Context::Scope contextScope(myContext);
206
 
206
 
207
    TryCatch tryCatch;
207
    TryCatch tryCatch;
208
 
208
 
209
    Handle<Script> script = Script::Compile(source, name);
209
    Handle<Script> script = Script::Compile(source, name);
210
 
210
 
211
    if (script.IsEmpty())
211
    if (script.IsEmpty())
212
    {
212
    {
213
        slog << formatException(&tryCatch);
213
        slog << formatException(&tryCatch);
214
        return false;
214
        return false;
215
    }
215
    }
216
    else
216
    else
217
    {
217
    {
218
        Handle<Value> result = script->Run();
218
        Handle<Value> result = script->Run();
219
 
219
 
220
        if (result.IsEmpty())
220
        if (result.IsEmpty())
221
        {
221
        {
222
            slog << formatException(&tryCatch);
222
            slog << formatException(&tryCatch);
223
            return false;
223
            return false;
224
        }
224
        }
225
 
225
 
226
        slog << "Loaded datastore " + storeName + "\n";
226
        slog << "Loaded datastore " + storeName + "\n";
227
    }
227
    }
228
 
228
 
229
    return true;
229
    return true;
230
}
230
}
231
 
231
 
232
bool VirtualMachine::loadScript(string scriptName)
232
bool VirtualMachine::loadScript(string scriptName)
233
{
233
{
234
    SyslogStream &slog = SyslogStream::getInstance();
234
    SyslogStream &slog = SyslogStream::getInstance();
235
 
235
 
236
    string basePath = Settings::get("BasePath") + "Services/";
236
    string basePath = Settings::get("BasePath") + "Services/";
237
    string scriptFileName = basePath + scriptName;
237
    string scriptFileName = basePath + scriptName;
238
 
238
 
239
    if (!file_exists(scriptFileName))
239
    if (!file_exists(scriptFileName))
240
    {
240
    {
241
        slog << "Failed to load " + scriptFileName + ", file does not exist.\n";
241
        slog << "Failed to load " + scriptFileName + ", file does not exist.\n";
242
        return false;
242
        return false;
243
    }
243
    }
244
 
244
 
245
    string scriptSource = file_get_contents(scriptFileName);
245
    string scriptSource = file_get_contents(scriptFileName);
246
 
246
 
247
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
247
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
248
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
248
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
249
 
249
 
250
    Context::Scope contextScope(myContext);
250
    Context::Scope contextScope(myContext);
251
 
251
 
252
    TryCatch tryCatch;
252
    TryCatch tryCatch;
253
 
253
 
254
    Handle<Script> script = Script::Compile(source, name);
254
    Handle<Script> script = Script::Compile(source, name);
255
 
255
 
256
    if (script.IsEmpty())
256
    if (script.IsEmpty())
257
    {
257
    {
258
        slog << formatException(&tryCatch);
258
        slog << formatException(&tryCatch);
259
        return false;
259
        return false;
260
    }
260
    }
261
    else
261
    else
262
    {
262
    {
263
        Handle<Value> result = script->Run();
263
        Handle<Value> result = script->Run();
264
 
264
 
265
        if (result.IsEmpty())
265
        if (result.IsEmpty())
266
        {
266
        {
267
            slog << formatException(&tryCatch);
267
            slog << formatException(&tryCatch);
268
            return false;
268
            return false;
269
        }
269
        }
270
 
270
 
271
        slog << "Loaded " + scriptName + "\n";
271
        slog << "Loaded " + scriptName + "\n";
272
    }
272
    }
273
 
273
 
274
    return true;
274
    return true;
275
}
275
}
276
 
276
 
277
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
277
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
278
{
278
{
279
    IntervalThread *intervalThread = new IntervalThread(timeout);
279
    IntervalThread *intervalThread = new IntervalThread(timeout);
280
 
280
 
281
    myIntervalThreads[intervalThread->getId()] = intervalThread;
281
    myIntervalThreads[intervalThread->getId()] = intervalThread;
282
    myIntervalThreads[intervalThread->getId()]->start();
282
    myIntervalThreads[intervalThread->getId()]->start();
283
 
283
 
284
    return intervalThread->getId();
284
    return intervalThread->getId();
285
}
285
}
286
 
286
 
287
bool VirtualMachine::stopIntervalThread(unsigned int id)
287
bool VirtualMachine::stopIntervalThread(unsigned int id)
288
{
288
{
289
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
289
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
290
    {
290
    {
291
        delete myIntervalThreads[id];
291
        delete myIntervalThreads[id];
292
        myIntervalThreads.erase(id);
292
        myIntervalThreads.erase(id);
293
        return true;
293
        return true;
294
    }
294
    }
295
 
295
 
296
    return false;
296
    return false;
297
}
297
}
298
 
298
 
299
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
299
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
300
{
300
{
301
    SocketThread *socketThread = new SocketThread(address, port, reconnectTimeout);
301
    SocketThread *socketThread = new SocketThread(address, port, reconnectTimeout);
302
    mySocketThreads[socketThread->getId()] = socketThread;
302
    mySocketThreads[socketThread->getId()] = socketThread;
303
    mySocketThreads[socketThread->getId()]->start();
303
    mySocketThreads[socketThread->getId()]->start();
304
 
304
 
305
    return socketThread->getId();
305
    return socketThread->getId();
306
}
306
}
307
 
307
 
308
bool VirtualMachine::stopSocketThread(unsigned int id)
308
bool VirtualMachine::stopSocketThread(unsigned int id)
309
{
309
{
310
    if (mySocketThreads.find(id) != mySocketThreads.end())
310
    if (mySocketThreads.find(id) != mySocketThreads.end())
311
    {
311
    {
312
        delete mySocketThreads[id];
312
        delete mySocketThreads[id];
313
        mySocketThreads.erase(id);
313
        mySocketThreads.erase(id);
314
        return true;
314
        return true;
315
    }
315
    }
316
 
316
 
317
    return false;
317
    return false;
318
}
318
}
319
 
319
 
320
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
320
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
321
{
321
{
322
    if (mySocketThreads.find(id) != mySocketThreads.end())
322
    if (mySocketThreads.find(id) != mySocketThreads.end())
323
    {
323
    {
324
        mySocketThreads[id]->send(data);
324
        mySocketThreads[id]->send(data);
325
    }
325
    }
326
}
326
}
327
 
327
 
328
void VirtualMachine::disconnectCommandClient(unsigned int id)
328
void VirtualMachine::disconnectCommandClient(unsigned int id)
329
{
329
{
330
    myCommandThread.disconnectClient(id);
330
    myCommandThread.disconnectClient(id);
331
}
331
}
332
 
332
 
333
void VirtualMachine::sendToCommandClient(unsigned int id, string data)
333
void VirtualMachine::sendToCommandClient(unsigned int id, string data)
334
{
334
{
335
    myCommandThread.sendTo(id, data);
335
    myCommandThread.sendTo(id, data);
336
}
336
}
337
 
337
 
338
void VirtualMachine::print(unsigned int id, string data)
338
void VirtualMachine::print(unsigned int id, string data)
339
{
339
{
340
    if (id == 0)
340
    if (id == 0)
341
    {
341
    {
342
        SyslogStream &slog = SyslogStream::getInstance();
342
        SyslogStream &slog = SyslogStream::getInstance();
343
        slog << data;
343
        slog << data;
344
    }
344
    }
345
    else
345
    else
346
    {
346
    {
347
        VirtualMachine &vm = VirtualMachine::getInstance();
347
        VirtualMachine &vm = VirtualMachine::getInstance();
348
        vm.sendToCommandClient(id, data);
348
        vm.sendToCommandClient(id, data);
349
    }
349
    }
350
}
350
}
351
 
351
 
352
bool VirtualMachine::runExpression(Expression expression)
352
bool VirtualMachine::runExpression(Expression expression)
353
{
353
{
354
    string scriptName = "runExpression";
354
    string scriptName = "runExpression";
355
 
355
 
356
    string scriptData = expression.getScript();
356
    string scriptData = expression.getScript();
357
 
357
 
358
    scriptData = "setClientId(" + itos(expression.getTargetId()) + ");\n" + scriptData + "\n";
358
    scriptData = "setClientId(" + itos(expression.getTargetId()) + ");\n" + scriptData + "\n";
359
 
359
 
360
    Handle<String> source =  String::New(scriptData.c_str(), scriptData.length());
360
    Handle<String> source =  String::New(scriptData.c_str(), scriptData.length());
361
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
361
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
362
 
362
 
363
    Context::Scope contextScope(myContext);
363
    Context::Scope contextScope(myContext);
364
 
364
 
365
    TryCatch tryCatch;
365
    TryCatch tryCatch;
366
 
366
 
367
    Handle<Script> script = Script::Compile(source, name);
367
    Handle<Script> script = Script::Compile(source, name);
368
 
368
 
369
    if (script.IsEmpty())
369
    if (script.IsEmpty())
370
    {
370
    {
371
        print(expression.getTargetId(), formatException(&tryCatch));
371
        print(expression.getTargetId(), formatException(&tryCatch));
372
        return false;
372
        return false;
373
    }
373
    }
374
    else
374
    else
375
    {
375
    {
376
        Handle<Value> result = script->Run();
376
        Handle<Value> result = script->Run();
377
 
377
 
378
        if (result.IsEmpty())
378
        if (result.IsEmpty())
379
        {
379
        {
380
            print(expression.getTargetId(), formatException(&tryCatch));
380
            print(expression.getTargetId(), formatException(&tryCatch));
381
            return false;
381
            return false;
382
        }
382
        }
383
        else if (expression.getTargetId() != 0)
383
        else if (expression.getTargetId() != 0)
384
        {
384
        {
385
             String::AsciiValue ascii(result);
385
             String::AsciiValue ascii(result);
386
             string resultString = *ascii;
386
             string resultString = *ascii;
387
 
387
 
388
             if (resultString != "undefined")
388
             if (resultString != "undefined")
389
             {
389
             {
390
                print(expression.getTargetId(), resultString + "\n");
390
                print(expression.getTargetId(), resultString + "\n");
391
             }
391
             }
392
        }
392
        }
393
    }
393
    }
394
 
394
 
395
    return true;
395
    return true;
396
}
396
}
397
 
397
 
398
 
398
 
399
Handle<Value> VirtualMachine::_quit(const Arguments& args)
399
Handle<Value> VirtualMachine::_quit(const Arguments& args)
400
{
400
{
401
    VirtualMachine &vm = VirtualMachine::getInstance();
401
    VirtualMachine &vm = VirtualMachine::getInstance();
402
 
402
 
403
    vm.disconnectCommandClient(args[0]->Uint32Value());
403
    vm.disconnectCommandClient(args[0]->Uint32Value());
404
 
404
 
405
    return Undefined();
405
    return Undefined();
406
}
406
}
407
 
407
 
408
Handle<Value> VirtualMachine::_log(const Arguments& args)
408
Handle<Value> VirtualMachine::_log(const Arguments& args)
409
{
409
{
410
    SyslogStream &slog = SyslogStream::getInstance();
410
    SyslogStream &slog = SyslogStream::getInstance();
411
 
411
 
412
    String::AsciiValue str(args[0]);
412
    String::AsciiValue str(args[0]);
413
 
413
 
414
    slog << *str;
414
    slog << *str;
415
 
415
 
416
    return Undefined();
416
    return Undefined();
417
}
417
}
418
 
418
 
419
Handle<Value> VirtualMachine::_print(const Arguments& args)
419
Handle<Value> VirtualMachine::_print(const Arguments& args)
420
{
420
{
421
    VirtualMachine &vm = VirtualMachine::getInstance();
421
    VirtualMachine &vm = VirtualMachine::getInstance();
422
 
422
 
423
    String::AsciiValue str(args[1]);
423
    String::AsciiValue str(args[1]);
424
 
424
 
425
    vm.print(args[0]->Uint32Value(), *str);
425
    vm.print(args[0]->Uint32Value(), *str);
426
 
426
 
427
    return Undefined();
427
    return Undefined();
428
}
428
}
429
 
429
 
430
Handle<Value> VirtualMachine::_sendCanMessage(const Arguments& args)
430
Handle<Value> VirtualMachine::_sendCanMessage(const Arguments& args)
431
{
431
{
432
    CanNetManager &canMan = CanNetManager::getInstance();
432
    CanNetManager &canMan = CanNetManager::getInstance();
433
 
433
 
434
    CanMessage canMessage;
434
    CanMessage canMessage;
435
 
435
 
436
    String::AsciiValue className(args[0]);
436
    String::AsciiValue className(args[0]);
437
    canMessage.setClassName(*className);
437
    canMessage.setClassName(*className);
438
    String::AsciiValue directionFlag(args[1]);
438
    String::AsciiValue directionFlag(args[1]);
439
    canMessage.setDirectionFlag(*directionFlag);
439
    canMessage.setDirectionFlag(*directionFlag);
440
    String::AsciiValue moduleName(args[2]);
440
    String::AsciiValue moduleName(args[2]);
441
    canMessage.setModuleName(*moduleName);
441
    canMessage.setModuleName(*moduleName);
442
    canMessage.setModuleId(args[3]->Uint32Value());
442
    canMessage.setModuleId(args[3]->Uint32Value());
443
    String::AsciiValue commandName(args[4]);
443
    String::AsciiValue commandName(args[4]);
444
    canMessage.setCommandName(*commandName);
444
    canMessage.setCommandName(*commandName);
445
 
445
 
446
    String::AsciiValue dataString(args[5]);
446
    String::AsciiValue dataString(args[5]);
447
 
447
 
448
    vector<string> parts = explode(",", trim(*dataString, ','));
448
    vector<string> parts = explode(",", trim(*dataString, ','));
449
    map<string, CanVariable> data;
449
    map<string, CanVariable> data;
450
 
450
 
451
    for (int n = 0; n < parts.size(); n++)
451
    for (int n = 0; n < parts.size(); n++)
452
    {
452
    {
453
        vector<string> keyAndValue = explode(":", parts[n]);
453
        vector<string> keyAndValue = explode(":", parts[n]);
454
 
454
 
455
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
455
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
456
    }
456
    }
457
 
457
 
458
    canMessage.setData(data);
458
    canMessage.setData(data);
459
   
459
   
460
    canMan.sendMessage(canMessage);
460
    canMan.sendMessage(canMessage);
461
 
461
 
462
    return Undefined();
462
    return Undefined();
463
}
463
}
464
 
464
 
465
Handle<Value> VirtualMachine::_sendCanNMTMessage(const Arguments& args)
465
Handle<Value> VirtualMachine::_sendCanNMTMessage(const Arguments& args)
466
{
466
{
467
    CanNetManager &canMan = CanNetManager::getInstance();
467
    CanNetManager &canMan = CanNetManager::getInstance();
468
 
468
 
469
    CanMessage canMessage;
469
    CanMessage canMessage;
470
 
470
 
471
    String::AsciiValue className(args[0]);
471
    String::AsciiValue className(args[0]);
472
    canMessage.setClassName(*className);
472
    canMessage.setClassName(*className);
473
    String::AsciiValue commandName(args[1]);
473
    String::AsciiValue commandName(args[1]);
474
    canMessage.setCommandName(*commandName);
474
    canMessage.setCommandName(*commandName);
475
 
475
 
476
    String::AsciiValue dataString(args[2]);
476
    String::AsciiValue dataString(args[2]);
477
 
477
 
478
    vector<string> parts = explode(",", trim(*dataString, ','));
478
    vector<string> parts = explode(",", trim(*dataString, ','));
479
    map<string, CanVariable> data;
479
    map<string, CanVariable> data;
480
 
480
 
481
    for (int n = 0; n < parts.size(); n++)
481
    for (int n = 0; n < parts.size(); n++)
482
    {
482
    {
483
        vector<string> keyAndValue = explode(":", parts[n]);
483
        vector<string> keyAndValue = explode(":", parts[n]);
484
 
484
 
485
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
485
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
486
    }
486
    }
487
 
487
 
488
    canMessage.setData(data);
488
    canMessage.setData(data);
489
 
489
 
490
    canMan.sendMessage(canMessage);
490
    canMan.sendMessage(canMessage);
491
 
491
 
492
    return Undefined();
492
    return Undefined();
493
}
493
}
494
 
494
 
495
Handle<Value> VirtualMachine::_loadScript(const Arguments& args)
495
Handle<Value> VirtualMachine::_loadScript(const Arguments& args)
496
{
496
{
497
    VirtualMachine &vm = VirtualMachine::getInstance();
497
    VirtualMachine &vm = VirtualMachine::getInstance();
498
 
498
 
499
    String::AsciiValue str(args[0]);
499
    String::AsciiValue str(args[0]);
500
 
500
 
501
    return Boolean::New(vm.loadScript(*str));
501
    return Boolean::New(vm.loadScript(*str));
502
}
502
}
503
 
503
 
504
Handle<Value> VirtualMachine::_loadDataStore(const Arguments& args)
504
Handle<Value> VirtualMachine::_loadDataStore(const Arguments& args)
505
{
505
{
506
    VirtualMachine &vm = VirtualMachine::getInstance();
506
    VirtualMachine &vm = VirtualMachine::getInstance();
507
 
507
 
508
    String::AsciiValue str(args[0]);
508
    String::AsciiValue str(args[0]);
509
 
509
 
510
    return Boolean::New(vm.loadDataStore(*str));
510
    return Boolean::New(vm.loadDataStore(*str));
511
}
511
}
512
 
512
 
513
Handle<Value> VirtualMachine::_startIntervalThread(const Arguments& args)
513
Handle<Value> VirtualMachine::_startIntervalThread(const Arguments& args)
514
{
514
{
515
    VirtualMachine &vm = VirtualMachine::getInstance();
515
    VirtualMachine &vm = VirtualMachine::getInstance();
516
    return Integer::New(vm.startIntervalThread(args[0]->Uint32Value()));
516
    return Integer::New(vm.startIntervalThread(args[0]->Uint32Value()));
517
}
517
}
518
 
518
 
519
Handle<Value> VirtualMachine::_stopIntervalThread(const Arguments& args)
519
Handle<Value> VirtualMachine::_stopIntervalThread(const Arguments& args)
520
{
520
{
521
    VirtualMachine &vm = VirtualMachine::getInstance();
521
    VirtualMachine &vm = VirtualMachine::getInstance();
522
    return Boolean::New(vm.stopIntervalThread(args[0]->Uint32Value()));
522
    return Boolean::New(vm.stopIntervalThread(args[0]->Uint32Value()));
523
}
523
}
524
 
524
 
525
Handle<Value> VirtualMachine::_startSocketThread(const Arguments& args)
525
Handle<Value> VirtualMachine::_startSocketThread(const Arguments& args)
526
{
526
{
527
    VirtualMachine &vm = VirtualMachine::getInstance();
527
    VirtualMachine &vm = VirtualMachine::getInstance();
528
 
528
 
529
    String::AsciiValue address(args[0]);
529
    String::AsciiValue address(args[0]);
530
 
530
 
531
    return Integer::New(vm.startSocketThread(*address, args[1]->Uint32Value(), args[2]->Uint32Value()));
531
    return Integer::New(vm.startSocketThread(*address, args[1]->Uint32Value(), args[2]->Uint32Value()));
532
}
532
}
533
 
533
 
534
Handle<Value> VirtualMachine::_stopSocketThread(const Arguments& args)
534
Handle<Value> VirtualMachine::_stopSocketThread(const Arguments& args)
535
{
535
{
536
    VirtualMachine &vm = VirtualMachine::getInstance();
536
    VirtualMachine &vm = VirtualMachine::getInstance();
537
 
537
 
538
    return Boolean::New(vm.stopSocketThread(args[0]->Uint32Value()));
538
    return Boolean::New(vm.stopSocketThread(args[0]->Uint32Value()));
539
}
539
}
540
 
540
 
541
Handle<Value> VirtualMachine::_sendToSocketThread(const Arguments& args)
541
Handle<Value> VirtualMachine::_sendToSocketThread(const Arguments& args)
542
{
542
{
543
    VirtualMachine &vm = VirtualMachine::getInstance();
543
    VirtualMachine &vm = VirtualMachine::getInstance();
544
 
544
 
545
    String::AsciiValue data(args[1]);
545
    String::AsciiValue data(args[1]);
546
 
546
 
547
    vm.sendToSocketThread(args[0]->Uint32Value(), *data);
547
    vm.sendToSocketThread(args[0]->Uint32Value(), *data);
548
 
548
 
549
    return Undefined();
549
    return Undefined();
550
}
550
}
551
 
551
 
552
Handle<Value> VirtualMachine::_uint2hex(const Arguments& args)
552
Handle<Value> VirtualMachine::_getFileContents(const Arguments& args)
-
 
553
{
-
 
554
    String::AsciiValue filename(args[0]);
-
 
555
 
-
 
556
    if (!file_exists(*filename))
553
{
557
    {
-
 
558
        return Undefined();
-
 
559
    }
-
 
560
 
554
    VirtualMachine &vm = VirtualMachine::getInstance();
561
    string content = file_get_contents(*filename);
-
 
562
 
-
 
563
    return String::New(content.c_str());
-
 
564
}
555
 
565
 
-
 
566
Handle<Value> VirtualMachine::_uint2hex(const Arguments& args)
-
 
567
{
556
    string hexId = uint2hex(args[0]->Uint32Value(), args[1]->Uint32Value());
568
    string hex = uint2hex(args[0]->Uint32Value(), args[1]->Uint32Value());
-
 
569
    return String::New(hex.c_str());
-
 
570
}
-
 
571
 
-
 
572
Handle<Value> VirtualMachine::_hex2bin(const Arguments& args)
-
 
573
{
-
 
574
    String::AsciiValue hex(args[0]);
-
 
575
    string bin = hex2bin(*hex);
-
 
576
    return String::New(bin.c_str());
-
 
577
}
557
 
578
 
-
 
579
Handle<Value> VirtualMachine::_bin2hex(const Arguments& args)
-
 
580
{
-
 
581
    String::AsciiValue bin(args[0]);
-
 
582
    string hex = bin2hex(*bin);
558
    return String::New(hexId.c_str());
583
    return String::New(hex.c_str());
-
 
584
}
-
 
585
 
-
 
586
Handle<Value> VirtualMachine::_bin2float(const Arguments& args)
-
 
587
{
-
 
588
    String::AsciiValue bin(args[0]);
-
 
589
    float f = bin2float(*bin);
-
 
590
    return Number::New(f);
-
 
591
}
-
 
592
 
-
 
593
Handle<Value> VirtualMachine::_float2bin(const Arguments& args)
-
 
594
{
-
 
595
    string bin = float2bin(args[0]->NumberValue(), args[1]->Uint32Value());
-
 
596
    return String::New(bin.c_str());
-
 
597
}
-
 
598
 
-
 
599
Handle<Value> VirtualMachine::_bin2uint(const Arguments& args)
-
 
600
{
-
 
601
    String::AsciiValue bin(args[0]);
-
 
602
    unsigned int num = bin2uint(*bin);
-
 
603
    return Uint32::New(num);
559
}
604
}
560
 
605
 
561
Handle<Value> VirtualMachine::_getFileContents(const Arguments& args)
606
Handle<Value> VirtualMachine::_uint2bin(const Arguments& args)
562
{
607
{
563
    String::AsciiValue filename(args[0]);
608
    string bin = uint2bin(args[0]->Uint32Value(), args[1]->Uint32Value());
564
 
-
 
565
    if (!file_exists(*filename))
-
 
566
    {
-
 
567
        return Undefined();
609
    return String::New(bin.c_str());
568
    }
610
}
569
 
611
 
570
    string content = file_get_contents(*filename);
-
 
571
 
-
 
572
    return String::New(content.c_str());
-
 
573
}
-
 
574
 
612
 
575
 
613