Subversion Repositories HomeAutomation

Rev

Rev 1402 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

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