From c6dbba89b067ac3e6fcf691f3c8a856ac3ef1b5c Mon Sep 17 00:00:00 2001 From: Hayk Martirosyan Date: Mon, 19 Jan 2015 01:19:02 -0800 Subject: [PATCH] Binary value support for last word in command --- CMakeLists.txt | 3 +++ README.md | 2 +- examples/binary_data.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/command.cpp | 8 ++++---- src/redox.cpp | 24 ++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 examples/binary_data.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b0e1c8a..3775642 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,4 +84,7 @@ if (examples) add_executable(multi_client examples/multi-client.cpp ${SRC_ALL}) target_link_libraries(multi_client ${LIB_REDIS}) + add_executable(binary_data examples/binary_data.cpp ${SRC_ALL}) + target_link_libraries(binary_data ${LIB_REDIS}) + endif() diff --git a/README.md b/README.md index 60c8afa..f09e539 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ redox ====== -Modern, asynchronous, and wicked fast C++11 bindings for Redis +Modern, asynchronous, and wicked fast C++11 client for Redis ## Overview diff --git a/examples/binary_data.cpp b/examples/binary_data.cpp new file mode 100644 index 0000000..2d68c65 --- /dev/null +++ b/examples/binary_data.cpp @@ -0,0 +1,44 @@ +/** +* Basic use of Redox to set and get binary data. +*/ + +#include +#include +#include +#include "../src/redox.hpp" + +using namespace std; + +/** +* Random string generator. +*/ +std::string random_string(size_t length) { + std::string str(length, 0); + std::generate_n(str.begin(), length, []{ return (unsigned char)rand(); }); + return str; +} + +int main(int argc, char* argv[]) { + + redox::Redox rdx = {"localhost", 6379}; // Initialize Redox + if(!rdx.start()) return 1; // Start the event loop + + rdx.del("binary"); + + string binary_data = random_string(10000); + + auto c = rdx.command_blocking("SET binary \"" + binary_data + "\""); + if(c->ok()) cout << "Reply: " << c->reply() << endl; + else cerr << "Failed to set key! Status: " << c->status() << endl; + c->free(); + + c = rdx.command_blocking("GET binary"); + if(c->ok()) { + if(c->reply() == binary_data) cout << "Binary data matches!" << endl; + else cerr << "Binary data differs!" << endl; + } + else cerr << "Failed to get key! Status: " << c->status() << endl; + c->free(); + + rdx.stop(); // Shut down the event loop +} diff --git a/src/command.cpp b/src/command.cpp index 3715003..675e980 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -46,7 +46,7 @@ void Command::invoke_callback() { invoke_error(REDOX_WRONG_TYPE); } else { - std::string s = reply_obj->str; + std::string s(reply_obj->str, reply_obj->len); invoke(s); } } @@ -129,7 +129,7 @@ void Command>::invoke_callback() { std::cerr << "[ERROR] " << cmd << ": Received non-array reply." << std::endl; invoke_error(REDOX_WRONG_TYPE); } - v.push_back(r->str); + v.emplace_back(r->str, r->len); } invoke(v); } @@ -153,7 +153,7 @@ void Command>::invoke_callback() { std::cerr << "[ERROR] " << cmd << ": Received non-array reply." << std::endl; invoke_error(REDOX_WRONG_TYPE); } - v.insert(r->str); + v.emplace(r->str, r->len); } invoke(v); } @@ -177,7 +177,7 @@ void Command>::invoke_callback() { std::cerr << "[ERROR] " << cmd << ": Received non-array reply." << std::endl; invoke_error(REDOX_WRONG_TYPE); } - v.insert(r->str); + v.emplace(r->str, r->len); } invoke(v); } diff --git a/src/redox.cpp b/src/redox.cpp index aec4319..1240df1 100644 --- a/src/redox.cpp +++ b/src/redox.cpp @@ -235,6 +235,30 @@ void Redox::command_callback(redisAsyncContext *ctx, void *r, void *privdata) { template bool Redox::submit_to_server(Command* c) { c->pending++; + + // Process binary data if trailing quotation. This is a limited implementation + // to allow binary data between the first and the last quotes of the command string, + // if the very last character of the command is a quote ('"'). + if(c->cmd[c->cmd.size()-1] == '"') { + + // Indices of the quotes + int first = c->cmd.find('"'); + int last = c->cmd.size()-1; + + // Proceed only if the first and last quotes are different + if(first != last) { + + string format = c->cmd.substr(0, first) + "%b"; + string value = c->cmd.substr(first+1, last-first-1); + if (redisAsyncCommand(c->rdx->ctx, command_callback, (void*)c->id, format.c_str(), value.c_str(), value.size()) != REDIS_OK) { + cerr << "[ERROR] Could not send \"" << c->cmd << "\": " << c->rdx->ctx->errstr << endl; + c->invoke_error(REDOX_SEND_ERROR); + return false; + } + return true; + } + } + if (redisAsyncCommand(c->rdx->ctx, command_callback, (void*)c->id, c->cmd.c_str()) != REDIS_OK) { cerr << "[ERROR] Could not send \"" << c->cmd << "\": " << c->rdx->ctx->errstr << endl; c->invoke_error(REDOX_SEND_ERROR); -- libgit2 0.21.4