Comparing version 0.1.9 to 0.1.10
@@ -111,3 +111,3 @@ # HIREDIS | ||
`reply->elements`. Every element in the multi bulk reply is a `redisReply` object as well | ||
and can be accessed via `reply->elements[..index..]`. | ||
and can be accessed via `reply->element[..index..]`. | ||
Redis may reply with nested arrays but this is fully supported. | ||
@@ -307,4 +307,38 @@ | ||
To be done. | ||
Hiredis comes with a reply parsing API that makes it easy for writing higher | ||
level language bindings. | ||
The reply parsing API consists of the following functions: | ||
redisReader *redisReaderCreate(void); | ||
void redisReaderFree(redisReader *reader); | ||
int redisReaderFeed(redisReader *reader, const char *buf, size_t len); | ||
int redisReaderGetReply(redisReader *reader, void **reply); | ||
### Usage | ||
The function `redisReaderCreate` creates a `redisReader` structure that holds a | ||
buffer with unparsed data and state for the protocol parser. | ||
Incoming data -- most likely from a socket -- can be placed in the internal | ||
buffer of the `redisReader` using `redisReaderFeed`. This function will make a | ||
copy of the buffer pointed to by `buf` for `len` bytes. This data is parsed | ||
when `redisReaderGetReply` is called. This function returns an integer status | ||
and a reply object (as described above) via `void **reply`. The returned status | ||
can be either `REDIS_OK` or `REDIS_ERR`, where the latter means something went | ||
wrong (either a protocol error, or an out of memory error). | ||
### Customizing replies | ||
The function `redisReaderGetReply` creates `redisReply` and makes the function | ||
argument `reply` point to the created `redisReply` variable. For instance, if | ||
the response of type `REDIS_REPLY_STATUS` then the `str` field of `redisReply` | ||
will hold the status as a vanilla C string. However, the functions that are | ||
responsible for creating instances of the `redisReply` can be customized by | ||
setting the `fn` field on the `redisReader` struct. This should be done | ||
immediately after creating the `redisReader`. | ||
For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c) | ||
uses customized reply object functions to create Ruby objects. | ||
## AUTHORS | ||
@@ -311,0 +345,0 @@ |
{ | ||
"name": "hiredis", | ||
"description": "Wrapper for reply processing code in hiredis", | ||
"version": "0.1.9", | ||
"version": "0.1.10", | ||
"homepage": "http://github.com/pietern/hiredis-node", | ||
@@ -13,3 +13,3 @@ "author": "Pieter Noordhuis <pcnoordhuis@gmail.com>", | ||
"preinstall": "node-waf configure build", | ||
"test": "expresso" | ||
"test": "node test/reader.js" | ||
}, | ||
@@ -16,0 +16,0 @@ "engines": { |
var assert = require("assert"), | ||
spawn = require('child_process').spawn, | ||
hiredis = require("../hiredis"); | ||
@@ -13,14 +12,28 @@ | ||
exports.testCreateReader = function() { | ||
var reader = new hiredis.Reader(); | ||
assert.isNotNull(reader); | ||
var passed = 0; | ||
var failed = 0; | ||
function test(str, fn) { | ||
try { | ||
fn(); | ||
passed++; | ||
} catch (err) { | ||
console.log("\x1B[1;31m" + str + " failed!\x1B[0m"); | ||
console.log(err.stack + "\n"); | ||
failed++; | ||
} | ||
} | ||
exports.testStatusReply = function() { | ||
test("CreateReader", function() { | ||
var reader = new hiredis.Reader(); | ||
assert.notEqual(reader, null); | ||
}); | ||
test("StatusReply", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("+OK\r\n"); | ||
assert.equal("OK", reader.get()); | ||
} | ||
}); | ||
exports.testStatusReplyAsBuffer = function() { | ||
test("StatusReplyAsBuffer", function() { | ||
var reader = new hiredis.Reader({ return_buffers: true }); | ||
@@ -31,18 +44,18 @@ reader.feed("+OK\r\n"); | ||
assert.equal("OK", reply.toString()); | ||
} | ||
}); | ||
exports.testIntegerReply = function() { | ||
test("IntegerReply", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed(":1\r\n"); | ||
assert.equal(1, reader.get()); | ||
} | ||
}); | ||
// This test fails since v8 doesn't to 64-bit integers... | ||
exports.testLargeIntegerReply = function() { | ||
test("LargeIntegerReply", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed(":9223372036854775807\r\n"); | ||
assert.equal("9223372036854775807", String(reader.get())); | ||
} | ||
}); | ||
exports.testErrorReply = function() { | ||
test("ErrorReply", function() { | ||
var reader = new hiredis.Reader(); | ||
@@ -53,5 +66,5 @@ reader.feed("-ERR foo\r\n"); | ||
assert.equal("ERR foo", reply.message); | ||
} | ||
}); | ||
exports.testErrorReplyWithReturnBuffers = function() { | ||
test("ErrorReplyWithReturnBuffers", function() { | ||
var reader = new hiredis.Reader({ return_buffers: true }); | ||
@@ -62,23 +75,23 @@ reader.feed("-ERR foo\r\n"); | ||
assert.equal("ERR foo", reply.message); | ||
} | ||
}); | ||
exports.testNullBulkReply = function() { | ||
test("NullBulkReply", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("$-1\r\n"); | ||
assert.equal(null, reader.get()); | ||
} | ||
}); | ||
exports.testEmptyBulkReply = function() { | ||
test("EmptyBulkReply", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("$0\r\n\r\n"); | ||
assert.equal("", reader.get()); | ||
} | ||
}); | ||
exports.testBulkReply = function() { | ||
test("BulkReply", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("$3\r\nfoo\r\n"); | ||
assert.equal("foo", reader.get()); | ||
} | ||
}); | ||
exports.testBulkReplyAsBuffer = function() { | ||
test("BulkReplyAsBuffer", function() { | ||
var reader = new hiredis.Reader({ return_buffers: true }); | ||
@@ -89,55 +102,55 @@ reader.feed("$3\r\nfoo\r\n"); | ||
assert.equal("foo", reply.toString()); | ||
} | ||
}); | ||
exports.testBulkReplyWithEncoding = function() { | ||
test("BulkReplyWithEncoding", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("$" + Buffer.byteLength("ā") + "\r\nā\r\n"); | ||
assert.equal("ā", reader.get()); | ||
} | ||
}); | ||
exports.testNullMultiBulkReply = function() { | ||
test("NullMultiBulkReply", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("*-1\r\n"); | ||
assert.equal(null, reader.get()); | ||
} | ||
}); | ||
exports.testEmptyMultiBulkReply = function() { | ||
test("EmptyMultiBulkReply", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("*0\r\n"); | ||
assert.eql([], reader.get()); | ||
} | ||
assert.deepEqual([], reader.get()); | ||
}); | ||
exports.testMultiBulkReply = function() { | ||
test("MultiBulkReply", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"); | ||
assert.eql(["foo", "bar"], reader.get()); | ||
} | ||
assert.deepEqual(["foo", "bar"], reader.get()); | ||
}); | ||
exports.testNestedMultiBulkReply = function() { | ||
test("NestedMultiBulkReply", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("*2\r\n*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$3\r\nqux\r\n"); | ||
assert.eql([["foo", "bar"], "qux"], reader.get()); | ||
} | ||
assert.deepEqual([["foo", "bar"], "qux"], reader.get()); | ||
}); | ||
exports.testMultiBulkReplyWithNonStringValues = function() { | ||
test("MultiBulkReplyWithNonStringValues", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("*3\r\n:1\r\n+OK\r\n$-1\r\n"); | ||
assert.eql([1, "OK", null], reader.get()); | ||
} | ||
assert.deepEqual([1, "OK", null], reader.get()); | ||
}); | ||
exports.testFeedWithBuffer = function() { | ||
test("FeedWithBuffer", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed(new Buffer("$3\r\nfoo\r\n")); | ||
assert.eql("foo", reader.get()); | ||
} | ||
assert.deepEqual("foo", reader.get()); | ||
}); | ||
exports.testUndefinedReplyOnIncompleteFeed = function() { | ||
test("UndefinedReplyOnIncompleteFeed", function() { | ||
var reader = new hiredis.Reader(); | ||
reader.feed("$3\r\nfoo"); | ||
assert.eql(undefined, reader.get()); | ||
assert.deepEqual(undefined, reader.get()); | ||
reader.feed("\r\n"); | ||
assert.eql("foo", reader.get()); | ||
} | ||
assert.deepEqual("foo", reader.get()); | ||
}); | ||
exports.testLeaks = function(beforeExit) { | ||
test("Leaks", function(beforeExit) { | ||
/* The "leaks" utility is only available on OSX. */ | ||
@@ -147,3 +160,3 @@ if (process.platform != "darwin") return; | ||
var done = 0; | ||
var leaks = spawn("leaks", [process.pid]); | ||
var leaks = require('child_process').spawn("leaks", [process.pid]); | ||
leaks.stdout.on("data", function(data) { | ||
@@ -162,8 +175,5 @@ var str = data.toString(); | ||
beforeExit(function() { | ||
setTimeout(function() { | ||
assert.ok(done, "Leaks test should have completed"); | ||
}, 100); | ||
process.on('exit', function() { | ||
assert.ok(done, "Leaks test should have completed"); | ||
}); | ||
} | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
219000
301
35