diff --git a/main.js b/main.js new file mode 100644 index 0000000..7b737ee --- /dev/null +++ b/main.js @@ -0,0 +1,52 @@ +var net = require('net'); + +var pool = require('./pool.js'); + +function Coin(options){ + this.options = options; +} +Coin.prototype = {}; + +var coins = [ + new Coin({ + name: 'Dogecoin', + symbol: 'doge', + algorithm: 'scrypt', + address: 'D5uXR7F6bTCJKRZBqj1D4gyHF9MHAd5oNs', + daemon: { + bin: 'dogecoind', + port: 8332, + user: 'test', + password: 'test', + blocknotify: '"blockNotify.js doge %s"', + startIfOffline: true + } + }) +]; + + +coins.forEach(function(coin){ + + coin.pool = new pool(coin); + +}); + + + + +var blockNotifyServer = net.createServer(function(c) { + console.log('server connected'); + var data = ''; + c.on('data', function(d){ + console.log('got blocknotify data'); + data += d; + if (data.slice(-1) === '\n'){ + c.end(); + } + }); + c.on('end', function() { + console.log(data); + console.log('server disconnected'); + }); +}); +//blockNotifyServer.listen(8124, function() {}); diff --git a/node_modules/buffertools/.mailmap b/node_modules/buffertools/.mailmap new file mode 100644 index 0000000..95c708b --- /dev/null +++ b/node_modules/buffertools/.mailmap @@ -0,0 +1,2 @@ +# update AUTHORS with: +# git log --all --reverse --format='%aN <%aE>' | perl -ne 'BEGIN{print "# Authors ordered by first contribution.\n"} print unless $h{$_}; $h{$_} = 1' > AUTHORS diff --git a/node_modules/buffertools/.npmignore b/node_modules/buffertools/.npmignore new file mode 100644 index 0000000..057457f --- /dev/null +++ b/node_modules/buffertools/.npmignore @@ -0,0 +1 @@ +buffertools.node diff --git a/node_modules/buffertools/AUTHORS b/node_modules/buffertools/AUTHORS new file mode 100644 index 0000000..acd7762 --- /dev/null +++ b/node_modules/buffertools/AUTHORS @@ -0,0 +1,6 @@ +# Authors ordered by first contribution. +Ben Noordhuis +Stefan Thomas +Nathan Rajlich +Dane Springmeyer +Barret Schloerke diff --git a/node_modules/buffertools/BoyerMoore.h b/node_modules/buffertools/BoyerMoore.h new file mode 100644 index 0000000..830f4eb --- /dev/null +++ b/node_modules/buffertools/BoyerMoore.h @@ -0,0 +1,127 @@ +/* adapted from http://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm */ +#ifndef BOYER_MOORE_H +#define BOYER_MOORE_H + +#include +#include +#include + +#define ALPHABET_SIZE (1 << CHAR_BIT) + +static void compute_prefix(const uint8_t* str, size_t size, int result[]) { + size_t q; + int k; + result[0] = 0; + + k = 0; + for (q = 1; q < size; q++) { + while (k > 0 && str[k] != str[q]) + k = result[k-1]; + + if (str[k] == str[q]) + k++; + + result[q] = k; + } +} + +static void prepare_badcharacter_heuristic(const uint8_t *str, size_t size, int result[ALPHABET_SIZE]) { + size_t i; + + for (i = 0; i < ALPHABET_SIZE; i++) + result[i] = -1; + + for (i = 0; i < size; i++) + result[str[i]] = i; +} + +void prepare_goodsuffix_heuristic(const uint8_t *normal, const size_t size, int result[]) { + const uint8_t *left = normal; + const uint8_t *right = left + size; + uint8_t * reversed = new uint8_t[size+1]; + uint8_t *tmp = reversed + size; + size_t i; + + /* reverse string */ + *tmp = 0; + while (left < right) + *(--tmp) = *(left++); + + int * prefix_normal = new int[size]; + int * prefix_reversed = new int[size]; + + compute_prefix(normal, size, prefix_normal); + compute_prefix(reversed, size, prefix_reversed); + + for (i = 0; i <= size; i++) { + result[i] = size - prefix_normal[size-1]; + } + + for (i = 0; i < size; i++) { + const int j = size - prefix_reversed[i]; + const int k = i - prefix_reversed[i]+1; + + if (result[j] > k) + result[j] = k; + } + + delete[] reversed; + delete[] prefix_normal; + delete[] prefix_reversed; +} + +/* +* Boyer-Moore search algorithm +*/ +const uint8_t *boyermoore_search(const uint8_t *haystack, size_t haystack_len, const uint8_t *needle, size_t needle_len) { + /* + * Simple checks + */ + if(haystack_len == 0) + return NULL; + if(needle_len == 0) + return NULL; + if(needle_len > haystack_len) + return NULL; + + /* + * Initialize heuristics + */ + int badcharacter[ALPHABET_SIZE]; + int * goodsuffix = new int[needle_len+1]; + + prepare_badcharacter_heuristic(needle, needle_len, badcharacter); + prepare_goodsuffix_heuristic(needle, needle_len, goodsuffix); + + /* + * Boyer-Moore search + */ + size_t s = 0; + while(s <= (haystack_len - needle_len)) + { + size_t j = needle_len; + while(j > 0 && needle[j-1] == haystack[s+j-1]) + j--; + + if(j > 0) + { + int k = badcharacter[haystack[s+j-1]]; + int m; + if(k < (int)j && (m = j-k-1) > goodsuffix[j]) + s+= m; + else + s+= goodsuffix[j]; + } + else + { + delete[] goodsuffix; + return haystack + s; + } + } + + delete[] goodsuffix; + /* not found */ + return NULL; +} + +#endif /* BoyerMoore.h */ diff --git a/node_modules/buffertools/LICENSE b/node_modules/buffertools/LICENSE new file mode 100644 index 0000000..6ee116f --- /dev/null +++ b/node_modules/buffertools/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2010, Ben Noordhuis + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/buffertools/README.md b/node_modules/buffertools/README.md new file mode 100644 index 0000000..7d9ed91 --- /dev/null +++ b/node_modules/buffertools/README.md @@ -0,0 +1,163 @@ +# node-buffertools + +Utilities for manipulating buffers. + +## Installing the module + +Easy! With [npm](http://npmjs.org/): + + npm install buffertools + +From source: + + node-gyp configure + node-gyp build + +Now you can include the module in your project. + + require('buffertools').extend(); // extend Buffer.prototype + var buf = new Buffer(42); // create a 42 byte buffer + buf.clear(); // clear it! + +If you don't want to extend the Buffer class's prototype (recommended): + + var buffertools = require('buffertools'); + var buf = new Buffer(42); + buffertools.clear(buf); + +## Methods + +Note that most methods that take a buffer as an argument, will also accept a string. + +### buffertools.extend([object], [object...]) + +Extend the arguments with the buffertools methods. If called without arguments, +defaults to `[Buffer.prototype, SlowBuffer.prototype]`. Extending prototypes +only makes sense for classes that derive from `Buffer`. + +buffertools v1.x extended the `Buffer` prototype by default. In v2.x, it is +opt-in. The reason for that is that buffertools was originally developed for +node.js v0.3 (or maybe v0.2, I don't remember exactly when buffers were added) +where the `Buffer` class was devoid of any useful methods. Over the years, it +has grown a number of utility methods, some of which conflict with the +buffertools methods of the same name, like `Buffer#fill()`. + +### Buffer#clear() +### buffertools.clear(buffer) + +Clear the buffer. This is equivalent to `Buffer#fill(0)`. +Returns the buffer object so you can chain method calls. + +### Buffer#compare(buffer|string) +### buffertools.compare(buffer, buffer|string) + +Lexicographically compare two buffers. Returns a number less than zero +if a < b, zero if a == b or greater than zero if a > b. + +Buffers are considered equal when they are of the same length and contain +the same binary data. + +Smaller buffers are considered to be less than larger ones. Some buffers +find this hurtful. + +### Buffer#concat(a, b, c, ...) +### buffertools.concat(a, b, c, ...) + +Concatenate two or more buffers/strings and return the result. Example: + + // identical to new Buffer('foobarbaz') + a = new Buffer('foo'); + b = new Buffer('bar'); + c = a.concat(b, 'baz'); + console.log(a, b, c); // "foo bar foobarbaz" + + // static variant + buffertools.concat('foo', new Buffer('bar'), 'baz'); + +### Buffer#equals(buffer|string) +### buffertools.equals(buffer, buffer|string) + +Returns true if this buffer equals the argument, false otherwise. + +Buffers are considered equal when they are of the same length and contain +the same binary data. + +Caveat emptor: If your buffers contain strings with different character encodings, +they will most likely *not* be equal. + +### Buffer#fill(integer|string|buffer) +### buffertools.fill(buffer, integer|string|buffer) + +Fill the buffer (repeatedly if necessary) with the argument. +Returns the buffer object so you can chain method calls. + +### Buffer#fromHex() +### buffertools.fromHex(buffer) + +Assumes this buffer contains hexadecimal data (packed, no whitespace) +and decodes it into binary data. Returns a new buffer with the decoded +content. Throws an exception if non-hexadecimal data is encountered. + +### Buffer#indexOf(buffer|string, [start=0]) +### buffertools.indexOf(buffer, buffer|string, [start=0]) + +Search this buffer for the first occurrence of the argument, starting at +offset `start`. Returns the zero-based index or -1 if there is no match. + +### Buffer#reverse() +### buffertools.reverse(buffer) + +Reverse the content of the buffer in place. Example: + + b = new Buffer('live'); + b.reverse(); + console.log(b); // "evil" + +### Buffer#toHex() +### buffertools.toHex(buffer) + +Returns the contents of this buffer encoded as a hexadecimal string. + +## Classes + +Singular, actually. To wit: + +## WritableBufferStream + +This is a regular node.js [writable stream](http://nodejs.org/docs/v0.3.4/api/streams.html#writable_Stream) +that accumulates the data it receives into a buffer. + +Example usage: + + // slurp stdin into a buffer + process.stdin.resume(); + ostream = new WritableBufferStream(); + util.pump(process.stdin, ostream); + console.log(ostream.getBuffer()); + +The stream never emits 'error' or 'drain' events. + +### WritableBufferStream.getBuffer() + +Return the data accumulated so far as a buffer. + +## TODO + +* Logical operations on buffers (AND, OR, XOR). +* Add lastIndexOf() functions. + +## License + +Copyright (c) 2010, Ben Noordhuis + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/buffertools/binding.gyp b/node_modules/buffertools/binding.gyp new file mode 100644 index 0000000..cf8db17 --- /dev/null +++ b/node_modules/buffertools/binding.gyp @@ -0,0 +1,22 @@ +# Copyright (c) 2010, Ben Noordhuis +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +{ + 'targets': [ + { + 'target_name': 'buffertools', + 'sources': [ 'buffertools.cc' ] + } + ] +} diff --git a/node_modules/buffertools/buffertools.cc b/node_modules/buffertools/buffertools.cc new file mode 100644 index 0000000..16ad4ab --- /dev/null +++ b/node_modules/buffertools/buffertools.cc @@ -0,0 +1,402 @@ +/* Copyright (c) 2010, Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "v8.h" +#include "node.h" +#include "node_buffer.h" + +#include +#include +#include +#include + +#include "BoyerMoore.h" + +using namespace v8; +using namespace node; + +namespace { + +// this is an application of the Curiously Recurring Template Pattern +template struct UnaryAction { + Handle apply( + Handle& buffer, + const Arguments& args, + uint32_t args_start); + + Handle operator()(const Arguments& args) { + HandleScope scope; + + uint32_t args_start = 0; + Local target = args.This(); + if (Buffer::HasInstance(target)) { + // Invoked as prototype method, no action required. + } else if (Buffer::HasInstance(args[0])) { + // First argument is the target buffer. + args_start = 1; + target = args[0]->ToObject(); + } else { + return ThrowException(Exception::TypeError(String::New( + "Argument should be a buffer object."))); + } + + return scope.Close(static_cast(this)->apply(target, args, args_start)); + } +}; + +template struct BinaryAction { + Handle apply( + Handle& buffer, + const uint8_t* data, + size_t size, + const Arguments& args, + uint32_t args_start); + + Handle operator()(const Arguments& args) { + HandleScope scope; + + uint32_t args_start = 0; + Local target = args.This(); + if (Buffer::HasInstance(target)) { + // Invoked as prototype method, no action required. + } else if (Buffer::HasInstance(args[0])) { + // First argument is the target buffer. + args_start = 1; + target = args[0]->ToObject(); + } else { + return ThrowException(Exception::TypeError(String::New( + "Argument should be a buffer object."))); + } + + if (args[args_start]->IsString()) { + String::Utf8Value s(args[args_start]); + return scope.Close(static_cast(this)->apply( + target, + (const uint8_t*) *s, + s.length(), + args, + args_start)); + } + + if (Buffer::HasInstance(args[args_start])) { + Local other = args[args_start]->ToObject(); + return scope.Close(static_cast(this)->apply( + target, + (const uint8_t*) Buffer::Data(other), + Buffer::Length(other), + args, + args_start)); + } + + Local illegalArgumentException = String::New( + "Second argument must be a string or a buffer."); + return ThrowException(Exception::TypeError(illegalArgumentException)); + } +}; + +// +// helper functions +// +Handle clear(Handle& buffer, int c) { + size_t length = Buffer::Length(buffer); + uint8_t* data = (uint8_t*) Buffer::Data(buffer); + memset(data, c, length); + return buffer; +} + +Handle fill(Handle& buffer, void* pattern, size_t size) { + size_t length = Buffer::Length(buffer); + uint8_t* data = (uint8_t*) Buffer::Data(buffer); + + if (size >= length) { + memcpy(data, pattern, length); + } else { + const int n_copies = length / size; + const int remainder = length % size; + for (int i = 0; i < n_copies; i++) { + memcpy(data + size * i, pattern, size); + } + memcpy(data + size * n_copies, pattern, remainder); + } + + return buffer; +} + +int compare(Handle& buffer, const uint8_t* data2, size_t length2) { + size_t length = Buffer::Length(buffer); + if (length != length2) { + return length > length2 ? 1 : -1; + } + + const uint8_t* data = (const uint8_t*) Buffer::Data(buffer); + return memcmp(data, data2, length); +} + +// +// actions +// +struct ClearAction: UnaryAction { + Handle apply(Handle& buffer, const Arguments& args, uint32_t args_start) { + return clear(buffer, 0); + } +}; + +struct FillAction: UnaryAction { + Handle apply(Handle& buffer, const Arguments& args, uint32_t args_start) { + if (args[args_start]->IsInt32()) { + int c = args[args_start]->Int32Value(); + return clear(buffer, c); + } + + if (args[args_start]->IsString()) { + String::Utf8Value s(args[args_start]); + return fill(buffer, *s, s.length()); + } + + if (Buffer::HasInstance(args[args_start])) { + Handle other = args[args_start]->ToObject(); + size_t length = Buffer::Length(other); + uint8_t* data = (uint8_t*) Buffer::Data(other); + return fill(buffer, data, length); + } + + Local illegalArgumentException = String::New( + "Second argument should be either a string, a buffer or an integer."); + return ThrowException(Exception::TypeError(illegalArgumentException)); + } +}; + +struct ReverseAction: UnaryAction { + // O(n/2) for all cases which is okay, might be optimized some more with whole-word swaps + // XXX won't this trash the L1 cache something awful? + Handle apply(Handle& buffer, const Arguments& args, uint32_t args_start) { + uint8_t* head = (uint8_t*) Buffer::Data(buffer); + uint8_t* tail = head + Buffer::Length(buffer) - 1; + + while (head < tail) { + uint8_t t = *head; + *head = *tail; + *tail = t; + ++head; + --tail; + } + + return buffer; + } +}; + +struct EqualsAction: BinaryAction { + Handle apply(Handle& buffer, const uint8_t* data, size_t size, const Arguments& args, uint32_t args_start) { + return compare(buffer, data, size) == 0 ? True() : False(); + } +}; + +struct CompareAction: BinaryAction { + Handle apply(Handle& buffer, const uint8_t* data, size_t size, const Arguments& args, uint32_t args_start) { + return Integer::New(compare(buffer, data, size)); + } +}; + +struct IndexOfAction: BinaryAction { + Handle apply(Handle& buffer, const uint8_t* data2, size_t size2, const Arguments& args, uint32_t args_start) { + const uint8_t* data = (const uint8_t*) Buffer::Data(buffer); + const size_t size = Buffer::Length(buffer); + + int32_t start = args[args_start + 1]->Int32Value(); + + if (start < 0) + start = size - std::min(size, -start); + else if (static_cast(start) > size) + start = size; + + const uint8_t* p = boyermoore_search( + data + start, size - start, data2, size2); + + const ptrdiff_t offset = p ? (p - data) : -1; + return Integer::New(offset); + } +}; + +static char toHexTable[] = "0123456789abcdef"; + +// CHECKME is this cache efficient? +static char fromHexTable[] = { + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,-1, + 10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 +}; + +inline Handle decodeHex(const uint8_t* const data, const size_t size, const Arguments& args, uint32_t args_start) { + if (size & 1) { + return ThrowException(Exception::Error(String::New( + "Odd string length, this is not hexadecimal data."))); + } + + if (size == 0) { + return String::Empty(); + } + + Handle& buffer = Buffer::New(size / 2)->handle_; + + uint8_t *src = (uint8_t *) data; + uint8_t *dst = (uint8_t *) (const uint8_t*) Buffer::Data(buffer); + + for (size_t i = 0; i < size; i += 2) { + int a = fromHexTable[*src++]; + int b = fromHexTable[*src++]; + + if (a == -1 || b == -1) { + return ThrowException(Exception::Error(String::New( + "This is not hexadecimal data."))); + } + + *dst++ = b | (a << 4); + } + + return buffer; +} + +struct FromHexAction: UnaryAction { + Handle apply(Handle& buffer, const Arguments& args, uint32_t args_start) { + const uint8_t* data = (const uint8_t*) Buffer::Data(buffer); + size_t length = Buffer::Length(buffer); + return decodeHex(data, length, args, args_start); + } +}; + +struct ToHexAction: UnaryAction { + Handle apply(Handle& buffer, const Arguments& args, uint32_t args_start) { + const size_t size = Buffer::Length(buffer); + const uint8_t* data = (const uint8_t*) Buffer::Data(buffer); + + if (size == 0) { + return String::Empty(); + } + + std::string s(size * 2, 0); + for (size_t i = 0; i < size; ++i) { + const uint8_t c = (uint8_t) data[i]; + s[i * 2] = toHexTable[c >> 4]; + s[i * 2 + 1] = toHexTable[c & 15]; + } + + return String::New(s.c_str(), s.size()); + } +}; + +// +// V8 function callbacks +// +Handle Clear(const Arguments& args) { + return ClearAction()(args); +} + +Handle Fill(const Arguments& args) { + return FillAction()(args); +} + +Handle Reverse(const Arguments& args) { + return ReverseAction()(args); +} + +Handle Equals(const Arguments& args) { + return EqualsAction()(args); +} + +Handle Compare(const Arguments& args) { + return CompareAction()(args); +} + +Handle IndexOf(const Arguments& args) { + return IndexOfAction()(args); +} + +Handle FromHex(const Arguments& args) { + return FromHexAction()(args); +} + +Handle ToHex(const Arguments& args) { + return ToHexAction()(args); +} + +Handle Concat(const Arguments& args) { + HandleScope scope; + + size_t size = 0; + for (int index = 0, length = args.Length(); index < length; ++index) { + Local arg = args[index]; + if (arg->IsString()) { + // Utf8Length() because we need the length in bytes, not characters + size += arg->ToString()->Utf8Length(); + } + else if (Buffer::HasInstance(arg)) { + size += Buffer::Length(arg->ToObject()); + } + else { + std::stringstream s; + s << "Argument #" << index << " is neither a string nor a buffer object."; + return ThrowException( + Exception::TypeError( + String::New(s.str().c_str()))); + } + } + + Buffer& dst = *Buffer::New(size); + uint8_t* s = (uint8_t*) Buffer::Data(dst.handle_); + + for (int index = 0, length = args.Length(); index < length; ++index) { + Local arg = args[index]; + if (arg->IsString()) { + String::Utf8Value v(arg); + memcpy(s, *v, v.length()); + s += v.length(); + } + else if (Buffer::HasInstance(arg)) { + Local b = arg->ToObject(); + const uint8_t* data = (const uint8_t*) Buffer::Data(b); + size_t length = Buffer::Length(b); + memcpy(s, data, length); + s += length; + } + else { + return ThrowException(Exception::Error(String::New( + "Congratulations! You have run into a bug: argument is neither a string nor a buffer object. " + "Please make the world a better place and report it."))); + } + } + + return scope.Close(dst.handle_); +} + +void RegisterModule(Handle target) { + target->Set(String::NewSymbol("concat"), FunctionTemplate::New(Concat)->GetFunction()); + target->Set(String::NewSymbol("fill"), FunctionTemplate::New(Fill)->GetFunction()); + target->Set(String::NewSymbol("clear"), FunctionTemplate::New(Clear)->GetFunction()); + target->Set(String::NewSymbol("reverse"), FunctionTemplate::New(Reverse)->GetFunction()); + target->Set(String::NewSymbol("equals"), FunctionTemplate::New(Equals)->GetFunction()); + target->Set(String::NewSymbol("compare"), FunctionTemplate::New(Compare)->GetFunction()); + target->Set(String::NewSymbol("indexOf"), FunctionTemplate::New(IndexOf)->GetFunction()); + target->Set(String::NewSymbol("fromHex"), FunctionTemplate::New(FromHex)->GetFunction()); + target->Set(String::NewSymbol("toHex"), FunctionTemplate::New(ToHex)->GetFunction()); +} + +} // anonymous namespace + +NODE_MODULE(buffertools, RegisterModule) diff --git a/node_modules/buffertools/buffertools.js b/node_modules/buffertools/buffertools.js new file mode 100644 index 0000000..132314f --- /dev/null +++ b/node_modules/buffertools/buffertools.js @@ -0,0 +1,115 @@ +/* Copyright (c) 2010, Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var buffertools = require('./build/Release/buffertools.node'); +var SlowBuffer = require('buffer').SlowBuffer; +var Buffer = require('buffer').Buffer; + +// requires node 3.1 +var events = require('events'); +var util = require('util'); + +exports.extend = function() { + var receivers; + if (arguments.length > 0) { + receivers = Array.prototype.slice.call(arguments); + } else if (typeof SlowBuffer === 'function') { + receivers = [Buffer.prototype, SlowBuffer.prototype]; + } else { + receivers = [Buffer.prototype]; + } + for (var i = 0, n = receivers.length; i < n; i += 1) { + var receiver = receivers[i]; + for (var key in buffertools) { + receiver[key] = buffertools[key]; + } + if (receiver !== exports) { + receiver.concat = function() { + var args = [this].concat(Array.prototype.slice.call(arguments)); + return buffertools.concat.apply(buffertools, args); + }; + } + } +}; +exports.extend(exports); + +// +// WritableBufferStream +// +// - never emits 'error' +// - never emits 'drain' +// +function WritableBufferStream() { + this.writable = true; + this.buffer = null; +} + +util.inherits(WritableBufferStream, events.EventEmitter); + +WritableBufferStream.prototype._append = function(buffer, encoding) { + if (!this.writable) { + throw new Error('Stream is not writable.'); + } + + if (Buffer.isBuffer(buffer)) { + // no action required + } + else if (typeof buffer == 'string') { + // TODO optimize + buffer = new Buffer(buffer, encoding || 'utf8'); + } + else { + throw new Error('Argument should be either a buffer or a string.'); + } + + // FIXME optimize! + if (this.buffer) { + this.buffer = buffertools.concat(this.buffer, buffer); + } + else { + this.buffer = new Buffer(buffer.length); + buffer.copy(this.buffer); + } +}; + +WritableBufferStream.prototype.write = function(buffer, encoding) { + this._append(buffer, encoding); + + // signal that it's safe to immediately write again + return true; +}; + +WritableBufferStream.prototype.end = function(buffer, encoding) { + if (buffer) { + this._append(buffer, encoding); + } + + this.emit('close'); + + this.writable = false; +}; + +WritableBufferStream.prototype.getBuffer = function() { + if (this.buffer) { + return this.buffer; + } + return new Buffer(0); +}; + +WritableBufferStream.prototype.toString = function() { + return this.getBuffer().toString(); +}; + +exports.WritableBufferStream = WritableBufferStream; diff --git a/node_modules/buffertools/build/Makefile b/node_modules/buffertools/build/Makefile new file mode 100644 index 0000000..ce32be1 --- /dev/null +++ b/node_modules/buffertools/build/Makefile @@ -0,0 +1,332 @@ +# We borrow heavily from the kernel build setup, though we are simpler since +# we don't have Kconfig tweaking settings on us. + +# The implicit make rules have it looking for RCS files, among other things. +# We instead explicitly write all the rules we care about. +# It's even quicker (saves ~200ms) to pass -r on the command line. +MAKEFLAGS=-r + +# The source directory tree. +srcdir := .. +abs_srcdir := $(abspath $(srcdir)) + +# The name of the builddir. +builddir_name ?= . + +# The V=1 flag on command line makes us verbosely print command lines. +ifdef V + quiet= +else + quiet=quiet_ +endif + +# Specify BUILDTYPE=Release on the command line for a release build. +BUILDTYPE ?= Release + +# Directory all our build output goes into. +# Note that this must be two directories beneath src/ for unit tests to pass, +# as they reach into the src/ directory for data with relative paths. +builddir ?= $(builddir_name)/$(BUILDTYPE) +abs_builddir := $(abspath $(builddir)) +depsdir := $(builddir)/.deps + +# Object output directory. +obj := $(builddir)/obj +abs_obj := $(abspath $(obj)) + +# We build up a list of every single one of the targets so we can slurp in the +# generated dependency rule Makefiles in one pass. +all_deps := + + + +CC.target ?= $(CC) +CFLAGS.target ?= $(CFLAGS) +CXX.target ?= $(CXX) +CXXFLAGS.target ?= $(CXXFLAGS) +LINK.target ?= $(LINK) +LDFLAGS.target ?= $(LDFLAGS) +AR.target ?= $(AR) + +# C++ apps need to be linked with g++. +# +# Note: flock is used to seralize linking. Linking is a memory-intensive +# process so running parallel links can often lead to thrashing. To disable +# the serialization, override LINK via an envrionment variable as follows: +# +# export LINK=g++ +# +# This will allow make to invoke N linker processes as specified in -jN. +LINK ?= flock $(builddir)/linker.lock $(CXX.target) + +# TODO(evan): move all cross-compilation logic to gyp-time so we don't need +# to replicate this environment fallback in make as well. +CC.host ?= gcc +CFLAGS.host ?= +CXX.host ?= g++ +CXXFLAGS.host ?= +LINK.host ?= $(CXX.host) +LDFLAGS.host ?= +AR.host ?= ar + +# Define a dir function that can handle spaces. +# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions +# "leading spaces cannot appear in the text of the first argument as written. +# These characters can be put into the argument value by variable substitution." +empty := +space := $(empty) $(empty) + +# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces +replace_spaces = $(subst $(space),?,$1) +unreplace_spaces = $(subst ?,$(space),$1) +dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) + +# Flags to make gcc output dependency info. Note that you need to be +# careful here to use the flags that ccache and distcc can understand. +# We write to a dep file on the side first and then rename at the end +# so we can't end up with a broken dep file. +depfile = $(depsdir)/$(call replace_spaces,$@).d +DEPFLAGS = -MMD -MF $(depfile).raw + +# We have to fixup the deps output in a few ways. +# (1) the file output should mention the proper .o file. +# ccache or distcc lose the path to the target, so we convert a rule of +# the form: +# foobar.o: DEP1 DEP2 +# into +# path/to/foobar.o: DEP1 DEP2 +# (2) we want missing files not to cause us to fail to build. +# We want to rewrite +# foobar.o: DEP1 DEP2 \ +# DEP3 +# to +# DEP1: +# DEP2: +# DEP3: +# so if the files are missing, they're just considered phony rules. +# We have to do some pretty insane escaping to get those backslashes +# and dollar signs past make, the shell, and sed at the same time. +# Doesn't work with spaces, but that's fine: .d files have spaces in +# their names replaced with other characters. +define fixup_dep +# The depfile may not exist if the input file didn't have any #includes. +touch $(depfile).raw +# Fixup path as in (1). +sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) +# Add extra rules as in (2). +# We remove slashes and replace spaces with new lines; +# remove blank lines; +# delete the first line and append a colon to the remaining lines. +sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ + grep -v '^$$' |\ + sed -e 1d -e 's|$$|:|' \ + >> $(depfile) +rm $(depfile).raw +endef + +# Command definitions: +# - cmd_foo is the actual command to run; +# - quiet_cmd_foo is the brief-output summary of the command. + +quiet_cmd_cc = CC($(TOOLSET)) $@ +cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< + +quiet_cmd_cxx = CXX($(TOOLSET)) $@ +cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< + +quiet_cmd_touch = TOUCH $@ +cmd_touch = touch $@ + +quiet_cmd_copy = COPY $@ +# send stderr to /dev/null to ignore messages when linking directories. +cmd_copy = rm -rf "$@" && cp -af "$<" "$@" + +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) + +# Due to circular dependencies between libraries :(, we wrap the +# special "figure out circular dependencies" flags around the entire +# input list during linking. +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) + +# We support two kinds of shared objects (.so): +# 1) shared_library, which is just bundling together many dependent libraries +# into a link line. +# 2) loadable_module, which is generating a module intended for dlopen(). +# +# They differ only slightly: +# In the former case, we want to package all dependent code into the .so. +# In the latter case, we want to package just the API exposed by the +# outermost module. +# This means shared_library uses --whole-archive, while loadable_module doesn't. +# (Note that --whole-archive is incompatible with the --start-group used in +# normal linking.) + +# Other shared-object link notes: +# - Set SONAME to the library filename so our binaries don't reference +# the local, absolute paths used on the link command-line. +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) + + +# Define an escape_quotes function to escape single quotes. +# This allows us to handle quotes properly as long as we always use +# use single quotes and escape_quotes. +escape_quotes = $(subst ','\'',$(1)) +# This comment is here just to include a ' to unconfuse syntax highlighting. +# Define an escape_vars function to escape '$' variable syntax. +# This allows us to read/write command lines with shell variables (e.g. +# $LD_LIBRARY_PATH), without triggering make substitution. +escape_vars = $(subst $$,$$$$,$(1)) +# Helper that expands to a shell command to echo a string exactly as it is in +# make. This uses printf instead of echo because printf's behaviour with respect +# to escape sequences is more portable than echo's across different shells +# (e.g., dash, bash). +exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' + +# Helper to compare the command we're about to run against the command +# we logged the last time we ran the command. Produces an empty +# string (false) when the commands match. +# Tricky point: Make has no string-equality test function. +# The kernel uses the following, but it seems like it would have false +# positives, where one string reordered its arguments. +# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ +# $(filter-out $(cmd_$@), $(cmd_$(1)))) +# We instead substitute each for the empty string into the other, and +# say they're equal if both substitutions produce the empty string. +# .d files contain ? instead of spaces, take that into account. +command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ + $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) + +# Helper that is non-empty when a prerequisite changes. +# Normally make does this implicitly, but we force rules to always run +# so we can check their command lines. +# $? -- new prerequisites +# $| -- order-only dependencies +prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) + +# Helper that executes all postbuilds until one fails. +define do_postbuilds + @E=0;\ + for p in $(POSTBUILDS); do\ + eval $$p;\ + E=$$?;\ + if [ $$E -ne 0 ]; then\ + break;\ + fi;\ + done;\ + if [ $$E -ne 0 ]; then\ + rm -rf "$@";\ + exit $$E;\ + fi +endef + +# do_cmd: run a command via the above cmd_foo names, if necessary. +# Should always run for a given target to handle command-line changes. +# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. +# Third argument, if non-zero, makes it do POSTBUILDS processing. +# Note: We intentionally do NOT call dirx for depfile, since it contains ? for +# spaces already and dirx strips the ? characters. +define do_cmd +$(if $(or $(command_changed),$(prereq_changed)), + @$(call exact_echo, $($(quiet)cmd_$(1))) + @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" + $(if $(findstring flock,$(word 1,$(cmd_$1))), + @$(cmd_$(1)) + @echo " $(quiet_cmd_$(1)): Finished", + @$(cmd_$(1)) + ) + @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) + @$(if $(2),$(fixup_dep)) + $(if $(and $(3), $(POSTBUILDS)), + $(call do_postbuilds) + ) +) +endef + +# Declare the "all" target first so it is the default, +# even though we don't have the deps yet. +.PHONY: all +all: + +# make looks for ways to re-generate included makefiles, but in our case, we +# don't have a direct way. Explicitly telling make that it has nothing to do +# for them makes it go faster. +%.d: ; + +# Use FORCE_DO_CMD to force a target to run. Should be coupled with +# do_cmd. +.PHONY: FORCE_DO_CMD +FORCE_DO_CMD: + +TOOLSET := target +# Suffix rules, putting all outputs into $(obj). +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) + +# Try building from generated source, too. +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) + +$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) + + +ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ + $(findstring $(join ^,$(prefix)),\ + $(join ^,buffertools.target.mk)))),) + include buffertools.target.mk +endif + +quiet_cmd_regen_makefile = ACTION Regenerating $@ +cmd_regen_makefile = cd $(srcdir); /usr/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "--toplevel-dir=." -I/home/matt/site/node_modules/buffertools/build/config.gypi -I/usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/home/matt/.node-gyp/0.10.24/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/home/matt/.node-gyp/0.10.24" "-Dmodule_root_dir=/home/matt/site/node_modules/buffertools" binding.gyp +Makefile: $(srcdir)/../../../.node-gyp/0.10.24/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi + $(call do_cmd,regen_makefile) + +# "all" is a concatenation of the "all" targets from all the included +# sub-makefiles. This is just here to clarify. +all: + +# Add in dependency-tracking rules. $(all_deps) is the list of every single +# target in our tree. Only consider the ones with .d (dependency) info: +d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) +ifneq ($(d_files),) + include $(d_files) +endif diff --git a/node_modules/buffertools/build/Release/.deps/Release/buffertools.node.d b/node_modules/buffertools/build/Release/.deps/Release/buffertools.node.d new file mode 100644 index 0000000..d4de781 --- /dev/null +++ b/node_modules/buffertools/build/Release/.deps/Release/buffertools.node.d @@ -0,0 +1 @@ +cmd_Release/buffertools.node := rm -rf "Release/buffertools.node" && cp -af "Release/obj.target/buffertools.node" "Release/buffertools.node" diff --git a/node_modules/buffertools/build/Release/.deps/Release/obj.target/buffertools.node.d b/node_modules/buffertools/build/Release/.deps/Release/obj.target/buffertools.node.d new file mode 100644 index 0000000..d93744f --- /dev/null +++ b/node_modules/buffertools/build/Release/.deps/Release/obj.target/buffertools.node.d @@ -0,0 +1 @@ +cmd_Release/obj.target/buffertools.node := flock ./Release/linker.lock g++ -shared -pthread -rdynamic -m64 -Wl,-soname=buffertools.node -o Release/obj.target/buffertools.node -Wl,--start-group Release/obj.target/buffertools/buffertools.o -Wl,--end-group diff --git a/node_modules/buffertools/build/Release/.deps/Release/obj.target/buffertools/buffertools.o.d b/node_modules/buffertools/build/Release/.deps/Release/obj.target/buffertools/buffertools.o.d new file mode 100644 index 0000000..0a9f5af --- /dev/null +++ b/node_modules/buffertools/build/Release/.deps/Release/obj.target/buffertools/buffertools.o.d @@ -0,0 +1,24 @@ +cmd_Release/obj.target/buffertools/buffertools.o := g++ '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/home/matt/.node-gyp/0.10.24/src -I/home/matt/.node-gyp/0.10.24/deps/uv/include -I/home/matt/.node-gyp/0.10.24/deps/v8/include -fPIC -Wall -Wextra -Wno-unused-parameter -pthread -m64 -O2 -fno-strict-aliasing -fno-tree-vrp -fno-omit-frame-pointer -fno-rtti -fno-exceptions -MMD -MF ./Release/.deps/Release/obj.target/buffertools/buffertools.o.d.raw -c -o Release/obj.target/buffertools/buffertools.o ../buffertools.cc +Release/obj.target/buffertools/buffertools.o: ../buffertools.cc \ + /home/matt/.node-gyp/0.10.24/deps/v8/include/v8.h \ + /home/matt/.node-gyp/0.10.24/deps/v8/include/v8stdint.h \ + /home/matt/.node-gyp/0.10.24/src/node.h \ + /home/matt/.node-gyp/0.10.24/deps/uv/include/uv.h \ + /home/matt/.node-gyp/0.10.24/deps/uv/include/uv-private/uv-unix.h \ + /home/matt/.node-gyp/0.10.24/deps/uv/include/uv-private/ngx-queue.h \ + /home/matt/.node-gyp/0.10.24/deps/uv/include/uv-private/uv-linux.h \ + /home/matt/.node-gyp/0.10.24/src/node_object_wrap.h \ + /home/matt/.node-gyp/0.10.24/src/node.h \ + /home/matt/.node-gyp/0.10.24/src/node_buffer.h ../BoyerMoore.h +../buffertools.cc: +/home/matt/.node-gyp/0.10.24/deps/v8/include/v8.h: +/home/matt/.node-gyp/0.10.24/deps/v8/include/v8stdint.h: +/home/matt/.node-gyp/0.10.24/src/node.h: +/home/matt/.node-gyp/0.10.24/deps/uv/include/uv.h: +/home/matt/.node-gyp/0.10.24/deps/uv/include/uv-private/uv-unix.h: +/home/matt/.node-gyp/0.10.24/deps/uv/include/uv-private/ngx-queue.h: +/home/matt/.node-gyp/0.10.24/deps/uv/include/uv-private/uv-linux.h: +/home/matt/.node-gyp/0.10.24/src/node_object_wrap.h: +/home/matt/.node-gyp/0.10.24/src/node.h: +/home/matt/.node-gyp/0.10.24/src/node_buffer.h: +../BoyerMoore.h: diff --git a/node_modules/buffertools/build/Release/buffertools.node b/node_modules/buffertools/build/Release/buffertools.node new file mode 100755 index 0000000..d53a3c4 Binary files /dev/null and b/node_modules/buffertools/build/Release/buffertools.node differ diff --git a/node_modules/buffertools/build/Release/linker.lock b/node_modules/buffertools/build/Release/linker.lock new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/buffertools/build/Release/obj.target/buffertools.node b/node_modules/buffertools/build/Release/obj.target/buffertools.node new file mode 100755 index 0000000..d53a3c4 Binary files /dev/null and b/node_modules/buffertools/build/Release/obj.target/buffertools.node differ diff --git a/node_modules/buffertools/build/Release/obj.target/buffertools/buffertools.o b/node_modules/buffertools/build/Release/obj.target/buffertools/buffertools.o new file mode 100644 index 0000000..9444174 Binary files /dev/null and b/node_modules/buffertools/build/Release/obj.target/buffertools/buffertools.o differ diff --git a/node_modules/buffertools/build/binding.Makefile b/node_modules/buffertools/build/binding.Makefile new file mode 100644 index 0000000..8c8414a --- /dev/null +++ b/node_modules/buffertools/build/binding.Makefile @@ -0,0 +1,6 @@ +# This file is generated by gyp; do not edit. + +export builddir_name ?= build/./. +.PHONY: all +all: + $(MAKE) buffertools diff --git a/node_modules/buffertools/build/buffertools.target.mk b/node_modules/buffertools/build/buffertools.target.mk new file mode 100644 index 0000000..49593af --- /dev/null +++ b/node_modules/buffertools/build/buffertools.target.mk @@ -0,0 +1,130 @@ +# This file is generated by gyp; do not edit. + +TOOLSET := target +TARGET := buffertools +DEFS_Debug := \ + '-D_LARGEFILE_SOURCE' \ + '-D_FILE_OFFSET_BITS=64' \ + '-DBUILDING_NODE_EXTENSION' \ + '-DDEBUG' \ + '-D_DEBUG' + +# Flags passed to all source files. +CFLAGS_Debug := \ + -fPIC \ + -Wall \ + -Wextra \ + -Wno-unused-parameter \ + -pthread \ + -m64 \ + -g \ + -O0 + +# Flags passed to only C files. +CFLAGS_C_Debug := + +# Flags passed to only C++ files. +CFLAGS_CC_Debug := \ + -fno-rtti \ + -fno-exceptions + +INCS_Debug := \ + -I/home/matt/.node-gyp/0.10.24/src \ + -I/home/matt/.node-gyp/0.10.24/deps/uv/include \ + -I/home/matt/.node-gyp/0.10.24/deps/v8/include + +DEFS_Release := \ + '-D_LARGEFILE_SOURCE' \ + '-D_FILE_OFFSET_BITS=64' \ + '-DBUILDING_NODE_EXTENSION' + +# Flags passed to all source files. +CFLAGS_Release := \ + -fPIC \ + -Wall \ + -Wextra \ + -Wno-unused-parameter \ + -pthread \ + -m64 \ + -O2 \ + -fno-strict-aliasing \ + -fno-tree-vrp \ + -fno-omit-frame-pointer + +# Flags passed to only C files. +CFLAGS_C_Release := + +# Flags passed to only C++ files. +CFLAGS_CC_Release := \ + -fno-rtti \ + -fno-exceptions + +INCS_Release := \ + -I/home/matt/.node-gyp/0.10.24/src \ + -I/home/matt/.node-gyp/0.10.24/deps/uv/include \ + -I/home/matt/.node-gyp/0.10.24/deps/v8/include + +OBJS := \ + $(obj).target/$(TARGET)/buffertools.o + +# Add to the list of files we specially track dependencies for. +all_deps += $(OBJS) + +# CFLAGS et al overrides must be target-local. +# See "Target-specific Variable Values" in the GNU Make manual. +$(OBJS): TOOLSET := $(TOOLSET) +$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) +$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) + +# Suffix rules, putting all outputs into $(obj). + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +# Try building from generated source, too. + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +# End of this set of suffix rules +### Rules for final target. +LDFLAGS_Debug := \ + -pthread \ + -rdynamic \ + -m64 + +LDFLAGS_Release := \ + -pthread \ + -rdynamic \ + -m64 + +LIBS := + +$(obj).target/buffertools.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) +$(obj).target/buffertools.node: LIBS := $(LIBS) +$(obj).target/buffertools.node: TOOLSET := $(TOOLSET) +$(obj).target/buffertools.node: $(OBJS) FORCE_DO_CMD + $(call do_cmd,solink_module) + +all_deps += $(obj).target/buffertools.node +# Add target alias +.PHONY: buffertools +buffertools: $(builddir)/buffertools.node + +# Copy this to the executable output path. +$(builddir)/buffertools.node: TOOLSET := $(TOOLSET) +$(builddir)/buffertools.node: $(obj).target/buffertools.node FORCE_DO_CMD + $(call do_cmd,copy) + +all_deps += $(builddir)/buffertools.node +# Short alias for building this executable. +.PHONY: buffertools.node +buffertools.node: $(obj).target/buffertools.node $(builddir)/buffertools.node + +# Add executable to "all" target. +.PHONY: all +all: $(builddir)/buffertools.node + diff --git a/node_modules/buffertools/build/config.gypi b/node_modules/buffertools/build/config.gypi new file mode 100644 index 0000000..f5332b9 --- /dev/null +++ b/node_modules/buffertools/build/config.gypi @@ -0,0 +1,115 @@ +# Do not edit. File was generated by node-gyp's "configure" step +{ + "target_defaults": { + "cflags": [], + "default_configuration": "Release", + "defines": [], + "include_dirs": [], + "libraries": [] + }, + "variables": { + "clang": 0, + "gcc_version": 48, + "host_arch": "x64", + "node_install_npm": "true", + "node_prefix": "/usr", + "node_shared_cares": "false", + "node_shared_http_parser": "false", + "node_shared_libuv": "false", + "node_shared_openssl": "false", + "node_shared_v8": "false", + "node_shared_zlib": "false", + "node_tag": "", + "node_unsafe_optimizations": 0, + "node_use_dtrace": "false", + "node_use_etw": "false", + "node_use_openssl": "true", + "node_use_perfctr": "false", + "node_use_systemtap": "false", + "python": "/usr/bin/python", + "target_arch": "x64", + "v8_enable_gdbjit": 0, + "v8_no_strict_aliasing": 1, + "v8_use_snapshot": "false", + "nodedir": "/home/matt/.node-gyp/0.10.24", + "copy_dev_lib": "true", + "standalone_static_library": 1, + "cache_lock_stale": "60000", + "sign_git_tag": "", + "always_auth": "", + "user_agent": "node/v0.10.24 linux x64", + "bin_links": "true", + "key": "", + "description": "true", + "fetch_retries": "2", + "heading": "npm", + "user": "", + "force": "", + "cache_min": "10", + "init_license": "ISC", + "editor": "vi", + "rollback": "true", + "cache_max": "null", + "userconfig": "/home/matt/.npmrc", + "engine_strict": "", + "init_author_name": "", + "init_author_url": "", + "tmp": "/home/matt/tmp", + "depth": "null", + "save_dev": "", + "usage": "", + "https_proxy": "", + "onload_script": "", + "rebuild_bundle": "true", + "save_bundle": "", + "shell": "/bin/bash", + "prefix": "/usr", + "registry": "https://registry.npmjs.org/", + "browser": "", + "cache_lock_wait": "10000", + "save_optional": "", + "searchopts": "", + "versions": "", + "cache": "/home/matt/.npm", + "ignore_scripts": "", + "searchsort": "name", + "version": "", + "local_address": "", + "viewer": "man", + "color": "true", + "fetch_retry_mintimeout": "10000", + "umask": "18", + "fetch_retry_maxtimeout": "60000", + "message": "%s", + "cert": "", + "global": "", + "link": "", + "save": "", + "unicode": "true", + "long": "", + "production": "", + "unsafe_perm": "true", + "node_version": "v0.10.24", + "tag": "latest", + "git_tag_version": "true", + "shrinkwrap": "true", + "fetch_retry_factor": "10", + "npat": "", + "proprietary_attribs": "true", + "strict_ssl": "true", + "username": "", + "dev": "", + "globalconfig": "/usr/etc/npmrc", + "init_module": "/home/matt/.npm-init.js", + "parseable": "", + "globalignorefile": "/usr/etc/npmignore", + "cache_lock_retries": "10", + "group": "1000", + "init_author_email": "", + "searchexclude": "", + "git": "git", + "optional": "true", + "email": "", + "json": "" + } +} diff --git a/node_modules/buffertools/package.json b/node_modules/buffertools/package.json new file mode 100644 index 0000000..d4b6c17 --- /dev/null +++ b/node_modules/buffertools/package.json @@ -0,0 +1,57 @@ +{ + "name": "buffertools", + "main": "buffertools", + "version": "2.0.0", + "keywords": [ + "buffer", + "buffers" + ], + "description": "Working with node.js buffers made easy.", + "homepage": "https://github.com/bnoordhuis/node-buffertools", + "author": { + "name": "Ben Noordhuis", + "email": "info@bnoordhuis.nl", + "url": "http://bnoordhuis.nl/" + }, + "repository": { + "type": "git", + "url": "https://github.com/bnoordhuis/node-buffertools.git" + }, + "engines": { + "node": ">=0.3.0" + }, + "license": "ISC", + "readmeFilename": "README.md", + "scripts": { + "install": "node-gyp rebuild" + }, + "gypfile": true, + "readme": "# node-buffertools\n\nUtilities for manipulating buffers.\n\n## Installing the module\n\nEasy! With [npm](http://npmjs.org/):\n\n\tnpm install buffertools\n\nFrom source:\n\n\tnode-gyp configure\n\tnode-gyp build\n\nNow you can include the module in your project.\n\n\trequire('buffertools').extend(); // extend Buffer.prototype\n\tvar buf = new Buffer(42); // create a 42 byte buffer\n\tbuf.clear(); // clear it!\n\nIf you don't want to extend the Buffer class's prototype (recommended):\n\n\tvar buffertools = require('buffertools');\n\tvar buf = new Buffer(42);\n\tbuffertools.clear(buf);\n\n## Methods\n\nNote that most methods that take a buffer as an argument, will also accept a string.\n\n### buffertools.extend([object], [object...])\n\nExtend the arguments with the buffertools methods. If called without arguments,\ndefaults to `[Buffer.prototype, SlowBuffer.prototype]`. Extending prototypes\nonly makes sense for classes that derive from `Buffer`.\n\nbuffertools v1.x extended the `Buffer` prototype by default. In v2.x, it is\nopt-in. The reason for that is that buffertools was originally developed for\nnode.js v0.3 (or maybe v0.2, I don't remember exactly when buffers were added)\nwhere the `Buffer` class was devoid of any useful methods. Over the years, it\nhas grown a number of utility methods, some of which conflict with the\nbuffertools methods of the same name, like `Buffer#fill()`.\n\n### Buffer#clear()\n### buffertools.clear(buffer)\n\nClear the buffer. This is equivalent to `Buffer#fill(0)`.\nReturns the buffer object so you can chain method calls.\n\n### Buffer#compare(buffer|string)\n### buffertools.compare(buffer, buffer|string)\n\nLexicographically compare two buffers. Returns a number less than zero\nif a < b, zero if a == b or greater than zero if a > b.\n\nBuffers are considered equal when they are of the same length and contain\nthe same binary data.\n\nSmaller buffers are considered to be less than larger ones. Some buffers\nfind this hurtful.\n\n### Buffer#concat(a, b, c, ...)\n### buffertools.concat(a, b, c, ...)\n\nConcatenate two or more buffers/strings and return the result. Example:\n\n\t// identical to new Buffer('foobarbaz')\n\ta = new Buffer('foo');\n\tb = new Buffer('bar');\n\tc = a.concat(b, 'baz');\n\tconsole.log(a, b, c); // \"foo bar foobarbaz\"\n\n\t// static variant\n\tbuffertools.concat('foo', new Buffer('bar'), 'baz');\n\n### Buffer#equals(buffer|string)\n### buffertools.equals(buffer, buffer|string)\n\nReturns true if this buffer equals the argument, false otherwise.\n\nBuffers are considered equal when they are of the same length and contain\nthe same binary data.\n\nCaveat emptor: If your buffers contain strings with different character encodings,\nthey will most likely *not* be equal.\n\n### Buffer#fill(integer|string|buffer)\n### buffertools.fill(buffer, integer|string|buffer)\n\nFill the buffer (repeatedly if necessary) with the argument.\nReturns the buffer object so you can chain method calls.\n\n### Buffer#fromHex()\n### buffertools.fromHex(buffer)\n\nAssumes this buffer contains hexadecimal data (packed, no whitespace)\nand decodes it into binary data. Returns a new buffer with the decoded\ncontent. Throws an exception if non-hexadecimal data is encountered.\n\n### Buffer#indexOf(buffer|string, [start=0])\n### buffertools.indexOf(buffer, buffer|string, [start=0])\n\nSearch this buffer for the first occurrence of the argument, starting at\noffset `start`. Returns the zero-based index or -1 if there is no match.\n\n### Buffer#reverse()\n### buffertools.reverse(buffer)\n\nReverse the content of the buffer in place. Example:\n\n\tb = new Buffer('live');\n\tb.reverse();\n\tconsole.log(b); // \"evil\"\n\n### Buffer#toHex()\n### buffertools.toHex(buffer)\n\nReturns the contents of this buffer encoded as a hexadecimal string.\n\n## Classes\n\nSingular, actually. To wit:\n\n## WritableBufferStream\n\nThis is a regular node.js [writable stream](http://nodejs.org/docs/v0.3.4/api/streams.html#writable_Stream)\nthat accumulates the data it receives into a buffer.\n\nExample usage:\n\n\t// slurp stdin into a buffer\n\tprocess.stdin.resume();\n\tostream = new WritableBufferStream();\n\tutil.pump(process.stdin, ostream);\n\tconsole.log(ostream.getBuffer());\n\nThe stream never emits 'error' or 'drain' events.\n\n### WritableBufferStream.getBuffer()\n\nReturn the data accumulated so far as a buffer.\n\n## TODO\n\n* Logical operations on buffers (AND, OR, XOR).\n* Add lastIndexOf() functions.\n\n## License\n\nCopyright (c) 2010, Ben Noordhuis \n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n", + "contributors": [ + { + "name": "Ben Noordhuis", + "email": "info@bnoordhuis.nl" + }, + { + "name": "Stefan Thomas", + "email": "justmoon@members.fsf.org" + }, + { + "name": "Nathan Rajlich", + "email": "nathan@tootallnate.net" + }, + { + "name": "Dane Springmeyer", + "email": "dane@dbsgeo.com" + }, + { + "name": "Barret Schloerke", + "email": "schloerke@gmail.com" + } + ], + "bugs": { + "url": "https://github.com/bnoordhuis/node-buffertools/issues" + }, + "_id": "buffertools@2.0.0", + "_from": "buffertools@" +} diff --git a/node_modules/buffertools/test.js b/node_modules/buffertools/test.js new file mode 100644 index 0000000..17cf123 --- /dev/null +++ b/node_modules/buffertools/test.js @@ -0,0 +1,136 @@ +/* Copyright (c) 2010, Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var buffertools = require('./buffertools'); +var Buffer = require('buffer').Buffer; +var assert = require('assert'); + +var WritableBufferStream = buffertools.WritableBufferStream; + +// Extend Buffer.prototype and SlowBuffer.prototype. +buffertools.extend(); + +// these trigger the code paths for UnaryAction and BinaryAction +assert.throws(function() { buffertools.clear({}); }); +assert.throws(function() { buffertools.equals({}, {}); }); + +var a = new Buffer('abcd'), b = new Buffer('abcd'), c = new Buffer('efgh'); +assert.ok(a.equals(b)); +assert.ok(!a.equals(c)); +assert.ok(a.equals('abcd')); +assert.ok(!a.equals('efgh')); + +assert.ok(a.compare(a) == 0); +assert.ok(a.compare(c) < 0); +assert.ok(c.compare(a) > 0); + +assert.ok(a.compare('abcd') == 0); +assert.ok(a.compare('efgh') < 0); +assert.ok(c.compare('abcd') > 0); + +b = new Buffer('****'); +assert.equal(b, b.clear()); +assert.equal(b.inspect(), ''); // FIXME brittle test + +b = new Buffer(4); +assert.equal(b, b.fill(42)); +assert.equal(b.inspect(), ''); + +b = new Buffer(4); +assert.equal(b, b.fill('*')); +assert.equal(b.inspect(), ''); + +b = new Buffer(4); +assert.equal(b, b.fill('ab')); +assert.equal(b.inspect(), ''); + +b = new Buffer(4); +assert.equal(b, b.fill('abcd1234')); +assert.equal(b.inspect(), ''); + +b = new Buffer('Hello, world!'); +assert.equal(-1, b.indexOf(new Buffer('foo'))); +assert.equal(0, b.indexOf(new Buffer('Hell'))); +assert.equal(7, b.indexOf(new Buffer('world'))); +assert.equal(7, b.indexOf(new Buffer('world!'))); +assert.equal(-1, b.indexOf('foo')); +assert.equal(0, b.indexOf('Hell')); +assert.equal(7, b.indexOf('world')); +assert.equal(-1, b.indexOf('')); +assert.equal(-1, b.indexOf('x')); +assert.equal(7, b.indexOf('w')); +assert.equal(0, b.indexOf('Hello, world!')); +assert.equal(-1, b.indexOf('Hello, world!1')); +assert.equal(7, b.indexOf('world', 7)); +assert.equal(-1, b.indexOf('world', 8)); +assert.equal(7, b.indexOf('world', -256)); +assert.equal(7, b.indexOf('world', -6)); +assert.equal(-1, b.indexOf('world', -5)); +assert.equal(-1, b.indexOf('world', 256)); +assert.equal(-1, b.indexOf('', 256)); + +b = new Buffer("\t \r\n"); +assert.equal('09200d0a', b.toHex()); +assert.equal(b.toString(), new Buffer('09200d0a').fromHex().toString()); + +// https://github.com/bnoordhuis/node-buffertools/pull/9 +b = new Buffer(4); +b[0] = 0x98; +b[1] = 0x95; +b[2] = 0x60; +b[3] = 0x2f; +assert.equal('9895602f', b.toHex()); + +assert.equal('', buffertools.concat()); +assert.equal('', buffertools.concat('')); +assert.equal('foobar', new Buffer('foo').concat('bar')); +assert.equal('foobarbaz', buffertools.concat(new Buffer('foo'), 'bar', new Buffer('baz'))); +assert.throws(function() { buffertools.concat('foo', 123, 'baz'); }); +// assert that the buffer is copied, not returned as-is +a = new Buffer('For great justice.'), b = buffertools.concat(a); +assert.equal(a.toString(), b.toString()); +assert.notEqual(a, b); + +assert.equal('', new Buffer('').reverse()); +assert.equal('For great justice.', new Buffer('.ecitsuj taerg roF').reverse()); + +// bug fix, see http://github.com/bnoordhuis/node-buffertools/issues#issue/5 +var endOfHeader = new Buffer('\r\n\r\n'); +assert.equal(0, endOfHeader.indexOf(endOfHeader)); +assert.equal(0, endOfHeader.indexOf('\r\n\r\n')); + +// feature request, see https://github.com/bnoordhuis/node-buffertools/issues#issue/8 +var closed = false; +var stream = new WritableBufferStream(); + +stream.on('close', function() { closed = true; }); +stream.write('Hello,'); +stream.write(' '); +stream.write('world!'); +stream.end(); + +assert.equal(true, closed); +assert.equal(false, stream.writable); +assert.equal('Hello, world!', stream.toString()); +assert.equal('Hello, world!', stream.getBuffer().toString()); + +// closed stream should throw +assert.throws(function() { stream.write('ZIG!'); }); + +// GH-10 indexOf sometimes incorrectly returns -1 +for (var i = 0; i < 100; i++) { + var buffer = new Buffer('9A8B3F4491734D18DEFC6D2FA96A2D3BC1020EECB811F037F977D039B4713B1984FBAB40FCB4D4833D4A31C538B76EB50F40FA672866D8F50D0A1063666721B8D8322EDEEC74B62E5F5B959393CD3FCE831CC3D1FA69D79C758853AFA3DC54D411043263596BAD1C9652970B80869DD411E82301DF93D47DCD32421A950EF3E555152E051C6943CC3CA71ED0461B37EC97C5A00EBACADAA55B9A7835F148DEF8906914617C6BD3A38E08C14735FC2EFE075CC61DFE5F2F9686AB0D0A3926604E320160FDC1A4488A323CB4308CDCA4FD9701D87CE689AF999C5C409854B268D00B063A89C2EEF6673C80A4F4D8D0A00163082EDD20A2F1861512F6FE9BB479A22A3D4ACDD2AA848254BA74613190957C7FCD106BF7441946D0E1A562DA68BC37752B1551B8855C8DA08DFE588902D44B2CAB163F3D7D7706B9CC78900D0AFD5DAE5492535A17DB17E24389F3BAA6F5A95B9F6FE955193D40932B5988BC53E49CAC81955A28B81F7B36A1EDA3B4063CBC187B0488FCD51FAE71E4FBAEE56059D847591B960921247A6B7C5C2A7A757EC62A2A2A2A2A2A2A25552591C03EF48994BD9F594A5E14672F55359EF1B38BF2976D1216C86A59847A6B7C4A5C585A0D0A2A6D9C8F8B9E999C2A836F786D577A79816F7C577A797D7E576B506B57A05B5B8C4A8D99989E8B8D9E644A6B9D9D8F9C9E4A504A6B968B93984A93984A988FA19D919C999F9A4A8B969E588C93988B9C938F9D588D8B9C9E9999989D58909C8F988D92588E0D0A3D79656E642073697A653D373035393620706172743D31207063726333323D33616230646235300D0A2E0D0A').fromHex(); + assert.equal(551, buffer.indexOf('=yend')); +} diff --git a/node_modules/buffertools/wscript b/node_modules/buffertools/wscript new file mode 100644 index 0000000..0aed740 --- /dev/null +++ b/node_modules/buffertools/wscript @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +# Copyright (c) 2010, Ben Noordhuis +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +def set_options(ctx): + ctx.tool_options('compiler_cxx') + +def configure(ctx): + ctx.check_tool('compiler_cxx') + ctx.check_tool('node_addon') + ctx.env.set_variant('Release') + +def build(ctx): + t = ctx.new_task_gen('cxx', 'shlib', 'node_addon') + t.target = 'buffertools' + t.source = 'buffertools.cc' diff --git a/transactions.js b/transactions.js new file mode 100644 index 0000000..4035d2a --- /dev/null +++ b/transactions.js @@ -0,0 +1,182 @@ +/* + +Ported from https://github.com/slush0/stratum-mining + + */ + + +var binpack = require('binpack'); +var buffertools = require('buffertools'); + +var util = require('./util.js'); + + +function COutPoint(){ + this.hash = 0; + this.n = 0; +} +COutPoint.prototype = { + deserialize: function(f){ + this.hash = util.hexFromReversedBuffer(f.read(32)); + this.n = f.read(4).readUInt32LE(0); + }, + serialize: function(){ + return Buffer.concat([ + util.uint256BufferFromHash(this.hash), + binpack.packUInt32(this.n, 'little') + ]); + } +}; + + +function CTxIn(){ + this.prevout = new COutPoint(); + this.scriptSig = ""; + this.nSequence = 0; +} +CTxIn.prototype = { + deserialize: function(f){ + this.prevout = new COutPoint(); + this.prevout.deserialize(f); + this.scriptSig = util.deser_string(f); + this.nSequence = f.read(4).readUInt32LE(0); + }, + serialize: function(){ + return Buffer.concat([ + this.prevout.serialize(), + util.ser_string(this.scriptSig), + binpack.packUInt32(this.nSequence, 'little') + ]); + } +}; + + +function CTxOut(){ + this.nValue = 0; + this.scriptPubKey = ''; +} +CTxOut.prototype = { + deserialize: function(f){ + this.nValue = f.read(8).readInt64LE(0); + this.scriptPubKey = util.deser_string(f); + }, + serialize: function(){ + return Buffer.concat([ + binpack.packInt64(this.nValue, 'little'), + util.ser_string(this.scriptPubKey) + ]); + } +}; + + +function CTransaction(){ + this.nVersion = 1; + this.vin = []; + this.vout = []; + this.nLockTime = 0; + this.sha256 = null; +}; +CTransaction.prototype = { + deserialize: function(f){ + util.makeBufferReadable(f); + this.nVersion = f.read(4).readInt32LE(0); + this.vin = util.deser_vector(f, CTxIn); + this.vout = util.deser_vector(f, CTxOut); + this.nLockTime = r.read(4).readUInt32LE(0); + this.sha256 = null; + }, + serialize: function(){ + return Buffer.concat([ + binpack.packInt32(this.nVersion, 'little'), + util.ser_vector(this.vin), + util.ser_vector(this.vout), + binpack.packUInt32(this.nLockTime, 'little') + ]); + } +}; +exports.CTransaction = CTransaction; + + +var extranonce_placeholder = new Buffer('f000000ff111111f', 'hex'); +exports.extranonce_size = extranonce_placeholder.length; + + +var GenerationNew = function(blockTemplate, address){ + return Buffer.concat([ + binpack.packInt32(1, 'little'), //transaction version + new Buffer([1]), //length of transaction inputs (which is 1, the coinbase) + Buffer.concat([ //serialized coinbase tx input + Buffer.concat([ //prevout + util.uint256BufferFromHash(0), //hash + binpack.packUInt32(Math.pow(2, 32) - 1, 'little') //index + ]), + util.ser_string(Buffer.concat([ //script length (varint), script + Buffer.concat([ + util.serializeNumber(blockTemplate.rpcData.height), + new Buffer(blockTemplate.rpcData.coinbaseaux.flags, 'hex'), + util.serializeNumber(Date.now() / 1000 | 0), + new Buffer([exports.extranonce_size]) + ]), + extranonce_placeholder, + util.ser_string('/stratum/') + ])), + binpack.packUInt32(0, 'little') //sequence number + ]), + util.ser_vector(this.vout), + binpack.packUInt32(0, 'little') //locktime + ]); +}; + +var Generation = exports.Generation = function Generation(coinbaseValue, coinbaseAuxFlags, height, address){ + var CTrans = new CTransaction(); + + var tx_in = new CTxIn(); + tx_in.prevout.hash = 0; + tx_in.prevout.n = Math.pow(2, 32) - 1; + tx_in._scriptSig_template = [ + Buffer.concat([ + util.serializeNumber(height), + new Buffer(coinbaseAuxFlags, 'hex'), + util.serializeNumber(Date.now() / 1000 | 0), + new Buffer([exports.extranonce_size]) + ]), + util.ser_string('/stratum/') + ]; + + tx_in.scriptSig = Buffer.concat([ + tx_in._scriptSig_template[0], + extranonce_placeholder, + tx_in._scriptSig_template[1] + ]); + + var tx_out = new CTxOut(); + tx_out.nValue = coinbaseValue; + tx_out.scriptPubKey = util.script_to_address(address); + + CTrans.vin.push(tx_in); + CTrans.vout.push(tx_out); + + var cTransBin = CTrans.serialize(); + var epIndex = buffertools.indexOf(cTransBin, extranonce_placeholder); + var p1 = cTransBin.slice(0, epIndex); + var p2 = cTransBin.slice(epIndex + extranonce_placeholder.length); + + this.tx = CTrans; + this.serialized = [p1, p2]; +} +Generation.prototype = { + setExtraNonce: function(extraNonce){ + if (extraNonce.length != exports.extranonce_size){ + throw "Incorrect extranonce size"; + } + + var part1 = this.tx.vin[0]._scriptSig_template[0]; + var part2 = this.tx.vin[0]._scriptSig_template[1]; + this.tx.vin[0].scriptSig = Buffer.concat([ + part1, + extraNonce, + part2 + ]); + + } +}; \ No newline at end of file