├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── appveyor.yml ├── benchmark ├── benchmark_cluster_npool.js ├── benchmark_npool.js ├── benchmark_single_thread.js ├── benchmark_threads_a_gogo.js └── threads_a_gogo │ ├── linux │ └── threads_a_gogo.node │ ├── mac │ └── threads_a_gogo.node │ └── win │ └── threads_a_gogo.node ├── binding.gyp ├── example ├── applesOranges.js ├── badScript.js ├── extraModule.js ├── fibonacciNumber.js ├── helloWorld.js ├── md5.js ├── nPoolExample.js ├── underscore.js ├── utf8_encode.js └── xml-to-json │ ├── dom-parser.js │ ├── dom.js │ ├── sax.js │ ├── xml2json.js │ ├── xmlParser.js │ └── xmlToJson.js ├── npool.cc ├── package.json ├── source ├── callback_queue.cc ├── callback_queue.h ├── file_manager.cc ├── file_manager.h ├── isolate_context.cc ├── isolate_context.h ├── json_utility.cc ├── json_utility.h ├── nrequire.cc ├── nrequire.h ├── thread.cc ├── thread.h ├── utilities.cc ├── utilities.h └── v8 │ └── array_buffer_allocator.h ├── test ├── createThreadPool.spec.js ├── destroyThreadPool.spec.js ├── loadFile.spec.js ├── moduleContext.spec.js ├── queueWork.spec.js ├── queueWorkExceptions.spec.js ├── removeFile.spec.js ├── requireEmulation.spec.js └── resources │ ├── compileErrorModule.js │ ├── exceptionParentModule.js │ ├── executionErrorModule.js │ ├── failedCompileRequireModule.js │ ├── failedExecutionRequireModule.js │ ├── failedRequireModule.js │ ├── fibonacciModule.js │ ├── helloWorld.js │ ├── moduleContextBase.js │ ├── require │ ├── anotherDirectory │ │ ├── requireModuleB.js │ │ └── requireModuleC.js │ ├── requireBaseModule.js │ └── requireModuleA.js │ ├── sub-modules │ ├── applesOranges.js │ ├── exceptionModule.js │ ├── notConstructorModule.js │ ├── subModuleContext.js │ └── underscore.js │ └── subModuleWorker.js └── threadpool ├── synchronize.c ├── synchronize.h ├── task_queue.c ├── task_queue.h ├── thread_pool.c └── thread_pool.h /.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - linux 3 | - osx 4 | sudo: false 5 | language: cpp 6 | addons: 7 | apt: 8 | sources: 9 | - ubuntu-toolchain-r-test 10 | packages: 11 | - g++-4.8 12 | env: 13 | matrix: 14 | - TRAVIS_NODE_VERSION="0.8" 15 | - TRAVIS_NODE_VERSION="0.10" 16 | - TRAVIS_NODE_VERSION="0.12" 17 | - TRAVIS_NODE_VERSION="iojs-v1" 18 | - TRAVIS_NODE_VERSION="iojs-v2" 19 | - TRAVIS_NODE_VERSION="iojs-v3" 20 | - TRAVIS_NODE_VERSION="4" 21 | - TRAVIS_NODE_VERSION="5" 22 | notifications: 23 | email: 24 | - ivan.hall@gmail.com 25 | install: 26 | - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION 27 | - if [[ $TRAVIS_NODE_VERSION == "0.8" ]]; then npm install npm@2 && node_modules/.bin/npm install npm; else npm install npm; fi 28 | - mv node_modules npm 29 | - npm/.bin/npm --version 30 | - if [[ $TRAVIS_OS_NAME == "linux" ]]; then export CXX=g++-4.8; fi 31 | - $CXX --version 32 | - npm/.bin/npm install 33 | script: 34 | - make test 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Ivan Hall 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of nPool nor the names of its contributors may be used 13 | to endorse or promote products derived from this software without specific 14 | prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | test: 2 | @./node_modules/.bin/mocha --reporter spec 3 | 4 | .PHONY: test -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # Test against these versions of Io.js and Node.js 2 | environment: 3 | matrix: 4 | # node.js 5 | - nodejs_version: "0.8" 6 | - nodejs_version: "0.10" 7 | - nodejs_version: "0.12" 8 | - nodejs_version: "4" 9 | - nodejs_version: "5" 10 | # io.js 11 | - nodejs_version: "1" 12 | - nodejs_version: "2" 13 | - nodejs_version: "3" 14 | 15 | platform: 16 | - x86 17 | - x64 18 | 19 | # Install scripts. (runs after repo cloning) 20 | install: 21 | # Get the latest stable version of Node.js or io.js 22 | - ps: if($env:nodejs_version -eq "0.8") {Install-Product node $env:nodejs_version $env:platform} 23 | - ps: if($env:nodejs_version -ne "0.8") {Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version $env:platform)} 24 | # Install latest npm for 0.8 25 | - IF %nodejs_version% == 0.8 npm -g install npm@2 26 | - IF %nodejs_version% == 0.8 set PATH=%APPDATA%\npm;%PATH% 27 | - IF %nodejs_version% == 0.8 npm -g install npm 28 | # Install latest npm for 0.10 29 | - IF %nodejs_version% == 0.10 npm -g install npm 30 | - IF %nodejs_version% == 0.10 set PATH=%APPDATA%\npm;%PATH% 31 | # Install latest npm for 0.12 32 | - IF %nodejs_version% == 0.12 npm -g install npm 33 | - IF %nodejs_version% == 0.12 set PATH=%APPDATA%\npm;%PATH% 34 | # Install the module under test 35 | - npm install 36 | 37 | # Post-install test scripts 38 | test_script: 39 | # Output useful info for debugging 40 | - node --version 41 | - npm --version 42 | # Run tests 43 | - node_modules\.bin\mocha --reporter spec 44 | 45 | # Don't actually build 46 | build: off 47 | -------------------------------------------------------------------------------- /benchmark/benchmark_cluster_npool.js: -------------------------------------------------------------------------------- 1 | try { 2 | var nPool = require('./../build/Release/npool'); 3 | } 4 | catch (e) { 5 | var nPool = require('./../build/Debug/npool'); 6 | } 7 | 8 | // load fib module and create thread pool 9 | var numThreads = +process.argv[3] || 1; 10 | nPool.loadFile(1, './../example/fibonacciNumber.js'); 11 | nPool.createThreadPool(numThreads); 12 | 13 | // work complete callback 14 | var callBackFunction = function (callbackObject, workId) { 15 | 16 | // context is of the http response that required work 17 | console.log("Response [" + workId + "/" + (workCount - 1) + "]: " + callbackObject.fibCalcResult); 18 | this.end(callbackObject.fibCalcResult.toString() + ' ' + workId.toString()); 19 | }; 20 | 21 | var workCount = 0; 22 | // work object to be passed to background threadpool 23 | var workObject = { 24 | workId: workCount, 25 | fileKey: 1, 26 | workFunction: "calcFibonacciNumber", 27 | workParam: { 28 | fibNumber: 35 29 | }, 30 | 31 | callbackFunction: callBackFunction 32 | }; 33 | 34 | // http response function 35 | var i = 0; 36 | var httpFunc = function f (req, res) { 37 | if((++i) % 10) { 38 | res.end("QUICK"); 39 | console.log("."); 40 | } 41 | else 42 | { 43 | console.log("**** Request " + workCount); 44 | workObject.workId = workCount++; 45 | workObject.callbackContext = res; 46 | nPool.queueWork(workObject); 47 | } 48 | }; 49 | 50 | var cluster = require('cluster'); 51 | var http = require('http'); 52 | var numCPUs = require('os').cpus().length; 53 | 54 | if (cluster.isMaster) { 55 | 56 | console.log("[ Master ]"); 57 | 58 | // Fork workers. 59 | for (var i = 0; i < numCPUs; i++) { 60 | cluster.fork(); 61 | } 62 | 63 | cluster.on('exit', function(worker, code, signal) { 64 | console.log('worker ' + worker.process.pid + ' died'); 65 | }); 66 | } else { 67 | console.log("[ Worker ]"); 68 | var port = process.argv[2] || 1234; 69 | var http = require('http'); 70 | http.createServer(httpFunc).listen(port); 71 | console.log('Application running! ' + port); 72 | } 73 | 74 | -------------------------------------------------------------------------------- /benchmark/benchmark_npool.js: -------------------------------------------------------------------------------- 1 | try { 2 | var nPool = require('./../build/Release/npool'); 3 | } 4 | catch (e) { 5 | var nPool = require('./../build/Debug/npool'); 6 | } 7 | 8 | // load fib module and create thread pool 9 | var numThreads = +process.argv[3] || 1; 10 | nPool.loadFile(1, './../example/fibonacciNumber.js'); 11 | nPool.createThreadPool(numThreads); 12 | 13 | // work complete callback 14 | var callBackFunction = function (callbackObject, workId) { 15 | 16 | // context is of the http response that required work 17 | console.log("Response [" + workId + "/" + (workCount - 1) + "]: " + callbackObject.fibCalcResult); 18 | this.end(callbackObject.fibCalcResult.toString() + ' ' + workId.toString()); 19 | }; 20 | 21 | var workCount = 0; 22 | // work object to be passed to background threadpool 23 | var workObject = { 24 | workId: workCount, 25 | fileKey: 1, 26 | workFunction: "calcFibonacciNumber", 27 | workParam: { 28 | fibNumber: 35 29 | }, 30 | 31 | callbackFunction: callBackFunction 32 | }; 33 | 34 | // http response function 35 | var i = 0; 36 | var httpFunc = function f (req, res) { 37 | if((++i) % 10) { 38 | res.end("QUICK"); 39 | console.log("."); 40 | } 41 | else 42 | { 43 | console.log("**** Request " + workCount); 44 | workObject.workId = workCount++; 45 | workObject.callbackContext = res; 46 | nPool.queueWork(workObject); 47 | } 48 | }; 49 | 50 | var port = process.argv[2] || 1234; 51 | var http = require('http'); 52 | http.createServer(httpFunc).listen(port); -------------------------------------------------------------------------------- /benchmark/benchmark_single_thread.js: -------------------------------------------------------------------------------- 1 | function fib (n) { 2 | return (n < 2) ? 1 : fib(n-2) + fib(n-1); 3 | } 4 | 5 | var i = 0; 6 | var n = 35; 7 | var count = 0; 8 | 9 | function f (req, res) { 10 | if((++i) % 10) { 11 | res.end("QUICK"); 12 | console.log("."); 13 | } 14 | else { 15 | var txt = count++ + ": " + fib(n); 16 | res.end(txt); 17 | console.log(txt); 18 | } 19 | } 20 | 21 | var port = process.argv[2] || 1234; 22 | var http = require('http'); 23 | http.globalAgent.maxSockets = 8192 + 2048; 24 | http.createServer(f).listen(port); 25 | 26 | console.log('Fibonacci server (NO THREADS) running @port: ' + port); -------------------------------------------------------------------------------- /benchmark/benchmark_threads_a_gogo.js: -------------------------------------------------------------------------------- 1 | function fib (n) { 2 | return (n < 2) ? 1 : fib(n-2) + fib(n-1); 3 | } 4 | 5 | var numThreads = +process.argv[3] || 1; 6 | console.log("Using " + numThreads + " threads"); 7 | 8 | var threads = []; 9 | var round_robin = 0; 10 | 11 | 12 | var t = require ('./threads_a_gogo/' + process.argv[4].toString() + '/threads_a_gogo'); 13 | 14 | while(numThreads--) { 15 | threads.push(t.create().eval(fib)); 16 | } 17 | 18 | var i = 0; 19 | var n = 35; 20 | var count = 0; 21 | var reqCount = 0; 22 | 23 | function f (req, res) { 24 | if((++i) % 10) { 25 | res.end("QUICK"); 26 | console.log("."); 27 | } 28 | else { 29 | console.log("**** Request " + reqCount++); 30 | round_robin = (++round_robin) % threads.length; 31 | threads[round_robin].eval('fib(' + n + ')', function cb (err, data) { 32 | if (err) throw err; 33 | var txt = ' ' + data; 34 | res.end(txt); 35 | console.log(count++ + ': ' + txt); 36 | }); 37 | } 38 | } 39 | 40 | var port = process.argv[2] || 1234; 41 | var http = require('http'); 42 | http.globalAgent.maxSockets = 8192 + 2048; 43 | http.createServer(f).listen(port); 44 | 45 | console.log('Fibonacci server (WITH THREADS) running @port: ' + port); -------------------------------------------------------------------------------- /benchmark/threads_a_gogo/linux/threads_a_gogo.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inh3/nPool/d75c8037adddc28f1827feb2563508787db70906/benchmark/threads_a_gogo/linux/threads_a_gogo.node -------------------------------------------------------------------------------- /benchmark/threads_a_gogo/mac/threads_a_gogo.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inh3/nPool/d75c8037adddc28f1827feb2563508787db70906/benchmark/threads_a_gogo/mac/threads_a_gogo.node -------------------------------------------------------------------------------- /benchmark/threads_a_gogo/win/threads_a_gogo.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inh3/nPool/d75c8037adddc28f1827feb2563508787db70906/benchmark/threads_a_gogo/win/threads_a_gogo.node -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'targets': [ 3 | 4 | # npool .node 5 | { 6 | 'target_name': 'npool', 7 | 8 | # only use windows delayed load hook for iojs versions 9 | 'win_delay_load_hook': " 0 && v < 4);\")", 10 | 11 | 'sources': [ 12 | 'npool.cc', 13 | './source/thread.cc', 14 | './source/file_manager.cc', 15 | './source/json_utility.cc', 16 | './source/callback_queue.cc', 17 | './source/utilities.cc', 18 | './source/nrequire.cc', 19 | './source/isolate_context.cc' 20 | ], 21 | 22 | 'include_dirs': [ 23 | './threadpool', 24 | './source', 25 | './source/v8', 26 | " 2 ? calcFib(n - 1) + calcFib(n - 2) : 1; 8 | }; 9 | 10 | // function that matches the unit of work defined work function 11 | this.calcFibonacciNumber = function (workParam) { 12 | return { 13 | fibCalcResult: calcFib(workParam.fibNumber) 14 | }; 15 | }; 16 | }; 17 | 18 | // replicate node.js module loading system 19 | module.exports = FibModule; -------------------------------------------------------------------------------- /example/helloWorld.js: -------------------------------------------------------------------------------- 1 | var ExtraModule = require('./extraModule.js'); 2 | 3 | var md5 = require('./md5.js'); 4 | 5 | var extraModule = new ExtraModule(); 6 | 7 | // object type function prototype 8 | var HelloWorld = function () { 9 | 10 | // private function 11 | function sayHelloWorld(workParam) { 12 | return "Hello World " + workParam.userName; 13 | }; 14 | 15 | // function that matches the unit of work defined work function 16 | this.getHelloWorld = function (workParam) { 17 | return { 18 | helloWorld: sayHelloWorld(workParam), 19 | utf8OutputString: "Τη γλώσσα μου έδωσαν ελληνική]" + workParam.utf8InputString, 20 | extra: md5(extraModule.getExtra()), 21 | underscoreVersion: extraModule.underscoreVersion 22 | }; 23 | }; 24 | }; 25 | 26 | // replicate node.js module loading system 27 | module.exports = HelloWorld; -------------------------------------------------------------------------------- /example/md5.js: -------------------------------------------------------------------------------- 1 | var utf8_encode = require('./utf8_encode.js'); 2 | 3 | function md5 (str) { 4 | // http://kevin.vanzonneveld.net 5 | // + original by: Webtoolkit.info (http://www.webtoolkit.info/) 6 | // + namespaced by: Michael White (http://getsprink.com) 7 | // + tweaked by: Jack 8 | // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 9 | // + input by: Brett Zamir (http://brett-zamir.me) 10 | // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 11 | // - depends on: utf8_encode 12 | // * example 1: md5('Kevin van Zonneveld'); 13 | // * returns 1: '6e658d4bfcb59cc13f96c14450ac40b9' 14 | var xl; 15 | 16 | var rotateLeft = function (lValue, iShiftBits) { 17 | return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits)); 18 | }; 19 | 20 | var addUnsigned = function (lX, lY) { 21 | var lX4, lY4, lX8, lY8, lResult; 22 | lX8 = (lX & 0x80000000); 23 | lY8 = (lY & 0x80000000); 24 | lX4 = (lX & 0x40000000); 25 | lY4 = (lY & 0x40000000); 26 | lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF); 27 | if (lX4 & lY4) { 28 | return (lResult ^ 0x80000000 ^ lX8 ^ lY8); 29 | } 30 | if (lX4 | lY4) { 31 | if (lResult & 0x40000000) { 32 | return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); 33 | } else { 34 | return (lResult ^ 0x40000000 ^ lX8 ^ lY8); 35 | } 36 | } else { 37 | return (lResult ^ lX8 ^ lY8); 38 | } 39 | }; 40 | 41 | var _F = function (x, y, z) { 42 | return (x & y) | ((~x) & z); 43 | }; 44 | var _G = function (x, y, z) { 45 | return (x & z) | (y & (~z)); 46 | }; 47 | var _H = function (x, y, z) { 48 | return (x ^ y ^ z); 49 | }; 50 | var _I = function (x, y, z) { 51 | return (y ^ (x | (~z))); 52 | }; 53 | 54 | var _FF = function (a, b, c, d, x, s, ac) { 55 | a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac)); 56 | return addUnsigned(rotateLeft(a, s), b); 57 | }; 58 | 59 | var _GG = function (a, b, c, d, x, s, ac) { 60 | a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac)); 61 | return addUnsigned(rotateLeft(a, s), b); 62 | }; 63 | 64 | var _HH = function (a, b, c, d, x, s, ac) { 65 | a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac)); 66 | return addUnsigned(rotateLeft(a, s), b); 67 | }; 68 | 69 | var _II = function (a, b, c, d, x, s, ac) { 70 | a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac)); 71 | return addUnsigned(rotateLeft(a, s), b); 72 | }; 73 | 74 | var convertToWordArray = function (str) { 75 | var lWordCount; 76 | var lMessageLength = str.length; 77 | var lNumberOfWords_temp1 = lMessageLength + 8; 78 | var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64; 79 | var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16; 80 | var lWordArray = new Array(lNumberOfWords - 1); 81 | var lBytePosition = 0; 82 | var lByteCount = 0; 83 | while (lByteCount < lMessageLength) { 84 | lWordCount = (lByteCount - (lByteCount % 4)) / 4; 85 | lBytePosition = (lByteCount % 4) * 8; 86 | lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition)); 87 | lByteCount++; 88 | } 89 | lWordCount = (lByteCount - (lByteCount % 4)) / 4; 90 | lBytePosition = (lByteCount % 4) * 8; 91 | lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition); 92 | lWordArray[lNumberOfWords - 2] = lMessageLength << 3; 93 | lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29; 94 | return lWordArray; 95 | }; 96 | 97 | var wordToHex = function (lValue) { 98 | var wordToHexValue = "", 99 | wordToHexValue_temp = "", 100 | lByte, lCount; 101 | for (lCount = 0; lCount <= 3; lCount++) { 102 | lByte = (lValue >>> (lCount * 8)) & 255; 103 | wordToHexValue_temp = "0" + lByte.toString(16); 104 | wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2); 105 | } 106 | return wordToHexValue; 107 | }; 108 | 109 | var x = [], 110 | k, AA, BB, CC, DD, a, b, c, d, S11 = 7, 111 | S12 = 12, 112 | S13 = 17, 113 | S14 = 22, 114 | S21 = 5, 115 | S22 = 9, 116 | S23 = 14, 117 | S24 = 20, 118 | S31 = 4, 119 | S32 = 11, 120 | S33 = 16, 121 | S34 = 23, 122 | S41 = 6, 123 | S42 = 10, 124 | S43 = 15, 125 | S44 = 21; 126 | 127 | str = utf8_encode(str); 128 | x = convertToWordArray(str); 129 | a = 0x67452301; 130 | b = 0xEFCDAB89; 131 | c = 0x98BADCFE; 132 | d = 0x10325476; 133 | 134 | xl = x.length; 135 | for (k = 0; k < xl; k += 16) { 136 | AA = a; 137 | BB = b; 138 | CC = c; 139 | DD = d; 140 | a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478); 141 | d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756); 142 | c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB); 143 | b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE); 144 | a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF); 145 | d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A); 146 | c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613); 147 | b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501); 148 | a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8); 149 | d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF); 150 | c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1); 151 | b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE); 152 | a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122); 153 | d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193); 154 | c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E); 155 | b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821); 156 | a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562); 157 | d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340); 158 | c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51); 159 | b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA); 160 | a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D); 161 | d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453); 162 | c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681); 163 | b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8); 164 | a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6); 165 | d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6); 166 | c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87); 167 | b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED); 168 | a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905); 169 | d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8); 170 | c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9); 171 | b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A); 172 | a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942); 173 | d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681); 174 | c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122); 175 | b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C); 176 | a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44); 177 | d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9); 178 | c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60); 179 | b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70); 180 | a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6); 181 | d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA); 182 | c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085); 183 | b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05); 184 | a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039); 185 | d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5); 186 | c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8); 187 | b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665); 188 | a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244); 189 | d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97); 190 | c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7); 191 | b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039); 192 | a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3); 193 | d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92); 194 | c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D); 195 | b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1); 196 | a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F); 197 | d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0); 198 | c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314); 199 | b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1); 200 | a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82); 201 | d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235); 202 | c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB); 203 | b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391); 204 | a = addUnsigned(a, AA); 205 | b = addUnsigned(b, BB); 206 | c = addUnsigned(c, CC); 207 | d = addUnsigned(d, DD); 208 | } 209 | 210 | var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d); 211 | 212 | return temp.toLowerCase(); 213 | } 214 | 215 | module.exports = md5; -------------------------------------------------------------------------------- /example/nPoolExample.js: -------------------------------------------------------------------------------- 1 | // load appropriate npool module 2 | var nPool = null; 3 | try { 4 | nPool = require('./../build/Release/npool'); 5 | } 6 | catch (e) { 7 | nPool = require('./../build/Debug/npool'); 8 | } 9 | 10 | 11 | // work complete callback from thread pool 12 | var fibonacciCallbackFunction = function (callbackObject, workId, exceptionObject) { 13 | 14 | console.log("----------------------------------------"); 15 | 16 | console.log("Callback Function: Fibonacci\n"); 17 | 18 | console.log("Callback Context:"); 19 | console.log(this); 20 | console.log(""); 21 | 22 | console.log("WorkId: " + workId + "\n"); 23 | 24 | if(exceptionObject == null) { 25 | console.log("Callback Object:"); 26 | console.log(callbackObject); 27 | console.log(""); 28 | } 29 | else { 30 | console.log(exceptionObject); 31 | } 32 | }; 33 | 34 | // work complete callback from thread pool 35 | var helloWorldCallbackFunction = function (callbackObject, workId, exceptionObject) { 36 | 37 | console.log("----------------------------------------"); 38 | 39 | console.log("Callback Function: Hello World\n"); 40 | 41 | console.log("Callback Context:"); 42 | console.log(this); 43 | console.log(""); 44 | 45 | console.log("WorkId: " + workId + "\n"); 46 | 47 | if(exceptionObject == null) { 48 | console.log("Callback Object:"); 49 | console.log(callbackObject); 50 | console.log(""); 51 | } 52 | else { 53 | console.log(exceptionObject); 54 | } 55 | }; 56 | 57 | // work complete callback from thread pool 58 | var applesOrangesCallbackFunction = function (callbackObject, workId, exceptionObject) { 59 | 60 | console.log("----------------------------------------"); 61 | 62 | console.log("Callback Function: Apples Oranges\n"); 63 | 64 | console.log("Callback Context:"); 65 | console.log(this); 66 | console.log(""); 67 | 68 | console.log("WorkId: " + workId + "\n"); 69 | 70 | if(exceptionObject == null) { 71 | console.log("Callback Object:"); 72 | console.log(callbackObject); 73 | console.log(""); 74 | } 75 | else { 76 | console.log(exceptionObject); 77 | } 78 | }; 79 | 80 | // object type to be used to demonstrate context param within unit of work 81 | function ContextA() { 82 | 83 | this.contextAProperty = "[Context A] Property"; 84 | this.contextAFunction = function() { console.log("[Context A] Function"); } 85 | } 86 | 87 | // object type to be used to demonstrate context param within unit of work 88 | function ContextB() { 89 | 90 | this.contextBProperty = "[Context B] Property"; 91 | this.contextBFunction = function() { console.log("[Context B] Function"); } 92 | } 93 | 94 | // object type to be used to demonstrate context param within unit of work 95 | function ContextC() { 96 | 97 | this.contextCProperty = "[Context C] Property"; 98 | this.contextCFunction = function() { console.log("[Context C] Function"); } 99 | } 100 | 101 | // load files defining object types 102 | nPool.loadFile(1, __dirname + '/fibonacciNumber.js'); 103 | nPool.loadFile(2, __dirname + '/helloWorld.js'); 104 | nPool.loadFile(3, __dirname + '/applesOranges.js'); 105 | nPool.loadFile(4, __dirname + '/badScript.js'); 106 | 107 | // create thread pool with two threads 108 | nPool.createThreadPool(2); 109 | 110 | // object instances to demonstrate context param 111 | var ContextAObject = new ContextA(); 112 | var ContextBObject = new ContextB(); 113 | var ContextCObject = new ContextC(); 114 | 115 | // set continous timeout on main thread every 250ms 116 | var startTime = (new Date()).getTime(); 117 | var count = 0; 118 | (function spinForever () { 119 | var diffTime = (new Date()).getTime() - startTime; 120 | console.log("** Time since last timeout: " + diffTime + " ms + (" + count + ")"); 121 | startTime = (new Date()).getTime(); 122 | 123 | // continue for ~25 seconds 124 | if(count++ < 100) { 125 | setTimeout(spinForever, 250); 126 | } 127 | else { 128 | nPool.destroyThreadPool(); 129 | nPool.removeFile(1); 130 | nPool.removeFile(2); 131 | nPool.removeFile(3); 132 | nPool.removeFile(4); 133 | nPool.removeFile(5); 134 | } 135 | })(); 136 | 137 | // add 6 units of work to thread pool queue 138 | for(var workCount = 0; workCount < 10; workCount++) { 139 | 140 | // create the unit of work object 141 | var unitOfWork = { 142 | workId: workCount, 143 | fileKey: 1, 144 | workFunction: "calcFibonacciNumber", 145 | workParam: { 146 | fibNumber: 40 147 | }, 148 | 149 | callbackFunction: fibonacciCallbackFunction, 150 | callbackContext: ContextAObject 151 | }; 152 | 153 | // queue some other work on a special condition 154 | if(workCount == 3) { 155 | unitOfWork.workId = 99; 156 | unitOfWork.fileKey = 2; 157 | unitOfWork.workFunction = "getHelloWorld"; 158 | unitOfWork.workParam = { 159 | userName: "nPool", 160 | utf8InputString: "grâwen tägelîch" 161 | }; 162 | 163 | unitOfWork.callbackFunction = helloWorldCallbackFunction; 164 | unitOfWork.callbackContext = ContextBObject 165 | 166 | } 167 | 168 | // queue some other work on a special condition 169 | if(workCount == 4) { 170 | unitOfWork.workId = 666; 171 | unitOfWork.fileKey = 4; 172 | unitOfWork.workFunction = "someFunction"; 173 | unitOfWork.workParam = { 174 | myProp: "property" 175 | }; 176 | 177 | unitOfWork.callbackFunction = helloWorldCallbackFunction; 178 | unitOfWork.callbackContext = ContextBObject 179 | } 180 | 181 | // this utilizes the node.js like module loading system 182 | // for pure javascript modules 183 | if(workCount == 6) { 184 | unitOfWork.workId = 1234; 185 | unitOfWork.fileKey = 3; 186 | unitOfWork.workFunction = "getFruitNames"; 187 | unitOfWork.workParam = { 188 | fruitArray: [ 189 | { 190 | name: "apple", 191 | color: "red" 192 | }, 193 | { 194 | name: "strawberry", 195 | color: "red" 196 | }, 197 | { 198 | name: "banana", 199 | color: "yellow" 200 | } 201 | ] 202 | }; 203 | 204 | unitOfWork.callbackFunction = applesOrangesCallbackFunction; 205 | unitOfWork.callbackContext = ContextCObject 206 | 207 | } 208 | 209 | // queue the unit of work 210 | nPool.queueWork(unitOfWork); 211 | } 212 | -------------------------------------------------------------------------------- /example/underscore.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.5.1 2 | // http://underscorejs.org 3 | // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 4 | // Underscore may be freely distributed under the MIT license. 5 | // 6 | // Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative 7 | // Reporters & Editors 8 | // 9 | // Permission is hereby granted, free of charge, to any person 10 | // obtaining a copy of this software and associated documentation 11 | // files (the "Software"), to deal in the Software without 12 | // restriction, including without limitation the rights to use, 13 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the 15 | // Software is furnished to do so, subject to the following 16 | // conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | // OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | !function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,v=e.reduce,h=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,w=i.bind,j=function(n){return n instanceof j?n:this instanceof j?(this._wrapped=n,void 0):new j(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):n._=j,j.VERSION="1.5.1";var A=j.each=j.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(j.has(n,a)&&t.call(e,n[a],a,n)===r)return};j.map=j.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var E="Reduce of empty array with no initial value";j.reduce=j.foldl=j.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduce===v)return e&&(t=j.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(E);return r},j.reduceRight=j.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduceRight===h)return e&&(t=j.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=j.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(E);return r},j.find=j.detect=function(n,t,r){var e;return O(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},j.filter=j.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},j.reject=function(n,t,r){return j.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},j.every=j.all=function(n,t,e){t||(t=j.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var O=j.some=j.any=function(n,t,e){t||(t=j.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};j.contains=j.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:O(n,function(n){return n===t})},j.invoke=function(n,t){var r=o.call(arguments,2),e=j.isFunction(t);return j.map(n,function(n){return(e?t:n[t]).apply(n,r)})},j.pluck=function(n,t){return j.map(n,function(n){return n[t]})},j.where=function(n,t,r){return j.isEmpty(t)?r?void 0:[]:j[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},j.findWhere=function(n,t){return j.where(n,t,!0)},j.max=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);if(!t&&j.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>e.computed&&(e={value:n,computed:a})}),e.value},j.min=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);if(!t&&j.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;ae||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.indexi;){var o=i+a>>>1;r.call(e,n[o])=0})})},j.difference=function(n){var t=c.apply(e,o.call(arguments,1));return j.filter(n,function(n){return!j.contains(t,n)})},j.zip=function(){for(var n=j.max(j.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=j.pluck(arguments,""+r);return t},j.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},j.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=j.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},j.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},j.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var M=function(){};j.bind=function(n,t){var r,e;if(w&&n.bind===w)return w.apply(n,o.call(arguments,1));if(!j.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));M.prototype=n.prototype;var u=new M;M.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},j.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},j.bindAll=function(n){var t=o.call(arguments,1);if(0===t.length)throw new Error("bindAll must be passed function names");return A(t,function(t){n[t]=j.bind(n[t],n)}),n},j.memoize=function(n,t){var r={};return t||(t=j.identity),function(){var e=t.apply(this,arguments);return j.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},j.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},j.defer=function(n){return j.delay.apply(j,[n,1].concat(o.call(arguments,1)))},j.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var c=function(){o=r.leading===!1?0:new Date,a=null,i=n.apply(e,u)};return function(){var l=new Date;o||r.leading!==!1||(o=l);var f=t-(l-o);return e=this,u=arguments,0>=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u)):a||r.trailing===!1||(a=setTimeout(c,f)),i}},j.debounce=function(n,t,r){var e,u=null;return function(){var i=this,a=arguments,o=function(){u=null,r||(e=n.apply(i,a))},c=r&&!u;return clearTimeout(u),u=setTimeout(o,t),c&&(e=n.apply(i,a)),e}},j.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},j.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},j.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},j.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},j.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)j.has(n,r)&&t.push(r);return t},j.values=function(n){var t=[];for(var r in n)j.has(n,r)&&t.push(n[r]);return t},j.pairs=function(n){var t=[];for(var r in n)j.has(n,r)&&t.push([r,n[r]]);return t},j.invert=function(n){var t={};for(var r in n)j.has(n,r)&&(t[n[r]]=r);return t},j.functions=j.methods=function(n){var t=[];for(var r in n)j.isFunction(n[r])&&t.push(r);return t.sort()},j.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},j.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},j.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)j.contains(r,u)||(t[u]=n[u]);return t},j.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]===void 0&&(n[r]=t[r])}),n},j.clone=function(n){return j.isObject(n)?j.isArray(n)?n.slice():j.extend({},n):n},j.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof j&&(n=n._wrapped),t instanceof j&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(j.isFunction(a)&&a instanceof a&&j.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c=0,f=!0;if("[object Array]"==u){if(c=n.length,f=c==t.length)for(;c--&&(f=S(n[c],t[c],r,e)););}else{for(var s in n)if(j.has(n,s)&&(c++,!(f=j.has(t,s)&&S(n[s],t[s],r,e))))break;if(f){for(s in t)if(j.has(t,s)&&!c--)break;f=!c}}return r.pop(),e.pop(),f};j.isEqual=function(n,t){return S(n,t,[],[])},j.isEmpty=function(n){if(null==n)return!0;if(j.isArray(n)||j.isString(n))return 0===n.length;for(var t in n)if(j.has(n,t))return!1;return!0},j.isElement=function(n){return!(!n||1!==n.nodeType)},j.isArray=x||function(n){return"[object Array]"==l.call(n)},j.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){j["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),j.isArguments(arguments)||(j.isArguments=function(n){return!(!n||!j.has(n,"callee"))}),"function"!=typeof/./&&(j.isFunction=function(n){return"function"==typeof n}),j.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},j.isNaN=function(n){return j.isNumber(n)&&n!=+n},j.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},j.isNull=function(n){return null===n},j.isUndefined=function(n){return n===void 0},j.has=function(n,t){return f.call(n,t)},j.noConflict=function(){return n._=t,this},j.identity=function(n){return n},j.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},j.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var I={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};I.unescape=j.invert(I.escape);var T={escape:new RegExp("["+j.keys(I.escape).join("")+"]","g"),unescape:new RegExp("("+j.keys(I.unescape).join("|")+")","g")};j.each(["escape","unescape"],function(n){j[n]=function(t){return null==t?"":(""+t).replace(T[n],function(t){return I[n][t]})}}),j.result=function(n,t){if(null==n)return void 0;var r=n[t];return j.isFunction(r)?r.call(n):r},j.mixin=function(n){A(j.functions(n),function(t){var r=j[t]=n[t];j.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(j,n))}})};var N=0;j.uniqueId=function(n){var t=++N+"";return n?n+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;j.template=function(n,t,r){var e;r=j.defaults({},r,j.templateSettings);var u=new RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(D,function(n){return"\\"+B[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,j);var c=function(n){return e.call(this,n,j)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},j.chain=function(n){return j(n).chain()};var z=function(n){return this._chain?j(n).chain():n};j.mixin(j),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];j.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];j.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),j.extend(j.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}.call(this); 31 | 32 | //# sourceMappingURL=underscore-min.map -------------------------------------------------------------------------------- /example/utf8_encode.js: -------------------------------------------------------------------------------- 1 | function utf8_encode (argString) { 2 | // http://kevin.vanzonneveld.net 3 | // + original by: Webtoolkit.info (http://www.webtoolkit.info/) 4 | // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 5 | // + improved by: sowberry 6 | // + tweaked by: Jack 7 | // + bugfixed by: Onno Marsman 8 | // + improved by: Yves Sucaet 9 | // + bugfixed by: Onno Marsman 10 | // + bugfixed by: Ulrich 11 | // + bugfixed by: Rafal Kukawski 12 | // + improved by: kirilloid 13 | // + bugfixed by: kirilloid 14 | // * example 1: utf8_encode('Kevin van Zonneveld'); 15 | // * returns 1: 'Kevin van Zonneveld' 16 | 17 | if (argString === null || typeof argString === "undefined") { 18 | return ""; 19 | } 20 | 21 | var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n"); 22 | var utftext = '', 23 | start, end, stringl = 0; 24 | 25 | start = end = 0; 26 | stringl = string.length; 27 | for (var n = 0; n < stringl; n++) { 28 | var c1 = string.charCodeAt(n); 29 | var enc = null; 30 | 31 | if (c1 < 128) { 32 | end++; 33 | } else if (c1 > 127 && c1 < 2048) { 34 | enc = String.fromCharCode( 35 | (c1 >> 6) | 192, 36 | ( c1 & 63) | 128 37 | ); 38 | } else if (c1 & 0xF800 != 0xD800) { 39 | enc = String.fromCharCode( 40 | (c1 >> 12) | 224, 41 | ((c1 >> 6) & 63) | 128, 42 | ( c1 & 63) | 128 43 | ); 44 | } else { // surrogate pairs 45 | if (c1 & 0xFC00 != 0xD800) { throw new RangeError("Unmatched trail surrogate at " + n); } 46 | var c2 = string.charCodeAt(++n); 47 | if (c2 & 0xFC00 != 0xDC00) { throw new RangeError("Unmatched lead surrogate at " + (n-1)); } 48 | c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000; 49 | enc = String.fromCharCode( 50 | (c1 >> 18) | 240, 51 | ((c1 >> 12) & 63) | 128, 52 | ((c1 >> 6) & 63) | 128, 53 | ( c1 & 63) | 128 54 | ); 55 | } 56 | if (enc !== null) { 57 | if (end > start) { 58 | utftext += string.slice(start, end); 59 | } 60 | utftext += enc; 61 | start = end = n + 1; 62 | } 63 | } 64 | 65 | if (end > start) { 66 | utftext += string.slice(start, stringl); 67 | } 68 | 69 | return utftext; 70 | } 71 | 72 | module.exports = utf8_encode; -------------------------------------------------------------------------------- /example/xml-to-json/dom-parser.js: -------------------------------------------------------------------------------- 1 | /* You can choose any one of those: 2 | 3 | The MIT License (MIT): 4 | 5 | http://opensource.org/licenses/MIT 6 | 7 | LGPL: 8 | 9 | http://www.gnu.org/licenses/lgpl.html 10 | 11 | https://github.com/jindw/xmldom 12 | */ 13 | 14 | function DOMParser(options){ 15 | this.options = 16 | options != true && //To the version (0.1.12) compatible 17 | options ||{locator:{}}; 18 | 19 | } 20 | DOMParser.prototype.parseFromString = function(source,mimeType){ 21 | var sax = new XMLReader(); 22 | var options = this.options; 23 | var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler 24 | var errorHandler = options.errorHandler; 25 | var locator = options.locator; 26 | var defaultNSMap = {}; 27 | var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"} 28 | if(locator){ 29 | domBuilder.setDocumentLocator(locator) 30 | } 31 | 32 | sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator); 33 | sax.domBuilder = options.domBuilder || domBuilder; 34 | if(/\/x?html?$/.test(mimeType)){ 35 | entityMap.nbsp = '\xa0'; 36 | entityMap.copy = '\xa9'; 37 | defaultNSMap['']= 'http://www.w3.org/1999/xhtml'; 38 | } 39 | sax.parse(source,defaultNSMap,entityMap); 40 | return domBuilder.document; 41 | } 42 | function buildErrorHandler(errorImpl,domBuilder,locator){ 43 | if(!errorImpl){ 44 | if(domBuilder instanceof DOMHandler){ 45 | return domBuilder; 46 | } 47 | errorImpl = domBuilder ; 48 | } 49 | var errorHandler = {} 50 | var isCallback = errorImpl instanceof Function; 51 | locator = locator||{} 52 | function build(key){ 53 | var fn = errorImpl[key]; 54 | if(!fn){ 55 | if(isCallback){ 56 | fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl; 57 | }else{ 58 | var i=arguments.length; 59 | while(--i){ 60 | if(fn = errorImpl[arguments[i]]){ 61 | break; 62 | } 63 | } 64 | } 65 | } 66 | errorHandler[key] = fn && function(msg){ 67 | fn(msg+_locator(locator)); 68 | }||function(){}; 69 | } 70 | build('warning','warn'); 71 | build('error','warn','warning'); 72 | build('fatalError','warn','warning','error'); 73 | return errorHandler; 74 | } 75 | /** 76 | * +ContentHandler+ErrorHandler 77 | * +LexicalHandler+EntityResolver2 78 | * -DeclHandler-DTDHandler 79 | * 80 | * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler 81 | * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2 82 | * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html 83 | */ 84 | function DOMHandler() { 85 | this.cdata = false; 86 | } 87 | function position(locator,node){ 88 | node.lineNumber = locator.lineNumber; 89 | node.columnNumber = locator.columnNumber; 90 | } 91 | /** 92 | * @see org.xml.sax.ContentHandler#startDocument 93 | * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html 94 | */ 95 | DOMHandler.prototype = { 96 | startDocument : function() { 97 | this.document = new DOMImplementation().createDocument(null, null, null); 98 | if (this.locator) { 99 | this.document.documentURI = this.locator.systemId; 100 | } 101 | }, 102 | startElement:function(namespaceURI, localName, qName, attrs) { 103 | var doc = this.document; 104 | var el = doc.createElementNS(namespaceURI, qName||localName); 105 | var len = attrs.length; 106 | appendElement(this, el); 107 | this.currentElement = el; 108 | 109 | this.locator && position(this.locator,el) 110 | for (var i = 0 ; i < len; i++) { 111 | var namespaceURI = attrs.getURI(i); 112 | var value = attrs.getValue(i); 113 | var qName = attrs.getQName(i); 114 | var attr = doc.createAttributeNS(namespaceURI, qName); 115 | if( attr.getOffset){ 116 | position(attr.getOffset(1),attr) 117 | } 118 | attr.value = attr.nodeValue = value; 119 | el.setAttributeNode(attr) 120 | } 121 | }, 122 | endElement:function(namespaceURI, localName, qName) { 123 | var current = this.currentElement 124 | var tagName = current.tagName; 125 | this.currentElement = current.parentNode; 126 | }, 127 | startPrefixMapping:function(prefix, uri) { 128 | }, 129 | endPrefixMapping:function(prefix) { 130 | }, 131 | processingInstruction:function(target, data) { 132 | var ins = this.document.createProcessingInstruction(target, data); 133 | this.locator && position(this.locator,ins) 134 | appendElement(this, ins); 135 | }, 136 | ignorableWhitespace:function(ch, start, length) { 137 | }, 138 | characters:function(chars, start, length) { 139 | chars = _toString.apply(this,arguments) 140 | //console.log(chars) 141 | if(this.currentElement && chars){ 142 | if (this.cdata) { 143 | var charNode = this.document.createCDATASection(chars); 144 | this.currentElement.appendChild(charNode); 145 | } else { 146 | var charNode = this.document.createTextNode(chars); 147 | this.currentElement.appendChild(charNode); 148 | } 149 | this.locator && position(this.locator,charNode) 150 | } 151 | }, 152 | skippedEntity:function(name) { 153 | }, 154 | endDocument:function() { 155 | this.document.normalize(); 156 | }, 157 | setDocumentLocator:function (locator) { 158 | if(this.locator = locator){// && !('lineNumber' in locator)){ 159 | locator.lineNumber = 0; 160 | } 161 | }, 162 | //LexicalHandler 163 | comment:function(chars, start, length) { 164 | chars = _toString.apply(this,arguments) 165 | var comm = this.document.createComment(chars); 166 | this.locator && position(this.locator,comm) 167 | appendElement(this, comm); 168 | }, 169 | 170 | startCDATA:function() { 171 | //used in characters() methods 172 | this.cdata = true; 173 | }, 174 | endCDATA:function() { 175 | this.cdata = false; 176 | }, 177 | 178 | startDTD:function(name, publicId, systemId) { 179 | var impl = this.document.implementation; 180 | if (impl && impl.createDocumentType) { 181 | var dt = impl.createDocumentType(name, publicId, systemId); 182 | this.locator && position(this.locator,dt) 183 | appendElement(this, dt); 184 | } 185 | }, 186 | /** 187 | * @see org.xml.sax.ErrorHandler 188 | * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html 189 | */ 190 | warning:function(error) { 191 | console.warn(error,_locator(this.locator)); 192 | }, 193 | error:function(error) { 194 | console.error(error,_locator(this.locator)); 195 | }, 196 | fatalError:function(error) { 197 | console.error(error,_locator(this.locator)); 198 | throw error; 199 | } 200 | } 201 | function _locator(l){ 202 | if(l){ 203 | return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']' 204 | } 205 | } 206 | function _toString(chars,start,length){ 207 | if(typeof chars == 'string'){ 208 | return chars.substr(start,length) 209 | }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)") 210 | if(chars.length >= start+length || start){ 211 | return new java.lang.String(chars,start,length)+''; 212 | } 213 | return chars; 214 | } 215 | } 216 | 217 | /* 218 | * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html 219 | * used method of org.xml.sax.ext.LexicalHandler: 220 | * #comment(chars, start, length) 221 | * #startCDATA() 222 | * #endCDATA() 223 | * #startDTD(name, publicId, systemId) 224 | * 225 | * 226 | * IGNORED method of org.xml.sax.ext.LexicalHandler: 227 | * #endDTD() 228 | * #startEntity(name) 229 | * #endEntity(name) 230 | * 231 | * 232 | * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html 233 | * IGNORED method of org.xml.sax.ext.DeclHandler 234 | * #attributeDecl(eName, aName, type, mode, value) 235 | * #elementDecl(name, model) 236 | * #externalEntityDecl(name, publicId, systemId) 237 | * #internalEntityDecl(name, value) 238 | * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html 239 | * IGNORED method of org.xml.sax.EntityResolver2 240 | * #resolveEntity(String name,String publicId,String baseURI,String systemId) 241 | * #resolveEntity(publicId, systemId) 242 | * #getExternalSubset(name, baseURI) 243 | * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html 244 | * IGNORED method of org.xml.sax.DTDHandler 245 | * #notationDecl(name, publicId, systemId) {}; 246 | * #unparsedEntityDecl(name, publicId, systemId, notationName) {}; 247 | */ 248 | "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){ 249 | DOMHandler.prototype[key] = function(){return null} 250 | }) 251 | 252 | /* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */ 253 | function appendElement (hander,node) { 254 | if (!hander.currentElement) { 255 | hander.document.appendChild(node); 256 | } else { 257 | hander.currentElement.appendChild(node); 258 | } 259 | }//appendChild and setAttributeNS are preformance key 260 | 261 | if(typeof require == 'function'){ 262 | //console.log("********* " + __dirname); 263 | 264 | var XMLReader = require(__dirname + './sax.js').XMLReader; 265 | var DOM = require(__dirname + './dom.js'); 266 | var DOMImplementation = exports.DOMImplementation = DOM.DOMImplementation; 267 | exports.XMLSerializer = DOM.XMLSerializer ; 268 | 269 | //var XMLReader = require(__dirname + './../../common/xmldom/sax.js').XMLReader; 270 | //var DOMImplementation = exports.DOMImplementation = require(__dirname + './../../common/xmldom/dom.js').DOMImplementation; 271 | //exports.XMLSerializer = require(__dirname + './../../common/xmldom/dom.js').XMLSerializer ; 272 | 273 | exports.DOMParser = DOMParser; 274 | } 275 | -------------------------------------------------------------------------------- /example/xml-to-json/xml2json.js: -------------------------------------------------------------------------------- 1 | /* This work is licensed under Creative Commons GNU LGPL License. 2 | 3 | License: http://creativecommons.org/licenses/LGPL/2.1/ 4 | Version: 0.9 5 | Author: Stefan Goessner/2006 6 | Web: http://goessner.net/ 7 | */ 8 | function xml2json(xml, tab) { 9 | var X = { 10 | toObj: function(xml) { 11 | var o = {}; 12 | if (xml.nodeType==1) { // element node .. 13 | if (xml.attributes.length) // element with attributes .. 14 | for (var i=0; i 1) 56 | o = X.escape(X.innerXml(xml)); 57 | else 58 | for (var n=xml.firstChild; n; n=n.nextSibling) 59 | o["#cdata"] = X.escape(n.nodeValue); 60 | } 61 | } 62 | if (!xml.attributes.length && !xml.firstChild) o = null; 63 | } 64 | else if (xml.nodeType==9) { // document.node 65 | o = X.toObj(xml.documentElement); 66 | } 67 | else 68 | alert("unhandled node type: " + xml.nodeType); 69 | return o; 70 | }, 71 | toJson: function(o, name, ind) { 72 | var json = name ? ("\""+name+"\"") : ""; 73 | if (o instanceof Array) { 74 | for (var i=0,n=o.length; i 1 ? ("\n"+ind+"\t"+o.join(",\n"+ind+"\t")+"\n"+ind) : o.join("")) + "]"; 77 | } 78 | else if (o == null) 79 | json += (name&&":") + "null"; 80 | else if (typeof(o) == "object") { 81 | var arr = []; 82 | for (var m in o) 83 | arr[arr.length] = X.toJson(o[m], m, ind+"\t"); 84 | json += (name?":{":"{") + (arr.length > 1 ? ("\n"+ind+"\t"+arr.join(",\n"+ind+"\t")+"\n"+ind) : arr.join("")) + "}"; 85 | } 86 | else if (typeof(o) == "string") 87 | json += (name&&":") + "\"" + o.toString() + "\""; 88 | else 89 | json += (name&&":") + o.toString(); 90 | return json; 91 | }, 92 | innerXml: function(node) { 93 | var s = "" 94 | if ("innerHTML" in node) 95 | s = node.innerHTML; 96 | else { 97 | var asXml = function(n) { 98 | var s = ""; 99 | if (n.nodeType == 1) { 100 | s += "<" + n.nodeName; 101 | for (var i=0; i"; 108 | } 109 | else 110 | s += "/>"; 111 | } 112 | else if (n.nodeType == 3) 113 | s += n.nodeValue; 114 | else if (n.nodeType == 4) 115 | s += ""; 116 | return s; 117 | }; 118 | for (var c=node.firstChild; c; c=c.nextSibling) 119 | s += asXml(c); 120 | } 121 | return s; 122 | }, 123 | escape: function(txt) { 124 | return txt.replace(/[\\]/g, "\\\\") 125 | .replace(/[\"]/g, '\\"') 126 | .replace(/[\n]/g, '\\n') 127 | .replace(/[\r]/g, '\\r'); 128 | }, 129 | removeWhite: function(e) { 130 | e.normalize(); 131 | for (var n = e.firstChild; n; ) { 132 | if (n.nodeType == 3) { // text node 133 | if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node 134 | var nxt = n.nextSibling; 135 | e.removeChild(n); 136 | n = nxt; 137 | } 138 | else 139 | n = n.nextSibling; 140 | } 141 | else if (n.nodeType == 1) { // element node 142 | X.removeWhite(n); 143 | n = n.nextSibling; 144 | } 145 | else // any other node 146 | n = n.nextSibling; 147 | } 148 | return e; 149 | } 150 | }; 151 | if (xml.nodeType == 9) // document node 152 | xml = xml.documentElement; 153 | var json = X.toJson(X.toObj(X.removeWhite(xml)), xml.nodeName, "\t"); 154 | //return "{\n" + tab + (tab ? json.replace(/\t/g, tab) : json.replace(/\t|\n/g, "")) + "\n}"; 155 | return JSON.parse('{' + json.replace(/\t|\n/g, "") + '}'); 156 | } 157 | 158 | module.exports = xml2json; -------------------------------------------------------------------------------- /example/xml-to-json/xmlParser.js: -------------------------------------------------------------------------------- 1 | var DOMParser = require('./dom-parser.js').DOMParser; 2 | var XML2JSON = require('./xml2json.js'); 3 | 4 | function XMLParser () { 5 | 6 | this.parseXmlData = function (xmlString) { 7 | 8 | var xmlDoc = new DOMParser().parseFromString(xmlString.xmlData, 'text/xml'); 9 | var json = XML2JSON(xmlDoc); 10 | 11 | console.log('*** XML Parser ***'); 12 | 13 | return { jsonObject: json }; 14 | }; 15 | } 16 | 17 | module.exports = XMLParser; -------------------------------------------------------------------------------- /example/xml-to-json/xmlToJson.js: -------------------------------------------------------------------------------- 1 | // load npool module 2 | var nPool = null; 3 | try { 4 | nPool = require('./../../build/Release/npool'); 5 | } 6 | catch (e) { 7 | nPool = require('./../../build/Debug/npool'); 8 | } 9 | 10 | // create thread pool and load xml parser 11 | nPool.createThreadPool(2); 12 | nPool.loadFile(1, './xmlParser.js'); 13 | 14 | // for timing 15 | var startTime = (new Date()).getTime(); 16 | 17 | // create the unit of work object 18 | var unitOfWork = { 19 | workId: 1, 20 | fileKey: 1, 21 | workFunction: 'parseXmlData', 22 | workParam: { 23 | xmlData: "