Merge in touch/etc
authorBrian Aker <brian@tangent.org>
Wed, 5 Oct 2011 21:43:41 +0000 (14:43 -0700)
committerBrian Aker <brian@tangent.org>
Wed, 5 Oct 2011 21:43:41 +0000 (14:43 -0700)
222 files changed:
.bzrignore
ChangeLog
Makefile.am
clients/include.am
clients/memtouch.cc [new file with mode: 0644]
clients/utilities.cc
clients/utilities.h
configure.ac
docs/libmemcached.rst
docs/memcached_servers.rst
example/interface_v0.c
example/interface_v1.c
example/memcached_light.c
libhashkit-1.0/algorithm.h [new file with mode: 0644]
libhashkit-1.0/behavior.h [new file with mode: 0644]
libhashkit-1.0/configure.h.in [new file with mode: 0644]
libhashkit-1.0/digest.h [new file with mode: 0644]
libhashkit-1.0/function.h [new file with mode: 0644]
libhashkit-1.0/has.h [new file with mode: 0644]
libhashkit-1.0/hashkit.h [new file with mode: 0644]
libhashkit-1.0/hashkit.hpp [new file with mode: 0644]
libhashkit-1.0/include.am [new file with mode: 0644]
libhashkit-1.0/str_algorithm.h [new file with mode: 0644]
libhashkit-1.0/strerror.h [new file with mode: 0644]
libhashkit-1.0/types.h [new file with mode: 0644]
libhashkit-1.0/visibility.h [new file with mode: 0644]
libhashkit/algorithm.h [deleted file]
libhashkit/behavior.h [deleted file]
libhashkit/common.h
libhashkit/configure.h.in [deleted file]
libhashkit/digest.h [deleted file]
libhashkit/function.h [deleted file]
libhashkit/has.h [deleted file]
libhashkit/hashkit.h
libhashkit/hashkit.hpp [deleted file]
libhashkit/include.am
libhashkit/is.h [new file with mode: 0644]
libhashkit/str_algorithm.h [deleted file]
libhashkit/strerror.h [deleted file]
libhashkit/types.h [deleted file]
libhashkit/visibility.h [deleted file]
libmemcached-1.0/allocators.h [new file with mode: 0644]
libmemcached-1.0/analyze.h [new file with mode: 0644]
libmemcached-1.0/auto.h [new file with mode: 0644]
libmemcached-1.0/basic_string.h [new file with mode: 0644]
libmemcached-1.0/behavior.h [new file with mode: 0644]
libmemcached-1.0/callback.h [new file with mode: 0644]
libmemcached-1.0/configure.h.in [new file with mode: 0644]
libmemcached-1.0/constants.h [new file with mode: 0644]
libmemcached-1.0/delete.h [new file with mode: 0644]
libmemcached-1.0/dump.h [new file with mode: 0644]
libmemcached-1.0/error.h [new file with mode: 0644]
libmemcached-1.0/exception.hpp [new file with mode: 0644]
libmemcached-1.0/exist.h [new file with mode: 0644]
libmemcached-1.0/fetch.h [new file with mode: 0644]
libmemcached-1.0/flush.h [new file with mode: 0644]
libmemcached-1.0/flush_buffers.h [new file with mode: 0644]
libmemcached-1.0/get.h [new file with mode: 0644]
libmemcached-1.0/hash.h [new file with mode: 0644]
libmemcached-1.0/include.am [new file with mode: 0644]
libmemcached-1.0/memcached.h [new file with mode: 0644]
libmemcached-1.0/memcached.hpp [new file with mode: 0644]
libmemcached-1.0/options.h [new file with mode: 0644]
libmemcached-1.0/parse.h [new file with mode: 0644]
libmemcached-1.0/platform.h [new file with mode: 0644]
libmemcached-1.0/quit.h [new file with mode: 0644]
libmemcached-1.0/result.h [new file with mode: 0644]
libmemcached-1.0/return.h [new file with mode: 0644]
libmemcached-1.0/sasl.h [new file with mode: 0644]
libmemcached-1.0/server.h [new file with mode: 0644]
libmemcached-1.0/server_list.h [new file with mode: 0644]
libmemcached-1.0/stats.h [new file with mode: 0644]
libmemcached-1.0/storage.h [new file with mode: 0644]
libmemcached-1.0/strerror.h [new file with mode: 0644]
libmemcached-1.0/string.h [new file with mode: 0644]
libmemcached-1.0/touch.h [new file with mode: 0644]
libmemcached-1.0/types.h [new file with mode: 0644]
libmemcached-1.0/verbosity.h [new file with mode: 0644]
libmemcached-1.0/version.h [new file with mode: 0644]
libmemcached-1.0/visibility.h [new file with mode: 0644]
libmemcached/allocators.cc
libmemcached/allocators.h [deleted file]
libmemcached/analyze.h [deleted file]
libmemcached/auto.cc
libmemcached/auto.h [deleted file]
libmemcached/basic_string.h [deleted file]
libmemcached/behavior.h [deleted file]
libmemcached/callback.cc
libmemcached/callback.h
libmemcached/common.h
libmemcached/configure.h.in [deleted file]
libmemcached/constants.h [deleted file]
libmemcached/csl/common.h
libmemcached/csl/symbol.h
libmemcached/delete.cc
libmemcached/delete.h [deleted file]
libmemcached/do.cc
libmemcached/dump.h [deleted file]
libmemcached/error.cc
libmemcached/error.h [deleted file]
libmemcached/error.hpp
libmemcached/exception.hpp [deleted file]
libmemcached/exist.cc
libmemcached/exist.h [deleted file]
libmemcached/fetch.h [deleted file]
libmemcached/flush.h [deleted file]
libmemcached/flush_buffers.h [deleted file]
libmemcached/get.cc
libmemcached/get.h [deleted file]
libmemcached/hash.h [deleted file]
libmemcached/hosts.cc
libmemcached/include.am
libmemcached/initialize_query.cc
libmemcached/io.cc
libmemcached/io.h
libmemcached/key.cc
libmemcached/key.hpp [new file with mode: 0644]
libmemcached/libmemcached_probes.d
libmemcached/libmemcached_probes.h
libmemcached/memcached.h
libmemcached/memcached.hpp
libmemcached/memcached/protocol_binary.h
libmemcached/memcached_util.h [deleted file]
libmemcached/namespace.h
libmemcached/options.h [deleted file]
libmemcached/parse.h [deleted file]
libmemcached/platform.h [deleted file]
libmemcached/protocol/ascii_handler.c [deleted file]
libmemcached/protocol/ascii_handler.h [deleted file]
libmemcached/protocol/binary_handler.c [deleted file]
libmemcached/protocol/binary_handler.h [deleted file]
libmemcached/protocol/cache.c [deleted file]
libmemcached/protocol/cache.h [deleted file]
libmemcached/protocol/callback.h [deleted file]
libmemcached/protocol/common.h [deleted file]
libmemcached/protocol/include.am [deleted file]
libmemcached/protocol/pedantic.c [deleted file]
libmemcached/protocol/protocol_handler.c [deleted file]
libmemcached/protocol_handler.h [deleted file]
libmemcached/quit.h [deleted file]
libmemcached/response.cc
libmemcached/result.h [deleted file]
libmemcached/return.h [deleted file]
libmemcached/sasl.cc
libmemcached/sasl.h [deleted file]
libmemcached/server.cc
libmemcached/server.h [deleted file]
libmemcached/server.hpp
libmemcached/server_list.h [deleted file]
libmemcached/stats.cc
libmemcached/stats.h [deleted file]
libmemcached/storage.cc
libmemcached/storage.h [deleted file]
libmemcached/strerror.h [deleted file]
libmemcached/string.h [deleted file]
libmemcached/touch.cc [new file with mode: 0644]
libmemcached/types.h [deleted file]
libmemcached/util.h
libmemcached/util/flush.cc [deleted file]
libmemcached/util/flush.h [deleted file]
libmemcached/util/include.am [deleted file]
libmemcached/util/pid.cc [deleted file]
libmemcached/util/pid.h [deleted file]
libmemcached/util/ping.cc [deleted file]
libmemcached/util/ping.h [deleted file]
libmemcached/util/pool.cc [deleted file]
libmemcached/util/pool.h [deleted file]
libmemcached/util/version.cc [deleted file]
libmemcached/util/version.h [deleted file]
libmemcached/verbosity.cc
libmemcached/verbosity.h [deleted file]
libmemcached/version.cc
libmemcached/version.h [deleted file]
libmemcached/virtual_bucket.c
libmemcached/visibility.h [deleted file]
libmemcachedprotocol-0.0/binary.h [new file with mode: 0644]
libmemcachedprotocol-0.0/callback.h [new file with mode: 0644]
libmemcachedprotocol-0.0/handler.h [new file with mode: 0644]
libmemcachedprotocol-0.0/include.am [new file with mode: 0644]
libmemcachedprotocol-0.0/vbucket.h [new file with mode: 0644]
libmemcachedprotocol/ascii_handler.c [new file with mode: 0644]
libmemcachedprotocol/ascii_handler.h [new file with mode: 0644]
libmemcachedprotocol/binary_handler.c [new file with mode: 0644]
libmemcachedprotocol/binary_handler.h [new file with mode: 0644]
libmemcachedprotocol/cache.c [new file with mode: 0644]
libmemcachedprotocol/cache.h [new file with mode: 0644]
libmemcachedprotocol/common.h [new file with mode: 0644]
libmemcachedprotocol/handler.c [new file with mode: 0644]
libmemcachedprotocol/include.am [new file with mode: 0644]
libmemcachedprotocol/pedantic.c [new file with mode: 0644]
libmemcachedutil-1.0/flush.h [new file with mode: 0644]
libmemcachedutil-1.0/include.am [new file with mode: 0644]
libmemcachedutil-1.0/pid.h [new file with mode: 0644]
libmemcachedutil-1.0/ping.h [new file with mode: 0644]
libmemcachedutil-1.0/pool.h [new file with mode: 0644]
libmemcachedutil-1.0/util.h [new file with mode: 0644]
libmemcachedutil-1.0/version.h [new file with mode: 0644]
libmemcachedutil/common.h [new file with mode: 0644]
libmemcachedutil/flush.cc [new file with mode: 0644]
libmemcachedutil/include.am [new file with mode: 0644]
libmemcachedutil/pid.cc [new file with mode: 0644]
libmemcachedutil/ping.cc [new file with mode: 0644]
libmemcachedutil/pool.cc [new file with mode: 0644]
libmemcachedutil/version.cc [new file with mode: 0644]
libtest/test.h
m4/progtest.m4 [deleted file]
support/libmemcached.spec.in
tests/atomsmasher.cc
tests/callbacks.cc [new file with mode: 0644]
tests/callbacks.h [new file with mode: 0644]
tests/failure.cc
tests/hash_plus.cc
tests/hashkit_functions.cc
tests/include.am
tests/libmemcached_world.h
tests/mem_functions.cc
tests/memtouch.cc [new file with mode: 0644]
tests/parser.cc
tests/plus.cpp
tests/touch.cc [new file with mode: 0644]
tests/touch.h [new file with mode: 0644]
win32/include.am

index 8432fe194ba45d4a528bb6aad1961ede81733500..dbe3e8943e3ec736662fdf864b90187e76e5abcf 100644 (file)
@@ -72,9 +72,9 @@ docs/html/
 docs/linkcheck/
 docs/text
 example/memcached_light
-libhashkit/configure.h
+libhashkit-1.0/configure.h
 libmemcached-?.??/
-libmemcached/configure.h
+libmemcached-1.0/configure.h
 libmemcached/dtrace_probes.h
 libmemcached/generated_probes.h
 libmemcached/memcached_configure.h
@@ -135,3 +135,6 @@ tests/memstat
 tests/memcat
 clients/memexist
 tests/memexist
+libmemcached/configure.h
+clients/memtouch
+tests/memtouch
index 29f628250ea7a08fa98d14ee1af0d4d6d31a126e..8e243d9841753917f3caf94c4870ffbfbb3b5991 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+
+* Dropped libmemcached/memcached_util.h (undocumented header file)
+
 0.53 Mon Sep 26 20:50:33 PDT 2011
   * Fix for FreeBSD/OpenBSD and -lm
   * Added memcached_exist()
index 2ecc8f2c1c175b46daf551b4b4a8aecab11cc789..d19991ecd98a55fd645f07447747f2456589118c 100644 (file)
@@ -28,16 +28,22 @@ EXTRA_DIST= \
 
 libmemcached_libmemcached_la_LDFLAGS=
 
+include libtest/include.am
+
+include libhashkit-1.0/include.am
+include libmemcached-1.0/include.am
+include libmemcachedprotocol-0.0/include.am
+include libmemcachedutil-1.0/include.am
+
 include clients/include.am
 include docs/include.am
 include example/include.am
 include libhashkit/include.am
 include libmemcached/include.am
-include libmemcached/util/include.am
-include libmemcached/protocol/include.am
+include libmemcachedutil/include.am
+include libmemcachedprotocol/include.am
 include libmemcachedinternal/include.am
 include libmemcachedinternal/util/include.am
-include libtest/include.am
 include poll/include.am
 include support/include.am
 include tests/include.am
index 31d3c0eb2df47a1259bb822d73a279d28bd3de78..bb35bdf5f27e44c1dd3d6029054f67002b4ed0b7 100644 (file)
@@ -17,6 +17,7 @@ bin_PROGRAMS+= \
        clients/memdump \
        clients/memerror \
        clients/memexist \
+       clients/memtouch \
        clients/memflush \
        clients/memparse \
        clients/memping \
@@ -70,6 +71,9 @@ clients_memrm_LDADD= $(CLIENTS_LDADDS)
 clients_memexist_SOURCES= clients/memexist.cc
 clients_memexist_LDADD= $(CLIENTS_LDADDS)
 
+clients_memtouch_SOURCES= clients/memtouch.cc
+clients_memtouch_LDADD= $(CLIENTS_LDADDS)
+
 clients_memflush_SOURCES= clients/memflush.cc
 clients_memflush_LDADD= $(CLIENTS_LDADDS)
 
diff --git a/clients/memtouch.cc b/clients/memtouch.cc
new file mode 100644 (file)
index 0000000..4f3be80
--- /dev/null
@@ -0,0 +1,241 @@
+/* LibMemcached
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ *
+ * Summary:
+ *
+ */
+
+#include <config.h>
+
+#include <cstdio>
+#include <cstring>
+#include <getopt.h>
+#include <iostream>
+#include <unistd.h>
+#include <libmemcached/memcached.h>
+
+#include "utilities.h"
+
+#define PROGRAM_NAME "memtouch"
+#define PROGRAM_DESCRIPTION "Update the expiration value of an alreasy existing value in the sever"
+
+
+/* Prototypes */
+void options_parse(int argc, char *argv[]);
+
+static int opt_binary= 0;
+static int opt_verbose= 0;
+static char *opt_servers= NULL;
+static char *opt_hash= NULL;
+static char *opt_username;
+static char *opt_passwd;
+
+time_t expiration= 0;
+
+int main(int argc, char *argv[])
+{
+  int return_code= EXIT_SUCCESS;
+
+  options_parse(argc, argv);
+  initialize_sockets();
+
+  if (opt_servers == NULL)
+  {
+    char *temp;
+
+    if ((temp= getenv("MEMCACHED_SERVERS")))
+    {
+      opt_servers= strdup(temp);
+    }
+    else
+    {
+      std::cerr << "No Servers provided" << std::endl;
+      return EXIT_FAILURE;
+    }
+  }
+
+  memcached_st *memc= memcached_create(NULL);
+  process_hash_option(memc, opt_hash);
+
+  memcached_server_st *servers= memcached_servers_parse(opt_servers);
+
+  memcached_server_push(memc, servers);
+  memcached_server_list_free(servers);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
+                         (uint64_t)opt_binary);
+
+  if (opt_username and LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+  {
+    memcached_free(memc);
+    std::cerr << "--username was supplied, but binary was not built with SASL support." << std::endl;
+    return EXIT_FAILURE;
+  }
+
+  if (opt_username)
+  {
+    memcached_return_t ret;
+    if (memcached_failed(ret= memcached_set_sasl_auth_data(memc, opt_username, opt_passwd)))
+    {
+      std::cerr << memcached_last_error_message(memc) << std::endl;
+      memcached_free(memc);
+      return EXIT_FAILURE;
+    }
+  }
+
+  while (optind < argc)
+  {
+    memcached_return_t rc= memcached_touch(memc, argv[optind], strlen(argv[optind]), expiration);
+    if (rc == MEMCACHED_NOTFOUND)
+    {
+      if (opt_verbose)
+      {
+        std::cout << "Could not find key \"" << argv[optind] << "\"" << std::endl;
+      }
+
+      return_code= EXIT_FAILURE;
+    }
+    else if (memcached_failed(rc))
+    {
+      if (opt_verbose)
+      {
+        std::cerr << "Fatal error for key \"" << argv[optind] << "\" :" <<  memcached_last_error_message(memc) << std::endl;
+      }
+
+      return_code= EXIT_FAILURE;
+    }
+    else // success
+    {
+      if (opt_verbose)
+      {
+        std::cout << "Found key " << argv[optind] << std::endl;
+      }
+    }
+
+    optind++;
+  }
+
+  memcached_free(memc);
+
+  if (opt_servers)
+  {
+    free(opt_servers);
+  }
+
+  if (opt_hash)
+  {
+    free(opt_hash);
+  }
+
+  return return_code;
+}
+
+
+void options_parse(int argc, char *argv[])
+{
+  memcached_programs_help_st help_options[]=
+  {
+    {0},
+  };
+
+  static struct option long_options[]=
+    {
+      {(OPTIONSTRING)"version", no_argument, NULL, OPT_VERSION},
+      {(OPTIONSTRING)"help", no_argument, NULL, OPT_HELP},
+      {(OPTIONSTRING)"quiet", no_argument, NULL, OPT_QUIET},
+      {(OPTIONSTRING)"verbose", no_argument, &opt_verbose, OPT_VERBOSE},
+      {(OPTIONSTRING)"debug", no_argument, &opt_verbose, OPT_DEBUG},
+      {(OPTIONSTRING)"servers", required_argument, NULL, OPT_SERVERS},
+      {(OPTIONSTRING)"hash", required_argument, NULL, OPT_HASH},
+      {(OPTIONSTRING)"binary", no_argument, NULL, OPT_BINARY},
+      {(OPTIONSTRING)"username", required_argument, NULL, OPT_USERNAME},
+      {(OPTIONSTRING)"password", required_argument, NULL, OPT_PASSWD},
+      {(OPTIONSTRING)"expire", required_argument, NULL, OPT_EXPIRE},
+      {0, 0, 0, 0},
+    };
+
+  bool opt_version= false;
+  bool opt_help= false;
+  int option_index= 0;
+
+  while (1)
+  {
+    int option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
+    if (option_rv == -1) 
+    {
+      break;
+    }
+
+    switch (option_rv)
+    {
+    case 0:
+      break;
+
+    case OPT_BINARY:
+      opt_binary = true;
+      break;
+
+    case OPT_VERBOSE: /* --verbose or -v */
+      opt_verbose = OPT_VERBOSE;
+      break;
+
+    case OPT_DEBUG: /* --debug or -d */
+      opt_verbose = OPT_DEBUG;
+      break;
+
+    case OPT_VERSION: /* --version or -V */
+      opt_version= true;
+      break;
+
+    case OPT_HELP: /* --help or -h */
+      opt_help= true;
+      break;
+
+    case OPT_SERVERS: /* --servers or -s */
+      opt_servers= strdup(optarg);
+      break;
+
+    case OPT_HASH:
+      opt_hash= strdup(optarg);
+      break;
+
+    case OPT_USERNAME:
+      opt_username= optarg;
+      break;
+
+    case OPT_PASSWD:
+      opt_passwd= optarg;
+      break;
+
+    case OPT_EXPIRE:
+      expiration= time_t(strtoul(optarg, (char **)NULL, 10));
+      break;
+
+    case OPT_QUIET:
+      close_stdio();
+      break;
+
+    case '?':
+      /* getopt_long already printed an error message. */
+      exit(EXIT_FAILURE);
+
+    default:
+      abort();
+    }
+  }
+
+  if (opt_version)
+  {
+    version_command(PROGRAM_NAME);
+    exit(EXIT_SUCCESS);
+  }
+
+  if (opt_help)
+  {
+    help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options);
+    exit(EXIT_SUCCESS);
+  }
+}
index 58717a94c5b10f4c0601987839107bee2d92f398..79f2f2aebcda1560a4750bc7f11175924fa1d0d3 100644 (file)
@@ -13,6 +13,7 @@
 #include <clients/utilities.h>
 
 #include <cstdio>
+#include <cassert>
 #include <cstdlib>
 #include <cstring>
 #include <ctype.h>
@@ -101,10 +102,11 @@ static const char *lookup_help(memcached_options option)
   case OPT_PASSWD: return "Password to use for SASL authentication";
   case OPT_FILE: return "Path to file in which to save result";
   case OPT_STAT_ARGS: return "Argument for statistics";
-  default: WATCHPOINT_ASSERT(0);
+  default:
+                      break;
   };
 
-  WATCHPOINT_ASSERT(0);
+  assert(0);
   return "forgot to document this function :)";
 }
 
index 0bac61a75aac155900181e821bb2339670e7139a..d036bccc1aec107f58f1a651095aa8098dd0cf40 100644 (file)
@@ -12,9 +12,8 @@
 #pragma once
 
 #include <getopt.h>
-#include <libmemcached/memcached.h>
-#include "libmemcached/watchpoint.h"
-#include "client_options.h"
+#include <libmemcached-1.0/memcached.h>
+#include "clients/client_options.h"
 
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
index b00ea9e5614cbf34132d14af2f4664f38ed37eda..fe346180d9c830a89facaa7ef22bca223396dd40 100644 (file)
@@ -183,8 +183,8 @@ SOCKET_SEND_FLAGS
 AC_CONFIG_FILES([
   Makefile
   docs/conf.py
-  libhashkit/configure.h
-  libmemcached/configure.h
+  libhashkit-1.0/configure.h
+  libmemcached-1.0/configure.h
   support/libmemcached.pc
   support/libmemcached.spec
   support/libmemcached-fc.spec
index 80da8fe882381fad51fcc5bbd731a86cdc3ace8d..a97db699575f35967327950f6c9a21d146855aa1 100644 (file)
@@ -12,7 +12,7 @@ Compile and link with -lmemcached
 
 =======
 
-libMemcached is an open source C/C++ client library and tools for the memcached server (http://danga.com/memcached). It has been designed to be light on memory usage, thread safe, and provide full access to server side methods.
+libMemcached is an open source C/C++ client library and tools for the memcached server (http://memcached.org/). It has been designed to be light on memory usage, thread safe, and provide full access to server side methods.
 
 libMemcached was designed to provide the greatest number of options to use Memcached. Some of the features provided:
 
@@ -31,7 +31,7 @@ DESCRIPTION
 
 "Memcached is a high-performance, distributed memory object caching
 system, generic in nature, but intended for use in speeding up dynamic web
-applications by alleviating database load." `http://danga.com/memcached/ <http://danga.com/memcached/>`_
+applications by alleviating database load." `http://memcached.org/ <http://memcached.org/>`_
 
 :program:`libmemcached` is a small, thread-safe client library for the
 memcached protocol. The code has all been written to allow
index 72da276496b5db9be99e7b3500d11066e27c4c95..ae5e7baeb1c868c42f76f08a4b02ce8bb23d98f1 100644 (file)
@@ -20,7 +20,7 @@ SYNOPSIS
 
 .. c:function:: memcached_return_t memcached_server_push (memcached_st *ptr, const memcached_server_st *list) 
 
-.. c:function:: memcached_server_instance_st memcached_server_by_key (const memcached_st *ptr, const char *key, size_t key_length, memcached_return_t *error)
+.. c:function:: memcached_server_instance_st memcached_server_by_key (memcached_st *ptr, const char *key, size_t key_length, memcached_return_t *error)
 
 .. c:function:: memcached_server_instance_st memcached_server_get_last_disconnect (const memcached_st *ptr)
 
index 1a847ccf111f819e44be76a62ce3312651028423..ef5ba47b57324b384a8c60e792205a57f5599cca 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-#include <libmemcached/protocol_handler.h>
+#include <libmemcachedprotocol-0.0/handler.h>
 #include <example/byteorder.h>
-#include "storage.h"
-#include "memcached_light.h"
+#include "example/storage.h"
+#include "example/memcached_light.h"
 
 static protocol_binary_response_status noop_command_handler(const void *cookie,
                                                             protocol_binary_request_header *header,
index 4fbfed5cbab75630c60e039ef398bba58971c232..d2b20712664ec8321b5b78be51fe38ef28e7e9a5 100644 (file)
@@ -18,7 +18,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <libmemcached/protocol_handler.h>
+#include <libmemcachedprotocol-0.0/handler.h>
 #include <example/byteorder.h>
 #include "storage.h"
 
index 0249ac6c1fc0240de25628539ab7c6037e6ba57a..ed89286187ba684bef47bfe7bac2baac04f59ac4 100644 (file)
@@ -34,7 +34,7 @@
 #include <string.h>
 #include <event.h>
 
-#include <libmemcached/protocol_handler.h>
+#include <libmemcachedprotocol-0.0/handler.h>
 #include <example/byteorder.h>
 #include "storage.h"
 #include "memcached_light.h"
diff --git a/libhashkit-1.0/algorithm.h b/libhashkit-1.0/algorithm.h
new file mode 100644 (file)
index 0000000..fa5f3ae
--- /dev/null
@@ -0,0 +1,85 @@
+/* HashKit
+ * Copyright (C) 2009 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ */
+
+/**
+ * @file
+ * @brief HashKit Header
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HASHKIT_API
+uint32_t libhashkit_one_at_a_time(const char *key, size_t key_length);
+
+HASHKIT_API
+uint32_t libhashkit_fnv1_64(const char *key, size_t key_length);
+
+HASHKIT_API
+uint32_t libhashkit_fnv1a_64(const char *key, size_t key_length);
+
+HASHKIT_API
+uint32_t libhashkit_fnv1_32(const char *key, size_t key_length);
+
+HASHKIT_API
+uint32_t libhashkit_fnv1a_32(const char *key, size_t key_length);
+
+HASHKIT_API
+uint32_t libhashkit_crc32(const char *key, size_t key_length);
+
+HASHKIT_API
+uint32_t libhashkit_hsieh(const char *key, size_t key_length);
+
+HASHKIT_API
+uint32_t libhashkit_murmur(const char *key, size_t key_length);
+
+HASHKIT_API
+uint32_t libhashkit_jenkins(const char *key, size_t key_length);
+
+HASHKIT_API
+uint32_t libhashkit_md5(const char *key, size_t key_length);
+
+HASHKIT_LOCAL
+uint32_t hashkit_one_at_a_time(const char *key, size_t key_length, void *context);
+
+HASHKIT_LOCAL
+uint32_t hashkit_fnv1_64(const char *key, size_t key_length, void *context);
+
+HASHKIT_LOCAL
+uint32_t hashkit_fnv1a_64(const char *key, size_t key_length, void *context);
+
+HASHKIT_LOCAL
+uint32_t hashkit_fnv1_32(const char *key, size_t key_length, void *context);
+
+HASHKIT_LOCAL
+uint32_t hashkit_fnv1a_32(const char *key, size_t key_length, void *context);
+
+HASHKIT_LOCAL
+uint32_t hashkit_crc32(const char *key, size_t key_length, void *context);
+
+HASHKIT_LOCAL
+uint32_t hashkit_hsieh(const char *key, size_t key_length, void *context);
+
+HASHKIT_LOCAL
+uint32_t hashkit_murmur(const char *key, size_t key_length, void *context);
+
+HASHKIT_LOCAL
+uint32_t hashkit_jenkins(const char *key, size_t key_length, void *context);
+
+HASHKIT_LOCAL
+uint32_t hashkit_md5(const char *key, size_t key_length, void *context);
+
+HASHKIT_API
+void libhashkit_md5_signature(const unsigned char *key, size_t length, unsigned char *result);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libhashkit-1.0/behavior.h b/libhashkit-1.0/behavior.h
new file mode 100644 (file)
index 0000000..0fb2258
--- /dev/null
@@ -0,0 +1,23 @@
+/* HashKit
+ * Copyright (C) 2009 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ */
+
+/**
+ * @file
+ * @brief HashKit Header
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libhashkit-1.0/configure.h.in b/libhashkit-1.0/configure.h.in
new file mode 100644 (file)
index 0000000..8aec386
--- /dev/null
@@ -0,0 +1,17 @@
+/* HashKit
+ * Copyright (C) 2009-2010 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libhashkit-1.0/digest.h b/libhashkit-1.0/digest.h
new file mode 100644 (file)
index 0000000..5a226b0
--- /dev/null
@@ -0,0 +1,27 @@
+/* HashKit
+ * Copyright (C) 2010 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HASHKIT_API
+uint32_t hashkit_digest(const hashkit_st *self, const char *key, size_t key_length);
+
+/**
+  This is a utilitly function provided so that you can directly access hashes with a hashkit_st.
+*/
+
+HASHKIT_API
+uint32_t libhashkit_digest(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libhashkit-1.0/function.h b/libhashkit-1.0/function.h
new file mode 100644 (file)
index 0000000..215d978
--- /dev/null
@@ -0,0 +1,41 @@
+/* HashKit
+ * Copyright (C) 2010 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+  This sets/gets the default function we will be using.
+*/
+HASHKIT_API
+hashkit_return_t hashkit_set_function(hashkit_st *hash, hashkit_hash_algorithm_t hash_algorithm);
+
+HASHKIT_API
+hashkit_return_t hashkit_set_custom_function(hashkit_st *hash, hashkit_hash_fn function, void *context);
+
+HASHKIT_API
+hashkit_hash_algorithm_t hashkit_get_function(const hashkit_st *hash);
+
+/**
+  This sets/gets the function we use for distribution.
+*/
+HASHKIT_API
+hashkit_return_t hashkit_set_distribution_function(hashkit_st *hash, hashkit_hash_algorithm_t hash_algorithm);
+
+HASHKIT_API
+hashkit_return_t hashkit_set_custom_distribution_function(hashkit_st *self, hashkit_hash_fn function, void *context);
+
+HASHKIT_API
+hashkit_hash_algorithm_t hashkit_get_distribution_function(const hashkit_st *self);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libhashkit-1.0/has.h b/libhashkit-1.0/has.h
new file mode 100644 (file)
index 0000000..8975c7a
--- /dev/null
@@ -0,0 +1,48 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HASHKIT_API
+bool libhashkit_has_algorithm(const hashkit_hash_algorithm_t);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libhashkit-1.0/hashkit.h b/libhashkit-1.0/hashkit.h
new file mode 100644 (file)
index 0000000..97af986
--- /dev/null
@@ -0,0 +1,93 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  HashKit library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2009-2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#pragma once
+
+
+#if !defined(__cplusplus)
+# include <stdbool.h>
+#endif
+#include <inttypes.h>
+#include <sys/types.h>
+
+#include <libhashkit-1.0/visibility.h>
+#include <libhashkit-1.0/configure.h>
+#include <libhashkit-1.0/types.h>
+#include <libhashkit-1.0/has.h>
+#include <libhashkit-1.0/algorithm.h>
+#include <libhashkit-1.0/behavior.h>
+#include <libhashkit-1.0/digest.h>
+#include <libhashkit-1.0/function.h>
+#include <libhashkit-1.0/str_algorithm.h>
+#include <libhashkit-1.0/strerror.h>
+
+struct hashkit_st
+{
+  struct hashkit_function_st {
+    hashkit_hash_fn function;
+    void *context;
+  } base_hash, distribution_hash;
+
+  struct {
+    bool is_base_same_distributed:1;
+  } flags;
+
+  struct {
+    bool is_allocated:1;
+  } options;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HASHKIT_API
+hashkit_st *hashkit_create(hashkit_st *hash);
+
+HASHKIT_API
+hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *ptr);
+
+HASHKIT_API
+bool hashkit_compare(const hashkit_st *first, const hashkit_st *second);
+
+HASHKIT_API
+void hashkit_free(hashkit_st *hash);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/libhashkit-1.0/hashkit.hpp b/libhashkit-1.0/hashkit.hpp
new file mode 100644 (file)
index 0000000..a865bf9
--- /dev/null
@@ -0,0 +1,97 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#include <libhashkit-1.0/hashkit.h>
+#include <string>
+
+class Hashkit {
+
+public:
+
+  Hashkit()
+  {
+    hashkit_create(&self);
+  }
+
+  Hashkit(const Hashkit& source)
+  {
+    hashkit_clone(&self, &source.self);
+  }
+
+  Hashkit& operator=(const Hashkit& source)
+  {
+    hashkit_free(&self);
+    hashkit_clone(&self, &source.self);
+
+    return *this;
+  }
+
+  friend bool operator==(const Hashkit &left, const Hashkit &right)
+  {
+    return hashkit_compare(&left.self, &right.self);
+  }
+
+  uint32_t digest(std::string& str)
+  {
+    return hashkit_digest(&self, str.c_str(), str.length());
+  }
+
+  uint32_t digest(const char *key, size_t key_length)
+  {
+    return hashkit_digest(&self, key, key_length);
+  }
+
+  hashkit_return_t set_function(hashkit_hash_algorithm_t hash_algorithm)
+  {
+    return hashkit_set_function(&self, hash_algorithm);
+  }
+
+  hashkit_return_t set_distribution_function(hashkit_hash_algorithm_t hash_algorithm)
+  {
+    return hashkit_set_function(&self, hash_algorithm);
+  }
+
+  ~Hashkit()
+  {
+    hashkit_free(&self);
+  }
+private:
+
+  hashkit_st self;
+};
diff --git a/libhashkit-1.0/include.am b/libhashkit-1.0/include.am
new file mode 100644 (file)
index 0000000..905e38f
--- /dev/null
@@ -0,0 +1,22 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+#
+
+EXTRA_DIST+= \
+            libhashkit-1.0/configure.h.in
+
+nobase_include_HEADERS+= \
+                        libhashkit-1.0/algorithm.h \
+                        libhashkit-1.0/behavior.h \
+                        libhashkit-1.0/configure.h \
+                        libhashkit-1.0/digest.h \
+                        libhashkit-1.0/function.h \
+                        libhashkit-1.0/has.h \
+                        libhashkit-1.0/hashkit.h \
+                        libhashkit-1.0/hashkit.hpp \
+                        libhashkit-1.0/strerror.h \
+                        libhashkit-1.0/str_algorithm.h \
+                        libhashkit-1.0/types.h \
+                        libhashkit-1.0/visibility.h
+
diff --git a/libhashkit-1.0/str_algorithm.h b/libhashkit-1.0/str_algorithm.h
new file mode 100644 (file)
index 0000000..bb05eb5
--- /dev/null
@@ -0,0 +1,48 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  HashKit
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HASHKIT_API
+const char *libhashkit_string_hash(hashkit_hash_algorithm_t type);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libhashkit-1.0/strerror.h b/libhashkit-1.0/strerror.h
new file mode 100644 (file)
index 0000000..0785f0c
--- /dev/null
@@ -0,0 +1,20 @@
+/* HashKit
+ * Copyright (C) 2009 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HASHKIT_API
+  const char *hashkit_strerror(hashkit_st *ptr, hashkit_return_t rc);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libhashkit-1.0/types.h b/libhashkit-1.0/types.h
new file mode 100644 (file)
index 0000000..e0f1f13
--- /dev/null
@@ -0,0 +1,96 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  HashKit
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#pragma once
+
+typedef enum {
+  HASHKIT_SUCCESS,
+  HASHKIT_FAILURE,
+  HASHKIT_MEMORY_ALLOCATION_FAILURE,
+  HASHKIT_INVALID_HASH,
+  HASHKIT_INVALID_ARGUMENT,
+  HASHKIT_MAXIMUM_RETURN /* Always add new error code before */
+} hashkit_return_t;
+
+static inline bool hashkit_success(const hashkit_return_t rc)
+{
+  return (rc == HASHKIT_SUCCESS);
+}
+
+static inline bool hashkit_failed(const hashkit_return_t rc)
+{
+  return (rc != HASHKIT_SUCCESS);
+}
+
+typedef enum {
+  HASHKIT_HASH_DEFAULT= 0, // hashkit_one_at_a_time()
+  HASHKIT_HASH_MD5,
+  HASHKIT_HASH_CRC,
+  HASHKIT_HASH_FNV1_64,
+  HASHKIT_HASH_FNV1A_64,
+  HASHKIT_HASH_FNV1_32,
+  HASHKIT_HASH_FNV1A_32,
+  HASHKIT_HASH_HSIEH,
+  HASHKIT_HASH_MURMUR,
+  HASHKIT_HASH_JENKINS,
+  HASHKIT_HASH_CUSTOM,
+  HASHKIT_HASH_MAX
+} hashkit_hash_algorithm_t;
+
+/**
+ * Hash distributions that are available to use.
+ */
+typedef enum
+{
+  HASHKIT_DISTRIBUTION_MODULA,
+  HASHKIT_DISTRIBUTION_RANDOM,
+  HASHKIT_DISTRIBUTION_KETAMA,
+  HASHKIT_DISTRIBUTION_MAX /* Always add new values before this. */
+} hashkit_distribution_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct hashkit_st hashkit_st;
+
+typedef uint32_t (*hashkit_hash_fn)(const char *key, size_t key_length, void *context);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libhashkit-1.0/visibility.h b/libhashkit-1.0/visibility.h
new file mode 100644 (file)
index 0000000..b8f194c
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Summary: interface for HashKit functions
+ * Description: visibitliy macros for HashKit library
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in this directory for full text.
+ * 
+ * Author: Monty Taylor
+ */
+
+/**
+ * @file
+ * @brief Visibility control macros
+ */
+
+#pragma once
+
+/**
+ *
+ * HASHKIT_API is used for the public API symbols. It either DLL imports or
+ * DLL exports (or does nothing for static build).
+ *
+ * HASHKIT_LOCAL is used for non-api symbols.
+ */
+
+#if defined(BUILDING_HASHKIT)
+# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
+#  define HASHKIT_API __attribute__ ((visibility("default")))
+#  define HASHKIT_LOCAL  __attribute__ ((visibility("hidden")))
+# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+#  define HASHKIT_API __global
+#  define HASHKIT_LOCAL __hidden
+# elif defined(_MSC_VER)
+#  define HASHKIT_API extern __declspec(dllexport) 
+#  define HASHKIT_LOCAL
+# else
+#  define HASHKIT_API
+#  define HASHKIT_LOCAL
+# endif /* defined(HAVE_VISIBILITY) */
+#else  /* defined(BUILDING_HASHKIT) */
+# if defined(_MSC_VER)
+#  define HASHKIT_API extern __declspec(dllimport) 
+#  define HASHKIT_LOCAL
+# else
+#  define HASHKIT_API
+#  define HASHKIT_LOCAL
+# endif /* defined(_MSC_VER) */
+#endif /* defined(BUILDING_HASHKIT) */
diff --git a/libhashkit/algorithm.h b/libhashkit/algorithm.h
deleted file mode 100644 (file)
index fa5f3ae..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* HashKit
- * Copyright (C) 2009 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- */
-
-/**
- * @file
- * @brief HashKit Header
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-HASHKIT_API
-uint32_t libhashkit_one_at_a_time(const char *key, size_t key_length);
-
-HASHKIT_API
-uint32_t libhashkit_fnv1_64(const char *key, size_t key_length);
-
-HASHKIT_API
-uint32_t libhashkit_fnv1a_64(const char *key, size_t key_length);
-
-HASHKIT_API
-uint32_t libhashkit_fnv1_32(const char *key, size_t key_length);
-
-HASHKIT_API
-uint32_t libhashkit_fnv1a_32(const char *key, size_t key_length);
-
-HASHKIT_API
-uint32_t libhashkit_crc32(const char *key, size_t key_length);
-
-HASHKIT_API
-uint32_t libhashkit_hsieh(const char *key, size_t key_length);
-
-HASHKIT_API
-uint32_t libhashkit_murmur(const char *key, size_t key_length);
-
-HASHKIT_API
-uint32_t libhashkit_jenkins(const char *key, size_t key_length);
-
-HASHKIT_API
-uint32_t libhashkit_md5(const char *key, size_t key_length);
-
-HASHKIT_LOCAL
-uint32_t hashkit_one_at_a_time(const char *key, size_t key_length, void *context);
-
-HASHKIT_LOCAL
-uint32_t hashkit_fnv1_64(const char *key, size_t key_length, void *context);
-
-HASHKIT_LOCAL
-uint32_t hashkit_fnv1a_64(const char *key, size_t key_length, void *context);
-
-HASHKIT_LOCAL
-uint32_t hashkit_fnv1_32(const char *key, size_t key_length, void *context);
-
-HASHKIT_LOCAL
-uint32_t hashkit_fnv1a_32(const char *key, size_t key_length, void *context);
-
-HASHKIT_LOCAL
-uint32_t hashkit_crc32(const char *key, size_t key_length, void *context);
-
-HASHKIT_LOCAL
-uint32_t hashkit_hsieh(const char *key, size_t key_length, void *context);
-
-HASHKIT_LOCAL
-uint32_t hashkit_murmur(const char *key, size_t key_length, void *context);
-
-HASHKIT_LOCAL
-uint32_t hashkit_jenkins(const char *key, size_t key_length, void *context);
-
-HASHKIT_LOCAL
-uint32_t hashkit_md5(const char *key, size_t key_length, void *context);
-
-HASHKIT_API
-void libhashkit_md5_signature(const unsigned char *key, size_t length, unsigned char *result);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libhashkit/behavior.h b/libhashkit/behavior.h
deleted file mode 100644 (file)
index 0fb2258..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* HashKit
- * Copyright (C) 2009 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- */
-
-/**
- * @file
- * @brief HashKit Header
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
index 5cf8b9f53e47cad78724be2180257fcf173ab2d0..4dece00f2337b6d52bfeb27386e3786724f0e079 100644 (file)
@@ -16,7 +16,8 @@
 #include <stdlib.h>
 #include <math.h>
 
-#include <libhashkit/hashkit.h>
+#include <libhashkit-1.0/hashkit.h>
+#include <libhashkit/is.h>
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/libhashkit/configure.h.in b/libhashkit/configure.h.in
deleted file mode 100644 (file)
index 8aec386..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* HashKit
- * Copyright (C) 2009-2010 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libhashkit/digest.h b/libhashkit/digest.h
deleted file mode 100644 (file)
index 5a226b0..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* HashKit
- * Copyright (C) 2010 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-HASHKIT_API
-uint32_t hashkit_digest(const hashkit_st *self, const char *key, size_t key_length);
-
-/**
-  This is a utilitly function provided so that you can directly access hashes with a hashkit_st.
-*/
-
-HASHKIT_API
-uint32_t libhashkit_digest(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libhashkit/function.h b/libhashkit/function.h
deleted file mode 100644 (file)
index 56fcc79..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* HashKit
- * Copyright (C) 2010 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- */
-
-#ifndef HASHKIT_FUNCTION_H
-#define HASHKIT_FUNCTION_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
-  This sets/gets the default function we will be using.
-*/
-HASHKIT_API
-hashkit_return_t hashkit_set_function(hashkit_st *hash, hashkit_hash_algorithm_t hash_algorithm);
-
-HASHKIT_API
-hashkit_return_t hashkit_set_custom_function(hashkit_st *hash, hashkit_hash_fn function, void *context);
-
-HASHKIT_API
-hashkit_hash_algorithm_t hashkit_get_function(const hashkit_st *hash);
-
-/**
-  This sets/gets the function we use for distribution.
-*/
-HASHKIT_API
-hashkit_return_t hashkit_set_distribution_function(hashkit_st *hash, hashkit_hash_algorithm_t hash_algorithm);
-
-HASHKIT_API
-hashkit_return_t hashkit_set_custom_distribution_function(hashkit_st *self, hashkit_hash_fn function, void *context);
-
-HASHKIT_API
-hashkit_hash_algorithm_t hashkit_get_distribution_function(const hashkit_st *self);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HASHKIT_FUNCTION_H */
diff --git a/libhashkit/has.h b/libhashkit/has.h
deleted file mode 100644 (file)
index 8975c7a..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-HASHKIT_API
-bool libhashkit_has_algorithm(const hashkit_hash_algorithm_t);
-
-#ifdef __cplusplus
-}
-#endif
index ad13ec51914aecad76e256f215053696c4eb8cc1..692d5915ccc3774bc4412230051d3e67fb8ed199 100644 (file)
@@ -3,7 +3,6 @@
  *  HashKit library
  *
  *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2009-2010 Brian Aker All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that the following conditions are
 
 #pragma once
 
-
-#if !defined(__cplusplus)
-# include <stdbool.h>
-#endif
-#include <inttypes.h>
-#include <sys/types.h>
-
-#include <libhashkit/visibility.h>
-#include <libhashkit/configure.h>
-#include <libhashkit/types.h>
-#include <libhashkit/has.h>
-#include <libhashkit/algorithm.h>
-#include <libhashkit/behavior.h>
-#include <libhashkit/digest.h>
-#include <libhashkit/function.h>
-#include <libhashkit/str_algorithm.h>
-#include <libhashkit/strerror.h>
-
-struct hashkit_st
-{
-  struct hashkit_function_st {
-    hashkit_hash_fn function;
-    void *context;
-  } base_hash, distribution_hash;
-
-  struct {
-    bool is_base_same_distributed:1;
-  } flags;
-
-  struct {
-    bool is_allocated:1;
-  } options;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-HASHKIT_API
-hashkit_st *hashkit_create(hashkit_st *hash);
-
-HASHKIT_API
-hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *ptr);
-
-HASHKIT_API
-bool hashkit_compare(const hashkit_st *first, const hashkit_st *second);
-
-HASHKIT_API
-void hashkit_free(hashkit_st *hash);
-
-#define hashkit_is_allocated(__object) ((__object)->options.is_allocated)
-#define hashkit_is_initialized(__object) ((__object)->options.is_initialized)
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
+#include <libhashkit-1.0/hashkit.h>
diff --git a/libhashkit/hashkit.hpp b/libhashkit/hashkit.hpp
deleted file mode 100644 (file)
index 7ead63d..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#include <libhashkit/hashkit.h>
-#include <string>
-
-class Hashkit {
-
-public:
-
-  Hashkit()
-  {
-    hashkit_create(&self);
-  }
-
-  Hashkit(const Hashkit& source)
-  {
-    hashkit_clone(&self, &source.self);
-  }
-
-  Hashkit& operator=(const Hashkit& source)
-  {
-    hashkit_free(&self);
-    hashkit_clone(&self, &source.self);
-
-    return *this;
-  }
-
-  friend bool operator==(const Hashkit &left, const Hashkit &right)
-  {
-    return hashkit_compare(&left.self, &right.self);
-  }
-
-  uint32_t digest(std::string& str)
-  {
-    return hashkit_digest(&self, str.c_str(), str.length());
-  }
-
-  uint32_t digest(const char *key, size_t key_length)
-  {
-    return hashkit_digest(&self, key, key_length);
-  }
-
-  hashkit_return_t set_function(hashkit_hash_algorithm_t hash_algorithm)
-  {
-    return hashkit_set_function(&self, hash_algorithm);
-  }
-
-  hashkit_return_t set_distribution_function(hashkit_hash_algorithm_t hash_algorithm)
-  {
-    return hashkit_set_function(&self, hash_algorithm);
-  }
-
-  ~Hashkit()
-  {
-    hashkit_free(&self);
-  }
-private:
-
-  hashkit_st self;
-};
index 72fec057f5f1c0d05d51a2f0bcc597380c2dc727..d9b769f69905843f50e65cb58dc53c2054a9e485 100644 (file)
 
 lib_LTLIBRARIES+= libhashkit/libhashkit.la
 
-EXTRA_DIST+= \
-            libhashkit/configure.h.in
+noinst_HEADERS+= \
+                libhashkit/common.h \
+                libhashkit/is.h
 
 
 nobase_include_HEADERS+= \
-                        libhashkit/algorithm.h \
-                        libhashkit/behavior.h \
-                        libhashkit/configure.h \
-                        libhashkit/digest.h \
-                        libhashkit/function.h \
-                        libhashkit/has.h \
-                        libhashkit/hashkit.h \
-                        libhashkit/hashkit.hpp \
-                        libhashkit/strerror.h \
-                        libhashkit/str_algorithm.h \
-                        libhashkit/types.h \
-                        libhashkit/visibility.h
-
-noinst_HEADERS+= \
-                libhashkit/common.h
+                        libhashkit/hashkit.h
 
 libhashkit_libhashkit_la_SOURCES= \
                                  libhashkit/algorithm.cc \
diff --git a/libhashkit/is.h b/libhashkit/is.h
new file mode 100644 (file)
index 0000000..e8e5772
--- /dev/null
@@ -0,0 +1,43 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  HashKit library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+
+#pragma once
+
+#define hashkit_is_allocated(__object) ((__object)->options.is_allocated)
+#define hashkit_is_initialized(__object) ((__object)->options.is_initialized)
+
diff --git a/libhashkit/str_algorithm.h b/libhashkit/str_algorithm.h
deleted file mode 100644 (file)
index bb05eb5..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  HashKit
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-HASHKIT_API
-const char *libhashkit_string_hash(hashkit_hash_algorithm_t type);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libhashkit/strerror.h b/libhashkit/strerror.h
deleted file mode 100644 (file)
index 3d6a908..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* HashKit
- * Copyright (C) 2009 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- */
-
-#ifndef HASHKIT_STRERROR_H
-#define HASHKIT_STRERROR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-HASHKIT_API
-  const char *hashkit_strerror(hashkit_st *ptr, hashkit_return_t rc);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HASHKIT_STRERROR_H */
diff --git a/libhashkit/types.h b/libhashkit/types.h
deleted file mode 100644 (file)
index e0f1f13..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  HashKit
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#pragma once
-
-typedef enum {
-  HASHKIT_SUCCESS,
-  HASHKIT_FAILURE,
-  HASHKIT_MEMORY_ALLOCATION_FAILURE,
-  HASHKIT_INVALID_HASH,
-  HASHKIT_INVALID_ARGUMENT,
-  HASHKIT_MAXIMUM_RETURN /* Always add new error code before */
-} hashkit_return_t;
-
-static inline bool hashkit_success(const hashkit_return_t rc)
-{
-  return (rc == HASHKIT_SUCCESS);
-}
-
-static inline bool hashkit_failed(const hashkit_return_t rc)
-{
-  return (rc != HASHKIT_SUCCESS);
-}
-
-typedef enum {
-  HASHKIT_HASH_DEFAULT= 0, // hashkit_one_at_a_time()
-  HASHKIT_HASH_MD5,
-  HASHKIT_HASH_CRC,
-  HASHKIT_HASH_FNV1_64,
-  HASHKIT_HASH_FNV1A_64,
-  HASHKIT_HASH_FNV1_32,
-  HASHKIT_HASH_FNV1A_32,
-  HASHKIT_HASH_HSIEH,
-  HASHKIT_HASH_MURMUR,
-  HASHKIT_HASH_JENKINS,
-  HASHKIT_HASH_CUSTOM,
-  HASHKIT_HASH_MAX
-} hashkit_hash_algorithm_t;
-
-/**
- * Hash distributions that are available to use.
- */
-typedef enum
-{
-  HASHKIT_DISTRIBUTION_MODULA,
-  HASHKIT_DISTRIBUTION_RANDOM,
-  HASHKIT_DISTRIBUTION_KETAMA,
-  HASHKIT_DISTRIBUTION_MAX /* Always add new values before this. */
-} hashkit_distribution_t;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct hashkit_st hashkit_st;
-
-typedef uint32_t (*hashkit_hash_fn)(const char *key, size_t key_length, void *context);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libhashkit/visibility.h b/libhashkit/visibility.h
deleted file mode 100644 (file)
index b8f194c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Summary: interface for HashKit functions
- * Description: visibitliy macros for HashKit library
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in this directory for full text.
- * 
- * Author: Monty Taylor
- */
-
-/**
- * @file
- * @brief Visibility control macros
- */
-
-#pragma once
-
-/**
- *
- * HASHKIT_API is used for the public API symbols. It either DLL imports or
- * DLL exports (or does nothing for static build).
- *
- * HASHKIT_LOCAL is used for non-api symbols.
- */
-
-#if defined(BUILDING_HASHKIT)
-# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
-#  define HASHKIT_API __attribute__ ((visibility("default")))
-#  define HASHKIT_LOCAL  __attribute__ ((visibility("hidden")))
-# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
-#  define HASHKIT_API __global
-#  define HASHKIT_LOCAL __hidden
-# elif defined(_MSC_VER)
-#  define HASHKIT_API extern __declspec(dllexport) 
-#  define HASHKIT_LOCAL
-# else
-#  define HASHKIT_API
-#  define HASHKIT_LOCAL
-# endif /* defined(HAVE_VISIBILITY) */
-#else  /* defined(BUILDING_HASHKIT) */
-# if defined(_MSC_VER)
-#  define HASHKIT_API extern __declspec(dllimport) 
-#  define HASHKIT_LOCAL
-# else
-#  define HASHKIT_API
-#  define HASHKIT_LOCAL
-# endif /* defined(_MSC_VER) */
-#endif /* defined(BUILDING_HASHKIT) */
diff --git a/libmemcached-1.0/allocators.h b/libmemcached-1.0/allocators.h
new file mode 100644 (file)
index 0000000..6e4455f
--- /dev/null
@@ -0,0 +1,87 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+struct memcached_allocator_t {
+  memcached_calloc_fn calloc;
+  memcached_free_fn free;
+  memcached_malloc_fn malloc;
+  memcached_realloc_fn realloc;
+  void *context;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_set_memory_allocators(memcached_st *ptr,
+                                                   memcached_malloc_fn mem_malloc,
+                                                   memcached_free_fn mem_free,
+                                                   memcached_realloc_fn mem_realloc,
+                                                   memcached_calloc_fn mem_calloc,
+                                                   void *context);
+
+LIBMEMCACHED_API
+void memcached_get_memory_allocators(const memcached_st *ptr,
+                                     memcached_malloc_fn *mem_malloc,
+                                     memcached_free_fn *mem_free,
+                                     memcached_realloc_fn *mem_realloc,
+                                     memcached_calloc_fn *mem_calloc);
+
+LIBMEMCACHED_API
+void *memcached_get_memory_allocators_context(const memcached_st *ptr);
+
+LIBMEMCACHED_LOCAL
+void _libmemcached_free(const memcached_st *ptr, void *mem, void *context);
+
+LIBMEMCACHED_LOCAL
+void *_libmemcached_malloc(const memcached_st *ptr, const size_t size, void *context);
+
+LIBMEMCACHED_LOCAL
+void *_libmemcached_realloc(const memcached_st *ptr, void *mem, const size_t size, void *context);
+
+LIBMEMCACHED_LOCAL
+void *_libmemcached_calloc(const memcached_st *ptr, size_t nelem, size_t size, void *context);
+
+LIBMEMCACHED_LOCAL
+struct memcached_allocator_t memcached_allocators_return_default(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/analyze.h b/libmemcached-1.0/analyze.h
new file mode 100644 (file)
index 0000000..955901a
--- /dev/null
@@ -0,0 +1,66 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+struct memcached_analysis_st {
+  memcached_st *root;
+  uint32_t average_item_size;
+  uint32_t longest_uptime;
+  uint32_t least_free_server;
+  uint32_t most_consumed_server;
+  uint32_t oldest_server;
+  double pool_hit_ratio;
+  uint64_t most_used_bytes;
+  uint64_t least_remaining_bytes;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_analysis_st *memcached_analyze(memcached_st *memc,
+                                         memcached_stat_st *memc_stat,
+                                         memcached_return_t *error);
+
+LIBMEMCACHED_API
+void memcached_analyze_free(memcached_analysis_st *);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/auto.h b/libmemcached-1.0/auto.h
new file mode 100644 (file)
index 0000000..f37d50f
--- /dev/null
@@ -0,0 +1,111 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_increment(memcached_st *ptr,
+                                         const char *key, size_t key_length,
+                                         uint32_t offset,
+                                         uint64_t *value);
+LIBMEMCACHED_API
+  memcached_return_t memcached_decrement(memcached_st *ptr,
+                                         const char *key, size_t key_length,
+                                         uint32_t offset,
+                                         uint64_t *value);
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_increment_by_key(memcached_st *ptr,
+                                                const char *group_key, size_t group_key_length,
+                                                const char *key, size_t key_length,
+                                                uint64_t offset,
+                                                uint64_t *value);
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_decrement_by_key(memcached_st *ptr,
+                                                const char *group_key, size_t group_key_length,
+                                                const char *key, size_t key_length,
+                                                uint64_t offset,
+                                                uint64_t *value);
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_increment_with_initial(memcached_st *ptr,
+                                                      const char *key,
+                                                      size_t key_length,
+                                                      uint64_t offset,
+                                                      uint64_t initial,
+                                                      time_t expiration,
+                                                      uint64_t *value);
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_decrement_with_initial(memcached_st *ptr,
+                                                      const char *key,
+                                                      size_t key_length,
+                                                      uint64_t offset,
+                                                      uint64_t initial,
+                                                      time_t expiration,
+                                                      uint64_t *value);
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_increment_with_initial_by_key(memcached_st *ptr,
+                                                             const char *group_key,
+                                                             size_t group_key_length,
+                                                             const char *key,
+                                                             size_t key_length,
+                                                             uint64_t offset,
+                                                             uint64_t initial,
+                                                             time_t expiration,
+                                                             uint64_t *value);
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_decrement_with_initial_by_key(memcached_st *ptr,
+                                                             const char *group_key,
+                                                             size_t group_key_length,
+                                                             const char *key,
+                                                             size_t key_length,
+                                                             uint64_t offset,
+                                                             uint64_t initial,
+                                                             time_t expiration,
+                                                             uint64_t *value);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/basic_string.h b/libmemcached-1.0/basic_string.h
new file mode 100644 (file)
index 0000000..de8d3d5
--- /dev/null
@@ -0,0 +1,55 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+// No assumptions of NULL should be made
+
+struct memcached_string_t {
+  const char *c_str;
+  size_t size;
+};
+
+#define memcached_size(X) (X).size;
+#define memcached_c_str(X) (X).c_str;
+#define memcached_string_param(X) (X).c_str, (X).size
+
+#ifdef __cplusplus
+#define memcached_string_printf(X) int((X).size), (X).c_str
+#else
+#define memcached_string_printf(X) (int)((X).size), (X).c_str
+#endif
+
diff --git a/libmemcached-1.0/behavior.h b/libmemcached-1.0/behavior.h
new file mode 100644 (file)
index 0000000..426f988
--- /dev/null
@@ -0,0 +1,86 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_behavior_set(memcached_st *ptr, const memcached_behavior_t flag, uint64_t data);
+
+LIBMEMCACHED_API
+uint64_t memcached_behavior_get(memcached_st *ptr, const memcached_behavior_t flag);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_behavior_set_distribution(memcached_st *ptr, memcached_server_distribution_t type);
+
+LIBMEMCACHED_API
+memcached_server_distribution_t memcached_behavior_get_distribution(memcached_st *ptr);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_behavior_set_key_hash(memcached_st *ptr, memcached_hash_t type);
+
+LIBMEMCACHED_API
+memcached_hash_t memcached_behavior_get_key_hash(memcached_st *ptr);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_behavior_set_distribution_hash(memcached_st *ptr, memcached_hash_t type);
+
+LIBMEMCACHED_API
+memcached_hash_t memcached_behavior_get_distribution_hash(memcached_st *ptr);
+
+LIBMEMCACHED_LOCAL
+bool _is_auto_eject_host(const memcached_st *ptr);
+
+LIBMEMCACHED_API
+  const char *libmemcached_string_behavior(const memcached_behavior_t flag);
+
+LIBMEMCACHED_API
+  const char *libmemcached_string_distribution(const memcached_server_distribution_t flag);
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_bucket_set(memcached_st *self,
+                                          const uint32_t *host_map,
+                                          const uint32_t *forward_map,
+                                          const uint32_t buckets,
+                                          const uint32_t replicas);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/callback.h b/libmemcached-1.0/callback.h
new file mode 100644 (file)
index 0000000..a9465d2
--- /dev/null
@@ -0,0 +1,61 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+struct memcached_callback_st {
+  memcached_execute_fn *callback;
+  void *context;
+  uint32_t number_of_callback;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_callback_set(memcached_st *ptr,
+                                          const memcached_callback_t flag,
+                                          const void *data);
+LIBMEMCACHED_API
+void *memcached_callback_get(memcached_st *ptr,
+                             const memcached_callback_t flag,
+                             memcached_return_t *error);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/configure.h.in b/libmemcached-1.0/configure.h.in
new file mode 100644 (file)
index 0000000..7b48be2
--- /dev/null
@@ -0,0 +1,52 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker, Trond Norbye All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+@DEPRECATED@
+@LIBMEMCACHED_WITH_SASL_SUPPORT@
+
+#define LIBMEMCACHED_VERSION_STRING "@VERSION@"
+#define LIBMEMCACHED_VERSION_HEX @PANDORA_HEX_VERSION@
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/constants.h b/libmemcached-1.0/constants.h
new file mode 100644 (file)
index 0000000..9c8ab64
--- /dev/null
@@ -0,0 +1,167 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#pragma once
+
+/* Public defines */
+#define MEMCACHED_DEFAULT_PORT 11211
+#define MEMCACHED_MAX_KEY 251 /* We add one to have it null terminated */
+#define MEMCACHED_MAX_BUFFER 8196
+#define MEMCACHED_MAX_HOST_SORT_LENGTH 86 /* Used for Ketama */
+#define MEMCACHED_POINTS_PER_SERVER 100
+#define MEMCACHED_POINTS_PER_SERVER_KETAMA 160
+#define MEMCACHED_CONTINUUM_SIZE MEMCACHED_POINTS_PER_SERVER*100 /* This would then set max hosts to 100 */
+#define MEMCACHED_STRIDE 4
+#define MEMCACHED_DEFAULT_TIMEOUT 5000
+#define MEMCACHED_DEFAULT_CONNECT_TIMEOUT 4000
+#define MEMCACHED_CONTINUUM_ADDITION 10 /* How many extra slots we should build for in the continuum */
+#define MEMCACHED_PREFIX_KEY_MAX_SIZE 128
+#define MEMCACHED_EXPIRATION_NOT_ADD 0xffffffffU
+#define MEMCACHED_VERSION_STRING_LENGTH 24
+#define MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH 20
+#define MEMCACHED_SERVER_FAILURE_LIMIT 5
+#define MEMCACHED_SERVER_FAILURE_RETRY_TIMEOUT 2
+
+
+enum memcached_server_distribution_t {
+  MEMCACHED_DISTRIBUTION_MODULA,
+  MEMCACHED_DISTRIBUTION_CONSISTENT,
+  MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA,
+  MEMCACHED_DISTRIBUTION_RANDOM,
+  MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY,
+  MEMCACHED_DISTRIBUTION_CONSISTENT_WEIGHTED,
+  MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET,
+  MEMCACHED_DISTRIBUTION_CONSISTENT_MAX
+};
+
+#ifndef __cplusplus
+typedef enum memcached_server_distribution_t memcached_server_distribution_t;
+#endif
+
+enum memcached_behavior_t {
+  MEMCACHED_BEHAVIOR_NO_BLOCK,
+  MEMCACHED_BEHAVIOR_TCP_NODELAY,
+  MEMCACHED_BEHAVIOR_HASH,
+  MEMCACHED_BEHAVIOR_KETAMA,
+  MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE,
+  MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE,
+  MEMCACHED_BEHAVIOR_CACHE_LOOKUPS,
+  MEMCACHED_BEHAVIOR_SUPPORT_CAS,
+  MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
+  MEMCACHED_BEHAVIOR_DISTRIBUTION,
+  MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,
+  MEMCACHED_BEHAVIOR_USER_DATA,
+  MEMCACHED_BEHAVIOR_SORT_HOSTS,
+  MEMCACHED_BEHAVIOR_VERIFY_KEY,
+  MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,
+  MEMCACHED_BEHAVIOR_RETRY_TIMEOUT,
+  MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED,
+  MEMCACHED_BEHAVIOR_KETAMA_HASH,
+  MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
+  MEMCACHED_BEHAVIOR_SND_TIMEOUT,
+  MEMCACHED_BEHAVIOR_RCV_TIMEOUT,
+  MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,
+  MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK,
+  MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK,
+  MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH,
+  MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY,
+  MEMCACHED_BEHAVIOR_NOREPLY,
+  MEMCACHED_BEHAVIOR_USE_UDP,
+  MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS,
+  MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
+  MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ,
+  MEMCACHED_BEHAVIOR_CORK,
+  MEMCACHED_BEHAVIOR_TCP_KEEPALIVE,
+  MEMCACHED_BEHAVIOR_TCP_KEEPIDLE,
+  MEMCACHED_BEHAVIOR_LOAD_FROM_FILE,
+  MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS,
+  MEMCACHED_BEHAVIOR_MAX
+};
+
+#ifndef __cplusplus
+typedef enum memcached_behavior_t memcached_behavior_t;
+#endif
+
+enum memcached_callback_t {
+  MEMCACHED_CALLBACK_PREFIX_KEY = 0,
+  MEMCACHED_CALLBACK_USER_DATA = 1,
+  MEMCACHED_CALLBACK_CLEANUP_FUNCTION = 2,
+  MEMCACHED_CALLBACK_CLONE_FUNCTION = 3,
+  MEMCACHED_CALLBACK_GET_FAILURE = 7,
+  MEMCACHED_CALLBACK_DELETE_TRIGGER = 8,
+  MEMCACHED_CALLBACK_MAX,
+  MEMCACHED_CALLBACK_NAMESPACE= MEMCACHED_CALLBACK_PREFIX_KEY
+};
+
+#ifndef __cplusplus
+typedef enum memcached_callback_t memcached_callback_t;
+#endif
+
+enum memcached_hash_t {
+  MEMCACHED_HASH_DEFAULT= 0,
+  MEMCACHED_HASH_MD5,
+  MEMCACHED_HASH_CRC,
+  MEMCACHED_HASH_FNV1_64,
+  MEMCACHED_HASH_FNV1A_64,
+  MEMCACHED_HASH_FNV1_32,
+  MEMCACHED_HASH_FNV1A_32,
+  MEMCACHED_HASH_HSIEH,
+  MEMCACHED_HASH_MURMUR,
+  MEMCACHED_HASH_JENKINS,
+  MEMCACHED_HASH_CUSTOM,
+  MEMCACHED_HASH_MAX
+};
+
+#ifndef __cplusplus
+typedef enum memcached_hash_t memcached_hash_t;
+#endif
+
+enum memcached_connection_t {
+  MEMCACHED_CONNECTION_TCP,
+  MEMCACHED_CONNECTION_UDP,
+  MEMCACHED_CONNECTION_UNIX_SOCKET
+};
+
+enum {
+  MEMCACHED_CONNECTION_UNKNOWN= 0,
+  MEMCACHED_CONNECTION_MAX= 0
+};
+
+#ifndef __cplusplus
+typedef enum memcached_connection_t memcached_connection_t;
+#endif
diff --git a/libmemcached-1.0/delete.h b/libmemcached-1.0/delete.h
new file mode 100644 (file)
index 0000000..617d585
--- /dev/null
@@ -0,0 +1,57 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_delete(memcached_st *ptr, const char *key, size_t key_length,
+                                    time_t expiration);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_delete_by_key(memcached_st *ptr,
+                                           const char *group_key, size_t group_key_length,
+                                           const char *key, size_t key_length,
+                                           time_t expiration);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/dump.h b/libmemcached-1.0/dump.h
new file mode 100644 (file)
index 0000000..b6e639e
--- /dev/null
@@ -0,0 +1,51 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_dump(memcached_st *ptr, memcached_dump_fn *function, void *context, uint32_t number_of_callbacks);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/error.h b/libmemcached-1.0/error.h
new file mode 100644 (file)
index 0000000..8b04e09
--- /dev/null
@@ -0,0 +1,64 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  LibMemcached
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+  const char *memcached_last_error_message(memcached_st *);
+
+LIBMEMCACHED_API
+  void memcached_error_print(const memcached_st *);
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_last_error(memcached_st *);
+
+LIBMEMCACHED_API
+  int memcached_last_error_errno(memcached_st *);
+
+LIBMEMCACHED_API
+  const char *memcached_server_error(memcached_server_instance_st ptr);
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_server_error_return(memcached_server_instance_st ptr);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/libmemcached-1.0/exception.hpp b/libmemcached-1.0/exception.hpp
new file mode 100644 (file)
index 0000000..4759072
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Summary: Exceptions for the C++ interface
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ */
+
+/**
+ * @file
+ * @brief Exception declarations
+ */
+
+#pragma once
+
+#include <stdexcept>
+#include <string>
+
+namespace memcache 
+{
+  class Exception : public std::runtime_error
+  {
+  public:
+    Exception(const std::string& msg, int in_errno)
+      : 
+        std::runtime_error(msg), 
+        _errno(in_errno) 
+    {}
+
+    Exception(const char *msg, int in_errno)
+      : 
+        std::runtime_error(std::string(msg)), 
+        _errno(in_errno) {}
+
+    virtual ~Exception() throw() {}
+
+    int getErrno() const 
+    { 
+      return _errno; 
+    }
+
+  private:
+    int _errno;
+  };
+
+  class Warning : public Exception
+  {
+  public:
+    Warning(const std::string& msg, int in_errno) : Exception(msg, in_errno) {}
+    Warning(const char *msg, int in_errno) : Exception(msg, in_errno) {}
+  };
+
+  class Error : public Exception
+  {
+  public:
+    Error(const std::string& msg, int in_errno) : Exception(msg, in_errno) {}
+    Error(const char *msg, int in_errno) : Exception(msg, in_errno) {}
+    virtual ~Error() throw() {}
+  };
+
+} /* namespace libmemcached */
diff --git a/libmemcached-1.0/exist.h b/libmemcached-1.0/exist.h
new file mode 100644 (file)
index 0000000..816fe2f
--- /dev/null
@@ -0,0 +1,43 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+memcached_return_t memcached_exist(memcached_st *memc, const char *key, size_t key_length);
+
+memcached_return_t memcached_exist_by_key(memcached_st *memc,
+                                          const char *group_key, size_t group_key_length,
+                                          const char *key, size_t key_length);
diff --git a/libmemcached-1.0/fetch.h b/libmemcached-1.0/fetch.h
new file mode 100644 (file)
index 0000000..bff186a
--- /dev/null
@@ -0,0 +1,53 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_fetch_execute(memcached_st *ptr,
+                                           memcached_execute_fn *callback,
+                                           void *context,
+                                           uint32_t number_of_callbacks);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/flush.h b/libmemcached-1.0/flush.h
new file mode 100644 (file)
index 0000000..820a98e
--- /dev/null
@@ -0,0 +1,49 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_flush(memcached_st *ptr, time_t expiration);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/flush_buffers.h b/libmemcached-1.0/flush_buffers.h
new file mode 100644 (file)
index 0000000..31b5868
--- /dev/null
@@ -0,0 +1,49 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_flush_buffers(memcached_st *mem);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/get.h b/libmemcached-1.0/get.h
new file mode 100644 (file)
index 0000000..32e4c5f
--- /dev/null
@@ -0,0 +1,110 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Public defines */
+LIBMEMCACHED_API
+char *memcached_get(memcached_st *ptr,
+                    const char *key, size_t key_length,
+                    size_t *value_length,
+                    uint32_t *flags,
+                    memcached_return_t *error);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_mget(memcached_st *ptr,
+                                  const char * const *keys,
+                                  const size_t *key_length,
+                                  size_t number_of_keys);
+
+LIBMEMCACHED_API
+char *memcached_get_by_key(memcached_st *ptr,
+                           const char *group_key, size_t group_key_length,
+                           const char *key, size_t key_length,
+                           size_t *value_length,
+                           uint32_t *flags,
+                           memcached_return_t *error);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_mget_by_key(memcached_st *ptr,
+                                         const char *group_key,
+                                         size_t group_key_length,
+                                         const char * const *keys,
+                                         const size_t *key_length,
+                                         const size_t number_of_keys);
+
+LIBMEMCACHED_API
+char *memcached_fetch(memcached_st *ptr,
+                      char *key,
+                      size_t *key_length,
+                      size_t *value_length,
+                      uint32_t *flags,
+                      memcached_return_t *error);
+
+LIBMEMCACHED_API
+memcached_result_st *memcached_fetch_result(memcached_st *ptr,
+                                            memcached_result_st *result,
+                                            memcached_return_t *error);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_mget_execute(memcached_st *ptr,
+                                          const char * const *keys,
+                                          const size_t *key_length,
+                                          const size_t number_of_keys,
+                                          memcached_execute_fn *callback,
+                                          void *context,
+                                          const uint32_t number_of_callbacks);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_mget_execute_by_key(memcached_st *ptr,
+                                                 const char *group_key,
+                                                 size_t group_key_length,
+                                                 const char * const *keys,
+                                                 const size_t *key_length,
+                                                 size_t number_of_keys,
+                                                 memcached_execute_fn *callback,
+                                                 void *context,
+                                                 const uint32_t number_of_callbacks);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/hash.h b/libmemcached-1.0/hash.h
new file mode 100644 (file)
index 0000000..6002a80
--- /dev/null
@@ -0,0 +1,68 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The two public hash bits */
+LIBMEMCACHED_API
+uint32_t memcached_generate_hash_value(const char *key, size_t key_length, memcached_hash_t hash_algorithm);
+
+LIBMEMCACHED_API
+const hashkit_st *memcached_get_hashkit(const memcached_st *ptr);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_set_hashkit(memcached_st *ptr, hashkit_st *hashk);
+
+LIBMEMCACHED_API
+uint32_t memcached_generate_hash(const memcached_st *ptr, const char *key, size_t key_length);
+
+LIBMEMCACHED_LOCAL
+uint32_t memcached_generate_hash_with_redistribution(memcached_st *ptr, const char *key, size_t key_length);
+
+LIBMEMCACHED_API
+void memcached_autoeject(memcached_st *ptr);
+
+LIBMEMCACHED_API
+  const char * libmemcached_string_hash(memcached_hash_t type);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/include.am b/libmemcached-1.0/include.am
new file mode 100644 (file)
index 0000000..39313c2
--- /dev/null
@@ -0,0 +1,47 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+EXTRA_DIST+= \
+            libmemcached-1.0/configure.h.in
+
+nobase_include_HEADERS+= \
+                        libmemcached-1.0/allocators.h \
+                        libmemcached-1.0/analyze.h \
+                        libmemcached-1.0/auto.h \
+                        libmemcached-1.0/basic_string.h \
+                        libmemcached-1.0/behavior.h \
+                        libmemcached-1.0/callback.h \
+                        libmemcached-1.0/configure.h \
+                        libmemcached-1.0/constants.h \
+                        libmemcached-1.0/delete.h \
+                        libmemcached-1.0/dump.h \
+                        libmemcached-1.0/error.h \
+                        libmemcached-1.0/exist.h \
+                        libmemcached-1.0/exception.hpp \
+                        libmemcached-1.0/fetch.h \
+                        libmemcached-1.0/flush.h \
+                        libmemcached-1.0/flush_buffers.h \
+                        libmemcached-1.0/get.h \
+                        libmemcached-1.0/hash.h \
+                        libmemcached-1.0/memcached.h \
+                        libmemcached-1.0/memcached.hpp \
+                        libmemcached-1.0/options.h \
+                        libmemcached-1.0/parse.h \
+                        libmemcached-1.0/quit.h \
+                        libmemcached-1.0/return.h \
+                         libmemcached-1.0/platform.h \
+                        libmemcached-1.0/result.h \
+                         libmemcached-1.0/sasl.h \
+                        libmemcached-1.0/server.h \
+                        libmemcached-1.0/server_list.h \
+                        libmemcached-1.0/stats.h \
+                        libmemcached-1.0/storage.h \
+                        libmemcached-1.0/strerror.h \
+                        libmemcached-1.0/string.h \
+                        libmemcached-1.0/touch.h \
+                        libmemcached-1.0/types.h \
+                        libmemcached-1.0/verbosity.h \
+                        libmemcached-1.0/version.h \
+                        libmemcached-1.0/visibility.h
+
diff --git a/libmemcached-1.0/memcached.h b/libmemcached-1.0/memcached.h
new file mode 100644 (file)
index 0000000..f97d333
--- /dev/null
@@ -0,0 +1,217 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+
+#if !defined(__cplusplus)
+# include <stdbool.h>
+#endif
+
+#include <libmemcached-1.0/visibility.h>
+#include <libmemcached-1.0/configure.h>
+#include <libmemcached-1.0/platform.h>
+#include <libmemcached-1.0/constants.h>
+#include <libmemcached-1.0/return.h>
+#include <libmemcached-1.0/types.h>
+#include <libmemcached-1.0/basic_string.h>
+#include <libmemcached-1.0/string.h>
+#include <libmemcached-1.0/error.h>
+#include <libmemcached-1.0/stats.h>
+#include <libhashkit-1.0/hashkit.h>
+
+// Everything above this line must be in the order specified.
+#include <libmemcached-1.0/allocators.h>
+#include <libmemcached-1.0/analyze.h>
+#include <libmemcached-1.0/auto.h>
+#include <libmemcached-1.0/behavior.h>
+#include <libmemcached-1.0/callback.h>
+#include <libmemcached-1.0/delete.h>
+#include <libmemcached-1.0/dump.h>
+#include <libmemcached-1.0/exist.h>
+#include <libmemcached-1.0/fetch.h>
+#include <libmemcached-1.0/flush.h>
+#include <libmemcached-1.0/flush_buffers.h>
+#include <libmemcached-1.0/get.h>
+#include <libmemcached-1.0/hash.h>
+#include <libmemcached-1.0/options.h>
+#include <libmemcached-1.0/parse.h>
+#include <libmemcached-1.0/quit.h>
+#include <libmemcached-1.0/result.h>
+#include <libmemcached-1.0/server.h>
+#include <libmemcached-1.0/server_list.h>
+#include <libmemcached-1.0/storage.h>
+#include <libmemcached-1.0/strerror.h>
+#include <libmemcached-1.0/touch.h>
+#include <libmemcached-1.0/verbosity.h>
+#include <libmemcached-1.0/version.h>
+#include <libmemcached-1.0/sasl.h>
+
+struct memcached_st {
+  /**
+    @note these are static and should not change without a call to behavior.
+  */
+  struct {
+    bool is_purging:1;
+    bool is_processing_input:1;
+    bool is_time_for_rebuild:1;
+  } state;
+
+  struct {
+    // Everything below here is pretty static.
+    bool auto_eject_hosts:1;
+    bool binary_protocol:1;
+    bool buffer_requests:1;
+    bool hash_with_namespace:1;
+    bool no_block:1; // Don't block
+    bool no_reply:1;
+    bool randomize_replica_read:1;
+    bool support_cas:1;
+    bool tcp_nodelay:1;
+    bool use_sort_hosts:1;
+    bool use_udp:1;
+    bool verify_key:1;
+    bool tcp_keepalive:1;
+  } flags;
+
+  memcached_server_distribution_t distribution;
+  hashkit_st hashkit;
+  struct {
+    unsigned int version;
+  } server_info;
+  uint32_t number_of_hosts;
+  memcached_server_st *servers;
+  memcached_server_st *last_disconnected_server;
+  int32_t snd_timeout;
+  int32_t rcv_timeout;
+  uint32_t server_failure_limit;
+  uint32_t io_msg_watermark;
+  uint32_t io_bytes_watermark;
+  uint32_t io_key_prefetch;
+  uint32_t tcp_keepidle;
+  int32_t poll_timeout;
+  int32_t connect_timeout; // How long we will wait on connect() before we will timeout
+  int32_t retry_timeout;
+  int send_size;
+  int recv_size;
+  void *user_data;
+  uint64_t query_id;
+  uint32_t number_of_replicas;
+  memcached_result_st result;
+
+  struct {
+    bool weighted;
+    uint32_t continuum_count; // Ketama
+    uint32_t continuum_points_counter; // Ketama
+    time_t next_distribution_rebuild; // Ketama
+    memcached_continuum_item_st *continuum; // Ketama
+  } ketama;
+
+  struct memcached_virtual_bucket_t *virtual_bucket;
+
+  struct memcached_allocator_t allocators;
+
+  memcached_clone_fn on_clone;
+  memcached_cleanup_fn on_cleanup;
+  memcached_trigger_key_fn get_key_failure;
+  memcached_trigger_delete_key_fn delete_trigger;
+  memcached_callback_st *callbacks;
+  struct memcached_sasl_st sasl;
+  struct memcached_error_t *error_messages;
+  struct memcached_array_st *_namespace;
+  struct {
+    uint32_t initial_pool_size;
+    uint32_t max_pool_size;
+    int32_t version; // This is used by pool and others to determine if the memcached_st is out of date.
+    struct memcached_array_st *filename;
+  } configure;
+  struct {
+    bool is_allocated:1;
+  } options;
+
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+void memcached_servers_reset(memcached_st *ptr);
+
+LIBMEMCACHED_API
+memcached_st *memcached_create(memcached_st *ptr);
+
+LIBMEMCACHED_API
+memcached_st *memcached(const char *string, size_t string_length);
+
+LIBMEMCACHED_API
+void memcached_free(memcached_st *ptr);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_reset(memcached_st *ptr);
+
+LIBMEMCACHED_API
+void memcached_reset_last_disconnected_server(memcached_st *ptr);
+
+LIBMEMCACHED_API
+memcached_st *memcached_clone(memcached_st *clone, const memcached_st *ptr);
+
+LIBMEMCACHED_API
+void *memcached_get_user_data(const memcached_st *ptr);
+
+LIBMEMCACHED_API
+void *memcached_set_user_data(memcached_st *ptr, void *data);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_push(memcached_st *destination, const memcached_st *source);
+
+LIBMEMCACHED_API
+memcached_server_instance_st memcached_server_instance_by_position(const memcached_st *ptr, uint32_t server_key);
+
+LIBMEMCACHED_API
+uint32_t memcached_server_count(const memcached_st *);
+
+LIBMEMCACHED_API
+uint64_t memcached_query_id(const memcached_st *);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/libmemcached-1.0/memcached.hpp b/libmemcached-1.0/memcached.hpp
new file mode 100644 (file)
index 0000000..66d6252
--- /dev/null
@@ -0,0 +1,827 @@
+/*
+ * Summary: C++ interface for memcached server
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Authors: Padraig O'Sullivan <osullivan.padraig@gmail.com>
+ *          Patrick Galbraith <patg@patg.net>
+ */
+
+/**
+ * @file memcached.hpp
+ * @brief Libmemcached C++ interface
+ */
+
+#pragma once
+
+#include <libmemcached-1.0/memcached.h>
+#if 0
+#include <libmemcached/exception.hpp>
+#endif
+
+#include <string.h>
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <map>
+
+namespace memcache
+{
+
+/**
+ * This is the core memcached library (if later, other objects
+ * are needed, they will be created from this class).
+ */
+class Memcache
+{
+public:
+
+  Memcache()
+  {
+    memc= memcached("", 0);
+  }
+
+  Memcache(const std::string &config)
+  {
+    memc= memcached(config.c_str(), config.size());
+  }
+
+  Memcache(const std::string &hostname, in_port_t port)
+  {
+    memc= memcached("", 0);
+    if (memc)
+      memcached_server_add(memc, hostname.c_str(), port);
+  }
+
+  Memcache(memcached_st *clone)
+  {
+    memc= memcached_clone(NULL, clone);
+  }
+
+  Memcache(const Memcache &rhs)
+  {
+    memc= memcached_clone(NULL, rhs.getImpl());
+  }
+
+  Memcache &operator=(const Memcache &rhs)
+  {
+    if (this != &rhs)
+    {
+      memcached_free(memc);
+      memc= memcached_clone(NULL, rhs.getImpl());
+    }
+
+    return *this;
+  }
+
+  ~Memcache()
+  {
+    memcached_free(memc);
+  }
+
+  /**
+   * Get the internal memcached_st *
+   */
+  const memcached_st *getImpl() const
+  {
+    return memc;
+  }
+
+  /**
+   * Return an error string for the given return structure.
+   *
+   * @param[in] rc a memcached_return_t structure
+   * @return error string corresponding to given return code in the library.
+   */
+  const std::string getError(memcached_return_t rc) const
+  {
+    /* first parameter to strerror is unused */
+    return memcached_strerror(NULL, rc);
+  }
+
+  bool error(std::string& error_message) const
+  {
+    if (memcached_failed(memcached_last_error(memc)))
+    {
+      error_message+= memcached_last_error_message(memc);
+      return true;
+    }
+
+    return false;
+  }
+
+  bool error() const
+  {
+    if (memcached_failed(memcached_last_error(memc)))
+    {
+      return true;
+    }
+
+    return false;
+  }
+
+  bool error(memcached_return_t& arg) const
+  {
+    arg= memcached_last_error(memc);
+    return memcached_failed(arg);
+  }
+
+  bool setBehavior(memcached_behavior_t flag, uint64_t data)
+  {
+    return (memcached_success(memcached_behavior_set(memc, flag, data)));
+  }
+
+  uint64_t getBehavior(memcached_behavior_t flag)
+  {
+    return memcached_behavior_get(memc, flag);
+  }
+
+  /**
+   * Configure the memcache object
+   *
+   * @param[in] in_config configuration
+   * @return true on success; false otherwise
+   */
+  bool configure(const std::string &configuration)
+  {
+    memcached_st *new_memc= memcached(configuration.c_str(), configuration.size());
+
+    if (new_memc)
+    {
+      memcached_free(memc);
+      memc= new_memc;
+
+      return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Add a server to the list of memcached servers to use.
+   *
+   * @param[in] server_name name of the server to add
+   * @param[in] port port number of server to add
+   * @return true on success; false otherwise
+   */
+  bool addServer(const std::string &server_name, in_port_t port)
+  {
+    return memcached_success(memcached_server_add(memc, server_name.c_str(), port));
+  }
+
+  /**
+   * Remove a server from the list of memcached servers to use.
+   *
+   * @param[in] server_name name of the server to remove
+   * @param[in] port port number of server to remove
+   * @return true on success; false otherwise
+   */
+  bool removeServer(const std::string &server_name, in_port_t port)
+  {
+    std::string tmp_str;
+    std::ostringstream strstm;
+    tmp_str.append(",");
+    tmp_str.append(server_name);
+    tmp_str.append(":");
+    strstm << port;
+    tmp_str.append(strstm.str());
+
+    //memcached_return_t rc= memcached_server_remove(server);
+    
+    return false;
+  }
+
+  /**
+   * Fetches an individual value from the server. mget() must always
+   * be called before using this method.
+   *
+   * @param[in] key key of object to fetch
+   * @param[out] ret_val store returned object in this vector
+   * @return a memcached return structure
+   */
+  memcached_return_t fetch(std::string &key,
+                           std::vector<char> &ret_val,
+                           uint32_t &flags,
+                           uint64_t &cas_value)
+  {
+    memcached_return_t rc;
+
+    memcached_result_st *result;
+    if ((result= memcached_fetch_result(memc, NULL, &rc)))
+    {
+      // Key
+      key.assign(memcached_result_key_value(result), memcached_result_key_length(result));
+
+      // Actual value, null terminated
+      ret_val.reserve(memcached_result_length(result) +1);
+      ret_val.assign(memcached_result_value(result), 
+                     memcached_result_value(result) +memcached_result_length(result));
+
+      // Misc
+      flags= memcached_result_flags(result);
+      cas_value= memcached_result_cas(result);
+    }
+    memcached_result_free(result);
+
+    return rc;
+  }
+
+  memcached_return_t fetch(std::string &key,
+                           std::vector<char> &ret_val)
+  {
+    uint32_t flags= 0;
+    uint64_t cas_value= 0;
+
+    return fetch(key, ret_val, flags, cas_value);
+  }
+
+  /**
+   * Fetches an individual value from the server.
+   *
+   * @param[in] key key of object whose value to get
+   * @param[out] ret_val object that is retrieved is stored in
+   *                     this vector
+   * @return true on success; false otherwise
+   */
+  bool get(const std::string &key, std::vector<char> &ret_val)
+  {
+    uint32_t flags= 0;
+    memcached_return_t rc;
+    size_t value_length= 0;
+
+    char *value= memcached_get(memc, key.c_str(), key.length(),
+                               &value_length, &flags, &rc);
+    if (value != NULL && ret_val.empty())
+    {
+      ret_val.reserve(value_length);
+      ret_val.assign(value, value + value_length);
+      free(value);
+      return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Fetches an individual from a server which is specified by
+   * the master_key parameter that is used for determining which
+   * server an object was stored in if key partitioning was
+   * used for storage.
+   *
+   * @param[in] master_key key that specifies server object is stored on
+   * @param[in] key key of object whose value to get
+   * @param[out] ret_val object that is retrieved is stored in
+   *                     this vector
+   * @return true on success; false otherwise
+   */
+  bool getByKey(const std::string &master_key,
+                const std::string &key,
+                std::vector<char> &ret_val)
+  {
+    uint32_t flags= 0;
+    memcached_return_t rc;
+    size_t value_length= 0;
+
+    char *value= memcached_get_by_key(memc,
+                                      master_key.c_str(), master_key.length(),
+                                      key.c_str(), key.length(),
+                                      &value_length, &flags, &rc);
+    if (value)
+    {
+      ret_val.reserve(value_length);
+      ret_val.assign(value, value + value_length);
+      free(value);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Selects multiple keys at once. This method always
+   * works asynchronously.
+   *
+   * @param[in] keys vector of keys to select
+   * @return true if all keys are found
+   */
+  bool mget(std::vector<std::string> &keys)
+  {
+    std::vector<const char *> real_keys;
+    std::vector<size_t> key_len;
+    /*
+     * Construct an array which will contain the length
+     * of each of the strings in the input vector. Also, to
+     * interface with the memcached C API, we need to convert
+     * the vector of std::string's to a vector of char *.
+     */
+    real_keys.reserve(keys.size());
+    key_len.reserve(keys.size());
+
+    std::vector<std::string>::iterator it= keys.begin();
+
+    while (it != keys.end())
+    {
+      real_keys.push_back(const_cast<char *>((*it).c_str()));
+      key_len.push_back((*it).length());
+      ++it;
+    }
+
+    /*
+     * If the std::vector of keys is empty then we cannot
+     * call memcached_mget as we will get undefined behavior.
+     */
+    if (not real_keys.empty())
+    {
+      return memcached_success(memcached_mget(memc, &real_keys[0], &key_len[0], real_keys.size()));
+    }
+
+    return false;
+  }
+
+  /**
+   * Writes an object to the server. If the object already exists, it will
+   * overwrite the existing object. This method always returns true
+   * when using non-blocking mode unless a network error occurs.
+   *
+   * @param[in] key key of object to write to server
+   * @param[in] value value of object to write to server
+   * @param[in] expiration time to keep the object stored in the server for
+   * @param[in] flags flags to store with the object
+   * @return true on succcess; false otherwise
+   */
+  bool set(const std::string &key,
+           const std::vector<char> &value,
+           time_t expiration,
+           uint32_t flags)
+  {
+    memcached_return_t rc= memcached_set(memc,
+                                         key.c_str(), key.length(),
+                                         &value[0], value.size(),
+                                         expiration, flags);
+    return memcached_success(rc);
+  }
+
+  /**
+   * Writes an object to a server specified by the master_key parameter.
+   * If the object already exists, it will overwrite the existing object.
+   *
+   * @param[in] master_key key that specifies server to write to
+   * @param[in] key key of object to write to server
+   * @param[in] value value of object to write to server
+   * @param[in] expiration time to keep the object stored in the server for
+   * @param[in] flags flags to store with the object
+   * @return true on succcess; false otherwise
+   */
+  bool setByKey(const std::string &master_key,
+                const std::string &key,
+                const std::vector<char> &value,
+                time_t expiration,
+                uint32_t flags)
+  {
+    return memcached_success(memcached_set_by_key(memc, master_key.c_str(),
+                                                  master_key.length(),
+                                                  key.c_str(), key.length(),
+                                                  &value[0], value.size(),
+                                                  expiration,
+                                                  flags));
+  }
+
+  /**
+   * Writes a list of objects to the server. Objects are specified by
+   * 2 vectors - 1 vector of keys and 1 vector of values.
+   *
+   * @param[in] keys vector of keys of objects to write to server
+   * @param[in] values vector of values of objects to write to server
+   * @param[in] expiration time to keep the objects stored in server for
+   * @param[in] flags flags to store with the objects
+   * @return true on success; false otherwise
+   */
+  bool setAll(std::vector<std::string> &keys,
+              std::vector< std::vector<char> *> &values,
+              time_t expiration,
+              uint32_t flags)
+  {
+    bool retval= true;
+    std::vector<std::string>::iterator key_it= keys.begin();
+    std::vector< std::vector<char> *>::iterator val_it= values.begin();
+    while (key_it != keys.end())
+    {
+      retval= set((*key_it), *(*val_it), expiration, flags);
+      if (retval == false)
+      {
+        return retval;
+      }
+      ++key_it;
+      ++val_it;
+    }
+    return retval;
+  }
+
+  /**
+   * Writes a list of objects to the server. Objects are specified by
+   * a map of keys to values.
+   *
+   * @param[in] key_value_map map of keys and values to store in server
+   * @param[in] expiration time to keep the objects stored in server for
+   * @param[in] flags flags to store with the objects
+   * @return true on success; false otherwise
+   */
+  bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
+              time_t expiration,
+              uint32_t flags)
+  {
+    bool retval= true;
+    std::map<const std::string, std::vector<char> >::iterator it= key_value_map.begin();
+
+    while (it != key_value_map.end())
+    {
+      retval= set(it->first, it->second, expiration, flags);
+      if (retval == false)
+      {
+        // We should tell the user what the key that failed was
+        return false;
+      }
+      ++it;
+    }
+    return true;
+  }
+
+  /**
+   * Increment the value of the object associated with the specified
+   * key by the offset given. The resulting value is saved in the value
+   * parameter.
+   *
+   * @param[in] key key of object in server whose value to increment
+   * @param[in] offset amount to increment object's value by
+   * @param[out] value store the result of the increment here
+   * @return true on success; false otherwise
+   */
+  bool increment(const std::string &key, uint32_t offset, uint64_t *value)
+  {
+    return memcached_success(memcached_increment(memc, key.c_str(), key.length(), offset, value));
+  }
+
+  /**
+   * Decrement the value of the object associated with the specified
+   * key by the offset given. The resulting value is saved in the value
+   * parameter.
+   *
+   * @param[in] key key of object in server whose value to decrement
+   * @param[in] offset amount to increment object's value by
+   * @param[out] value store the result of the decrement here
+   * @return true on success; false otherwise
+   */
+  bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
+  {
+    return memcached_success(memcached_decrement(memc, key.c_str(),
+                                                 key.length(),
+                                                 offset, value));
+  }
+
+
+  /**
+   * Add an object with the specified key and value to the server. This
+   * function returns false if the object already exists on the server.
+   *
+   * @param[in] key key of object to add
+   * @param[in] value of object to add
+   * @return true on success; false otherwise
+   */
+  bool add(const std::string &key, const std::vector<char> &value)
+  {
+    return memcached_success(memcached_add(memc, key.c_str(), key.length(),
+                                           &value[0], value.size(), 0, 0));
+  }
+
+  /**
+   * Add an object with the specified key and value to the server. This
+   * function returns false if the object already exists on the server. The
+   * server to add the object to is specified by the master_key parameter.
+   *
+   * @param[in[ master_key key of server to add object to
+   * @param[in] key key of object to add
+   * @param[in] value of object to add
+   * @return true on success; false otherwise
+   */
+  bool addByKey(const std::string &master_key,
+                const std::string &key,
+                const std::vector<char> &value)
+  {
+    return memcached_success(memcached_add_by_key(memc,
+                                                  master_key.c_str(),
+                                                  master_key.length(),
+                                                  key.c_str(),
+                                                  key.length(),
+                                                  &value[0],
+                                                  value.size(),
+                                                  0, 0));
+  }
+
+  /**
+   * Replaces an object on the server. This method only succeeds
+   * if the object is already present on the server.
+   *
+   * @param[in] key key of object to replace
+   * @param[in[ value value to replace object with
+   * @return true on success; false otherwise
+   */
+  bool replace(const std::string &key, const std::vector<char> &value)
+  {
+    return memcached_success(memcached_replace(memc, key.c_str(), key.length(),
+                                               &value[0], value.size(),
+                                               0, 0));
+  }
+
+  /**
+   * Replaces an object on the server. This method only succeeds
+   * if the object is already present on the server. The server
+   * to replace the object on is specified by the master_key param.
+   *
+   * @param[in] master_key key of server to replace object on
+   * @param[in] key key of object to replace
+   * @param[in[ value value to replace object with
+   * @return true on success; false otherwise
+   */
+  bool replaceByKey(const std::string &master_key,
+                    const std::string &key,
+                    const std::vector<char> &value)
+  {
+    return memcached_success(memcached_replace_by_key(memc,
+                                                      master_key.c_str(),
+                                                      master_key.length(),
+                                                      key.c_str(),
+                                                      key.length(),
+                                                      &value[0],
+                                                      value.size(),
+                                                      0, 0));
+  }
+
+  /**
+   * Places a segment of data before the last piece of data stored.
+   *
+   * @param[in] key key of object whose value we will prepend data to
+   * @param[in] value data to prepend to object's value
+   * @return true on success; false otherwise
+   */
+  bool prepend(const std::string &key, const std::vector<char> &value)
+  {
+    return memcached_success(memcached_prepend(memc, key.c_str(), key.length(),
+                                               &value[0], value.size(), 0, 0));
+  }
+
+  /**
+   * Places a segment of data before the last piece of data stored. The
+   * server on which the object where we will be prepending data is stored
+   * on is specified by the master_key parameter.
+   *
+   * @param[in] master_key key of server where object is stored
+   * @param[in] key key of object whose value we will prepend data to
+   * @param[in] value data to prepend to object's value
+   * @return true on success; false otherwise
+   */
+  bool prependByKey(const std::string &master_key,
+                    const std::string &key,
+                    const std::vector<char> &value)
+  {
+    return memcached_success(memcached_prepend_by_key(memc,
+                                                      master_key.c_str(),
+                                                      master_key.length(),
+                                                      key.c_str(),
+                                                      key.length(),
+                                                      &value[0],
+                                                      value.size(),
+                                                      0,
+                                                      0));
+  }
+
+  /**
+   * Places a segment of data at the end of the last piece of data stored.
+   *
+   * @param[in] key key of object whose value we will append data to
+   * @param[in] value data to append to object's value
+   * @return true on success; false otherwise
+   */
+  bool append(const std::string &key, const std::vector<char> &value)
+  {
+    return memcached_success(memcached_append(memc,
+                                              key.c_str(),
+                                              key.length(),
+                                              &value[0],
+                                              value.size(),
+                                              0, 0));
+  }
+
+  /**
+   * Places a segment of data at the end of the last piece of data stored. The
+   * server on which the object where we will be appending data is stored
+   * on is specified by the master_key parameter.
+   *
+   * @param[in] master_key key of server where object is stored
+   * @param[in] key key of object whose value we will append data to
+   * @param[in] value data to append to object's value
+   * @return true on success; false otherwise
+   */
+  bool appendByKey(const std::string &master_key,
+                   const std::string &key,
+                   const std::vector<char> &value)
+  {
+    return memcached_success(memcached_append_by_key(memc,
+                                                     master_key.c_str(),
+                                                     master_key.length(),
+                                                     key.c_str(),
+                                                     key.length(),
+                                                     &value[0],
+                                                     value.size(),
+                                                     0, 0));
+  }
+
+  /**
+   * Overwrite data in the server as long as the cas_arg value
+   * is still the same in the server.
+   *
+   * @param[in] key key of object in server
+   * @param[in] value value to store for object in server
+   * @param[in] cas_arg "cas" value
+   */
+  bool cas(const std::string &key,
+           const std::vector<char> &value,
+           uint64_t cas_arg)
+  {
+    return memcached_success(memcached_cas(memc, key.c_str(), key.length(),
+                                           &value[0], value.size(),
+                                           0, 0, cas_arg));
+  }
+
+  /**
+   * Overwrite data in the server as long as the cas_arg value
+   * is still the same in the server. The server to use is
+   * specified by the master_key parameter.
+   *
+   * @param[in] master_key specifies server to operate on
+   * @param[in] key key of object in server
+   * @param[in] value value to store for object in server
+   * @param[in] cas_arg "cas" value
+   */
+  bool casByKey(const std::string &master_key,
+                const std::string &key,
+                const std::vector<char> &value,
+                uint64_t cas_arg)
+  {
+    return memcached_success(memcached_cas_by_key(memc,
+                                                  master_key.c_str(),
+                                                  master_key.length(),
+                                                  key.c_str(),
+                                                  key.length(),
+                                                  &value[0],
+                                                  value.size(),
+                                                  0, 0, cas_arg));
+  }
+
+  /**
+   * Delete an object from the server specified by the key given.
+   *
+   * @param[in] key key of object to delete
+   * @return true on success; false otherwise
+   */
+  bool remove(const std::string &key)
+  {
+    return memcached_success(memcached_delete(memc, key.c_str(), key.length(), 0));
+  }
+
+  /**
+   * Delete an object from the server specified by the key given.
+   *
+   * @param[in] key key of object to delete
+   * @param[in] expiration time to delete the object after
+   * @return true on success; false otherwise
+   */
+  bool remove(const std::string &key, time_t expiration)
+  {
+    return memcached_success(memcached_delete(memc,
+                                              key.c_str(),
+                                              key.length(),
+                                              expiration));
+  }
+
+  /**
+   * Delete an object from the server specified by the key given.
+   *
+   * @param[in] master_key specifies server to remove object from
+   * @param[in] key key of object to delete
+   * @return true on success; false otherwise
+   */
+  bool removeByKey(const std::string &master_key,
+                   const std::string &key)
+  {
+    return memcached_success(memcached_delete_by_key(memc,
+                                                     master_key.c_str(),
+                                                     master_key.length(),
+                                                     key.c_str(),
+                                                     key.length(),
+                                                     0));
+  }
+
+  /**
+   * Delete an object from the server specified by the key given.
+   *
+   * @param[in] master_key specifies server to remove object from
+   * @param[in] key key of object to delete
+   * @param[in] expiration time to delete the object after
+   * @return true on success; false otherwise
+   */
+  bool removeByKey(const std::string &master_key,
+                   const std::string &key,
+                   time_t expiration)
+  {
+    return memcached_success(memcached_delete_by_key(memc,
+                                                     master_key.c_str(),
+                                                     master_key.length(),
+                                                     key.c_str(),
+                                                     key.length(),
+                                                     expiration));
+  }
+
+  /**
+   * Wipe the contents of memcached servers.
+   *
+   * @param[in] expiration time to wait until wiping contents of
+   *                       memcached servers
+   * @return true on success; false otherwise
+   */
+  bool flush(time_t expiration= 0)
+  {
+    return memcached_success(memcached_flush(memc, expiration));
+  }
+
+  /**
+   * Get the library version string.
+   * @return std::string containing a copy of the library version string.
+   */
+  const std::string libVersion() const
+  {
+    const char *ver= memcached_lib_version();
+    const std::string version(ver);
+    return version;
+  }
+
+  /**
+   * Retrieve memcached statistics. Populate a std::map with the retrieved
+   * stats. Each server will map to another std::map of the key:value stats.
+   *
+   * @param[out] stats_map a std::map to be populated with the memcached
+   *                       stats
+   * @return true on success; false otherwise
+   */
+  bool getStats(std::map< std::string, std::map<std::string, std::string> >
+                &stats_map)
+  {
+    memcached_return_t rc;
+    memcached_stat_st *stats= memcached_stat(memc, NULL, &rc);
+
+    if (rc != MEMCACHED_SUCCESS &&
+        rc != MEMCACHED_SOME_ERRORS)
+    {
+      return false;
+    }
+
+    uint32_t server_count= memcached_server_count(memc);
+
+    /*
+     * For each memcached server, construct a std::map for its stats and add
+     * it to the std::map of overall stats.
+     */
+    for (uint32_t x= 0; x < server_count; x++)
+    {
+      memcached_server_instance_st instance=
+        memcached_server_instance_by_position(memc, x);
+      std::ostringstream strstm;
+      std::string server_name(memcached_server_name(instance));
+      server_name.append(":");
+      strstm << memcached_server_port(instance);
+      server_name.append(strstm.str());
+
+      std::map<std::string, std::string> server_stats;
+      char **list= NULL;
+      char **ptr= NULL;
+
+      list= memcached_stat_get_keys(memc, &stats[x], &rc);
+      for (ptr= list; *ptr; ptr++)
+      {
+        char *value= memcached_stat_get_value(memc, &stats[x], *ptr, &rc);
+        server_stats[*ptr]= value;
+        free(value);
+      }
+     
+      stats_map[server_name]= server_stats;
+      free(list);
+    }
+
+    memcached_stat_free(memc, stats);
+    return true;
+  }
+
+private:
+  memcached_st *memc;
+};
+
+}
diff --git a/libmemcached-1.0/options.h b/libmemcached-1.0/options.h
new file mode 100644 (file)
index 0000000..f5a6e06
--- /dev/null
@@ -0,0 +1,49 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+  memcached_return_t libmemcached_check_configuration(const char *option_string, size_t length, char *error_buffer, size_t error_buffer_size);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/parse.h b/libmemcached-1.0/parse.h
new file mode 100644 (file)
index 0000000..a91f769
--- /dev/null
@@ -0,0 +1,23 @@
+/* LibMemcached
+ * Copyright (C) 2010 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ *
+ * Summary: Work with fetching results
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_server_list_st memcached_servers_parse(const char *server_strings);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/platform.h b/libmemcached-1.0/platform.h
new file mode 100644 (file)
index 0000000..1924828
--- /dev/null
@@ -0,0 +1,56 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker, Trond Norbye All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+
+#ifdef WIN32
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+typedef short in_port_t;
+typedef SOCKET memcached_socket_t;
+#else
+typedef int memcached_socket_t;
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/un.h>
+#include <netinet/tcp.h>
+
+#endif /* WIN32 */
diff --git a/libmemcached-1.0/quit.h b/libmemcached-1.0/quit.h
new file mode 100644 (file)
index 0000000..0338eaf
--- /dev/null
@@ -0,0 +1,55 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+void memcached_quit(memcached_st *ptr);
+
+LIBMEMCACHED_LOCAL
+void memcached_quit_server(memcached_server_st *ptr, bool io_death);
+
+LIBMEMCACHED_LOCAL
+void send_quit(memcached_st *ptr);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/result.h b/libmemcached-1.0/result.h
new file mode 100644 (file)
index 0000000..41608b5
--- /dev/null
@@ -0,0 +1,100 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+struct memcached_result_st {
+  uint32_t item_flags;
+  time_t item_expiration;
+  size_t key_length;
+  uint64_t item_cas;
+  memcached_st *root;
+  memcached_string_st value;
+  uint64_t count;
+  char item_key[MEMCACHED_MAX_KEY];
+  struct {
+    bool is_allocated:1;
+    bool is_initialized:1;
+  } options;
+  /* Add result callback function */
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Result Struct */
+LIBMEMCACHED_API
+void memcached_result_free(memcached_result_st *result);
+
+LIBMEMCACHED_API
+void memcached_result_reset(memcached_result_st *ptr);
+
+LIBMEMCACHED_API
+memcached_result_st *memcached_result_create(const memcached_st *ptr,
+                                             memcached_result_st *result);
+
+LIBMEMCACHED_API
+const char *memcached_result_key_value(const memcached_result_st *self);
+
+LIBMEMCACHED_API
+size_t memcached_result_key_length(const memcached_result_st *self);
+
+LIBMEMCACHED_API
+const char *memcached_result_value(const memcached_result_st *self);
+
+LIBMEMCACHED_API
+size_t memcached_result_length(const memcached_result_st *self);
+
+LIBMEMCACHED_API
+uint32_t memcached_result_flags(const memcached_result_st *self);
+
+LIBMEMCACHED_API
+uint64_t memcached_result_cas(const memcached_result_st *self);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_result_set_value(memcached_result_st *ptr, const char *value, size_t length);
+
+LIBMEMCACHED_API
+void memcached_result_set_flags(memcached_result_st *self, uint32_t flags);
+
+LIBMEMCACHED_API
+void memcached_result_set_expiration(memcached_result_st *self, time_t expiration);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/libmemcached-1.0/return.h b/libmemcached-1.0/return.h
new file mode 100644 (file)
index 0000000..fa36243
--- /dev/null
@@ -0,0 +1,129 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+enum memcached_return_t {
+  MEMCACHED_SUCCESS,
+  MEMCACHED_FAILURE,
+  MEMCACHED_HOST_LOOKUP_FAILURE, // getaddrinfo() and getnameinfo() only
+  MEMCACHED_CONNECTION_FAILURE,
+  MEMCACHED_CONNECTION_BIND_FAILURE,  // DEPRECATED, see MEMCACHED_HOST_LOOKUP_FAILURE
+  MEMCACHED_WRITE_FAILURE,
+  MEMCACHED_READ_FAILURE,
+  MEMCACHED_UNKNOWN_READ_FAILURE,
+  MEMCACHED_PROTOCOL_ERROR,
+  MEMCACHED_CLIENT_ERROR,
+  MEMCACHED_SERVER_ERROR,
+  MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE, // DEPRECATED
+  MEMCACHED_DATA_EXISTS,
+  MEMCACHED_DATA_DOES_NOT_EXIST,
+  MEMCACHED_NOTSTORED,
+  MEMCACHED_STORED,
+  MEMCACHED_NOTFOUND,
+  MEMCACHED_MEMORY_ALLOCATION_FAILURE,
+  MEMCACHED_PARTIAL_READ,
+  MEMCACHED_SOME_ERRORS,
+  MEMCACHED_NO_SERVERS,
+  MEMCACHED_END,
+  MEMCACHED_DELETED,
+  MEMCACHED_VALUE,
+  MEMCACHED_STAT,
+  MEMCACHED_ITEM,
+  MEMCACHED_ERRNO,
+  MEMCACHED_FAIL_UNIX_SOCKET, // DEPRECATED
+  MEMCACHED_NOT_SUPPORTED,
+  MEMCACHED_NO_KEY_PROVIDED, /* Deprecated. Use MEMCACHED_BAD_KEY_PROVIDED! */
+  MEMCACHED_FETCH_NOTFINISHED,
+  MEMCACHED_TIMEOUT,
+  MEMCACHED_BUFFERED,
+  MEMCACHED_BAD_KEY_PROVIDED,
+  MEMCACHED_INVALID_HOST_PROTOCOL,
+  MEMCACHED_SERVER_MARKED_DEAD,
+  MEMCACHED_UNKNOWN_STAT_KEY,
+  MEMCACHED_E2BIG,
+  MEMCACHED_INVALID_ARGUMENTS,
+  MEMCACHED_KEY_TOO_BIG,
+  MEMCACHED_AUTH_PROBLEM,
+  MEMCACHED_AUTH_FAILURE,
+  MEMCACHED_AUTH_CONTINUE,
+  MEMCACHED_PARSE_ERROR,
+  MEMCACHED_PARSE_USER_ERROR,
+  MEMCACHED_DEPRECATED,
+  MEMCACHED_IN_PROGRESS,
+  MEMCACHED_SERVER_TEMPORARILY_DISABLED,
+  MEMCACHED_MAXIMUM_RETURN /* Always add new error code before */
+};
+
+#ifndef __cplusplus
+typedef enum memcached_return_t memcached_return_t;
+#endif
+
+static inline bool memcached_success(memcached_return_t rc)
+{
+  return (rc == MEMCACHED_BUFFERED ||
+          rc == MEMCACHED_DELETED ||
+          rc == MEMCACHED_END || 
+          rc == MEMCACHED_ITEM || 
+          rc == MEMCACHED_STAT || 
+          rc == MEMCACHED_STORED || 
+          rc == MEMCACHED_SUCCESS || 
+          rc == MEMCACHED_VALUE);
+}
+
+static inline bool memcached_failed(memcached_return_t rc)
+{
+  return (rc != MEMCACHED_SUCCESS && 
+          rc != MEMCACHED_END && 
+          rc != MEMCACHED_STORED && 
+          rc != MEMCACHED_STAT && 
+          rc != MEMCACHED_DELETED &&
+          rc != MEMCACHED_BUFFERED &&
+          rc != MEMCACHED_VALUE);
+}
+
+static inline bool memcached_fatal(memcached_return_t rc)
+{
+  return (rc != MEMCACHED_SUCCESS && 
+          rc != MEMCACHED_END && 
+          rc != MEMCACHED_STORED && 
+          rc != MEMCACHED_STAT && 
+          rc != MEMCACHED_DELETED &&
+          rc != MEMCACHED_BUFFERED &&
+          rc != MEMCACHED_VALUE);
+}
+
+#define memcached_continue(__memcached_return_t) ((__memcached_return_t) == MEMCACHED_IN_PROGRESS)
diff --git a/libmemcached-1.0/sasl.h b/libmemcached-1.0/sasl.h
new file mode 100644 (file)
index 0000000..8602246
--- /dev/null
@@ -0,0 +1,83 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT
+#include <sasl/sasl.h>
+#else
+#define sasl_callback_t void
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+void memcached_set_sasl_callbacks(memcached_st *ptr,
+                                  const sasl_callback_t *callbacks);
+
+LIBMEMCACHED_API
+memcached_return_t  memcached_set_sasl_auth_data(memcached_st *ptr,
+                                                 const char *username,
+                                                 const char *password);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_destroy_sasl_auth_data(memcached_st *ptr);
+
+
+LIBMEMCACHED_API
+sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *ptr);
+
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_clone_sasl(memcached_st *clone, const  memcached_st *source);
+
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *server);
+
+#ifdef __cplusplus
+}
+#endif
+
+struct memcached_sasl_st {
+  sasl_callback_t *callbacks;
+  /*
+   ** Did we allocate data inside the callbacks, or did the user
+   ** supply that.
+ */
+  bool is_allocated;
+};
diff --git a/libmemcached-1.0/server.h b/libmemcached-1.0/server.h
new file mode 100644 (file)
index 0000000..38ab40a
--- /dev/null
@@ -0,0 +1,183 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#pragma once
+
+#ifndef WIN32
+#include <netdb.h>
+#endif
+
+#ifdef NI_MAXHOST
+#define MEMCACHED_NI_MAXHOST NI_MAXHOST
+#else
+#define MEMCACHED_NI_MAXHOST 1025
+#endif
+
+enum memcached_server_state_t {
+  MEMCACHED_SERVER_STATE_NEW, // fd == -1, no address lookup has been done
+  MEMCACHED_SERVER_STATE_ADDRINFO, // ADDRRESS information has been gathered
+  MEMCACHED_SERVER_STATE_IN_PROGRESS,
+  MEMCACHED_SERVER_STATE_CONNECTED,
+  MEMCACHED_SERVER_STATE_IN_TIMEOUT
+};
+
+struct memcached_server_st {
+  struct {
+    bool is_allocated:1;
+    bool is_initialized:1;
+    bool is_shutting_down:1;
+    bool is_dead:1;
+  } options;
+  uint32_t number_of_hosts;
+  uint32_t cursor_active;
+  in_port_t port;
+  memcached_socket_t fd;
+  uint32_t io_bytes_sent; /* # bytes sent since last read */
+  uint32_t server_failure_counter;
+  uint64_t server_failure_counter_query_id;
+  uint32_t weight;
+  uint32_t version;
+  enum memcached_server_state_t state;
+  struct {
+    uint32_t read;
+    uint32_t write;
+  } io_wait_count;
+  uint8_t major_version; // Default definition of UINT8_MAX means that it has not been set.
+  uint8_t micro_version; // ditto
+  uint8_t minor_version; // ditto
+  memcached_connection_t type;
+  char *read_ptr;
+  size_t read_buffer_length;
+  size_t read_data_length;
+  size_t write_buffer_offset;
+  struct addrinfo *address_info;
+  struct addrinfo *address_info_next;
+  time_t next_retry;
+  memcached_st *root;
+  uint64_t limit_maxbytes;
+  struct memcached_error_t *error_messages;
+  char read_buffer[MEMCACHED_MAX_BUFFER];
+  char write_buffer[MEMCACHED_MAX_BUFFER];
+  char hostname[MEMCACHED_NI_MAXHOST];
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_server_cursor(const memcached_st *ptr,
+                                           const memcached_server_fn *callback,
+                                           void *context,
+                                           uint32_t number_of_callbacks);
+
+LIBMEMCACHED_API
+  memcached_server_instance_st memcached_server_by_key(memcached_st *ptr,
+                                                       const char *key,
+                                                       size_t key_length,
+                                                       memcached_return_t *error);
+
+LIBMEMCACHED_API
+void memcached_server_error_reset(memcached_server_st *ptr);
+
+LIBMEMCACHED_API
+void memcached_server_free(memcached_server_st *ptr);
+
+LIBMEMCACHED_LOCAL
+memcached_server_st *memcached_server_clone(memcached_server_st *destination,
+                                            memcached_server_st *source);
+
+LIBMEMCACHED_API
+memcached_server_instance_st memcached_server_get_last_disconnect(const memcached_st *ptr);
+
+
+LIBMEMCACHED_API
+memcached_return_t memcached_server_add_udp(memcached_st *ptr,
+                                            const char *hostname,
+                                            in_port_t port);
+LIBMEMCACHED_API
+memcached_return_t memcached_server_add_unix_socket(memcached_st *ptr,
+                                                    const char *filename);
+LIBMEMCACHED_API
+memcached_return_t memcached_server_add(memcached_st *ptr,
+                                        const char *hostname, in_port_t port);
+
+LIBMEMCACHED_LOCAL
+  memcached_return_t memcached_server_add_parsed(memcached_st *ptr,
+                                                 const char *hostname,
+                                                 size_t hostname_length,
+                                                 in_port_t port,
+                                                 uint32_t weight);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_server_add_udp_with_weight(memcached_st *ptr,
+                                                        const char *hostname,
+                                                        in_port_t port,
+                                                        uint32_t weight);
+LIBMEMCACHED_API
+memcached_return_t memcached_server_add_unix_socket_with_weight(memcached_st *ptr,
+                                                                const char *filename,
+                                                                uint32_t weight);
+LIBMEMCACHED_API
+memcached_return_t memcached_server_add_with_weight(memcached_st *ptr, const char *hostname,
+                                                    in_port_t port,
+                                                    uint32_t weight);
+
+/**
+  Operations on Single Servers.
+*/
+LIBMEMCACHED_API
+uint32_t memcached_server_response_count(const memcached_server_instance_st self);
+
+LIBMEMCACHED_API
+const char *memcached_server_name(const memcached_server_instance_st self);
+
+LIBMEMCACHED_API
+in_port_t memcached_server_port(const memcached_server_instance_st self);
+
+LIBMEMCACHED_API
+const char *memcached_server_type(const memcached_server_instance_st ptr);
+
+
+LIBMEMCACHED_LOCAL
+void __server_free(memcached_server_st *);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/libmemcached-1.0/server_list.h b/libmemcached-1.0/server_list.h
new file mode 100644 (file)
index 0000000..8fe6dc7
--- /dev/null
@@ -0,0 +1,77 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Server List Public functions */
+LIBMEMCACHED_API
+  void memcached_server_list_free(memcached_server_list_st ptr);
+
+LIBMEMCACHED_API
+  memcached_return_t memcached_server_push(memcached_st *ptr, const memcached_server_list_st list);
+
+LIBMEMCACHED_API
+  memcached_server_list_st memcached_server_list_append(memcached_server_list_st ptr,
+                                                        const char *hostname,
+                                                        in_port_t port,
+                                                        memcached_return_t *error);
+LIBMEMCACHED_API
+  memcached_server_list_st memcached_server_list_append_with_weight(memcached_server_list_st ptr,
+                                                                    const char *hostname,
+                                                                    in_port_t port,
+                                                                    uint32_t weight,
+                                                                    memcached_return_t *error);
+LIBMEMCACHED_API
+  uint32_t memcached_server_list_count(const memcached_server_list_st ptr);
+
+LIBMEMCACHED_LOCAL
+  uint32_t memcached_servers_set_count(memcached_server_list_st servers, uint32_t count);
+
+LIBMEMCACHED_LOCAL
+  memcached_server_st *memcached_server_list(const memcached_st *);
+
+LIBMEMCACHED_LOCAL
+  void memcached_server_list_set(memcached_st *self, memcached_server_list_st list);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/libmemcached-1.0/stats.h b/libmemcached-1.0/stats.h
new file mode 100644 (file)
index 0000000..f2d064a
--- /dev/null
@@ -0,0 +1,96 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+struct memcached_stat_st {
+  unsigned long connection_structures;
+  unsigned long curr_connections;
+  unsigned long curr_items;
+  pid_t pid;
+  unsigned long pointer_size;
+  unsigned long rusage_system_microseconds;
+  unsigned long rusage_system_seconds;
+  unsigned long rusage_user_microseconds;
+  unsigned long rusage_user_seconds;
+  unsigned long threads;
+  unsigned long time;
+  unsigned long total_connections;
+  unsigned long total_items;
+  unsigned long uptime;
+  unsigned long long bytes;
+  unsigned long long bytes_read;
+  unsigned long long bytes_written;
+  unsigned long long cmd_get;
+  unsigned long long cmd_set;
+  unsigned long long evictions;
+  unsigned long long get_hits;
+  unsigned long long get_misses;
+  unsigned long long limit_maxbytes;
+  char version[MEMCACHED_VERSION_STRING_LENGTH];
+  void *__future; // @todo create a new structure to place here for future usage
+  memcached_st *root;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+void memcached_stat_free(const memcached_st *, memcached_stat_st *);
+
+LIBMEMCACHED_API
+memcached_stat_st *memcached_stat(memcached_st *ptr, char *args, memcached_return_t *error);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_stat_servername(memcached_stat_st *memc_stat, char *args,
+                                             const char *hostname, in_port_t port);
+
+LIBMEMCACHED_API
+char *memcached_stat_get_value(const memcached_st *ptr, memcached_stat_st *memc_stat,
+                               const char *key, memcached_return_t *error);
+
+LIBMEMCACHED_API
+char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *memc_stat,
+                                memcached_return_t *error);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_stat_execute(memcached_st *memc, const char *args,  memcached_stat_fn func, void *context);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/libmemcached-1.0/storage.h b/libmemcached-1.0/storage.h
new file mode 100644 (file)
index 0000000..e634235
--- /dev/null
@@ -0,0 +1,131 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* All of the functions for adding data to the server */
+LIBMEMCACHED_API
+memcached_return_t memcached_set(memcached_st *ptr, const char *key, size_t key_length,
+                                 const char *value, size_t value_length,
+                                 time_t expiration,
+                                 uint32_t  flags);
+LIBMEMCACHED_API
+memcached_return_t memcached_add(memcached_st *ptr, const char *key, size_t key_length,
+                                 const char *value, size_t value_length,
+                                 time_t expiration,
+                                 uint32_t  flags);
+LIBMEMCACHED_API
+memcached_return_t memcached_replace(memcached_st *ptr, const char *key, size_t key_length,
+                                     const char *value, size_t value_length,
+                                     time_t expiration,
+                                     uint32_t  flags);
+LIBMEMCACHED_API
+memcached_return_t memcached_append(memcached_st *ptr,
+                                    const char *key, size_t key_length,
+                                    const char *value, size_t value_length,
+                                    time_t expiration,
+                                    uint32_t flags);
+LIBMEMCACHED_API
+memcached_return_t memcached_prepend(memcached_st *ptr,
+                                     const char *key, size_t key_length,
+                                     const char *value, size_t value_length,
+                                     time_t expiration,
+                                     uint32_t flags);
+LIBMEMCACHED_API
+memcached_return_t memcached_cas(memcached_st *ptr,
+                                 const char *key, size_t key_length,
+                                 const char *value, size_t value_length,
+                                 time_t expiration,
+                                 uint32_t flags,
+                                 uint64_t cas);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_set_by_key(memcached_st *ptr,
+                                        const char *group_key, size_t group_key_length,
+                                        const char *key, size_t key_length,
+                                        const char *value, size_t value_length,
+                                        time_t expiration,
+                                        uint32_t flags);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_add_by_key(memcached_st *ptr,
+                                        const char *group_key, size_t group_key_length,
+                                        const char *key, size_t key_length,
+                                        const char *value, size_t value_length,
+                                        time_t expiration,
+                                        uint32_t flags);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_replace_by_key(memcached_st *ptr,
+                                            const char *group_key, size_t group_key_length,
+                                            const char *key, size_t key_length,
+                                            const char *value, size_t value_length,
+                                            time_t expiration,
+                                            uint32_t flags);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_prepend_by_key(memcached_st *ptr,
+                                            const char *group_key, size_t group_key_length,
+                                            const char *key, size_t key_length,
+                                            const char *value, size_t value_length,
+                                            time_t expiration,
+                                            uint32_t flags);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_append_by_key(memcached_st *ptr,
+                                           const char *group_key, size_t group_key_length,
+                                           const char *key, size_t key_length,
+                                           const char *value, size_t value_length,
+                                           time_t expiration,
+                                           uint32_t flags);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_cas_by_key(memcached_st *ptr,
+                                        const char *group_key, size_t group_key_length,
+                                        const char *key, size_t key_length,
+                                        const char *value, size_t value_length,
+                                        time_t expiration,
+                                        uint32_t flags,
+                                        uint64_t cas);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/strerror.h b/libmemcached-1.0/strerror.h
new file mode 100644 (file)
index 0000000..8e1e0fa
--- /dev/null
@@ -0,0 +1,50 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+const char *memcached_strerror(memcached_st *ptr, memcached_return_t rc);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/string.h b/libmemcached-1.0/string.h
new file mode 100644 (file)
index 0000000..42d0e40
--- /dev/null
@@ -0,0 +1,107 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+/**
+  Strings are always under our control so we make some assumptions
+  about them.
+
+  1) is_initialized is always valid.
+  2) A string once intialized will always be, until free where we
+     unset this flag.
+  3) A string always has a root.
+*/
+
+struct memcached_string_st {
+  char *end;
+  char *string;
+  size_t current_size;
+  memcached_st *root;
+  struct {
+    bool is_allocated:1;
+    bool is_initialized:1;
+  } options;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_LOCAL
+memcached_string_st *memcached_string_create(memcached_st *ptr,
+                                             memcached_string_st *string,
+                                             size_t initial_size);
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_string_check(memcached_string_st *string, size_t need);
+
+LIBMEMCACHED_LOCAL
+char *memcached_string_c_copy(memcached_string_st *string);
+
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_string_append_character(memcached_string_st *string,
+                                                     char character);
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_string_append(memcached_string_st *string,
+                                           const char *value, size_t length);
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_string_reset(memcached_string_st *string);
+
+LIBMEMCACHED_LOCAL
+void memcached_string_free(memcached_string_st *string);
+
+LIBMEMCACHED_LOCAL
+size_t memcached_string_length(const memcached_string_st *self);
+
+LIBMEMCACHED_LOCAL
+size_t memcached_string_size(const memcached_string_st *self);
+
+LIBMEMCACHED_LOCAL
+const char *memcached_string_value(const memcached_string_st *self);
+
+LIBMEMCACHED_LOCAL
+char *memcached_string_take_value(memcached_string_st *self);
+
+LIBMEMCACHED_LOCAL
+char *memcached_string_value_mutable(const memcached_string_st *self);
+
+LIBMEMCACHED_LOCAL
+void memcached_string_set_length(memcached_string_st *self, size_t length);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/touch.h b/libmemcached-1.0/touch.h
new file mode 100644 (file)
index 0000000..e143c03
--- /dev/null
@@ -0,0 +1,59 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+LIBMEMCACHED_API
+memcached_return_t memcached_touch(memcached_st *ptr,
+                                   const char *key, size_t key_length,
+                                   time_t expiration);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_touch_by_key(memcached_st *ptr,
+                                          const char *group_key, size_t group_key_length,
+                                          const char *key, size_t key_length,
+                                          time_t expiration);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/types.h b/libmemcached-1.0/types.h
new file mode 100644 (file)
index 0000000..3a4ae3b
--- /dev/null
@@ -0,0 +1,117 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#pragma once
+
+typedef struct memcached_st memcached_st;
+typedef struct memcached_stat_st memcached_stat_st;
+typedef struct memcached_analysis_st memcached_analysis_st;
+typedef struct memcached_result_st memcached_result_st;
+typedef struct memcached_array_st memcached_array_st;
+typedef struct memcached_error_t memcached_error_t;
+
+// All of the flavors of memcache_server_st
+typedef struct memcached_server_st memcached_server_st;
+typedef const struct memcached_server_st *memcached_server_instance_st;
+typedef struct memcached_server_st *memcached_server_list_st;
+
+typedef struct memcached_callback_st memcached_callback_st;
+
+// The following two structures are internal, and never exposed to users.
+typedef struct memcached_string_st memcached_string_st;
+typedef struct memcached_string_t memcached_string_t;
+typedef struct memcached_continuum_item_st memcached_continuum_item_st;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef memcached_return_t (*memcached_clone_fn)(memcached_st *destination, const memcached_st *source);
+typedef memcached_return_t (*memcached_cleanup_fn)(const memcached_st *ptr);
+
+/**
+  Memory allocation functions.
+*/
+typedef void (*memcached_free_fn)(const memcached_st *ptr, void *mem, void *context);
+typedef void *(*memcached_malloc_fn)(const memcached_st *ptr, const size_t size, void *context);
+typedef void *(*memcached_realloc_fn)(const memcached_st *ptr, void *mem, const size_t size, void *context);
+typedef void *(*memcached_calloc_fn)(const memcached_st *ptr, size_t nelem, const size_t elsize, void *context);
+
+
+typedef memcached_return_t (*memcached_execute_fn)(const memcached_st *ptr, memcached_result_st *result, void *context);
+typedef memcached_return_t (*memcached_server_fn)(const memcached_st *ptr, memcached_server_instance_st server, void *context);
+typedef memcached_return_t (*memcached_stat_fn)(memcached_server_instance_st server,
+                                                const char *key, size_t key_length,
+                                                const char *value, size_t value_length,
+                                                void *context);
+
+/**
+  Trigger functions.
+*/
+typedef memcached_return_t (*memcached_trigger_key_fn)(const memcached_st *ptr,
+                                                       const char *key, size_t key_length,
+                                                       memcached_result_st *result);
+typedef memcached_return_t (*memcached_trigger_delete_key_fn)(const memcached_st *ptr,
+                                                              const char *key, size_t key_length);
+
+typedef memcached_return_t (*memcached_dump_fn)(const memcached_st *ptr,
+                                                const char *key,
+                                                size_t key_length,
+                                                void *context);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+  @note The following definitions are just here for backwards compatibility.
+*/
+typedef memcached_return_t memcached_return;
+typedef memcached_server_distribution_t memcached_server_distribution;
+typedef memcached_behavior_t memcached_behavior;
+typedef memcached_callback_t memcached_callback;
+typedef memcached_hash_t memcached_hash;
+typedef memcached_connection_t memcached_connection;
+typedef memcached_clone_fn memcached_clone_func;
+typedef memcached_cleanup_fn memcached_cleanup_func;
+typedef memcached_execute_fn memcached_execute_function;
+typedef memcached_server_fn memcached_server_function;
+typedef memcached_trigger_key_fn memcached_trigger_key;
+typedef memcached_trigger_delete_key_fn memcached_trigger_delete_key;
+typedef memcached_dump_fn memcached_dump_func;
diff --git a/libmemcached-1.0/verbosity.h b/libmemcached-1.0/verbosity.h
new file mode 100644 (file)
index 0000000..2994648
--- /dev/null
@@ -0,0 +1,50 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_verbosity(memcached_st *ptr, uint32_t verbosity);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/version.h b/libmemcached-1.0/version.h
new file mode 100644 (file)
index 0000000..c443acc
--- /dev/null
@@ -0,0 +1,52 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+memcached_return_t memcached_version(memcached_st *ptr);
+
+LIBMEMCACHED_API
+const char * memcached_lib_version(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcached-1.0/visibility.h b/libmemcached-1.0/visibility.h
new file mode 100644 (file)
index 0000000..d4e4eea
--- /dev/null
@@ -0,0 +1,67 @@
+/* LibMemcached
+ * Copyright (C) 2006-2009 Brian Aker 
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ *
+ * Summary: Interface for memcached server.
+ *
+ * Author: Trond Norbye
+ *
+ */
+
+/**
+ * @file
+ * @brief Visibility control macros
+ */
+
+#pragma once
+
+/**
+ *
+ * LIBMEMCACHED_API is used for the public API symbols. It either DLL imports or
+ * DLL exports (or does nothing for static build).
+ *
+ * LIBMEMCACHED_LOCAL is used for non-api symbols.
+ */
+
+#if defined(BUILDING_LIBMEMCACHEDINTERNAL)
+# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
+#  define LIBMEMCACHED_API __attribute__ ((visibility("default")))
+#  define LIBMEMCACHED_LOCAL  __attribute__ ((visibility("default")))
+# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+#  define LIBMEMCACHED_API __global
+#  define LIBMEMCACHED_LOCAL __global
+# elif defined(_MSC_VER)
+#  define LIBMEMCACHED_API extern __declspec(dllexport) 
+#  define LIBMEMCACHED_LOCAL extern __declspec(dllexport)
+# else
+#  define LIBMEMCACHED_API
+#  define LIBMEMCACHED_LOCAL
+# endif
+#else
+# if defined(BUILDING_LIBMEMCACHED)
+#  if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
+#   define LIBMEMCACHED_API __attribute__ ((visibility("default")))
+#   define LIBMEMCACHED_LOCAL  __attribute__ ((visibility("hidden")))
+#  elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+#   define LIBMEMCACHED_API __global
+#   define LIBMEMCACHED_LOCAL __hidden
+#  elif defined(_MSC_VER)
+#   define LIBMEMCACHED_API extern __declspec(dllexport) 
+#   define LIBMEMCACHED_LOCAL
+#  else
+#   define LIBMEMCACHED_API
+#   define LIBMEMCACHED_LOCAL
+#  endif /* defined(HAVE_VISIBILITY) */
+# else  /* defined(BUILDING_LIBMEMCACHED) */
+#  if defined(_MSC_VER)
+#   define LIBMEMCACHED_API extern __declspec(dllimport) 
+#   define LIBMEMCACHED_LOCAL
+#  else
+#   define LIBMEMCACHED_API
+#   define LIBMEMCACHED_LOCAL
+#  endif /* defined(_MSC_VER) */
+# endif /* defined(BUILDING_LIBMEMCACHED) */
+#endif /* defined(BUILDING_LIBMEMCACHEDINTERNAL) */
index cc41f2c37a7bb1adddad5e6c365be07e42fb9409..d18372b4ba6ca9793e1f60787487c36a80bfff7d 100644 (file)
@@ -90,11 +90,11 @@ memcached_return_t memcached_set_memory_allocators(memcached_st *self,
   }
 
   /* All should be set, or none should be set */
-  if (mem_malloc == NULL && mem_free == NULL && mem_realloc == NULL && mem_calloc == NULL) 
+  if (mem_malloc == NULL and mem_free == NULL and mem_realloc == NULL and mem_calloc == NULL) 
   {
     self->allocators= memcached_allocators_return_default();
   }
-  else if (mem_malloc == NULL || mem_free == NULL || mem_realloc == NULL || mem_calloc == NULL)
+  else if (mem_malloc == NULL or mem_free == NULL or mem_realloc == NULL or mem_calloc == NULL)
   {
     return memcached_set_error(*self, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("NULL parameter provided for one or more allocators"));
   }
diff --git a/libmemcached/allocators.h b/libmemcached/allocators.h
deleted file mode 100644 (file)
index 6e4455f..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-struct memcached_allocator_t {
-  memcached_calloc_fn calloc;
-  memcached_free_fn free;
-  memcached_malloc_fn malloc;
-  memcached_realloc_fn realloc;
-  void *context;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_set_memory_allocators(memcached_st *ptr,
-                                                   memcached_malloc_fn mem_malloc,
-                                                   memcached_free_fn mem_free,
-                                                   memcached_realloc_fn mem_realloc,
-                                                   memcached_calloc_fn mem_calloc,
-                                                   void *context);
-
-LIBMEMCACHED_API
-void memcached_get_memory_allocators(const memcached_st *ptr,
-                                     memcached_malloc_fn *mem_malloc,
-                                     memcached_free_fn *mem_free,
-                                     memcached_realloc_fn *mem_realloc,
-                                     memcached_calloc_fn *mem_calloc);
-
-LIBMEMCACHED_API
-void *memcached_get_memory_allocators_context(const memcached_st *ptr);
-
-LIBMEMCACHED_LOCAL
-void _libmemcached_free(const memcached_st *ptr, void *mem, void *context);
-
-LIBMEMCACHED_LOCAL
-void *_libmemcached_malloc(const memcached_st *ptr, const size_t size, void *context);
-
-LIBMEMCACHED_LOCAL
-void *_libmemcached_realloc(const memcached_st *ptr, void *mem, const size_t size, void *context);
-
-LIBMEMCACHED_LOCAL
-void *_libmemcached_calloc(const memcached_st *ptr, size_t nelem, size_t size, void *context);
-
-LIBMEMCACHED_LOCAL
-struct memcached_allocator_t memcached_allocators_return_default(void);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/analyze.h b/libmemcached/analyze.h
deleted file mode 100644 (file)
index 955901a..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-struct memcached_analysis_st {
-  memcached_st *root;
-  uint32_t average_item_size;
-  uint32_t longest_uptime;
-  uint32_t least_free_server;
-  uint32_t most_consumed_server;
-  uint32_t oldest_server;
-  double pool_hit_ratio;
-  uint64_t most_used_bytes;
-  uint64_t least_remaining_bytes;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_analysis_st *memcached_analyze(memcached_st *memc,
-                                         memcached_stat_st *memc_stat,
-                                         memcached_return_t *error);
-
-LIBMEMCACHED_API
-void memcached_analyze_free(memcached_analysis_st *);
-
-#ifdef __cplusplus
-}
-#endif
index d0b7dd4813bb3116738f5713d4e048b68496954b..b2e4f534def078ece54f55682561b3b0eb765eac 100644 (file)
@@ -120,9 +120,6 @@ static memcached_return_t binary_incr_decr(memcached_st *ptr, uint8_t cmd,
 {
   bool no_reply= ptr->flags.no_reply;
 
-  if (memcached_server_count(ptr) == 0)
-    return memcached_set_error(*ptr, MEMCACHED_NO_SERVERS, MEMCACHED_AT);
-
   uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
   memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
 
@@ -148,9 +145,9 @@ static memcached_return_t binary_incr_decr(memcached_st *ptr, uint8_t cmd,
 
   struct libmemcached_io_vector_st vector[]=
   {
-    { sizeof(request.bytes), request.bytes },
-    { memcached_array_size(ptr->_namespace), memcached_array_string(ptr->_namespace) },
-    { key_length, key }
+    { request.bytes, sizeof(request.bytes) },
+    { memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace) },
+    { key, key_length }
   };
 
   memcached_return_t rc;
@@ -161,7 +158,9 @@ static memcached_return_t binary_incr_decr(memcached_st *ptr, uint8_t cmd,
   }
 
   if (no_reply)
+  {
     return MEMCACHED_SUCCESS;
+  }
 
   return memcached_response(instance, (char*)value, sizeof(*value), NULL);
 }
@@ -190,8 +189,10 @@ memcached_return_t memcached_increment_by_key(memcached_st *ptr,
 {
   memcached_return_t rc;
   uint64_t local_value;
-  if (not value)
+  if (value == NULL)
+  {
     value= &local_value;
+  }
 
   if (memcached_failed(rc= initialize_query(ptr)))
   {
@@ -228,8 +229,10 @@ memcached_return_t memcached_decrement_by_key(memcached_st *ptr,
                                               uint64_t *value)
 {
   uint64_t local_value;
-  if (not value)
+  if (value == NULL)
+  {
     value= &local_value;
+  }
 
   memcached_return_t rc;
   if (memcached_failed(rc= initialize_query(ptr)))
@@ -270,8 +273,10 @@ memcached_return_t memcached_increment_with_initial(memcached_st *ptr,
                                                     uint64_t *value)
 {
   uint64_t local_value;
-  if (! value)
+  if (value == NULL)
+  {
     value= &local_value;
+  }
 
   return memcached_increment_with_initial_by_key(ptr, key, key_length,
                                                  key, key_length,
@@ -289,8 +294,10 @@ memcached_return_t memcached_increment_with_initial_by_key(memcached_st *ptr,
                                                          uint64_t *value)
 {
   uint64_t local_value;
-  if (not value)
+  if (value == NULL)
+  {
     value= &local_value;
+  }
 
   memcached_return_t rc;
   if (memcached_failed(rc= initialize_query(ptr)))
@@ -305,12 +312,16 @@ memcached_return_t memcached_increment_with_initial_by_key(memcached_st *ptr,
 
   LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_START();
   if (ptr->flags.binary_protocol)
+  {
     rc= binary_incr_decr(ptr, PROTOCOL_BINARY_CMD_INCREMENT,
                          group_key, group_key_length, key, key_length,
                          offset, initial, (uint32_t)expiration,
                          value);
+  }
   else
+  {
     rc= MEMCACHED_PROTOCOL_ERROR;
+  }
 
   LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_END();
 
@@ -326,8 +337,10 @@ memcached_return_t memcached_decrement_with_initial(memcached_st *ptr,
                                                     uint64_t *value)
 {
   uint64_t local_value;
-  if (! value)
+  if (value == NULL)
+  {
     value= &local_value;
+  }
 
   return memcached_decrement_with_initial_by_key(ptr, key, key_length,
                                                  key, key_length,
@@ -345,8 +358,10 @@ memcached_return_t memcached_decrement_with_initial_by_key(memcached_st *ptr,
                                                            uint64_t *value)
 {
   uint64_t local_value;
-  if (not value)
+  if (value == NULL)
+  {
     value= &local_value;
+  }
 
   memcached_return_t rc;
   if (memcached_failed(rc= memcached_validate_key_length(key_length, ptr->flags.binary_protocol)))
diff --git a/libmemcached/auto.h b/libmemcached/auto.h
deleted file mode 100644 (file)
index f37d50f..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_increment(memcached_st *ptr,
-                                         const char *key, size_t key_length,
-                                         uint32_t offset,
-                                         uint64_t *value);
-LIBMEMCACHED_API
-  memcached_return_t memcached_decrement(memcached_st *ptr,
-                                         const char *key, size_t key_length,
-                                         uint32_t offset,
-                                         uint64_t *value);
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_increment_by_key(memcached_st *ptr,
-                                                const char *group_key, size_t group_key_length,
-                                                const char *key, size_t key_length,
-                                                uint64_t offset,
-                                                uint64_t *value);
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_decrement_by_key(memcached_st *ptr,
-                                                const char *group_key, size_t group_key_length,
-                                                const char *key, size_t key_length,
-                                                uint64_t offset,
-                                                uint64_t *value);
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_increment_with_initial(memcached_st *ptr,
-                                                      const char *key,
-                                                      size_t key_length,
-                                                      uint64_t offset,
-                                                      uint64_t initial,
-                                                      time_t expiration,
-                                                      uint64_t *value);
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_decrement_with_initial(memcached_st *ptr,
-                                                      const char *key,
-                                                      size_t key_length,
-                                                      uint64_t offset,
-                                                      uint64_t initial,
-                                                      time_t expiration,
-                                                      uint64_t *value);
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_increment_with_initial_by_key(memcached_st *ptr,
-                                                             const char *group_key,
-                                                             size_t group_key_length,
-                                                             const char *key,
-                                                             size_t key_length,
-                                                             uint64_t offset,
-                                                             uint64_t initial,
-                                                             time_t expiration,
-                                                             uint64_t *value);
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_decrement_with_initial_by_key(memcached_st *ptr,
-                                                             const char *group_key,
-                                                             size_t group_key_length,
-                                                             const char *key,
-                                                             size_t key_length,
-                                                             uint64_t offset,
-                                                             uint64_t initial,
-                                                             time_t expiration,
-                                                             uint64_t *value);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/basic_string.h b/libmemcached/basic_string.h
deleted file mode 100644 (file)
index de8d3d5..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-// No assumptions of NULL should be made
-
-struct memcached_string_t {
-  const char *c_str;
-  size_t size;
-};
-
-#define memcached_size(X) (X).size;
-#define memcached_c_str(X) (X).c_str;
-#define memcached_string_param(X) (X).c_str, (X).size
-
-#ifdef __cplusplus
-#define memcached_string_printf(X) int((X).size), (X).c_str
-#else
-#define memcached_string_printf(X) (int)((X).size), (X).c_str
-#endif
-
diff --git a/libmemcached/behavior.h b/libmemcached/behavior.h
deleted file mode 100644 (file)
index 426f988..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_behavior_set(memcached_st *ptr, const memcached_behavior_t flag, uint64_t data);
-
-LIBMEMCACHED_API
-uint64_t memcached_behavior_get(memcached_st *ptr, const memcached_behavior_t flag);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_behavior_set_distribution(memcached_st *ptr, memcached_server_distribution_t type);
-
-LIBMEMCACHED_API
-memcached_server_distribution_t memcached_behavior_get_distribution(memcached_st *ptr);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_behavior_set_key_hash(memcached_st *ptr, memcached_hash_t type);
-
-LIBMEMCACHED_API
-memcached_hash_t memcached_behavior_get_key_hash(memcached_st *ptr);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_behavior_set_distribution_hash(memcached_st *ptr, memcached_hash_t type);
-
-LIBMEMCACHED_API
-memcached_hash_t memcached_behavior_get_distribution_hash(memcached_st *ptr);
-
-LIBMEMCACHED_LOCAL
-bool _is_auto_eject_host(const memcached_st *ptr);
-
-LIBMEMCACHED_API
-  const char *libmemcached_string_behavior(const memcached_behavior_t flag);
-
-LIBMEMCACHED_API
-  const char *libmemcached_string_distribution(const memcached_server_distribution_t flag);
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_bucket_set(memcached_st *self,
-                                          const uint32_t *host_map,
-                                          const uint32_t *forward_map,
-                                          const uint32_t buckets,
-                                          const uint32_t replicas);
-
-#ifdef __cplusplus
-}
-#endif
index 84f99359d78d138e697ca80f8b84f1107fc82c4d..83d8ce8fc8ca33a1a16a684dd4b0796ef4417e65 100644 (file)
@@ -30,57 +30,56 @@ memcached_return_t memcached_callback_set(memcached_st *ptr,
     {
       return memcached_set_namespace(ptr, (char*)data, data ? strlen((char*)data) : 0);
     }
+
   case MEMCACHED_CALLBACK_USER_DATA:
     {
       ptr->user_data= const_cast<void *>(data);
       break;
     }
+
   case MEMCACHED_CALLBACK_CLEANUP_FUNCTION:
     {
       memcached_cleanup_fn func= *(memcached_cleanup_fn *)&data;
       ptr->on_cleanup= func;
       break;
     }
+
   case MEMCACHED_CALLBACK_CLONE_FUNCTION:
     {
       memcached_clone_fn func= *(memcached_clone_fn *)&data;
       ptr->on_clone= func;
       break;
     }
-#ifdef MEMCACHED_ENABLE_DEPRECATED
-  case MEMCACHED_CALLBACK_MALLOC_FUNCTION:
-    {
-      memcached_malloc_function func= *(memcached_malloc_fn *)&data;
-      ptr->call_malloc= func;
-      break;
-    }
-  case MEMCACHED_CALLBACK_REALLOC_FUNCTION:
-    {
-      memcached_realloc_function func= *(memcached_realloc_fn *)&data;
-      ptr->call_realloc= func;
-      break;
-    }
-  case MEMCACHED_CALLBACK_FREE_FUNCTION:
-    {
-      memcached_free_function func= *(memcached_free_fn *)&data;
-      ptr->call_free= func;
-      break;
-    }
-#endif
+
   case MEMCACHED_CALLBACK_GET_FAILURE:
     {
       memcached_trigger_key_fn func= *(memcached_trigger_key_fn *)&data;
       ptr->get_key_failure= func;
       break;
     }
+
   case MEMCACHED_CALLBACK_DELETE_TRIGGER:
     {
+      if (data) // NULL would mean we are disabling.
+      {
+        if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS)) 
+        {
+          return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("Delete triggers cannot be used if buffering is enabled"));
+        }
+
+        if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_NOREPLY)) 
+        {
+          return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("Delete triggers cannot be used if MEMCACHED_BEHAVIOR_NOREPLY is set"));
+        }
+      }
+
       memcached_trigger_delete_key_fn func= *(memcached_trigger_delete_key_fn *)&data;
       ptr->delete_trigger= func;
       break;
     }
+
   case MEMCACHED_CALLBACK_MAX:
-    return MEMCACHED_FAILURE;
+    return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("Invalid callback supplied"));
   }
 
   return MEMCACHED_SUCCESS;
@@ -97,67 +96,59 @@ void *memcached_callback_get(memcached_st *ptr,
     error = &local_error;
   }
 
+  if (ptr == NULL)
+  {
+    *error= MEMCACHED_INVALID_ARGUMENTS;
+    return NULL;
+  }
+
   switch (flag)
   {
   case MEMCACHED_CALLBACK_PREFIX_KEY:
     {
+      *error= MEMCACHED_SUCCESS;
       if (ptr->_namespace)
       {
-        *error= MEMCACHED_SUCCESS;
         return (void *)memcached_array_string(ptr->_namespace);
       }
-      else
-      {
-        *error= MEMCACHED_FAILURE;
-        return NULL;
-      }
+      return NULL;
     }
+
   case MEMCACHED_CALLBACK_USER_DATA:
     {
       *error= ptr->user_data ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
       return (void *)ptr->user_data;
     }
+
   case MEMCACHED_CALLBACK_CLEANUP_FUNCTION:
     {
       *error= ptr->on_cleanup ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
       return *(void **)&ptr->on_cleanup;
     }
+
   case MEMCACHED_CALLBACK_CLONE_FUNCTION:
     {
       *error= ptr->on_clone ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
       return *(void **)&ptr->on_clone;
     }
-#ifdef MEMCACHED_ENABLE_DEPRECATED
-  case MEMCACHED_CALLBACK_MALLOC_FUNCTION:
-    {
-      *error= ptr->call_malloc ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
-      return *(void **)&ptr->call_malloc;
-    }
-  case MEMCACHED_CALLBACK_REALLOC_FUNCTION:
-    {
-      *error= ptr->call_realloc ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
-      return *(void **)&ptr->call_realloc;
-    }
-  case MEMCACHED_CALLBACK_FREE_FUNCTION:
-    {
-      *error= ptr->call_free ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
-      return *(void **)&ptr->call_free;
-    }
-#endif
+
   case MEMCACHED_CALLBACK_GET_FAILURE:
     {
       *error= ptr->get_key_failure ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
       return *(void **)&ptr->get_key_failure;
     }
+
   case MEMCACHED_CALLBACK_DELETE_TRIGGER:
     {
       *error= ptr->delete_trigger ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
       return *(void **)&ptr->delete_trigger;
     }
+
   case MEMCACHED_CALLBACK_MAX:
-  default:
-    assert_msg(0, "Invalid behavior passed to memcached_behavior_set()");
-    *error= MEMCACHED_FAILURE;
-    return NULL;
+    break;
   }
+
+  assert_msg(0, "Invalid behavior passed to memcached_behavior_set()");
+  *error= MEMCACHED_FAILURE;
+  return NULL;
 }
index a9465d2e3e2061e9438860904cf5769d4ba8b1bc..3949ea3def7a5cb1027d38dcbb2e24e4502cde70 100644 (file)
@@ -1,9 +1,9 @@
 /*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
  * 
- *  Libmemcached library
+ *  Libmemcached Client and Server 
  *
  *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *  All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that the following conditions are
 
 #pragma once
 
-struct memcached_callback_st {
-  memcached_execute_fn *callback;
-  void *context;
-  uint32_t number_of_callback;
-};
+test_return_t test_MEMCACHED_CALLBACK_DELETE_TRIGGER(memcached_st *);
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_callback_set(memcached_st *ptr,
-                                          const memcached_callback_t flag,
-                                          const void *data);
-LIBMEMCACHED_API
-void *memcached_callback_get(memcached_st *ptr,
-                             const memcached_callback_t flag,
-                             memcached_return_t *error);
-
-#ifdef __cplusplus
-}
-#endif
+test_return_t test_MEMCACHED_CALLBACK_DELETE_TRIGGER_and_MEMCACHED_BEHAVIOR_NOREPLY(memcached_st *);
index 6de9bbd1e24298026597a8de9d31353b1c8d82e8..477351954e9cae5de2619ac92bd17b7d3f7ee5e2 100644 (file)
 #include <strings.h>
 #endif
 
-#include <libmemcached/memcached.h>
+#include <libmemcached-1.0/memcached.h>
 #include <libmemcached/watchpoint.h>
 #include <libmemcached/is.h>
-#include <libmemcached/namespace.h>
 
 #include <libmemcached/server_instance.h>
 
@@ -116,11 +115,13 @@ memcached_return_t memcached_server_execute(memcached_st *ptr,
 #include <libmemcached/initialize_query.h>
 #include <libmemcached/response.h>
 #include <libmemcached/namespace.h>
+#include <libmemcached/virtual_bucket.h>
 
 #ifdef __cplusplus
 #include <libmemcached/backtrace.hpp>
 #include <libmemcached/assert.hpp>
 #include <libmemcached/server.hpp>
+#include <libmemcached/key.hpp>
 #endif
 
 #include <libmemcached/continuum.hpp>
@@ -155,43 +156,9 @@ memcached_return_t run_distribution(memcached_st *ptr);
 #define memcached_server_response_decrement(A) (A)->cursor_active--
 #define memcached_server_response_reset(A) (A)->cursor_active=0
 
-#ifdef __cplusplus
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_key_test(const memcached_st& memc,
-                                      const char * const *keys,
-                                      const size_t *key_length,
-                                      size_t number_of_keys);
-#endif
-
 LIBMEMCACHED_LOCAL
 memcached_return_t memcached_purge(memcached_server_write_instance_st ptr);
 
-
-static inline memcached_return_t memcached_validate_key_length(size_t key_length, bool binary)
-{
-  if (key_length == 0)
-  {
-    return MEMCACHED_BAD_KEY_PROVIDED;
-  }
-
-  if (binary)
-  {
-    if (key_length > 0xffff)
-    {
-      return MEMCACHED_BAD_KEY_PROVIDED;
-    }
-  }
-  else
-  {
-    if (key_length >= MEMCACHED_MAX_KEY)
-    {
-      return MEMCACHED_BAD_KEY_PROVIDED;
-    }
-  }
-
-  return MEMCACHED_SUCCESS;
-}
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/libmemcached/configure.h.in b/libmemcached/configure.h.in
deleted file mode 100644 (file)
index 7b48be2..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker, Trond Norbye All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-@DEPRECATED@
-@LIBMEMCACHED_WITH_SASL_SUPPORT@
-
-#define LIBMEMCACHED_VERSION_STRING "@VERSION@"
-#define LIBMEMCACHED_VERSION_HEX @PANDORA_HEX_VERSION@
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/constants.h b/libmemcached/constants.h
deleted file mode 100644 (file)
index 106aec4..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#pragma once
-
-/* Public defines */
-#define MEMCACHED_DEFAULT_PORT 11211
-#define MEMCACHED_MAX_KEY 251 /* We add one to have it null terminated */
-#define MEMCACHED_MAX_BUFFER 8196
-#define MEMCACHED_MAX_HOST_SORT_LENGTH 86 /* Used for Ketama */
-#define MEMCACHED_POINTS_PER_SERVER 100
-#define MEMCACHED_POINTS_PER_SERVER_KETAMA 160
-#define MEMCACHED_CONTINUUM_SIZE MEMCACHED_POINTS_PER_SERVER*100 /* This would then set max hosts to 100 */
-#define MEMCACHED_STRIDE 4
-#define MEMCACHED_DEFAULT_TIMEOUT 5000
-#define MEMCACHED_DEFAULT_CONNECT_TIMEOUT 4000
-#define MEMCACHED_CONTINUUM_ADDITION 10 /* How many extra slots we should build for in the continuum */
-#define MEMCACHED_PREFIX_KEY_MAX_SIZE 128
-#define MEMCACHED_EXPIRATION_NOT_ADD 0xffffffffU
-#define MEMCACHED_VERSION_STRING_LENGTH 24
-#define MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH 20
-#define MEMCACHED_SERVER_FAILURE_LIMIT 5
-#define MEMCACHED_SERVER_FAILURE_RETRY_TIMEOUT 2
-
-
-enum memcached_server_distribution_t {
-  MEMCACHED_DISTRIBUTION_MODULA,
-  MEMCACHED_DISTRIBUTION_CONSISTENT,
-  MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA,
-  MEMCACHED_DISTRIBUTION_RANDOM,
-  MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY,
-  MEMCACHED_DISTRIBUTION_CONSISTENT_WEIGHTED,
-  MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET,
-  MEMCACHED_DISTRIBUTION_CONSISTENT_MAX
-};
-
-#ifndef __cplusplus
-typedef enum memcached_server_distribution_t memcached_server_distribution_t;
-#endif
-
-enum memcached_behavior_t {
-  MEMCACHED_BEHAVIOR_NO_BLOCK,
-  MEMCACHED_BEHAVIOR_TCP_NODELAY,
-  MEMCACHED_BEHAVIOR_HASH,
-  MEMCACHED_BEHAVIOR_KETAMA,
-  MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE,
-  MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE,
-  MEMCACHED_BEHAVIOR_CACHE_LOOKUPS,
-  MEMCACHED_BEHAVIOR_SUPPORT_CAS,
-  MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
-  MEMCACHED_BEHAVIOR_DISTRIBUTION,
-  MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,
-  MEMCACHED_BEHAVIOR_USER_DATA,
-  MEMCACHED_BEHAVIOR_SORT_HOSTS,
-  MEMCACHED_BEHAVIOR_VERIFY_KEY,
-  MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,
-  MEMCACHED_BEHAVIOR_RETRY_TIMEOUT,
-  MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED,
-  MEMCACHED_BEHAVIOR_KETAMA_HASH,
-  MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
-  MEMCACHED_BEHAVIOR_SND_TIMEOUT,
-  MEMCACHED_BEHAVIOR_RCV_TIMEOUT,
-  MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,
-  MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK,
-  MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK,
-  MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH,
-  MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY,
-  MEMCACHED_BEHAVIOR_NOREPLY,
-  MEMCACHED_BEHAVIOR_USE_UDP,
-  MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS,
-  MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
-  MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ,
-  MEMCACHED_BEHAVIOR_CORK,
-  MEMCACHED_BEHAVIOR_TCP_KEEPALIVE,
-  MEMCACHED_BEHAVIOR_TCP_KEEPIDLE,
-  MEMCACHED_BEHAVIOR_LOAD_FROM_FILE,
-  MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS,
-  MEMCACHED_BEHAVIOR_MAX
-};
-
-#ifndef __cplusplus
-typedef enum memcached_behavior_t memcached_behavior_t;
-#endif
-
-enum memcached_callback_t {
-  MEMCACHED_CALLBACK_PREFIX_KEY = 0,
-  MEMCACHED_CALLBACK_USER_DATA = 1,
-  MEMCACHED_CALLBACK_CLEANUP_FUNCTION = 2,
-  MEMCACHED_CALLBACK_CLONE_FUNCTION = 3,
-#ifdef MEMCACHED_ENABLE_DEPRECATED
-  MEMCACHED_CALLBACK_MALLOC_FUNCTION = 4,
-  MEMCACHED_CALLBACK_REALLOC_FUNCTION = 5,
-  MEMCACHED_CALLBACK_FREE_FUNCTION = 6,
-#endif
-  MEMCACHED_CALLBACK_GET_FAILURE = 7,
-  MEMCACHED_CALLBACK_DELETE_TRIGGER = 8,
-  MEMCACHED_CALLBACK_MAX,
-  MEMCACHED_CALLBACK_NAMESPACE= MEMCACHED_CALLBACK_PREFIX_KEY
-};
-
-#ifndef __cplusplus
-typedef enum memcached_callback_t memcached_callback_t;
-#endif
-
-enum memcached_hash_t {
-  MEMCACHED_HASH_DEFAULT= 0,
-  MEMCACHED_HASH_MD5,
-  MEMCACHED_HASH_CRC,
-  MEMCACHED_HASH_FNV1_64,
-  MEMCACHED_HASH_FNV1A_64,
-  MEMCACHED_HASH_FNV1_32,
-  MEMCACHED_HASH_FNV1A_32,
-  MEMCACHED_HASH_HSIEH,
-  MEMCACHED_HASH_MURMUR,
-  MEMCACHED_HASH_JENKINS,
-  MEMCACHED_HASH_CUSTOM,
-  MEMCACHED_HASH_MAX
-};
-
-#ifndef __cplusplus
-typedef enum memcached_hash_t memcached_hash_t;
-#endif
-
-enum memcached_connection_t {
-  MEMCACHED_CONNECTION_TCP,
-  MEMCACHED_CONNECTION_UDP,
-  MEMCACHED_CONNECTION_UNIX_SOCKET
-};
-
-enum {
-  MEMCACHED_CONNECTION_UNKNOWN= 0,
-  MEMCACHED_CONNECTION_MAX= 0
-};
-
-#ifndef __cplusplus
-typedef enum memcached_connection_t memcached_connection_t;
-#endif
index 9c39bb0d8200ba330d1c5ecb6632c251f3172712..325d36fe92d868a22ed2563ef1f39002637a015a 100644 (file)
@@ -38,4 +38,5 @@
 #pragma once
 
 #include <libmemcached/common.h>
+#include <libmemcached/csl/server.h>
 
index ed917da7f893fcc54a94ac15f0b5ca8e6ad0e395..423d93f31f08f42702c763e9a46a990dcb49bc26 100644 (file)
@@ -37,9 +37,7 @@
 
 #pragma once
 
-#include <libmemcached/basic_string.h>
-#include <libmemcached/constants.h>
-#include <libmemcached/csl/server.h>
+#include <libmemcached/csl/common.h>
 
 union YYSTYPE
 {
index 669d8ae130e5c5f7b118fae59e66ef311734da49..91799bbd3397d5932d0b9c2a84de6679b5c2ebb0 100644 (file)
@@ -45,195 +45,142 @@ memcached_return_t memcached_delete(memcached_st *ptr, const char *key, size_t k
                                  key, key_length, expiration);
 }
 
-static inline memcached_return_t binary_delete(memcached_st *ptr,
-                                               uint32_t server_key,
-                                               const char *key,
-                                               size_t key_length,
-                                               bool flush);
-
-memcached_return_t memcached_delete_by_key(memcached_st *ptr,
-                                           const char *group_key, size_t group_key_length,
-                                           const char *key, size_t key_length,
-                                           time_t expiration)
+static inline memcached_return_t ascii_delete(memcached_st *ptr,
+                                              memcached_server_write_instance_st instance,
+                                              uint32_t ,
+                                              const char *key,
+                                              size_t key_length,
+                                              uint64_t expiration,
+                                              bool& reply,
+                                              bool& flush)
 {
   char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-  memcached_server_write_instance_st instance;
+  int send_length;
 
-  LIBMEMCACHED_MEMCACHED_DELETE_START();
-
-  memcached_return_t rc;
-  if (memcached_failed(rc= initialize_query(ptr)))
+  if (expiration)
   {
-    return rc;
-  }
-
-  rc= memcached_validate_key_length(key_length,
-                                    ptr->flags.binary_protocol);
-
-  if (memcached_failed(rc))
-  {
-    return rc;
-  }
-
-  uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
-  instance= memcached_server_instance_fetch(ptr, server_key);
-
-  bool to_write= (ptr->flags.buffer_requests) ? false : true;
-
-  bool no_reply= (ptr->flags.no_reply);
-
-  if (ptr->flags.binary_protocol)
-  {
-    likely (! expiration)
+    if ((instance->major_version == 1 and
+         instance->minor_version > 2) or
+        instance->major_version > 1)
     {
-      rc= binary_delete(ptr, server_key, key, key_length, to_write);
+      return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, 
+                                 memcached_literal_param("Memcached server version does not allow expiration of deleted items"));
     }
     else
     {
-      rc= MEMCACHED_INVALID_ARGUMENTS;
-    }
-  }
-  else
-  {
-    int send_length;
+      /* ensure that we are connected, otherwise we might bump the
+       * command counter before connection */
+      memcached_return_t rc;
+      if ((rc= memcached_connect(instance)) != MEMCACHED_SUCCESS)
+      {
+        WATCHPOINT_ERROR(rc);
+        return rc;
+      }
 
-    unlikely (expiration)
-    {
-       if ((instance->major_version == 1 &&
-            instance->minor_version > 2) ||
-           instance->major_version > 1)
-       {
-         rc= MEMCACHED_INVALID_ARGUMENTS;
-         goto error;
-       }
-       else
-       {
-          /* ensure that we are connected, otherwise we might bump the
-           * command counter before connection */
-          if ((rc= memcached_connect(instance)) != MEMCACHED_SUCCESS)
+      if (instance->minor_version == 0)
+      {
+        if (reply == false or flush == false)
+        {
+          /* We might get out of sync with the server if we send this command
+           * to a server newer than 1.2.x..  enable reply and buffered mode.
+         */
+          flush= true;
+          if (reply == false)
           {
-            WATCHPOINT_ERROR(rc);
-            return rc;
+            memcached_server_response_increment(instance);
           }
+          reply= true;
+        }
+      }
 
-          if (instance->minor_version == 0)
-          {
-             if (no_reply or to_write == false)
-             {
-                /* We might get out of sync with the server if we
-                 * send this command to a server newer than 1.2.x..
-                 * disable no_reply and buffered mode.
-                 */
-                to_write= true;
-                if (no_reply)
-                   memcached_server_response_increment(instance);
-                no_reply= false;
-             }
-          }
-          send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
-                                "delete %.*s%.*s %u%s\r\n",
-                                memcached_print_array(ptr->_namespace),
-                                (int) key_length, key,
-                                (uint32_t)expiration,
-                                no_reply ? " noreply" :"" );
-       }
-    }
-    else
-    {
       send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
-                            "delete %.*s%.*s%s\r\n",
+                            "delete %.*s%.*s %u%s\r\n",
                             memcached_print_array(ptr->_namespace),
-                            (int)key_length, key, no_reply ? " noreply" :"");
-    }
-
-    if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0)
-    {
-      rc=  memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, 
-                               memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)"));
-      goto error;
-    }
-
-    if (ptr->flags.use_udp and to_write == false)
-    {
-      if (send_length > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH)
-        return MEMCACHED_WRITE_FAILURE;
-
-      if (send_length + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
-      {
-        memcached_io_write(instance, NULL, 0, true);
-      }
+                            (int) key_length, key,
+                            (uint32_t)expiration,
+                            reply ? "" :  " noreply");
     }
-
-    rc= memcached_do(instance, buffer, (size_t)send_length, to_write);
   }
-
-  if (rc != MEMCACHED_SUCCESS)
+  else
   {
-    goto error;
+    send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
+                          "delete %.*s%.*s%s\r\n",
+                          memcached_print_array(ptr->_namespace),
+                          (int)key_length, key, 
+                          reply ? "" :  " noreply");
   }
 
-  if (to_write == false)
+  if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0)
   {
-    rc= MEMCACHED_BUFFERED;
+    return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, 
+                               memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)"));
   }
-  else if (no_reply == false)
+
+  if (ptr->flags.use_udp and flush == false)
   {
-    rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
-    if (rc == MEMCACHED_DELETED)
+    if (send_length > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH)
     {
-      rc= MEMCACHED_SUCCESS;
+      return MEMCACHED_WRITE_FAILURE;
     }
-  }
 
-  if (rc == MEMCACHED_SUCCESS and ptr->delete_trigger)
-  {
-    ptr->delete_trigger(ptr, key, key_length);
+    if (send_length +instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
+    {
+      memcached_io_write(instance, NULL, 0, true);
+    }
   }
 
-error:
-  LIBMEMCACHED_MEMCACHED_DELETE_END();
-  return rc;
+  return memcached_do(instance, buffer, (size_t)send_length, flush);
 }
 
 static inline memcached_return_t binary_delete(memcached_st *ptr,
+                                               memcached_server_write_instance_st instance,
                                                uint32_t server_key,
                                                const char *key,
                                                size_t key_length,
-                                               bool flush)
+                                               time_t expiration,
+                                               bool& reply,
+                                               bool& flush)
 {
-  memcached_server_write_instance_st instance;
   protocol_binary_request_delete request= {};
 
-  instance= memcached_server_instance_fetch(ptr, server_key);
+  // No expiration is supported in the binary protocol
+  if (expiration)
+  {
+    return MEMCACHED_INVALID_ARGUMENTS;
+  }
 
   request.message.header.request.magic= PROTOCOL_BINARY_REQ;
-  if (ptr->flags.no_reply)
+  if (reply)
   {
-    request.message.header.request.opcode= PROTOCOL_BINARY_CMD_DELETEQ;
+    request.message.header.request.opcode= PROTOCOL_BINARY_CMD_DELETE;
   }
   else
   {
-    request.message.header.request.opcode= PROTOCOL_BINARY_CMD_DELETE;
+    request.message.header.request.opcode= PROTOCOL_BINARY_CMD_DELETEQ;
   }
   request.message.header.request.keylen= htons((uint16_t)(key_length + memcached_array_size(ptr->_namespace)));
   request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
   request.message.header.request.bodylen= htonl((uint32_t)(key_length + memcached_array_size(ptr->_namespace)));
 
-  if (ptr->flags.use_udp && ! flush)
+  if (ptr->flags.use_udp and flush == false)
   {
     size_t cmd_size= sizeof(request.bytes) + key_length;
     if (cmd_size > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH)
+    {
       return MEMCACHED_WRITE_FAILURE;
+    }
 
-    if (cmd_size + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
+    if (cmd_size +instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
+    {
       memcached_io_write(instance, NULL, 0, true);
+    }
   }
 
   struct libmemcached_io_vector_st vector[]=
   {
-    { sizeof(request.bytes), request.bytes},
-    { memcached_array_size(ptr->_namespace), memcached_array_string(ptr->_namespace) },
-    { key_length, key },
+    { request.bytes, sizeof(request.bytes) },
+    { memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace) },
+    { key, key_length }
   };
 
   memcached_return_t rc= MEMCACHED_SUCCESS;
@@ -243,7 +190,7 @@ static inline memcached_return_t binary_delete(memcached_st *ptr,
     memcached_io_reset(instance);
   }
 
-  unlikely (ptr->number_of_replicas > 0)
+  if (ptr->number_of_replicas > 0)
   {
     request.message.header.request.opcode= PROTOCOL_BINARY_CMD_DELETEQ;
 
@@ -270,3 +217,82 @@ static inline memcached_return_t binary_delete(memcached_st *ptr,
 
   return rc;
 }
+
+memcached_return_t memcached_delete_by_key(memcached_st *ptr,
+                                           const char *group_key, size_t group_key_length,
+                                           const char *key, size_t key_length,
+                                           time_t expiration)
+{
+  LIBMEMCACHED_MEMCACHED_DELETE_START();
+
+  memcached_return_t rc;
+  if (memcached_failed(rc= initialize_query(ptr)))
+  {
+    return rc;
+  }
+
+  rc= memcached_validate_key_length(key_length, ptr->flags.binary_protocol);
+  if (memcached_failed(rc))
+  {
+    return rc;
+  }
+  
+  // If a delete trigger exists, we need a response, so no buffering/noreply
+  if (ptr->delete_trigger)
+  {
+    if (ptr->flags.buffer_requests)
+    {
+      return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, 
+                                 memcached_literal_param("Delete triggers cannot be used if buffering is enabled"));
+    }
+
+    if (ptr->flags.no_reply)
+    {
+      return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, 
+                                 memcached_literal_param("Delete triggers cannot be used if MEMCACHED_BEHAVIOR_NOREPLY is set"));
+    }
+  }
+
+
+  uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
+  memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
+
+  bool to_write= (ptr->flags.buffer_requests) ? false : true;
+
+  // Invert the logic to make it simpler to read the code
+  bool reply= (ptr->flags.no_reply) ? false : true;
+
+  if (ptr->flags.binary_protocol)
+  {
+    rc= binary_delete(ptr, instance, server_key, key, key_length, expiration, reply, to_write);
+  }
+  else
+  {
+    rc= ascii_delete(ptr, instance, server_key, key, key_length, expiration, reply, to_write);
+  }
+
+  if (rc == MEMCACHED_SUCCESS)
+  {
+    if (to_write == false)
+    {
+      rc= MEMCACHED_BUFFERED;
+    }
+    else if (reply)
+    {
+      char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+      rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
+      if (rc == MEMCACHED_DELETED)
+      {
+        rc= MEMCACHED_SUCCESS;
+      }
+    }
+
+    if (rc == MEMCACHED_SUCCESS and ptr->delete_trigger)
+    {
+      ptr->delete_trigger(ptr, key, key_length);
+    }
+  }
+
+  LIBMEMCACHED_MEMCACHED_DELETE_END();
+  return rc;
+}
diff --git a/libmemcached/delete.h b/libmemcached/delete.h
deleted file mode 100644 (file)
index 617d585..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_delete(memcached_st *ptr, const char *key, size_t key_length,
-                                    time_t expiration);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_delete_by_key(memcached_st *ptr,
-                                           const char *group_key, size_t group_key_length,
-                                           const char *key, size_t key_length,
-                                           time_t expiration);
-
-#ifdef __cplusplus
-}
-#endif
index 5e9e65f280e20b314f89e8727b9a13b46829b276..551b28ea57ce21393fcbaefbb47dc800b7f20724 100644 (file)
 memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const void *command,
                                 size_t command_length, bool with_flush)
 {
-  memcached_return_t rc;
-  ssize_t sent_length;
-
-  WATCHPOINT_ASSERT(command_length);
-  WATCHPOINT_ASSERT(command);
+  assert_msg(command_length, "Programming error, somehow a command had a length of zero");
+  assert_msg(command, "Programming error, somehow a command was NULL");
 
+  memcached_return_t rc;
   if (memcached_failed(rc= memcached_connect(ptr)))
   {
     WATCHPOINT_ASSERT(rc == memcached_last_error(ptr->root));
@@ -37,9 +35,9 @@ memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const vo
     memcached_io_write(ptr, NULL, 0, true);
   }
 
-  sent_length= memcached_io_write(ptr, command, command_length, with_flush);
+  ssize_t sent_length= memcached_io_write(ptr, command, command_length, with_flush);
 
-  if (sent_length == -1 || (size_t)sent_length != command_length)
+  if (sent_length == -1 or size_t(sent_length) != command_length)
   {
     rc= MEMCACHED_WRITE_FAILURE;
   }
@@ -56,7 +54,6 @@ memcached_return_t memcached_vdo(memcached_server_write_instance_st ptr,
                                  bool with_flush)
 {
   memcached_return_t rc;
-  ssize_t sent_length;
 
   WATCHPOINT_ASSERT(count);
   WATCHPOINT_ASSERT(vector);
@@ -78,7 +75,7 @@ memcached_return_t memcached_vdo(memcached_server_write_instance_st ptr,
     memcached_io_write(ptr, NULL, 0, true);
   }
 
-  sent_length= memcached_io_writev(ptr, vector, count, with_flush);
+  ssize_t sent_length= memcached_io_writev(ptr, vector, count, with_flush);
 
   size_t command_length= 0;
   for (uint32_t x= 0; x < count; ++x, vector++)
diff --git a/libmemcached/dump.h b/libmemcached/dump.h
deleted file mode 100644 (file)
index b6e639e..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_dump(memcached_st *ptr, memcached_dump_fn *function, void *context, uint32_t number_of_callbacks);
-
-
-#ifdef __cplusplus
-}
-#endif
index d6b7f16613734bdea1e86c59a0339a8247eb8c2e..e22871cd12b91f426116f2f020b53e6c6d76d846 100644 (file)
@@ -58,11 +58,15 @@ static void _set(memcached_server_st& server, memcached_st& memc)
   }
 
   if (memc.error_messages == NULL)
+  {
     return;
+  }
 
   memcached_error_t *error= (struct memcached_error_t *)libmemcached_malloc(&memc, sizeof(struct memcached_error_t));
-  if (not error) // Bad business if this happens
+  if (error == NULL) // Bad business if this happens
+  {
     return;
+  }
 
   memcpy(error, memc.error_messages, sizeof(memcached_error_t));
   error->next= server.error_messages;
@@ -71,7 +75,6 @@ static void _set(memcached_server_st& server, memcached_st& memc)
 
 static void _set(memcached_st& memc, memcached_string_t *str, memcached_return_t &rc, const char *at, int local_errno= 0)
 {
-  (void)at;
   if (memc.error_messages && memc.error_messages->query_id != memc.query_id)
   {
     memcached_error_free(memc);
@@ -110,8 +113,10 @@ static void _set(memcached_st& memc, memcached_string_t *str, memcached_return_t
   }
 
   memcached_error_t *error= (struct memcached_error_t *)libmemcached_malloc(&memc, sizeof(struct memcached_error_t));
-  if (not error) // Bad business if this happens
+  if (error == NULL) // Bad business if this happens
+  {
     return;
+  }
 
   error->root= &memc;
   error->query_id= memc.query_id;
@@ -188,7 +193,9 @@ memcached_return_t memcached_set_error(memcached_st& memc, memcached_return_t rc
 {
   assert_msg(rc != MEMCACHED_ERRNO, "Programmer error, MEMCACHED_ERRNO was set to be returned to client");
   if (memcached_success(rc))
-    return MEMCACHED_SUCCESS;
+  {
+    return rc;
+  }
 
   _set(memc, &str, rc, at);
 
@@ -214,7 +221,9 @@ memcached_return_t memcached_set_error(memcached_server_st& self, memcached_retu
   assert_msg(rc != MEMCACHED_ERRNO, "Programmer error, MEMCACHED_ERRNO was set to be returned to client");
   assert_msg(rc != MEMCACHED_SOME_ERRORS, "Programmer error, MEMCACHED_SOME_ERRORS was about to be set on a memcached_server_st");
   if (memcached_success(rc))
-    return MEMCACHED_SUCCESS;
+  {
+    return rc;
+  }
 
   char hostname_port_message[MAX_ERROR_LENGTH];
   int size;
@@ -232,29 +241,37 @@ memcached_return_t memcached_set_error(memcached_server_st& self, memcached_retu
 
   memcached_string_t error_host= { hostname_port_message, size };
 
-  if (not self.root)
+  assert(self.root);
+  if (self.root == NULL)
+  {
     return rc;
+  }
 
   _set(*self.root, &error_host, rc, at);
   _set(self, (*self.root));
+  assert(self.root->error_messages);
+  assert(self.error_messages);
 
   return rc;
 }
 
 memcached_return_t memcached_set_error(memcached_server_st& self, memcached_return_t rc, const char *at)
 {
-  assert_msg(rc != MEMCACHED_ERRNO, "Programmer error, MEMCACHED_ERRNO was set to be returned to client");
   assert_msg(rc != MEMCACHED_SOME_ERRORS, "Programmer error, MEMCACHED_SOME_ERRORS was about to be set on a memcached_server_st");
   if (memcached_success(rc))
-    return MEMCACHED_SUCCESS;
+  {
+    return rc;
+  }
 
   char hostname_port[NI_MAXHOST +NI_MAXSERV + sizeof("host : ")];
   int size= snprintf(hostname_port, sizeof(hostname_port), "host: %s:%d", self.hostname, int(self.port));
 
   memcached_string_t error_host= { hostname_port, size};
 
-  if (not self.root)
+  if (self.root == NULL)
+  {
     return rc;
+  }
 
   _set(*self.root, &error_host, rc, at);
   _set(self, *self.root);
@@ -266,7 +283,9 @@ memcached_return_t memcached_set_error(memcached_st& self, memcached_return_t rc
 {
   assert_msg(rc != MEMCACHED_ERRNO, "Programmer error, MEMCACHED_ERRNO was set to be returned to client");
   if (memcached_success(rc))
-    return MEMCACHED_SUCCESS;
+  {
+    return rc;
+  }
 
   _set(self, NULL, rc, at);
 
@@ -287,8 +306,10 @@ memcached_return_t memcached_set_errno(memcached_server_st& self, int local_errn
 
 memcached_return_t memcached_set_errno(memcached_st& self, int local_errno, const char *at)
 {
-  if (not local_errno)
+  if (local_errno == 0)
+  {
     return MEMCACHED_SUCCESS;
+  }
 
   memcached_return_t rc= MEMCACHED_ERRNO;
   _set(self, NULL, rc, at, local_errno);
@@ -298,8 +319,10 @@ memcached_return_t memcached_set_errno(memcached_st& self, int local_errno, cons
 
 memcached_return_t memcached_set_errno(memcached_st& memc, int local_errno, const char *at, memcached_string_t& str)
 {
-  if (not local_errno)
+  if (local_errno == 0)
+  {
     return MEMCACHED_SUCCESS;
+  }
 
   memcached_return_t rc= MEMCACHED_ERRNO;
   _set(memc, &str, rc, at, local_errno);
@@ -309,8 +332,10 @@ memcached_return_t memcached_set_errno(memcached_st& memc, int local_errno, cons
 
 memcached_return_t memcached_set_errno(memcached_server_st& self, int local_errno, const char *at, memcached_string_t& str)
 {
-  if (not local_errno)
+  if (local_errno == 0)
+  {
     return MEMCACHED_SUCCESS;
+  }
 
   char hostname_port_message[MAX_ERROR_LENGTH];
   int size;
@@ -340,8 +365,10 @@ memcached_return_t memcached_set_errno(memcached_server_st& self, int local_errn
 
 memcached_return_t memcached_set_errno(memcached_server_st& self, int local_errno, const char *at)
 {
-  if (not local_errno)
+  if (local_errno == 0)
+  {
     return MEMCACHED_SUCCESS;
+  }
 
   char hostname_port_message[MAX_ERROR_LENGTH];
   int size = snprintf(hostname_port_message, sizeof(hostname_port_message), "host: %s:%d",
@@ -389,7 +416,9 @@ void memcached_error_print(const memcached_st *self)
 static void _error_free(memcached_error_t *error)
 {
   if (not error)
+  {
     return;
+  }
 
   _error_free(error->next);
 
@@ -422,11 +451,15 @@ const char *memcached_last_error_message(memcached_st *memc)
     return memcached_strerror(memc, MEMCACHED_INVALID_ARGUMENTS);
   }
 
-  if (not memc->error_messages)
+  if (memc->error_messages == NULL)
+  {
     return memcached_strerror(memc, MEMCACHED_SUCCESS);
+  }
 
-  if (not memc->error_messages->size)
+  if (memc->error_messages->size == 0)
+  {
     return memcached_strerror(memc, memc->error_messages->rc);
+  }
 
   return memc->error_messages->message;
 }
diff --git a/libmemcached/error.h b/libmemcached/error.h
deleted file mode 100644 (file)
index 8b04e09..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  LibMemcached
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-  const char *memcached_last_error_message(memcached_st *);
-
-LIBMEMCACHED_API
-  void memcached_error_print(const memcached_st *);
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_last_error(memcached_st *);
-
-LIBMEMCACHED_API
-  int memcached_last_error_errno(memcached_st *);
-
-LIBMEMCACHED_API
-  const char *memcached_server_error(memcached_server_instance_st ptr);
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_server_error_return(memcached_server_instance_st ptr);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
index 252101aca05e06f6db137f172ee3a832757ac18a..c2cdcc51c53b3744cde15261a71d5ae0a5c1fe0a 100644 (file)
@@ -35,7 +35,7 @@
  *
  */
 
-#include <libmemcached/error.h>
+#include <libmemcached/common.h>
 
 #pragma once
 
diff --git a/libmemcached/exception.hpp b/libmemcached/exception.hpp
deleted file mode 100644 (file)
index 4759072..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Summary: Exceptions for the C++ interface
- *
- * Copy: See Copyright for the status of this software.
- *
- */
-
-/**
- * @file
- * @brief Exception declarations
- */
-
-#pragma once
-
-#include <stdexcept>
-#include <string>
-
-namespace memcache 
-{
-  class Exception : public std::runtime_error
-  {
-  public:
-    Exception(const std::string& msg, int in_errno)
-      : 
-        std::runtime_error(msg), 
-        _errno(in_errno) 
-    {}
-
-    Exception(const char *msg, int in_errno)
-      : 
-        std::runtime_error(std::string(msg)), 
-        _errno(in_errno) {}
-
-    virtual ~Exception() throw() {}
-
-    int getErrno() const 
-    { 
-      return _errno; 
-    }
-
-  private:
-    int _errno;
-  };
-
-  class Warning : public Exception
-  {
-  public:
-    Warning(const std::string& msg, int in_errno) : Exception(msg, in_errno) {}
-    Warning(const char *msg, int in_errno) : Exception(msg, in_errno) {}
-  };
-
-  class Error : public Exception
-  {
-  public:
-    Error(const std::string& msg, int in_errno) : Exception(msg, in_errno) {}
-    Error(const char *msg, int in_errno) : Exception(msg, in_errno) {}
-    virtual ~Error() throw() {}
-  };
-
-} /* namespace libmemcached */
index b8d4b0d876a325255d6ec9d36a94098f75b087de..b68ba466db760fab7683c66d2c61c5a884575a69 100644 (file)
@@ -40,14 +40,14 @@ static memcached_return_t ascii_exist(memcached_st *memc, memcached_server_write
 {
   struct libmemcached_io_vector_st vector[]=
   {
-    { sizeof("add ") -1, "add " },
-    { memcached_array_size(memc->_namespace), memcached_array_string(memc->_namespace) },
-    { key_length, key },
-    { sizeof(" 0") -1, " 0" },
-    { sizeof(" 2678400") -1, " 2678400" },
-    { sizeof(" 0") -1, " 0" },
-    { 2, "\r\n" },
-    { 2, "\r\n" }
+    { memcached_literal_param("add ") },
+    { memcached_array_string(memc->_namespace), memcached_array_size(memc->_namespace) },
+    { key, key_length },
+    { memcached_literal_param(" 0") },
+    { memcached_literal_param(" 2678400") },
+    { memcached_literal_param(" 0") },
+    { memcached_literal_param("\r\n") },
+    { memcached_literal_param("\r\n") }
   };
 
   /* Send command header */
@@ -89,9 +89,9 @@ static memcached_return_t binary_exist(memcached_st *memc, memcached_server_writ
 
   struct libmemcached_io_vector_st vector[]=
   {
-    { send_length, request.bytes },
-    { memcached_array_size(memc->_namespace), memcached_array_string(memc->_namespace) },
-    { key_length, key }
+    { request.bytes, send_length },
+    { memcached_array_string(memc->_namespace), memcached_array_size(memc->_namespace) },
+    { key, key_length }
   };
 
   /* write the header */
diff --git a/libmemcached/exist.h b/libmemcached/exist.h
deleted file mode 100644 (file)
index 816fe2f..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-memcached_return_t memcached_exist(memcached_st *memc, const char *key, size_t key_length);
-
-memcached_return_t memcached_exist_by_key(memcached_st *memc,
-                                          const char *group_key, size_t group_key_length,
-                                          const char *key, size_t key_length);
diff --git a/libmemcached/fetch.h b/libmemcached/fetch.h
deleted file mode 100644 (file)
index bff186a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_fetch_execute(memcached_st *ptr,
-                                           memcached_execute_fn *callback,
-                                           void *context,
-                                           uint32_t number_of_callbacks);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/flush.h b/libmemcached/flush.h
deleted file mode 100644 (file)
index 820a98e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_flush(memcached_st *ptr, time_t expiration);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/flush_buffers.h b/libmemcached/flush_buffers.h
deleted file mode 100644 (file)
index 31b5868..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_flush_buffers(memcached_st *mem);
-
-#ifdef __cplusplus
-}
-#endif
index 3c91b495fc527f009cdb8dd5b68023d198fae5e9..a78d73efecc2ef07d985795c6700ec09001ac3e4 100644 (file)
@@ -298,10 +298,10 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr,
 
     struct libmemcached_io_vector_st vector[]=
     {
-      { get_command_length, get_command },
-      { memcached_array_size(ptr->_namespace), memcached_array_string(ptr->_namespace) },
-      { key_length[x], keys[x] },
-      { 1, " " }
+      { get_command, get_command_length },
+      { memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace) },
+      { keys[x], key_length[x] },
+      { memcached_literal_param(" ") }
     };
 
 
@@ -500,9 +500,9 @@ static memcached_return_t simple_binary_mget(memcached_st *ptr,
 
     struct libmemcached_io_vector_st vector[]=
     {
-      { sizeof(request.bytes), request.bytes },
-      { memcached_array_size(ptr->_namespace), memcached_array_string(ptr->_namespace) },
-      { key_length[x], keys[x] }
+      { request.bytes, sizeof(request.bytes) },
+      { memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace) },
+      { keys[x], key_length[x] }
     };
 
     if (memcached_io_writev(instance, vector, 3, flush) == -1)
@@ -634,9 +634,9 @@ static memcached_return_t replication_binary_mget(memcached_st *ptr,
      */
       struct libmemcached_io_vector_st vector[]=
       {
-        { sizeof(request.bytes), request.bytes },
-        { memcached_array_size(ptr->_namespace), memcached_array_string(ptr->_namespace) },
-        { key_length[x], keys[x] }
+        { request.bytes, sizeof(request.bytes) },
+        { memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace) },
+        { keys[x], key_length[x] }
       };
 
       if (memcached_io_writev(instance, vector, 3, true) == -1)
@@ -652,7 +652,9 @@ static memcached_return_t replication_binary_mget(memcached_st *ptr,
     }
 
     if (success)
+    {
       break;
+    }
   }
 
   return rc;
diff --git a/libmemcached/get.h b/libmemcached/get.h
deleted file mode 100644 (file)
index 32e4c5f..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Public defines */
-LIBMEMCACHED_API
-char *memcached_get(memcached_st *ptr,
-                    const char *key, size_t key_length,
-                    size_t *value_length,
-                    uint32_t *flags,
-                    memcached_return_t *error);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_mget(memcached_st *ptr,
-                                  const char * const *keys,
-                                  const size_t *key_length,
-                                  size_t number_of_keys);
-
-LIBMEMCACHED_API
-char *memcached_get_by_key(memcached_st *ptr,
-                           const char *group_key, size_t group_key_length,
-                           const char *key, size_t key_length,
-                           size_t *value_length,
-                           uint32_t *flags,
-                           memcached_return_t *error);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_mget_by_key(memcached_st *ptr,
-                                         const char *group_key,
-                                         size_t group_key_length,
-                                         const char * const *keys,
-                                         const size_t *key_length,
-                                         const size_t number_of_keys);
-
-LIBMEMCACHED_API
-char *memcached_fetch(memcached_st *ptr,
-                      char *key,
-                      size_t *key_length,
-                      size_t *value_length,
-                      uint32_t *flags,
-                      memcached_return_t *error);
-
-LIBMEMCACHED_API
-memcached_result_st *memcached_fetch_result(memcached_st *ptr,
-                                            memcached_result_st *result,
-                                            memcached_return_t *error);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_mget_execute(memcached_st *ptr,
-                                          const char * const *keys,
-                                          const size_t *key_length,
-                                          const size_t number_of_keys,
-                                          memcached_execute_fn *callback,
-                                          void *context,
-                                          const uint32_t number_of_callbacks);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_mget_execute_by_key(memcached_st *ptr,
-                                                 const char *group_key,
-                                                 size_t group_key_length,
-                                                 const char * const *keys,
-                                                 const size_t *key_length,
-                                                 size_t number_of_keys,
-                                                 memcached_execute_fn *callback,
-                                                 void *context,
-                                                 const uint32_t number_of_callbacks);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/hash.h b/libmemcached/hash.h
deleted file mode 100644 (file)
index 6002a80..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The two public hash bits */
-LIBMEMCACHED_API
-uint32_t memcached_generate_hash_value(const char *key, size_t key_length, memcached_hash_t hash_algorithm);
-
-LIBMEMCACHED_API
-const hashkit_st *memcached_get_hashkit(const memcached_st *ptr);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_set_hashkit(memcached_st *ptr, hashkit_st *hashk);
-
-LIBMEMCACHED_API
-uint32_t memcached_generate_hash(const memcached_st *ptr, const char *key, size_t key_length);
-
-LIBMEMCACHED_LOCAL
-uint32_t memcached_generate_hash_with_redistribution(memcached_st *ptr, const char *key, size_t key_length);
-
-LIBMEMCACHED_API
-void memcached_autoeject(memcached_st *ptr);
-
-LIBMEMCACHED_API
-  const char * libmemcached_string_hash(memcached_hash_t type);
-
-#ifdef __cplusplus
-}
-#endif
index 179b7c29289c39dda38cd6a2a0932c6da1a441c2..304565597eabcb7f013424a7b962869633587a5a 100644 (file)
@@ -362,9 +362,9 @@ static memcached_return_t server_add(memcached_st *ptr,
   memcached_server_st *new_host_list= static_cast<memcached_server_st*>(libmemcached_realloc(ptr, memcached_server_list(ptr),
                                                                                              sizeof(memcached_server_st) * (ptr->number_of_hosts + 1)));
 
-  if (not new_host_list)
+  if (new_host_list == NULL)
   {
-    return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+    return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
   }
 
   memcached_server_list_set(ptr, new_host_list);
@@ -372,7 +372,7 @@ static memcached_return_t server_add(memcached_st *ptr,
   /* TODO: Check return type */
   memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, memcached_server_count(ptr));
 
-  if (not __server_create_with(ptr, instance, hostname, port, weight, type))
+  if (__server_create_with(ptr, instance, hostname, port, weight, type) == NULL)
   {
     return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
   }
index c29da7878ff3778388e8a3b098d83d57c69728be..e3f5fa3fef99cc418f825a4b126f77c960cc172b 100644 (file)
@@ -7,11 +7,16 @@ libmemcached_libmemcached_la_SOURCES =
 include libmemcached/csl/include.am
 
 EXTRA_DIST+= \
-            libmemcached/configure.h.in \
             libmemcached/libmemcached_probes.d \
             libmemcached/memcached/README.txt
 
+nobase_include_HEADERS+= \
+                        libmemcached/memcached.h \
+                        libmemcached/memcached.hpp \
+                        libmemcached/util.h
+
 noinst_HEADERS+= \
+                libmemcached/array.h \
                 libmemcached/assert.hpp \
                 libmemcached/backtrace.hpp \
                 libmemcached/byteorder.h \
@@ -24,64 +29,19 @@ noinst_HEADERS+= \
                 libmemcached/io.h \
                 libmemcached/io.hpp \
                 libmemcached/is.h \
+                libmemcached/key.hpp \
                 libmemcached/libmemcached_probes.h \
+                libmemcached/memcached/protocol_binary.h \
+                libmemcached/memcached/vbucket.h \
                 libmemcached/memory.h \
+                libmemcached/namespace.h \
                 libmemcached/options.hpp \
-                libmemcached/protocol/ascii_handler.h \
-                libmemcached/protocol/binary_handler.h \
-                libmemcached/protocol/common.h \
                 libmemcached/response.h \
                 libmemcached/server.hpp \
                 libmemcached/server_instance.h \
                 libmemcached/string.hpp \
-                libmemcached/virtual_bucket.h
-
-nobase_include_HEADERS+= \
-                        libmemcached/allocators.h \
-                        libmemcached/analyze.h \
-                        libmemcached/array.h \
-                        libmemcached/auto.h \
-                        libmemcached/basic_string.h \
-                        libmemcached/behavior.h \
-                        libmemcached/callback.h \
-                        libmemcached/configure.h \
-                        libmemcached/constants.h \
-                        libmemcached/delete.h \
-                        libmemcached/dump.h \
-                        libmemcached/error.h \
-                        libmemcached/exist.h \
-                        libmemcached/exception.hpp \
-                        libmemcached/fetch.h \
-                        libmemcached/flush.h \
-                        libmemcached/flush_buffers.h \
-                        libmemcached/get.h \
-                        libmemcached/hash.h \
-                        libmemcached/memcached.h \
-                        libmemcached/memcached.hpp \
-                        libmemcached/memcached/protocol_binary.h \
-                        libmemcached/memcached/vbucket.h \
-                        libmemcached/options.h \
-                        libmemcached/parse.h \
-                        libmemcached/namespace.h \
-                        libmemcached/protocol/cache.h \
-                        libmemcached/protocol/callback.h \
-                        libmemcached/protocol_handler.h \
-                        libmemcached/quit.h \
-                        libmemcached/return.h \
-                         libmemcached/platform.h \
-                        libmemcached/result.h \
-                         libmemcached/sasl.h \
-                        libmemcached/server.h \
-                        libmemcached/server_list.h \
-                        libmemcached/stats.h \
-                        libmemcached/storage.h \
-                        libmemcached/strerror.h \
-                        libmemcached/string.h \
-                        libmemcached/types.h \
-                        libmemcached/verbosity.h \
-                        libmemcached/version.h \
-                        libmemcached/visibility.h \
-                        libmemcached/watchpoint.h
+                libmemcached/virtual_bucket.h \
+                libmemcached/watchpoint.h
 
 lib_LTLIBRARIES+= libmemcached/libmemcached.la
 libmemcached_libmemcached_la_CFLAGS= -DBUILDING_LIBMEMCACHED
@@ -108,6 +68,7 @@ libmemcached_libmemcached_la_SOURCES+= \
                                       libmemcached/flush.cc \
                                       libmemcached/flush_buffers.cc \
                                       libmemcached/get.cc \
+                                      libmemcached/touch.cc \
                                       libmemcached/hash.cc \
                                       libmemcached/hosts.cc \
                                       libmemcached/initialize_query.cc \
index 027b156672cfe547a5b86560c37e4a51573360cf..5950158b053feb22a6205ef825719d08277d04a3 100644 (file)
@@ -38,7 +38,7 @@
 
 memcached_return_t initialize_query(memcached_st *self)
 {
-  if (not self)
+  if (self == NULL)
   {
     return MEMCACHED_INVALID_ARGUMENTS;
   }
index e97a6c88ed68825ea6cbdd14629871e39329408c..c6d647be64cdaf73efcbd21d319ea79a7f88e4a7 100644 (file)
@@ -610,13 +610,10 @@ memcached_return_t memcached_io_slurp(memcached_server_write_instance_st ptr)
 static ssize_t _io_write(memcached_server_write_instance_st ptr,
                          const void *buffer, size_t length, bool with_flush)
 {
-  size_t original_length;
-  const char* buffer_ptr;
-
   WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
 
-  original_length= length;
-  buffer_ptr= static_cast<const char *>(buffer);
+  size_t original_length= length;
+  const char *buffer_ptr= static_cast<const char *>(buffer);
 
   while (length)
   {
index 3591de922badf79d8ca27e81457053b420abeea8..6d3e2fa248831f4c7bceec1d6d9302eb0e475a16 100644 (file)
@@ -60,8 +60,8 @@ struct udp_datagram_header_st
 
 struct libmemcached_io_vector_st
 {
-  size_t length;
   const void *buffer;
+  size_t length;
 };
 
 #ifdef __cplusplus
index 02e0c2b326dbfcb51400c04e8c2c17c3a36dd58e..ea98c729f02b92f5fdf187623dba9ec4a37b0ad0 100644 (file)
 
 #include <libmemcached/common.h>
 
-memcached_return_t memcached_key_test(const memcached_st &memc,
+memcached_return_t memcached_key_test(memcached_st &memc,
                                       const char * const *keys,
                                       const size_t *key_length,
                                       size_t number_of_keys)
 {
+  if (keys == NULL or key_length == NULL)
+  {
+    return memcached_set_error(memc, MEMCACHED_BAD_KEY_PROVIDED, MEMCACHED_AT);
+  }
+
   if (not memc.flags.verify_key)
+  {
+    for (uint32_t x= 0; x < number_of_keys; x++)
+    {
+      memcached_return_t rc= memcached_validate_key_length(*(key_length +x), false);
+      if (memcached_failed(rc))
+      {
+        return rc;
+      }
+    }
+
     return MEMCACHED_SUCCESS;
+  }
 
   if (memc.flags.binary_protocol)
+  {
+    for (uint32_t x= 0; x < number_of_keys; x++)
+    {
+      memcached_return_t rc= memcached_validate_key_length(*(key_length +x), false);
+      if (memcached_failed(rc))
+      {
+        return rc;
+      }
+    }
+
     return MEMCACHED_SUCCESS;
+  }
 
   for (uint32_t x= 0; x < number_of_keys; x++)
   {
diff --git a/libmemcached/key.hpp b/libmemcached/key.hpp
new file mode 100644 (file)
index 0000000..ddd557d
--- /dev/null
@@ -0,0 +1,67 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+memcached_return_t memcached_key_test(memcached_st& memc,
+                                      const char * const *keys,
+                                      const size_t *key_length,
+                                      size_t number_of_keys);
+
+static inline memcached_return_t memcached_validate_key_length(size_t key_length, bool binary)
+{
+  if (key_length == 0)
+  {
+    return MEMCACHED_BAD_KEY_PROVIDED;
+  }
+
+  if (binary)
+  {
+    if (key_length > 0xffff)
+    {
+      return MEMCACHED_BAD_KEY_PROVIDED;
+    }
+  }
+  else
+  {
+    if (key_length >= MEMCACHED_MAX_KEY)
+    {
+      return MEMCACHED_BAD_KEY_PROVIDED;
+    }
+  }
+
+  return MEMCACHED_SUCCESS;
+}
index 1163b524f049b5f9e103eb9cb7543694a99afc9f..28d8402eb6ffc324e28c0e7e95032d334d5575d4 100644 (file)
@@ -19,6 +19,8 @@ provider libmemcached {
        probe memcached_replace_end();
        probe memcached_get_start();
        probe memcached_get_end();
+       probe memcached_touch_start();
+       probe memcached_touch_end();
        probe memcached_mget_start();
        probe memcached_mget_end();
        probe memcached_connect_start();
index e9a649d1ef29a7641f09f7ab6e53347ba92a4389..9dba8aa12dd7cd162ed7ccc81e85a9f5b183ee64 100644 (file)
@@ -1,5 +1,5 @@
 /*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
+ *
  *  Libmemcached library
  *
  *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
 #define        LIBMEMCACHED_MEMCACHED_GET_END_ENABLED() (0)
 #define        LIBMEMCACHED_MEMCACHED_GET_START()
 #define        LIBMEMCACHED_MEMCACHED_GET_START_ENABLED() (0)
+#define        LIBMEMCACHED_MEMCACHED_TOUCH_END()
+#define        LIBMEMCACHED_MEMCACHED_TOUCH_END_ENABLED() (0)
+#define        LIBMEMCACHED_MEMCACHED_TOUCH_START()
+#define        LIBMEMCACHED_MEMCACHED_TOUCH_START_ENABLED() (0)
 #define        LIBMEMCACHED_MEMCACHED_INCREMENT_END()
 #define        LIBMEMCACHED_MEMCACHED_INCREMENT_END_ENABLED() (0)
 #define        LIBMEMCACHED_MEMCACHED_INCREMENT_START()
index 9309d8b9b04cf650768d2d2451fecdb39b8b72c6..a45077eeaa374666a53436be7ebd7cff1dea53a2 100644 (file)
@@ -1,9 +1,8 @@
 /*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
+ *
  *  Libmemcached library
  *
  *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that the following conditions are
 
 #pragma once
 
-#include <inttypes.h>
-#include <stdlib.h>
-#include <sys/types.h>
-
-
-#if !defined(__cplusplus)
-# include <stdbool.h>
-#endif
-
-#include <libmemcached/visibility.h>
-#include <libmemcached/configure.h>
-#include <libmemcached/platform.h>
-#include <libmemcached/constants.h>
-#include <libmemcached/return.h>
-#include <libmemcached/types.h>
-#include <libmemcached/string.h>
-#include <libmemcached/array.h>
-#include <libmemcached/error.h>
-#include <libmemcached/stats.h>
-#include <libhashkit/hashkit.h>
-
-// Everything above this line must be in the order specified.
-#include <libmemcached/allocators.h>
-#include <libmemcached/analyze.h>
-#include <libmemcached/auto.h>
-#include <libmemcached/behavior.h>
-#include <libmemcached/callback.h>
-#include <libmemcached/delete.h>
-#include <libmemcached/dump.h>
-#include <libmemcached/exist.h>
-#include <libmemcached/fetch.h>
-#include <libmemcached/flush.h>
-#include <libmemcached/flush_buffers.h>
-#include <libmemcached/get.h>
-#include <libmemcached/hash.h>
-#include <libmemcached/namespace.h>
-#include <libmemcached/options.h>
-#include <libmemcached/parse.h>
-#include <libmemcached/quit.h>
-#include <libmemcached/result.h>
-#include <libmemcached/server.h>
-#include <libmemcached/server_list.h>
-#include <libmemcached/storage.h>
-#include <libmemcached/strerror.h>
-#include <libmemcached/verbosity.h>
-#include <libmemcached/version.h>
-#include <libmemcached/sasl.h>
-
-struct memcached_st {
-  /**
-    @note these are static and should not change without a call to behavior.
-  */
-  struct {
-    bool is_purging:1;
-    bool is_processing_input:1;
-    bool is_time_for_rebuild:1;
-  } state;
-
-  struct {
-    // Everything below here is pretty static.
-    bool auto_eject_hosts:1;
-    bool binary_protocol:1;
-    bool buffer_requests:1;
-    bool hash_with_namespace:1;
-    bool no_block:1; // Don't block
-    bool no_reply:1;
-    bool randomize_replica_read:1;
-    bool support_cas:1;
-    bool tcp_nodelay:1;
-    bool use_sort_hosts:1;
-    bool use_udp:1;
-    bool verify_key:1;
-    bool tcp_keepalive:1;
-  } flags;
-
-  memcached_server_distribution_t distribution;
-  hashkit_st hashkit;
-  struct {
-    unsigned int version;
-  } server_info;
-  uint32_t number_of_hosts;
-  memcached_server_st *servers;
-  memcached_server_st *last_disconnected_server;
-  int32_t snd_timeout;
-  int32_t rcv_timeout;
-  uint32_t server_failure_limit;
-  uint32_t io_msg_watermark;
-  uint32_t io_bytes_watermark;
-  uint32_t io_key_prefetch;
-  uint32_t tcp_keepidle;
-  int32_t poll_timeout;
-  int32_t connect_timeout; // How long we will wait on connect() before we will timeout
-  int32_t retry_timeout;
-  int send_size;
-  int recv_size;
-  void *user_data;
-  uint64_t query_id;
-  uint32_t number_of_replicas;
-  memcached_result_st result;
-
-  struct {
-    bool weighted;
-    uint32_t continuum_count; // Ketama
-    uint32_t continuum_points_counter; // Ketama
-    time_t next_distribution_rebuild; // Ketama
-    memcached_continuum_item_st *continuum; // Ketama
-  } ketama;
-
-  struct memcached_virtual_bucket_t *virtual_bucket;
-
-  struct memcached_allocator_t allocators;
-
-  memcached_clone_fn on_clone;
-  memcached_cleanup_fn on_cleanup;
-  memcached_trigger_key_fn get_key_failure;
-  memcached_trigger_delete_key_fn delete_trigger;
-  memcached_callback_st *callbacks;
-  struct memcached_sasl_st sasl;
-  struct memcached_error_t *error_messages;
-  struct memcached_array_st *_namespace;
-  struct {
-    uint32_t initial_pool_size;
-    uint32_t max_pool_size;
-    int32_t version; // This is used by pool and others to determine if the memcached_st is out of date.
-    struct memcached_array_st *filename;
-  } configure;
-  struct {
-    bool is_allocated:1;
-  } options;
-
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-void memcached_servers_reset(memcached_st *ptr);
-
-LIBMEMCACHED_API
-memcached_st *memcached_create(memcached_st *ptr);
-
-LIBMEMCACHED_API
-memcached_st *memcached(const char *string, size_t string_length);
-
-LIBMEMCACHED_API
-void memcached_free(memcached_st *ptr);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_reset(memcached_st *ptr);
-
-LIBMEMCACHED_API
-void memcached_reset_last_disconnected_server(memcached_st *ptr);
-
-LIBMEMCACHED_API
-memcached_st *memcached_clone(memcached_st *clone, const memcached_st *ptr);
-
-LIBMEMCACHED_API
-void *memcached_get_user_data(const memcached_st *ptr);
-
-LIBMEMCACHED_API
-void *memcached_set_user_data(memcached_st *ptr, void *data);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_push(memcached_st *destination, const memcached_st *source);
-
-LIBMEMCACHED_API
-memcached_server_instance_st memcached_server_instance_by_position(const memcached_st *ptr, uint32_t server_key);
-
-LIBMEMCACHED_API
-uint32_t memcached_server_count(const memcached_st *);
-
-LIBMEMCACHED_API
-uint64_t memcached_query_id(const memcached_st *);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
+#include <libmemcached-1.0/memcached.h>
index 8c5ca934c9055fda7b1539d927256697f1a53ac9..d38e6d24ac646050615cc9accf213d8cbfb05a70 100644 (file)
-/*
- * Summary: C++ interface for memcached server
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
  *
- * Copy: See Copyright for the status of this software.
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * Authors: Padraig O'Sullivan <osullivan.padraig@gmail.com>
- *          Patrick Galbraith <patg@patg.net>
- */
-
-/**
- * @file memcached.hpp
- * @brief Libmemcached C++ interface
  */
 
 #pragma once
 
-#include <libmemcached/memcached.h>
-#include <libmemcached/exception.hpp>
-
-#include <string.h>
-
-#include <sstream>
-#include <string>
-#include <vector>
-#include <map>
-
-namespace memcache
-{
-
-/**
- * This is the core memcached library (if later, other objects
- * are needed, they will be created from this class).
- */
-class Memcache
-{
-public:
-
-  Memcache()
-  {
-    memc= memcached("", 0);
-  }
-
-  Memcache(const std::string &config)
-  {
-    memc= memcached(config.c_str(), config.size());
-  }
-
-  Memcache(const std::string &hostname, in_port_t port)
-  {
-    memc= memcached("", 0);
-    if (memc)
-      memcached_server_add(memc, hostname.c_str(), port);
-  }
-
-  Memcache(memcached_st *clone)
-  {
-    memc= memcached_clone(NULL, clone);
-  }
-
-  Memcache(const Memcache &rhs)
-  {
-    memc= memcached_clone(NULL, rhs.getImpl());
-  }
-
-  Memcache &operator=(const Memcache &rhs)
-  {
-    if (this != &rhs)
-    {
-      memcached_free(memc);
-      memc= memcached_clone(NULL, rhs.getImpl());
-    }
-
-    return *this;
-  }
-
-  ~Memcache()
-  {
-    memcached_free(memc);
-  }
-
-  /**
-   * Get the internal memcached_st *
-   */
-  const memcached_st *getImpl() const
-  {
-    return memc;
-  }
-
-  /**
-   * Return an error string for the given return structure.
-   *
-   * @param[in] rc a memcached_return_t structure
-   * @return error string corresponding to given return code in the library.
-   */
-  const std::string getError(memcached_return_t rc) const
-  {
-    /* first parameter to strerror is unused */
-    return memcached_strerror(NULL, rc);
-  }
-
-  bool error(std::string& error_message) const
-  {
-    if (memcached_failed(memcached_last_error(memc)))
-    {
-      error_message+= memcached_last_error_message(memc);
-      return true;
-    }
-
-    return false;
-  }
-
-  bool error() const
-  {
-    if (memcached_failed(memcached_last_error(memc)))
-    {
-      return true;
-    }
-
-    return false;
-  }
-
-  bool error(memcached_return_t& arg) const
-  {
-    arg= memcached_last_error(memc);
-    return memcached_failed(arg);
-  }
-
-  bool setBehavior(memcached_behavior_t flag, uint64_t data)
-  {
-    return (memcached_success(memcached_behavior_set(memc, flag, data)));
-  }
-
-  uint64_t getBehavior(memcached_behavior_t flag)
-  {
-    return memcached_behavior_get(memc, flag);
-  }
-
-  /**
-   * Configure the memcache object
-   *
-   * @param[in] in_config configuration
-   * @return true on success; false otherwise
-   */
-  bool configure(const std::string &configuration)
-  {
-    memcached_st *new_memc= memcached(configuration.c_str(), configuration.size());
-
-    if (new_memc)
-    {
-      memcached_free(memc);
-      memc= new_memc;
-
-      return true;
-    }
-
-    return false;
-  }
-
-  /**
-   * Add a server to the list of memcached servers to use.
-   *
-   * @param[in] server_name name of the server to add
-   * @param[in] port port number of server to add
-   * @return true on success; false otherwise
-   */
-  bool addServer(const std::string &server_name, in_port_t port)
-  {
-    return memcached_success(memcached_server_add(memc, server_name.c_str(), port));
-  }
-
-  /**
-   * Remove a server from the list of memcached servers to use.
-   *
-   * @param[in] server_name name of the server to remove
-   * @param[in] port port number of server to remove
-   * @return true on success; false otherwise
-   */
-  bool removeServer(const std::string &server_name, in_port_t port)
-  {
-    std::string tmp_str;
-    std::ostringstream strstm;
-    tmp_str.append(",");
-    tmp_str.append(server_name);
-    tmp_str.append(":");
-    strstm << port;
-    tmp_str.append(strstm.str());
-
-    //memcached_return_t rc= memcached_server_remove(server);
-    
-    return false;
-  }
-
-  /**
-   * Fetches an individual value from the server. mget() must always
-   * be called before using this method.
-   *
-   * @param[in] key key of object to fetch
-   * @param[out] ret_val store returned object in this vector
-   * @return a memcached return structure
-   */
-  memcached_return_t fetch(std::string &key,
-                           std::vector<char> &ret_val,
-                           uint32_t &flags,
-                           uint64_t &cas_value)
-  {
-    memcached_return_t rc;
-
-    memcached_result_st *result;
-    if ((result= memcached_fetch_result(memc, NULL, &rc)))
-    {
-      // Key
-      key.assign(memcached_result_key_value(result), memcached_result_key_length(result));
-
-      // Actual value, null terminated
-      ret_val.reserve(memcached_result_length(result) +1);
-      ret_val.assign(memcached_result_value(result), 
-                     memcached_result_value(result) +memcached_result_length(result));
-
-      // Misc
-      flags= memcached_result_flags(result);
-      cas_value= memcached_result_cas(result);
-    }
-    memcached_result_free(result);
-
-    return rc;
-  }
-
-  memcached_return_t fetch(std::string &key,
-                           std::vector<char> &ret_val)
-  {
-    uint32_t flags= 0;
-    uint64_t cas_value= 0;
-
-    return fetch(key, ret_val, flags, cas_value);
-  }
-
-  /**
-   * Fetches an individual value from the server.
-   *
-   * @param[in] key key of object whose value to get
-   * @param[out] ret_val object that is retrieved is stored in
-   *                     this vector
-   * @return true on success; false otherwise
-   */
-  bool get(const std::string &key, std::vector<char> &ret_val)
-  {
-    uint32_t flags= 0;
-    memcached_return_t rc;
-    size_t value_length= 0;
-
-    char *value= memcached_get(memc, key.c_str(), key.length(),
-                               &value_length, &flags, &rc);
-    if (value != NULL && ret_val.empty())
-    {
-      ret_val.reserve(value_length);
-      ret_val.assign(value, value + value_length);
-      free(value);
-      return true;
-    }
-
-    return false;
-  }
-
-  /**
-   * Fetches an individual from a server which is specified by
-   * the master_key parameter that is used for determining which
-   * server an object was stored in if key partitioning was
-   * used for storage.
-   *
-   * @param[in] master_key key that specifies server object is stored on
-   * @param[in] key key of object whose value to get
-   * @param[out] ret_val object that is retrieved is stored in
-   *                     this vector
-   * @return true on success; false otherwise
-   */
-  bool getByKey(const std::string &master_key,
-                const std::string &key,
-                std::vector<char> &ret_val)
-  {
-    uint32_t flags= 0;
-    memcached_return_t rc;
-    size_t value_length= 0;
-
-    char *value= memcached_get_by_key(memc,
-                                      master_key.c_str(), master_key.length(),
-                                      key.c_str(), key.length(),
-                                      &value_length, &flags, &rc);
-    if (value)
-    {
-      ret_val.reserve(value_length);
-      ret_val.assign(value, value + value_length);
-      free(value);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Selects multiple keys at once. This method always
-   * works asynchronously.
-   *
-   * @param[in] keys vector of keys to select
-   * @return true if all keys are found
-   */
-  bool mget(std::vector<std::string> &keys)
-  {
-    std::vector<const char *> real_keys;
-    std::vector<size_t> key_len;
-    /*
-     * Construct an array which will contain the length
-     * of each of the strings in the input vector. Also, to
-     * interface with the memcached C API, we need to convert
-     * the vector of std::string's to a vector of char *.
-     */
-    real_keys.reserve(keys.size());
-    key_len.reserve(keys.size());
-
-    std::vector<std::string>::iterator it= keys.begin();
-
-    while (it != keys.end())
-    {
-      real_keys.push_back(const_cast<char *>((*it).c_str()));
-      key_len.push_back((*it).length());
-      ++it;
-    }
-
-    /*
-     * If the std::vector of keys is empty then we cannot
-     * call memcached_mget as we will get undefined behavior.
-     */
-    if (not real_keys.empty())
-    {
-      return memcached_success(memcached_mget(memc, &real_keys[0], &key_len[0], real_keys.size()));
-    }
-
-    return false;
-  }
-
-  /**
-   * Writes an object to the server. If the object already exists, it will
-   * overwrite the existing object. This method always returns true
-   * when using non-blocking mode unless a network error occurs.
-   *
-   * @param[in] key key of object to write to server
-   * @param[in] value value of object to write to server
-   * @param[in] expiration time to keep the object stored in the server for
-   * @param[in] flags flags to store with the object
-   * @return true on succcess; false otherwise
-   */
-  bool set(const std::string &key,
-           const std::vector<char> &value,
-           time_t expiration,
-           uint32_t flags)
-  {
-    memcached_return_t rc= memcached_set(memc,
-                                         key.c_str(), key.length(),
-                                         &value[0], value.size(),
-                                         expiration, flags);
-    return memcached_success(rc);
-  }
-
-  /**
-   * Writes an object to a server specified by the master_key parameter.
-   * If the object already exists, it will overwrite the existing object.
-   *
-   * @param[in] master_key key that specifies server to write to
-   * @param[in] key key of object to write to server
-   * @param[in] value value of object to write to server
-   * @param[in] expiration time to keep the object stored in the server for
-   * @param[in] flags flags to store with the object
-   * @return true on succcess; false otherwise
-   */
-  bool setByKey(const std::string &master_key,
-                const std::string &key,
-                const std::vector<char> &value,
-                time_t expiration,
-                uint32_t flags)
-  {
-    return memcached_success(memcached_set_by_key(memc, master_key.c_str(),
-                                                  master_key.length(),
-                                                  key.c_str(), key.length(),
-                                                  &value[0], value.size(),
-                                                  expiration,
-                                                  flags));
-  }
-
-  /**
-   * Writes a list of objects to the server. Objects are specified by
-   * 2 vectors - 1 vector of keys and 1 vector of values.
-   *
-   * @param[in] keys vector of keys of objects to write to server
-   * @param[in] values vector of values of objects to write to server
-   * @param[in] expiration time to keep the objects stored in server for
-   * @param[in] flags flags to store with the objects
-   * @return true on success; false otherwise
-   */
-  bool setAll(std::vector<std::string> &keys,
-              std::vector< std::vector<char> *> &values,
-              time_t expiration,
-              uint32_t flags)
-  {
-    bool retval= true;
-    std::vector<std::string>::iterator key_it= keys.begin();
-    std::vector< std::vector<char> *>::iterator val_it= values.begin();
-    while (key_it != keys.end())
-    {
-      retval= set((*key_it), *(*val_it), expiration, flags);
-      if (retval == false)
-      {
-        return retval;
-      }
-      ++key_it;
-      ++val_it;
-    }
-    return retval;
-  }
-
-  /**
-   * Writes a list of objects to the server. Objects are specified by
-   * a map of keys to values.
-   *
-   * @param[in] key_value_map map of keys and values to store in server
-   * @param[in] expiration time to keep the objects stored in server for
-   * @param[in] flags flags to store with the objects
-   * @return true on success; false otherwise
-   */
-  bool setAll(std::map<const std::string, std::vector<char> > &key_value_map,
-              time_t expiration,
-              uint32_t flags)
-  {
-    bool retval= true;
-    std::map<const std::string, std::vector<char> >::iterator it= key_value_map.begin();
-
-    while (it != key_value_map.end())
-    {
-      retval= set(it->first, it->second, expiration, flags);
-      if (retval == false)
-      {
-        // We should tell the user what the key that failed was
-        return false;
-      }
-      ++it;
-    }
-    return true;
-  }
-
-  /**
-   * Increment the value of the object associated with the specified
-   * key by the offset given. The resulting value is saved in the value
-   * parameter.
-   *
-   * @param[in] key key of object in server whose value to increment
-   * @param[in] offset amount to increment object's value by
-   * @param[out] value store the result of the increment here
-   * @return true on success; false otherwise
-   */
-  bool increment(const std::string &key, uint32_t offset, uint64_t *value)
-  {
-    return memcached_success(memcached_increment(memc, key.c_str(), key.length(), offset, value));
-  }
-
-  /**
-   * Decrement the value of the object associated with the specified
-   * key by the offset given. The resulting value is saved in the value
-   * parameter.
-   *
-   * @param[in] key key of object in server whose value to decrement
-   * @param[in] offset amount to increment object's value by
-   * @param[out] value store the result of the decrement here
-   * @return true on success; false otherwise
-   */
-  bool decrement(const std::string &key, uint32_t offset, uint64_t *value)
-  {
-    return memcached_success(memcached_decrement(memc, key.c_str(),
-                                                 key.length(),
-                                                 offset, value));
-  }
-
-
-  /**
-   * Add an object with the specified key and value to the server. This
-   * function returns false if the object already exists on the server.
-   *
-   * @param[in] key key of object to add
-   * @param[in] value of object to add
-   * @return true on success; false otherwise
-   */
-  bool add(const std::string &key, const std::vector<char> &value)
-  {
-    return memcached_success(memcached_add(memc, key.c_str(), key.length(),
-                                           &value[0], value.size(), 0, 0));
-  }
-
-  /**
-   * Add an object with the specified key and value to the server. This
-   * function returns false if the object already exists on the server. The
-   * server to add the object to is specified by the master_key parameter.
-   *
-   * @param[in[ master_key key of server to add object to
-   * @param[in] key key of object to add
-   * @param[in] value of object to add
-   * @return true on success; false otherwise
-   */
-  bool addByKey(const std::string &master_key,
-                const std::string &key,
-                const std::vector<char> &value)
-  {
-    return memcached_success(memcached_add_by_key(memc,
-                                                  master_key.c_str(),
-                                                  master_key.length(),
-                                                  key.c_str(),
-                                                  key.length(),
-                                                  &value[0],
-                                                  value.size(),
-                                                  0, 0));
-  }
-
-  /**
-   * Replaces an object on the server. This method only succeeds
-   * if the object is already present on the server.
-   *
-   * @param[in] key key of object to replace
-   * @param[in[ value value to replace object with
-   * @return true on success; false otherwise
-   */
-  bool replace(const std::string &key, const std::vector<char> &value)
-  {
-    return memcached_success(memcached_replace(memc, key.c_str(), key.length(),
-                                               &value[0], value.size(),
-                                               0, 0));
-  }
-
-  /**
-   * Replaces an object on the server. This method only succeeds
-   * if the object is already present on the server. The server
-   * to replace the object on is specified by the master_key param.
-   *
-   * @param[in] master_key key of server to replace object on
-   * @param[in] key key of object to replace
-   * @param[in[ value value to replace object with
-   * @return true on success; false otherwise
-   */
-  bool replaceByKey(const std::string &master_key,
-                    const std::string &key,
-                    const std::vector<char> &value)
-  {
-    return memcached_success(memcached_replace_by_key(memc,
-                                                      master_key.c_str(),
-                                                      master_key.length(),
-                                                      key.c_str(),
-                                                      key.length(),
-                                                      &value[0],
-                                                      value.size(),
-                                                      0, 0));
-  }
-
-  /**
-   * Places a segment of data before the last piece of data stored.
-   *
-   * @param[in] key key of object whose value we will prepend data to
-   * @param[in] value data to prepend to object's value
-   * @return true on success; false otherwise
-   */
-  bool prepend(const std::string &key, const std::vector<char> &value)
-  {
-    return memcached_success(memcached_prepend(memc, key.c_str(), key.length(),
-                                               &value[0], value.size(), 0, 0));
-  }
-
-  /**
-   * Places a segment of data before the last piece of data stored. The
-   * server on which the object where we will be prepending data is stored
-   * on is specified by the master_key parameter.
-   *
-   * @param[in] master_key key of server where object is stored
-   * @param[in] key key of object whose value we will prepend data to
-   * @param[in] value data to prepend to object's value
-   * @return true on success; false otherwise
-   */
-  bool prependByKey(const std::string &master_key,
-                    const std::string &key,
-                    const std::vector<char> &value)
-  {
-    return memcached_success(memcached_prepend_by_key(memc,
-                                                      master_key.c_str(),
-                                                      master_key.length(),
-                                                      key.c_str(),
-                                                      key.length(),
-                                                      &value[0],
-                                                      value.size(),
-                                                      0,
-                                                      0));
-  }
-
-  /**
-   * Places a segment of data at the end of the last piece of data stored.
-   *
-   * @param[in] key key of object whose value we will append data to
-   * @param[in] value data to append to object's value
-   * @return true on success; false otherwise
-   */
-  bool append(const std::string &key, const std::vector<char> &value)
-  {
-    return memcached_success(memcached_append(memc,
-                                              key.c_str(),
-                                              key.length(),
-                                              &value[0],
-                                              value.size(),
-                                              0, 0));
-  }
-
-  /**
-   * Places a segment of data at the end of the last piece of data stored. The
-   * server on which the object where we will be appending data is stored
-   * on is specified by the master_key parameter.
-   *
-   * @param[in] master_key key of server where object is stored
-   * @param[in] key key of object whose value we will append data to
-   * @param[in] value data to append to object's value
-   * @return true on success; false otherwise
-   */
-  bool appendByKey(const std::string &master_key,
-                   const std::string &key,
-                   const std::vector<char> &value)
-  {
-    return memcached_success(memcached_append_by_key(memc,
-                                                     master_key.c_str(),
-                                                     master_key.length(),
-                                                     key.c_str(),
-                                                     key.length(),
-                                                     &value[0],
-                                                     value.size(),
-                                                     0, 0));
-  }
-
-  /**
-   * Overwrite data in the server as long as the cas_arg value
-   * is still the same in the server.
-   *
-   * @param[in] key key of object in server
-   * @param[in] value value to store for object in server
-   * @param[in] cas_arg "cas" value
-   */
-  bool cas(const std::string &key,
-           const std::vector<char> &value,
-           uint64_t cas_arg)
-  {
-    return memcached_success(memcached_cas(memc, key.c_str(), key.length(),
-                                           &value[0], value.size(),
-                                           0, 0, cas_arg));
-  }
-
-  /**
-   * Overwrite data in the server as long as the cas_arg value
-   * is still the same in the server. The server to use is
-   * specified by the master_key parameter.
-   *
-   * @param[in] master_key specifies server to operate on
-   * @param[in] key key of object in server
-   * @param[in] value value to store for object in server
-   * @param[in] cas_arg "cas" value
-   */
-  bool casByKey(const std::string &master_key,
-                const std::string &key,
-                const std::vector<char> &value,
-                uint64_t cas_arg)
-  {
-    return memcached_success(memcached_cas_by_key(memc,
-                                                  master_key.c_str(),
-                                                  master_key.length(),
-                                                  key.c_str(),
-                                                  key.length(),
-                                                  &value[0],
-                                                  value.size(),
-                                                  0, 0, cas_arg));
-  }
-
-  /**
-   * Delete an object from the server specified by the key given.
-   *
-   * @param[in] key key of object to delete
-   * @return true on success; false otherwise
-   */
-  bool remove(const std::string &key)
-  {
-    return memcached_success(memcached_delete(memc, key.c_str(), key.length(), 0));
-  }
-
-  /**
-   * Delete an object from the server specified by the key given.
-   *
-   * @param[in] key key of object to delete
-   * @param[in] expiration time to delete the object after
-   * @return true on success; false otherwise
-   */
-  bool remove(const std::string &key, time_t expiration)
-  {
-    return memcached_success(memcached_delete(memc,
-                                              key.c_str(),
-                                              key.length(),
-                                              expiration));
-  }
-
-  /**
-   * Delete an object from the server specified by the key given.
-   *
-   * @param[in] master_key specifies server to remove object from
-   * @param[in] key key of object to delete
-   * @return true on success; false otherwise
-   */
-  bool removeByKey(const std::string &master_key,
-                   const std::string &key)
-  {
-    return memcached_success(memcached_delete_by_key(memc,
-                                                     master_key.c_str(),
-                                                     master_key.length(),
-                                                     key.c_str(),
-                                                     key.length(),
-                                                     0));
-  }
-
-  /**
-   * Delete an object from the server specified by the key given.
-   *
-   * @param[in] master_key specifies server to remove object from
-   * @param[in] key key of object to delete
-   * @param[in] expiration time to delete the object after
-   * @return true on success; false otherwise
-   */
-  bool removeByKey(const std::string &master_key,
-                   const std::string &key,
-                   time_t expiration)
-  {
-    return memcached_success(memcached_delete_by_key(memc,
-                                                     master_key.c_str(),
-                                                     master_key.length(),
-                                                     key.c_str(),
-                                                     key.length(),
-                                                     expiration));
-  }
-
-  /**
-   * Wipe the contents of memcached servers.
-   *
-   * @param[in] expiration time to wait until wiping contents of
-   *                       memcached servers
-   * @return true on success; false otherwise
-   */
-  bool flush(time_t expiration= 0)
-  {
-    return memcached_success(memcached_flush(memc, expiration));
-  }
-
-  /**
-   * Get the library version string.
-   * @return std::string containing a copy of the library version string.
-   */
-  const std::string libVersion() const
-  {
-    const char *ver= memcached_lib_version();
-    const std::string version(ver);
-    return version;
-  }
-
-  /**
-   * Retrieve memcached statistics. Populate a std::map with the retrieved
-   * stats. Each server will map to another std::map of the key:value stats.
-   *
-   * @param[out] stats_map a std::map to be populated with the memcached
-   *                       stats
-   * @return true on success; false otherwise
-   */
-  bool getStats(std::map< std::string, std::map<std::string, std::string> >
-                &stats_map)
-  {
-    memcached_return_t rc;
-    memcached_stat_st *stats= memcached_stat(memc, NULL, &rc);
-
-    if (rc != MEMCACHED_SUCCESS &&
-        rc != MEMCACHED_SOME_ERRORS)
-    {
-      return false;
-    }
-
-    uint32_t server_count= memcached_server_count(memc);
-
-    /*
-     * For each memcached server, construct a std::map for its stats and add
-     * it to the std::map of overall stats.
-     */
-    for (uint32_t x= 0; x < server_count; x++)
-    {
-      memcached_server_instance_st instance=
-        memcached_server_instance_by_position(memc, x);
-      std::ostringstream strstm;
-      std::string server_name(memcached_server_name(instance));
-      server_name.append(":");
-      strstm << memcached_server_port(instance);
-      server_name.append(strstm.str());
-
-      std::map<std::string, std::string> server_stats;
-      char **list= NULL;
-      char **ptr= NULL;
-
-      list= memcached_stat_get_keys(memc, &stats[x], &rc);
-      for (ptr= list; *ptr; ptr++)
-      {
-        char *value= memcached_stat_get_value(memc, &stats[x], *ptr, &rc);
-        server_stats[*ptr]= value;
-        free(value);
-      }
-     
-      stats_map[server_name]= server_stats;
-      free(list);
-    }
-
-    memcached_stat_free(memc, stats);
-    return true;
-  }
-
-private:
-  memcached_st *memc;
-};
+#include <libmemcached-1.0/memcached.hpp>
 
-}
index 7a253ae7d616e80309507afc0834beb092290cd9..ad6202e8d0060ce71ccb6aad586c1a0e2bafb25b 100644 (file)
@@ -122,6 +122,8 @@ extern "C"
         PROTOCOL_BINARY_CMD_TOUCH = 0x1c,
         PROTOCOL_BINARY_CMD_GAT = 0x1d,
         PROTOCOL_BINARY_CMD_GATQ = 0x1e,
+        PROTOCOL_BINARY_CMD_GATK = 0x23,
+        PROTOCOL_BINARY_CMD_GATKQ = 0x24,
 
         PROTOCOL_BINARY_CMD_SASL_LIST_MECHS = 0x20,
         PROTOCOL_BINARY_CMD_SASL_AUTH = 0x21,
diff --git a/libmemcached/memcached_util.h b/libmemcached/memcached_util.h
deleted file mode 100644 (file)
index c0a4620..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-
-#include <libmemcached/util/pid.h>
-#include <libmemcached/util/flush.h>
-#include <libmemcached/util/ping.h>
-#include <libmemcached/util/pool.h>
-#include <libmemcached/util/version.h>
index 015c024dcf48517daf59103d59d501d24d67f488..04622571d569edfac74d7886006bc6d0434cb4ef 100644 (file)
@@ -44,7 +44,7 @@ extern "C" {
 LIBMEMCACHED_LOCAL
   memcached_return_t memcached_set_namespace(memcached_st *self, const char *str, size_t length);
 
-LIBMEMCACHED_API
+LIBMEMCACHED_LOCAL
   const char * memcached_get_namespace(memcached_st *self);
 
 #ifdef __cplusplus
diff --git a/libmemcached/options.h b/libmemcached/options.h
deleted file mode 100644 (file)
index f5a6e06..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-  memcached_return_t libmemcached_check_configuration(const char *option_string, size_t length, char *error_buffer, size_t error_buffer_size);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/parse.h b/libmemcached/parse.h
deleted file mode 100644 (file)
index a91f769..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* LibMemcached
- * Copyright (C) 2010 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- *
- * Summary: Work with fetching results
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_server_list_st memcached_servers_parse(const char *server_strings);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/platform.h b/libmemcached/platform.h
deleted file mode 100644 (file)
index 1924828..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker, Trond Norbye All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-
-#ifdef WIN32
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-typedef short in_port_t;
-typedef SOCKET memcached_socket_t;
-#else
-typedef int memcached_socket_t;
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/un.h>
-#include <netinet/tcp.h>
-
-#endif /* WIN32 */
diff --git a/libmemcached/protocol/ascii_handler.c b/libmemcached/protocol/ascii_handler.c
deleted file mode 100644 (file)
index 2cceff2..0000000
+++ /dev/null
@@ -1,961 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <libmemcached/protocol/common.h>
-#include <libmemcached/byteorder.h>
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/**
- * Try to parse a key from the string.
- * @pointer start pointer to a pointer to the string (IN and OUT)
- * @return length of the string of -1 if this was an illegal key (invalid
- *         characters or invalid length)
- * @todo add length!
- */
-static uint16_t parse_ascii_key(char **start)
-{
-  uint16_t len= 0;
-  char *c= *start;
-  /* Strip leading whitespaces */
-  while (isspace(*c))
-  {
-    ++c;
-  }
-
-  *start= c;
-
-  while (*c != '\0' && !isspace(*c) && !iscntrl(*c))
-  {
-    ++c;
-    ++len;
-  }
-
-
-  if (len == 0 || len > 240 || (*c != '\0' && *c != '\r' && iscntrl(*c)))
-  {
-    return 0;
-  }
-
-  return len;
-}
-
-/**
- * Spool a zero-terminated string
- * @param client destination
- * @param text the text to spool
- * @return status of the spool operation
- */
-static protocol_binary_response_status
-spool_string(memcached_protocol_client_st *client, const char *text)
-{
-  return client->root->spool(client, text, strlen(text));
-}
-
-/**
- * Send a "CLIENT_ERROR" message back to the client with the correct
- * format of the command being sent
- * @param client the client to send the message to
- */
-static void send_command_usage(memcached_protocol_client_st *client)
-{
-  const char *errmsg[]= {
-    [GET_CMD]= "CLIENT_ERROR: Syntax error: get <key>*\r\n",
-    [GETS_CMD]= "CLIENT_ERROR: Syntax error: gets <key>*\r\n",
-    [SET_CMD]= "CLIENT_ERROR: Syntax error: set <key> <flags> <exptime> <bytes> [noreply]\r\n",
-    [ADD_CMD]= "CLIENT_ERROR: Syntax error: add <key> <flags> <exptime> <bytes> [noreply]\r\n",
-    [REPLACE_CMD]= "CLIENT_ERROR: Syntax error: replace <key> <flags> <exptime> <bytes> [noreply]\r\n",
-    [CAS_CMD]= "CLIENT_ERROR: Syntax error: cas <key> <flags> <exptime> <bytes> <casid> [noreply]\r\n",
-    [APPEND_CMD]= "CLIENT_ERROR: Syntax error: append <key> <flags> <exptime> <bytes> [noreply]\r\n",
-    [PREPEND_CMD]= "CLIENT_ERROR: Syntax error: prepend <key> <flags> <exptime> <bytes> [noreply]\r\n",
-    [DELETE_CMD]= "CLIENT_ERROR: Syntax error: delete <key> [noreply]\r\n",
-    [INCR_CMD]= "CLIENT_ERROR: Syntax error: incr <key> <value> [noreply]\r\n",
-    [DECR_CMD]= "CLIENT_ERROR: Syntax error: decr <key> <value> [noreply]\r\n",
-    [STATS_CMD]= "CLIENT_ERROR: Syntax error: stats [key]\r\n",
-    [FLUSH_ALL_CMD]= "CLIENT_ERROR: Syntax error: flush_all [timeout] [noreply]\r\n",
-    [VERSION_CMD]= "CLIENT_ERROR: Syntax error: version\r\n",
-    [QUIT_CMD]="CLIENT_ERROR: Syntax error: quit\r\n",
-
-    [VERBOSITY_CMD]= "CLIENT_ERROR: Syntax error: verbosity <num>\r\n",
-    [UNKNOWN_CMD]= "CLIENT_ERROR: Unknown command\r\n",
-  };
-
-  client->mute = false;
-  spool_string(client, errmsg[client->ascii_command]);
-}
-
-/**
- * Callback for the VERSION responses
- * @param cookie client identifier
- * @param text the length of the body
- * @param textlen the length of the body
- */
-static protocol_binary_response_status
-ascii_version_response_handler(const void *cookie,
-                               const void *text,
-                               uint32_t textlen)
-{
-  memcached_protocol_client_st *client= (memcached_protocol_client_st*)cookie;
-  spool_string(client, "VERSION ");
-  client->root->spool(client, text, textlen);
-  spool_string(client, "\r\n");
-  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
-}
-
-/**
- * Callback for the GET/GETQ/GETK and GETKQ responses
- * @param cookie client identifier
- * @param key the key for the item
- * @param keylen the length of the key
- * @param body the length of the body
- * @param bodylen the length of the body
- * @param flags the flags for the item
- * @param cas the CAS id for the item
- */
-static protocol_binary_response_status
-ascii_get_response_handler(const void *cookie,
-                           const void *key,
-                           uint16_t keylen,
-                           const void *body,
-                           uint32_t bodylen,
-                           uint32_t flags,
-                           uint64_t cas)
-{
-  memcached_protocol_client_st *client= (void*)cookie;
-  char buffer[300];
-  strcpy(buffer, "VALUE ");
-  const char *source= key;
-  char *dest= buffer + 6;
-
-  for (int x= 0; x < keylen; ++x)
-  {
-    if (*source != '\0' && !isspace(*source) && !iscntrl(*source))
-    {
-      *dest= *source;
-    }
-    else
-    {
-      return PROTOCOL_BINARY_RESPONSE_EINVAL; /* key constraints in ascii */
-    }
-
-    ++dest;
-    ++source;
-  }
-
-  size_t used= (size_t)(dest - buffer);
-
-  if (client->ascii_command == GETS_CMD)
-  {
-    snprintf(dest, sizeof(buffer) - used, " %u %u %" PRIu64 "\r\n", flags,
-             bodylen, cas);
-  }
-  else
-  {
-    snprintf(dest, sizeof(buffer) - used, " %u %u\r\n", flags, bodylen);
-  }
-
-  client->root->spool(client, buffer, strlen(buffer));
-  client->root->spool(client, body, bodylen);
-  client->root->spool(client, "\r\n", 2);
-
-  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
-}
-
-/**
- * Callback for the STAT responses
- * @param cookie client identifier
- * @param key the key for the item
- * @param keylen the length of the key
- * @param body the length of the body
- * @param bodylen the length of the body
- */
-static protocol_binary_response_status
-ascii_stat_response_handler(const void *cookie,
-                     const void *key,
-                     uint16_t keylen,
-                     const void *body,
-                     uint32_t bodylen)
-{
-
-  memcached_protocol_client_st *client= (void*)cookie;
-
-  if (key != NULL)
-  {
-    spool_string(client, "STAT ");
-    client->root->spool(client, key, keylen);
-    spool_string(client, " ");
-    client->root->spool(client, body, bodylen);
-    spool_string(client, "\r\n");
-  }
-  else
-  {
-    spool_string(client, "END\r\n");
-  }
-
-  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
-}
-
-/**
- * Process a get or a gets request.
- * @param client the client handle
- * @param buffer the complete get(s) command
- * @param end the last character in the command
- */
-static void ascii_process_gets(memcached_protocol_client_st *client,
-                               char *buffer, char *end)
-{
-  char *key= buffer;
-
-  /* Skip command */
-  key += (client->ascii_command == GETS_CMD) ? 5 : 4;
-
-  int num_keys= 0;
-  while (key < end)
-  {
-    uint16_t nkey= parse_ascii_key(&key);
-    if (nkey == 0) /* Invalid key... stop processing this line */
-    {
-      break;
-    }
-
-    (void)client->root->callback->interface.v1.get(client, key, nkey,
-                                                   ascii_get_response_handler);
-    key += nkey;
-    ++num_keys;
-  }
-
-  if (num_keys == 0)
-  {
-    send_command_usage(client);
-  }
-  else
-    client->root->spool(client, "END\r\n", 5);
-}
-
-/**
- * Try to split up the command line "asdf asdf asdf asdf\n" into an
- * argument vector for easier parsing.
- * @param start the first character in the command line
- * @param end the last character in the command line ("\n")
- * @param vec the vector to insert the pointers into
- * @size the number of elements in the vector
- * @return the number of tokens in the vector
- */
-static int ascii_tokenize_command(char *str, char *end, char **vec, int size)
-{
-  int elem= 0;
-
-  while (str < end)
-  {
-    /* Skip leading blanks */
-    while (str < end && isspace(*str))
-    {
-      ++str;
-    }
-
-    if (str == end)
-    {
-      return elem;
-    }
-
-    vec[elem++]= str;
-    /* find the next non-blank field */
-    while (str < end && !isspace(*str))
-    {
-      ++str;
-    }
-
-    /* zero-terminate it for easier parsing later on */
-    *str= '\0';
-    ++str;
-
-    /* Is the vector full? */
-    if (elem == size)
-    {
-      break;
-    }
-  }
-
-  return elem;
-}
-
-/**
- * If we for some reasons needs to push the line back to read more
- * data we have to reverse the tokenization. Just do the brain-dead replace
- * of all '\0' to ' ' and set the last character to '\n'. We could have used
- * the vector we created, but then we would have to search for all of the
- * spaces we ignored...
- * @param start pointer to the first character in the buffer to recover
- * @param end pointer to the last character in the buffer to recover
- */
-static void recover_tokenize_command(char *start, char *end)
-{
-  while (start < end)
-  {
-    if (*start == '\0')
-      *start= ' ';
-    ++start;
-  }
-
-  *end= '\n';
-}
-
-/**
- * Convert the textual command into a comcode
- */
-static enum ascii_cmd ascii_to_cmd(char *start, size_t length)
-{
-  struct {
-    const char *cmd;
-    size_t len;
-    enum ascii_cmd cc;
-  } commands[]= {
-    { .cmd= "get", .len= 3, .cc= GET_CMD },
-    { .cmd= "gets", .len= 4, .cc= GETS_CMD },
-    { .cmd= "set", .len= 3, .cc= SET_CMD },
-    { .cmd= "add", .len= 3, .cc= ADD_CMD },
-    { .cmd= "replace", .len= 7, .cc= REPLACE_CMD },
-    { .cmd= "cas", .len= 3, .cc= CAS_CMD },
-    { .cmd= "append", .len= 6, .cc= APPEND_CMD },
-    { .cmd= "prepend", .len= 7, .cc= PREPEND_CMD },
-    { .cmd= "delete", .len= 6, .cc= DELETE_CMD },
-    { .cmd= "incr", .len= 4, .cc= INCR_CMD },
-    { .cmd= "decr", .len= 4, .cc= DECR_CMD },
-    { .cmd= "stats", .len= 5, .cc= STATS_CMD },
-    { .cmd= "flush_all", .len= 9, .cc= FLUSH_ALL_CMD },
-    { .cmd= "version", .len= 7, .cc= VERSION_CMD },
-    { .cmd= "quit", .len= 4, .cc= QUIT_CMD },
-    { .cmd= "verbosity", .len= 9, .cc= VERBOSITY_CMD },
-    { .cmd= NULL, .len= 0, .cc= UNKNOWN_CMD }};
-
-  int x= 0;
-  while (commands[x].len > 0) {
-    if (length >= commands[x].len)
-    {
-      if (strncmp(start, commands[x].cmd, commands[x].len) == 0)
-      {
-        /* Potential hit */
-        if (length == commands[x].len || isspace(*(start + commands[x].len)))
-        {
-          return commands[x].cc;
-        }
-      }
-    }
-    ++x;
-  }
-
-  return UNKNOWN_CMD;
-}
-
-/**
- * Perform a delete operation.
- *
- * @param client client requesting the deletion
- * @param tokens the command as a vector
- * @param ntokens the number of items in the vector
- */
-static void process_delete(memcached_protocol_client_st *client,
-                           char **tokens, int ntokens)
-{
-  char *key= tokens[1];
-  uint16_t nkey;
-
-  if (ntokens != 2 || (nkey= parse_ascii_key(&key)) == 0)
-  {
-    send_command_usage(client);
-    return;
-  }
-
-  if (client->root->callback->interface.v1.delete == NULL)
-  {
-    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-    return;
-  }
-
-  protocol_binary_response_status rval;
-  rval= client->root->callback->interface.v1.delete(client, key, nkey, 0);
-
-  if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
-  {
-    spool_string(client, "DELETED\r\n");
-  }
-  else if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT)
-  {
-    spool_string(client, "NOT_FOUND\r\n");
-  }
-  else
-  {
-    char msg[80];
-    snprintf(msg, sizeof(msg), "SERVER_ERROR: delete failed %u\r\n",(uint32_t)rval);
-    spool_string(client, msg);
-  }
-}
-
-static void process_arithmetic(memcached_protocol_client_st *client,
-                               char **tokens, int ntokens)
-{
-  char *key= tokens[1];
-  uint16_t nkey;
-
-  if (ntokens != 3 || (nkey= parse_ascii_key(&key)) == 0)
-  {
-    send_command_usage(client);
-    return;
-  }
-
-  uint64_t cas;
-  uint64_t result;
-  uint64_t delta= strtoull(tokens[2], NULL, 10);
-
-  protocol_binary_response_status rval;
-  if (client->ascii_command == INCR_CMD)
-  {
-    if (client->root->callback->interface.v1.increment == NULL)
-    {
-      spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-      return;
-    }
-    rval= client->root->callback->interface.v1.increment(client,
-                                                         key, nkey,
-                                                         delta, 0,
-                                                         0,
-                                                         &result,
-                                                         &cas);
-  }
-  else
-  {
-    if (client->root->callback->interface.v1.decrement == NULL)
-    {
-      spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-      return;
-    }
-    rval= client->root->callback->interface.v1.decrement(client,
-                                                         key, nkey,
-                                                         delta, 0,
-                                                         0,
-                                                         &result,
-                                                         &cas);
-  }
-
-  if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
-  {
-    char buffer[80];
-    snprintf(buffer, sizeof(buffer), "%"PRIu64"\r\n", result);
-    spool_string(client, buffer);
-  }
-  else
-  {
-    spool_string(client, "NOT_FOUND\r\n");
-  }
-}
-
-/**
- * Process the stats command (with or without a key specified)
- * @param key pointer to the first character after "stats"
- * @param end pointer to the "\n"
- */
-static void process_stats(memcached_protocol_client_st *client,
-                          char *key, char *end)
-{
-  if (client->root->callback->interface.v1.stat == NULL)
-  {
-    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-    return;
-  }
-
-  while (isspace(*key))
-    key++;
-
-  uint16_t nkey= (uint16_t)(end - key);
-  (void)client->root->callback->interface.v1.stat(client, key, nkey,
-                                                  ascii_stat_response_handler);
-}
-
-static void process_version(memcached_protocol_client_st *client,
-                            char **tokens, int ntokens)
-{
-  (void)tokens;
-  if (ntokens != 1)
-  {
-    send_command_usage(client);
-    return;
-  }
-
-  if (client->root->callback->interface.v1.version == NULL)
-  {
-    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-    return;
-  }
-
- client->root->callback->interface.v1.version(client,
-                                              ascii_version_response_handler);
-}
-
-static void process_flush(memcached_protocol_client_st *client,
-                          char **tokens, int ntokens)
-{
-  if (ntokens > 2)
-  {
-    send_command_usage(client);
-    return;
-  }
-
-  if (client->root->callback->interface.v1.flush == NULL)
-  {
-    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-    return;
-  }
-
-  uint32_t timeout= 0;
-  if (ntokens == 2)
-  {
-    timeout= (uint32_t)strtoul(tokens[1], NULL, 10);
-  }
-
-  protocol_binary_response_status rval;
-  rval= client->root->callback->interface.v1.flush(client, timeout);
-  if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
-    spool_string(client, "OK\r\n");
-  else
-    spool_string(client, "SERVER_ERROR: internal error\r\n");
-}
-
-/**
- * Process one of the storage commands
- * @param client the client performing the operation
- * @param tokens the command tokens
- * @param ntokens the number of tokens
- * @param start pointer to the first character in the line
- * @param end pointer to the pointer where the last character of this
- *            command is (IN and OUT)
- * @param length the number of bytes available
- * @return -1 if an error occurs (and we should just terminate the connection
- *            because we are out of sync)
- *         0 storage command completed, continue processing
- *         1 We need more data, so just go ahead and wait for more!
- */
-static inline int process_storage_command(memcached_protocol_client_st *client,
-                                     char **tokens, int ntokens, char *start,
-                                     char **end, ssize_t length)
-{
-  (void)ntokens; /* already checked */
-  char *key= tokens[1];
-  uint16_t nkey= parse_ascii_key(&key);
-  if (nkey == 0)
-  {
-    /* return error */
-    spool_string(client, "CLIENT_ERROR: bad key\r\n");
-    return -1;
-  }
-
-  uint32_t flags= (uint32_t)strtoul(tokens[2], NULL, 10);
-  uint32_t timeout= (uint32_t)strtoul(tokens[3], NULL, 10);
-  unsigned long nbytes= strtoul(tokens[4], NULL, 10);
-
-  /* Do we have all data? */
-  unsigned long need= nbytes + (unsigned long)((*end - start) + 1) + 2; /* \n\r\n */
-  if ((ssize_t)need > length)
-  {
-    /* Keep on reading */
-    recover_tokenize_command(start, *end);
-    return 1;
-  }
-
-  void *data= (*end) + 1;
-  uint64_t cas= 0;
-  uint64_t result_cas;
-  protocol_binary_response_status rval;
-  switch (client->ascii_command)
-  {
-  case SET_CMD:
-    rval= client->root->callback->interface.v1.set(client, key,
-                                                   (uint16_t)nkey,
-                                                   data,
-                                                   (uint32_t)nbytes,
-                                                   flags,
-                                                   timeout, cas,
-                                                   &result_cas);
-    break;
-  case ADD_CMD:
-    rval= client->root->callback->interface.v1.add(client, key,
-                                                   (uint16_t)nkey,
-                                                   data,
-                                                   (uint32_t)nbytes,
-                                                   flags,
-                                                   timeout, &result_cas);
-    break;
-  case CAS_CMD:
-    cas= strtoull(tokens[5], NULL, 10);
-    /* FALLTHROUGH */
-  case REPLACE_CMD:
-    rval= client->root->callback->interface.v1.replace(client, key,
-                                                       (uint16_t)nkey,
-                                                       data,
-                                                       (uint32_t)nbytes,
-                                                       flags,
-                                                       timeout, cas,
-                                                       &result_cas);
-    break;
-  case APPEND_CMD:
-    rval= client->root->callback->interface.v1.append(client, key,
-                                                      (uint16_t)nkey,
-                                                      data,
-                                                      (uint32_t)nbytes,
-                                                      cas,
-                                                      &result_cas);
-    break;
-  case PREPEND_CMD:
-    rval= client->root->callback->interface.v1.prepend(client, key,
-                                                       (uint16_t)nkey,
-                                                       data,
-                                                       (uint32_t)nbytes,
-                                                       cas,
-                                                       &result_cas);
-    break;
-
-    /* gcc complains if I don't put all of the enums in here.. */
-  case GET_CMD:
-  case GETS_CMD:
-  case DELETE_CMD:
-  case DECR_CMD:
-  case INCR_CMD:
-  case STATS_CMD:
-  case FLUSH_ALL_CMD:
-  case VERSION_CMD:
-  case QUIT_CMD:
-  case VERBOSITY_CMD:
-  case UNKNOWN_CMD:
-  default:
-    abort(); /* impossible */
-  }
-
-  if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
-  {
-    spool_string(client, "STORED\r\n");
-  }
-  else
-  {
-    if (client->ascii_command == CAS_CMD)
-    {
-      if (rval == PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS)
-      {
-        spool_string(client, "EXISTS\r\n");
-      }
-      else if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT)
-      {
-        spool_string(client, "NOT_FOUND\r\n");
-      }
-      else
-      {
-        spool_string(client, "NOT_STORED\r\n");
-      }
-    }
-    else
-    {
-      spool_string(client, "NOT_STORED\r\n");
-    }
-  }
-
-  *end += nbytes + 2;
-
-  return 0;
-}
-
-static int process_cas_command(memcached_protocol_client_st *client,
-                                char **tokens, int ntokens, char *start,
-                                char **end, ssize_t length)
-{
-  if (ntokens != 6)
-  {
-    send_command_usage(client);
-    return false;
-  }
-
-  if (client->root->callback->interface.v1.replace == NULL)
-  {
-    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-    return false;
-  }
-
-  return process_storage_command(client, tokens, ntokens, start, end, length);
-}
-
-static int process_set_command(memcached_protocol_client_st *client,
-                                char **tokens, int ntokens, char *start,
-                                char **end, ssize_t length)
-{
-  if (ntokens != 5)
-  {
-    send_command_usage(client);
-    return false;
-  }
-
-  if (client->root->callback->interface.v1.set == NULL)
-  {
-    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-    return false;
-  }
-
-  return process_storage_command(client, tokens, ntokens, start, end, length);
-}
-
-static int process_add_command(memcached_protocol_client_st *client,
-                                char **tokens, int ntokens, char *start,
-                                char **end, ssize_t length)
-{
-  if (ntokens != 5)
-  {
-    send_command_usage(client);
-    return false;
-  }
-
-  if (client->root->callback->interface.v1.add == NULL)
-  {
-    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-    return false;
-  }
-
-  return process_storage_command(client, tokens, ntokens, start, end, length);
-}
-
-static int process_replace_command(memcached_protocol_client_st *client,
-                                    char **tokens, int ntokens, char *start,
-                                    char **end, ssize_t length)
-{
-  if (ntokens != 5)
-  {
-    send_command_usage(client);
-    return false;
-  }
-
-  if (client->root->callback->interface.v1.replace == NULL)
-  {
-    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-    return false;
-  }
-
-  return process_storage_command(client, tokens, ntokens, start, end, length);
-}
-
-static int process_append_command(memcached_protocol_client_st *client,
-                                   char **tokens, int ntokens, char *start,
-                                   char **end, ssize_t length)
-{
-  if (ntokens != 5)
-  {
-    send_command_usage(client);
-    return false;
-  }
-
-  if (client->root->callback->interface.v1.append == NULL)
-  {
-    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-    return false;
-  }
-
-  return process_storage_command(client, tokens, ntokens, start, end, length);
-}
-
-static int process_prepend_command(memcached_protocol_client_st *client,
-                                    char **tokens, int ntokens, char *start,
-                                    char **end, ssize_t length)
-{
-  if (ntokens != 5)
-  {
-    send_command_usage(client);
-    return false;
-  }
-
-  if (client->root->callback->interface.v1.prepend == NULL)
-  {
-    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
-    return false;
-  }
-
-  return process_storage_command(client, tokens, ntokens, start, end, length);
-}
-
-/**
- * The ASCII protocol support is just one giant big hack. Instead of adding
- * a optimal ascii support, I just convert the ASCII commands to the binary
- * protocol and calls back into the command handlers for the binary protocol ;)
- */
-memcached_protocol_event_t memcached_ascii_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr)
-{
-  char *ptr= (char*)client->root->input_buffer;
-  *endptr= ptr;
-
-  do {
-    /* Do we have \n (indicating the command preamble)*/
-    char *end= memchr(ptr, '\n', (size_t)*length);
-    if (end == NULL)
-    {
-      *endptr= ptr;
-      return MEMCACHED_PROTOCOL_READ_EVENT;
-    }
-
-    client->ascii_command= ascii_to_cmd(ptr, (size_t)(*length));
-
-    /* A multiget lists all of the keys, and I don't want to have an
-     * avector of let's say 512 pointers to tokenize all of them, so let's
-     * just handle them immediately
-     */
-    if (client->ascii_command == GET_CMD ||
-        client->ascii_command == GETS_CMD) {
-      if (client->root->callback->interface.v1.get != NULL)
-        ascii_process_gets(client, ptr, end);
-      else
-        spool_string(client, "SERVER_ERROR: Command not implemented\n");
-    } else {
-      /* None of the defined commands takes 10 parameters, so lets just use
-       * that as a maximum limit.
-       */
-      char *tokens[10];
-      int ntokens= ascii_tokenize_command(ptr, end, tokens, 10);
-
-      if (ntokens < 10)
-      {
-        client->mute= strcmp(tokens[ntokens - 1], "noreply") == 0;
-        if (client->mute)
-          --ntokens; /* processed noreply token*/
-      }
-
-      int error= 0;
-
-      switch (client->ascii_command) {
-      case SET_CMD:
-        error= process_set_command(client, tokens, ntokens, ptr, &end, *length);
-        break;
-      case ADD_CMD:
-        error= process_add_command(client, tokens, ntokens, ptr, &end, *length);
-        break;
-      case REPLACE_CMD:
-        error= process_replace_command(client, tokens, ntokens,
-                                       ptr, &end, *length);
-        break;
-      case CAS_CMD:
-        error= process_cas_command(client, tokens, ntokens, ptr, &end, *length);
-        break;
-      case APPEND_CMD:
-        error= process_append_command(client, tokens, ntokens,
-                                      ptr, &end, *length);
-        break;
-      case PREPEND_CMD:
-        error= process_prepend_command(client, tokens, ntokens,
-                                       ptr, &end, *length);
-       break;
-      case DELETE_CMD:
-        process_delete(client, tokens, ntokens);
-        break;
-
-      case INCR_CMD: /* FALLTHROUGH */
-      case DECR_CMD:
-        process_arithmetic(client, tokens, ntokens);
-        break;
-      case STATS_CMD:
-        if (client->mute)
-        {
-          send_command_usage(client);
-        }
-        else
-        {
-          recover_tokenize_command(ptr, end);
-          process_stats(client, ptr + 6, end);
-        }
-        break;
-      case FLUSH_ALL_CMD:
-        process_flush(client, tokens, ntokens);
-        break;
-      case VERSION_CMD:
-        if (client->mute)
-        {
-          send_command_usage(client);
-        }
-        else
-        {
-          process_version(client, tokens, ntokens);
-        }
-        break;
-      case QUIT_CMD:
-        if (ntokens != 1 || client->mute)
-        {
-          send_command_usage(client);
-        }
-        else
-        {
-          if (client->root->callback->interface.v1.quit != NULL)
-            client->root->callback->interface.v1.quit(client);
-
-          return MEMCACHED_PROTOCOL_ERROR_EVENT;
-        }
-        break;
-
-      case VERBOSITY_CMD:
-        if (ntokens != 2)
-          send_command_usage(client);
-        else
-          spool_string(client, "OK\r\n");
-        break;
-
-      case UNKNOWN_CMD:
-        send_command_usage(client);
-        break;
-
-      case GET_CMD:
-      case GETS_CMD:
-      default:
-        /* Should already be handled */
-        abort();
-      }
-
-      if (error == -1)
-        return MEMCACHED_PROTOCOL_ERROR_EVENT;
-      else if (error == 1)
-        return MEMCACHED_PROTOCOL_READ_EVENT;
-    }
-
-    /* Move past \n */
-    ++end;
-    *length -= end - ptr;
-    ptr= end;
-  } while (*length > 0);
-
-  *endptr= ptr;
-  return MEMCACHED_PROTOCOL_READ_EVENT;
-}
diff --git a/libmemcached/protocol/ascii_handler.h b/libmemcached/protocol/ascii_handler.h
deleted file mode 100644 (file)
index 02f8831..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-LIBMEMCACHED_LOCAL
-memcached_protocol_event_t memcached_ascii_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr);
diff --git a/libmemcached/protocol/binary_handler.c b/libmemcached/protocol/binary_handler.c
deleted file mode 100644 (file)
index 0997ebb..0000000
+++ /dev/null
@@ -1,1121 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <libmemcached/protocol/common.h>
-#include <libmemcached/byteorder.h>
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdio.h>
-
-/*
-** **********************************************************************
-** INTERNAL INTERFACE
-** **********************************************************************
-*/
-
-/**
- * Send a preformatted packet back to the client. If the connection is in
- * pedantic mode, it will validate the packet and refuse to send it if it
- * breaks the specification.
- *
- * @param cookie client identification
- * @param request the original request packet
- * @param response the packet to send
- * @return The status of the operation
- */
-static protocol_binary_response_status
-raw_response_handler(const void *cookie,
-                     protocol_binary_request_header *request,
-                     protocol_binary_response_header *response)
-{
-  memcached_protocol_client_st *client= (void*)cookie;
-
-  if (client->root->pedantic &&
-      !memcached_binary_protocol_pedantic_check_response(request, response))
-  {
-    return PROTOCOL_BINARY_RESPONSE_EINVAL;
-  }
-
-  if (!client->root->drain(client))
-  {
-    return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
-  }
-
-  size_t len= sizeof(*response) + htonl(response->response.bodylen);
-  size_t offset= 0;
-  char *ptr= (void*)response;
-
-  if (client->output == NULL)
-  {
-    /* I can write directly to the socket.... */
-    do
-    {
-      size_t num_bytes= len - offset;
-      ssize_t nw= client->root->send(client,
-                                     client->sock,
-                                     ptr + offset,
-                                     num_bytes);
-      if (nw == -1)
-      {
-        if (get_socket_errno() == EWOULDBLOCK)
-        {
-          break;
-        }
-        else if (get_socket_errno() != EINTR)
-        {
-          client->error= errno;
-          return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
-        }
-      }
-      else
-      {
-        offset += (size_t)nw;
-      }
-    } while (offset < len);
-  }
-
-  return client->root->spool(client, ptr, len - offset);
-}
-
-/*
- * Version 0 of the interface is really low level and protocol specific,
- * while the version 1 of the interface is more API focused. We need a
- * way to translate between the command codes on the wire and the
- * application level interface in V1, so let's just use the V0 of the
- * interface as a map instead of creating a huuuge switch :-)
- */
-
-/**
- * Callback for the GET/GETQ/GETK and GETKQ responses
- * @param cookie client identifier
- * @param key the key for the item
- * @param keylen the length of the key
- * @param body the length of the body
- * @param bodylen the length of the body
- * @param flags the flags for the item
- * @param cas the CAS id for the item
- */
-static protocol_binary_response_status
-get_response_handler(const void *cookie,
-                     const void *key,
-                     uint16_t keylen,
-                     const void *body,
-                     uint32_t bodylen,
-                     uint32_t flags,
-                     uint64_t cas) {
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  uint8_t opcode= client->current_command->request.opcode;
-
-  if (opcode == PROTOCOL_BINARY_CMD_GET || opcode == PROTOCOL_BINARY_CMD_GETQ)
-  {
-    keylen= 0;
-  }
-
-  protocol_binary_response_get response= {
-    .message.header.response= {
-      .magic= PROTOCOL_BINARY_RES,
-      .opcode= opcode,
-      .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-      .opaque= client->current_command->request.opaque,
-      .cas= memcached_htonll(cas),
-      .keylen= htons(keylen),
-      .extlen= 4,
-      .bodylen= htonl(bodylen + keylen + 4),
-    },
-  };
-
-  response.message.body.flags= htonl(flags);
-
-  protocol_binary_response_status rval;
-  const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS;
-  if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success ||
-      (rval= client->root->spool(client, key, keylen)) != success ||
-      (rval= client->root->spool(client, body, bodylen)) != success)
-  {
-    return rval;
-  }
-
-  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
-}
-
-/**
- * Callback for the STAT responses
- * @param cookie client identifier
- * @param key the key for the item
- * @param keylen the length of the key
- * @param body the length of the body
- * @param bodylen the length of the body
- */
-static protocol_binary_response_status stat_response_handler(const void *cookie,
-                                                             const void *key,
-                                                             uint16_t keylen,
-                                                             const void *body,
-                                                             uint32_t bodylen)
-{
-
-  memcached_protocol_client_st *client= (void*)cookie;
-
-  protocol_binary_response_no_extras response= {
-    .message.header.response= {
-      .magic= PROTOCOL_BINARY_RES,
-      .opcode= client->current_command->request.opcode,
-      .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-      .opaque= client->current_command->request.opaque,
-      .keylen= htons(keylen),
-      .bodylen= htonl(bodylen + keylen),
-      .cas= 0
-    },
-  };
-
-  protocol_binary_response_status rval;
-  const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS;
-  if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success ||
-      (rval= client->root->spool(client, key, keylen)) != success ||
-      (rval= client->root->spool(client, body, bodylen)) != success)
-  {
-    return rval;
-  }
-
-  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
-}
-
-/**
- * Callback for the VERSION responses
- * @param cookie client identifier
- * @param text the length of the body
- * @param textlen the length of the body
- */
-static protocol_binary_response_status
-version_response_handler(const void *cookie,
-                         const void *text,
-                         uint32_t textlen) {
-
-  memcached_protocol_client_st *client= (void*)cookie;
-
-  protocol_binary_response_no_extras response= {
-    .message.header.response= {
-      .magic= PROTOCOL_BINARY_RES,
-      .opcode= client->current_command->request.opcode,
-      .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-      .opaque= client->current_command->request.opaque,
-      .bodylen= htonl(textlen),
-      .cas= 0
-    },
-  };
-
-  protocol_binary_response_status rval;
-  const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS;
-  if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success ||
-      (rval= client->root->spool(client, text, textlen)) != success)
-  {
-    return rval;
-  }
-
-  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
-}
-
-/**
- * Callback for ADD and ADDQ
- * @param cookie the calling client
- * @param header the add/addq command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-add_command_handler(const void *cookie,
-                    protocol_binary_request_header *header,
-                    memcached_binary_protocol_raw_response_handler response_handler)
-{
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.add != NULL)
-  {
-    uint16_t keylen= ntohs(header->request.keylen);
-    uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
-    protocol_binary_request_add *request= (void*)header;
-    uint32_t flags= ntohl(request->message.body.flags);
-    uint32_t timeout= ntohl(request->message.body.expiration);
-    char *key= ((char*)header) + sizeof(*header) + 8;
-    char *data= key + keylen;
-    uint64_t cas;
-
-    rval= client->root->callback->interface.v1.add(cookie, key, keylen,
-                                                   data, datalen, flags,
-                                                   timeout, &cas);
-
-    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
-        header->request.opcode == PROTOCOL_BINARY_CMD_ADD)
-    {
-      /* Send a positive request */
-      protocol_binary_response_no_extras response= {
-        .message= {
-          .header.response= {
-            .magic= PROTOCOL_BINARY_RES,
-            .opcode= PROTOCOL_BINARY_CMD_ADD,
-            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-            .opaque= header->request.opaque,
-            .cas= memcached_ntohll(cas)
-          }
-        }
-      };
-      rval= response_handler(cookie, header, (void*)&response);
-    }
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for DECREMENT and DECREMENTQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-decrement_command_handler(const void *cookie,
-                          protocol_binary_request_header *header,
-                          memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.decrement != NULL)
-  {
-    uint16_t keylen= ntohs(header->request.keylen);
-    protocol_binary_request_decr *request= (void*)header;
-    uint64_t init= memcached_ntohll(request->message.body.initial);
-    uint64_t delta= memcached_ntohll(request->message.body.delta);
-    uint32_t timeout= ntohl(request->message.body.expiration);
-    void *key= request->bytes + sizeof(request->bytes);
-    uint64_t result;
-    uint64_t cas;
-
-    rval= client->root->callback->interface.v1.decrement(cookie, key, keylen,
-                                                         delta, init, timeout,
-                                                         &result, &cas);
-    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
-        header->request.opcode == PROTOCOL_BINARY_CMD_DECREMENT)
-    {
-      /* Send a positive request */
-      protocol_binary_response_decr response= {
-        .message= {
-          .header.response= {
-            .magic= PROTOCOL_BINARY_RES,
-            .opcode= PROTOCOL_BINARY_CMD_DECREMENT,
-            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-            .opaque= header->request.opaque,
-            .cas= memcached_ntohll(cas),
-            .bodylen= htonl(8)
-          },
-          .body.value= memcached_htonll(result)
-        }
-      };
-      rval= response_handler(cookie, header, (void*)&response);
-    }
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for DELETE and DELETEQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-delete_command_handler(const void *cookie,
-                       protocol_binary_request_header *header,
-                       memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.delete != NULL)
-  {
-    uint16_t keylen= ntohs(header->request.keylen);
-    void *key= (header +1);
-    uint64_t cas= memcached_ntohll(header->request.cas);
-    rval= client->root->callback->interface.v1.delete(cookie, key, keylen, cas);
-    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
-        header->request.opcode == PROTOCOL_BINARY_CMD_DELETE)
-    {
-      /* Send a positive request */
-      protocol_binary_response_no_extras response= {
-        .message= {
-          .header.response= {
-            .magic= PROTOCOL_BINARY_RES,
-            .opcode= PROTOCOL_BINARY_CMD_DELETE,
-            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-            .opaque= header->request.opaque,
-          }
-        }
-      };
-      rval= response_handler(cookie, header, (void*)&response);
-    }
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for FLUSH and FLUSHQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-flush_command_handler(const void *cookie,
-                      protocol_binary_request_header *header,
-                      memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.flush != NULL)
-  {
-    protocol_binary_request_flush *flush= (void*)header;
-    uint32_t timeout= 0;
-    if (htonl(header->request.bodylen) == 4)
-    {
-      timeout= ntohl(flush->message.body.expiration);
-    }
-
-    rval= client->root->callback->interface.v1.flush(cookie, timeout);
-    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
-        header->request.opcode == PROTOCOL_BINARY_CMD_FLUSH)
-    {
-      /* Send a positive request */
-      protocol_binary_response_no_extras response= {
-        .message= {
-          .header.response= {
-            .magic= PROTOCOL_BINARY_RES,
-            .opcode= PROTOCOL_BINARY_CMD_FLUSH,
-            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-            .opaque= header->request.opaque,
-          }
-        }
-      };
-      rval= response_handler(cookie, header, (void*)&response);
-    }
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for GET, GETK, GETQ, GETKQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-get_command_handler(const void *cookie,
-                    protocol_binary_request_header *header,
-                    memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.get != NULL)
-  {
-    uint16_t keylen= ntohs(header->request.keylen);
-    void *key= (header + 1);
-    rval= client->root->callback->interface.v1.get(cookie, key, keylen,
-                                                   get_response_handler);
-
-    if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT &&
-        (header->request.opcode == PROTOCOL_BINARY_CMD_GETQ ||
-         header->request.opcode == PROTOCOL_BINARY_CMD_GETKQ))
-    {
-      /* Quiet commands shouldn't respond on cache misses */
-      rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
-    }
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for INCREMENT and INCREMENTQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-increment_command_handler(const void *cookie,
-                          protocol_binary_request_header *header,
-                          memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.increment != NULL)
-  {
-    uint16_t keylen= ntohs(header->request.keylen);
-    protocol_binary_request_incr *request= (void*)header;
-    uint64_t init= memcached_ntohll(request->message.body.initial);
-    uint64_t delta= memcached_ntohll(request->message.body.delta);
-    uint32_t timeout= ntohl(request->message.body.expiration);
-    void *key= request->bytes + sizeof(request->bytes);
-    uint64_t cas;
-    uint64_t result;
-
-    rval= client->root->callback->interface.v1.increment(cookie, key, keylen,
-                                                         delta, init, timeout,
-                                                         &result, &cas);
-    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
-        header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENT)
-    {
-      /* Send a positive request */
-      protocol_binary_response_incr response= {
-        .message= {
-          .header.response= {
-            .magic= PROTOCOL_BINARY_RES,
-            .opcode= PROTOCOL_BINARY_CMD_INCREMENT,
-            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-            .opaque= header->request.opaque,
-            .cas= memcached_ntohll(cas),
-            .bodylen= htonl(8)
-          },
-          .body.value= memcached_htonll(result)
-        }
-      };
-
-      rval= response_handler(cookie, header, (void*)&response);
-    }
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for noop. Inform the v1 interface about the noop packet, and
- * create and send a packet back to the client
- *
- * @param cookie the calling client
- * @param header the command
- * @param response_handler the response handler
- * @return the result of the operation
- */
-static protocol_binary_response_status
-noop_command_handler(const void *cookie,
-                     protocol_binary_request_header *header,
-                     memcached_binary_protocol_raw_response_handler response_handler)
-{
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.noop != NULL)
-  {
-    client->root->callback->interface.v1.noop(cookie);
-  }
-
-  protocol_binary_response_no_extras response= {
-    .message= {
-      .header.response= {
-        .magic= PROTOCOL_BINARY_RES,
-        .opcode= PROTOCOL_BINARY_CMD_NOOP,
-        .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-        .opaque= header->request.opaque,
-      }
-    }
-  };
-
-  return response_handler(cookie, header, (void*)&response);
-}
-
-/**
- * Callback for APPEND and APPENDQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-append_command_handler(const void *cookie,
-                       protocol_binary_request_header *header,
-                       memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.append != NULL)
-  {
-    uint16_t keylen= ntohs(header->request.keylen);
-    uint32_t datalen= ntohl(header->request.bodylen) - keylen;
-    char *key= (void*)(header +1);
-    char *data= key +keylen;
-    uint64_t cas= memcached_ntohll(header->request.cas);
-    uint64_t result_cas;
-
-    rval= client->root->callback->interface.v1.append(cookie, key, keylen,
-                                                      data, datalen, cas,
-                                                      &result_cas);
-    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
-        header->request.opcode == PROTOCOL_BINARY_CMD_APPEND)
-    {
-      /* Send a positive request */
-      protocol_binary_response_no_extras response= {
-        .message= {
-          .header.response= {
-            .magic= PROTOCOL_BINARY_RES,
-            .opcode= PROTOCOL_BINARY_CMD_APPEND,
-            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-            .opaque= header->request.opaque,
-            .cas= memcached_ntohll(result_cas),
-          },
-        }
-      };
-      rval= response_handler(cookie, header, (void*)&response);
-    }
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for PREPEND and PREPENDQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-prepend_command_handler(const void *cookie,
-                        protocol_binary_request_header *header,
-                        memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.prepend != NULL)
-  {
-    uint16_t keylen= ntohs(header->request.keylen);
-    uint32_t datalen= ntohl(header->request.bodylen) - keylen;
-    char *key= (char*)(header + 1);
-    char *data= key + keylen;
-    uint64_t cas= memcached_ntohll(header->request.cas);
-    uint64_t result_cas;
-    rval= client->root->callback->interface.v1.prepend(cookie, key, keylen,
-                                                       data, datalen, cas,
-                                                       &result_cas);
-    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
-        header->request.opcode == PROTOCOL_BINARY_CMD_PREPEND)
-    {
-      /* Send a positive request */
-      protocol_binary_response_no_extras response= {
-        .message= {
-          .header.response= {
-            .magic= PROTOCOL_BINARY_RES,
-            .opcode= PROTOCOL_BINARY_CMD_PREPEND,
-            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-            .opaque= header->request.opaque,
-            .cas= memcached_ntohll(result_cas),
-          },
-        }
-      };
-      rval= response_handler(cookie, header, (void*)&response);
-    }
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for QUIT and QUITQ. Notify the client and shut down the connection
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-quit_command_handler(const void *cookie,
-                     protocol_binary_request_header *header,
-                     memcached_binary_protocol_raw_response_handler response_handler)
-{
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.quit != NULL)
-  {
-    client->root->callback->interface.v1.quit(cookie);
-  }
-
-  protocol_binary_response_no_extras response= {
-    .message= {
-      .header.response= {
-        .magic= PROTOCOL_BINARY_RES,
-        .opcode= PROTOCOL_BINARY_CMD_QUIT,
-        .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-        .opaque= header->request.opaque
-      }
-    }
-  };
-
-  if (header->request.opcode == PROTOCOL_BINARY_CMD_QUIT)
-  {
-    response_handler(cookie, header, (void*)&response);
-  }
-
-  /* I need a better way to signal to close the connection */
-  return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
-}
-
-/**
- * Callback for REPLACE and REPLACEQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-replace_command_handler(const void *cookie,
-                        protocol_binary_request_header *header,
-                        memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.replace != NULL)
-  {
-    uint16_t keylen= ntohs(header->request.keylen);
-    uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
-    protocol_binary_request_replace *request= (void*)header;
-    uint32_t flags= ntohl(request->message.body.flags);
-    uint32_t timeout= ntohl(request->message.body.expiration);
-    char *key= ((char*)header) + sizeof(*header) + 8;
-    char *data= key + keylen;
-    uint64_t cas= memcached_ntohll(header->request.cas);
-    uint64_t result_cas;
-
-    rval= client->root->callback->interface.v1.replace(cookie, key, keylen,
-                                                       data, datalen, flags,
-                                                       timeout, cas,
-                                                       &result_cas);
-    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
-        header->request.opcode == PROTOCOL_BINARY_CMD_REPLACE)
-    {
-      /* Send a positive request */
-      protocol_binary_response_no_extras response= {
-        .message= {
-          .header.response= {
-            .magic= PROTOCOL_BINARY_RES,
-            .opcode= PROTOCOL_BINARY_CMD_REPLACE,
-            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-            .opaque= header->request.opaque,
-            .cas= memcached_ntohll(result_cas),
-          },
-        }
-      };
-      rval= response_handler(cookie, header, (void*)&response);
-    }
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for SET and SETQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-set_command_handler(const void *cookie,
-                    protocol_binary_request_header *header,
-                    memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.set != NULL)
-  {
-    uint16_t keylen= ntohs(header->request.keylen);
-    uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
-    protocol_binary_request_replace *request= (void*)header;
-    uint32_t flags= ntohl(request->message.body.flags);
-    uint32_t timeout= ntohl(request->message.body.expiration);
-    char *key= ((char*)header) + sizeof(*header) + 8;
-    char *data= key + keylen;
-    uint64_t cas= memcached_ntohll(header->request.cas);
-    uint64_t result_cas;
-
-
-    rval= client->root->callback->interface.v1.set(cookie, key, keylen,
-                                                   data, datalen, flags,
-                                                   timeout, cas, &result_cas);
-    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
-        header->request.opcode == PROTOCOL_BINARY_CMD_SET)
-    {
-      /* Send a positive request */
-      protocol_binary_response_no_extras response= {
-        .message= {
-          .header.response= {
-            .magic= PROTOCOL_BINARY_RES,
-            .opcode= PROTOCOL_BINARY_CMD_SET,
-            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
-            .opaque= header->request.opaque,
-            .cas= memcached_ntohll(result_cas),
-          },
-        }
-      };
-      rval= response_handler(cookie, header, (void*)&response);
-    }
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for STAT
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-stat_command_handler(const void *cookie,
-                     protocol_binary_request_header *header,
-                     memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.stat != NULL)
-  {
-    uint16_t keylen= ntohs(header->request.keylen);
-
-    rval= client->root->callback->interface.v1.stat(cookie,
-                                                    (void*)(header + 1),
-                                                    keylen,
-                                                    stat_response_handler);
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * Callback for VERSION
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-version_command_handler(const void *cookie,
-                        protocol_binary_request_header *header,
-                        memcached_binary_protocol_raw_response_handler response_handler)
-{
-  (void)response_handler;
-  (void)header;
-  protocol_binary_response_status rval;
-
-  memcached_protocol_client_st *client= (void*)cookie;
-  if (client->root->callback->interface.v1.version != NULL)
-  {
-    rval= client->root->callback->interface.v1.version(cookie,
-                                                       version_response_handler);
-  }
-  else
-  {
-    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  }
-
-  return rval;
-}
-
-/**
- * The map to remap between the com codes and the v1 logical setting
- */
-static memcached_binary_protocol_command_handler comcode_v0_v1_remap[256]= {
-  [PROTOCOL_BINARY_CMD_ADDQ]= add_command_handler,
-  [PROTOCOL_BINARY_CMD_ADD]= add_command_handler,
-  [PROTOCOL_BINARY_CMD_APPENDQ]= append_command_handler,
-  [PROTOCOL_BINARY_CMD_APPEND]= append_command_handler,
-  [PROTOCOL_BINARY_CMD_DECREMENTQ]= decrement_command_handler,
-  [PROTOCOL_BINARY_CMD_DECREMENT]= decrement_command_handler,
-  [PROTOCOL_BINARY_CMD_DELETEQ]= delete_command_handler,
-  [PROTOCOL_BINARY_CMD_DELETE]= delete_command_handler,
-  [PROTOCOL_BINARY_CMD_FLUSHQ]= flush_command_handler,
-  [PROTOCOL_BINARY_CMD_FLUSH]= flush_command_handler,
-  [PROTOCOL_BINARY_CMD_GETKQ]= get_command_handler,
-  [PROTOCOL_BINARY_CMD_GETK]= get_command_handler,
-  [PROTOCOL_BINARY_CMD_GETQ]= get_command_handler,
-  [PROTOCOL_BINARY_CMD_GET]= get_command_handler,
-  [PROTOCOL_BINARY_CMD_INCREMENTQ]= increment_command_handler,
-  [PROTOCOL_BINARY_CMD_INCREMENT]= increment_command_handler,
-  [PROTOCOL_BINARY_CMD_NOOP]= noop_command_handler,
-  [PROTOCOL_BINARY_CMD_PREPENDQ]= prepend_command_handler,
-  [PROTOCOL_BINARY_CMD_PREPEND]= prepend_command_handler,
-  [PROTOCOL_BINARY_CMD_QUITQ]= quit_command_handler,
-  [PROTOCOL_BINARY_CMD_QUIT]= quit_command_handler,
-  [PROTOCOL_BINARY_CMD_REPLACEQ]= replace_command_handler,
-  [PROTOCOL_BINARY_CMD_REPLACE]= replace_command_handler,
-  [PROTOCOL_BINARY_CMD_SETQ]= set_command_handler,
-  [PROTOCOL_BINARY_CMD_SET]= set_command_handler,
-  [PROTOCOL_BINARY_CMD_STAT]= stat_command_handler,
-  [PROTOCOL_BINARY_CMD_VERSION]= version_command_handler,
-};
-
-/**
- * Try to execute a command. Fire the pre/post functions and the specialized
- * handler function if it's set. If not, the unknown probe should be fired
- * if it's present.
- * @param client the client connection to operate on
- * @param header the command to execute
- * @return true if success or false if a fatal error occured so that the
- *         connection should be shut down.
- */
-static protocol_binary_response_status execute_command(memcached_protocol_client_st *client, protocol_binary_request_header *header)
-{
-  if (client->root->pedantic &&
-      memcached_binary_protocol_pedantic_check_request(header))
-  {
-      /* @todo return invalid command packet */
-  }
-
-  /* we got all data available, execute the callback! */
-  if (client->root->callback->pre_execute != NULL)
-  {
-    client->root->callback->pre_execute(client, header);
-  }
-
-  protocol_binary_response_status rval;
-  rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
-  uint8_t cc= header->request.opcode;
-
-  switch (client->root->callback->interface_version)
-  {
-  case 0:
-    if (client->root->callback->interface.v0.comcode[cc] != NULL) {
-      rval= client->root->callback->interface.v0.comcode[cc](client, header, raw_response_handler);
-    }
-    break;
-  case 1:
-    if (comcode_v0_v1_remap[cc] != NULL) {
-      rval= comcode_v0_v1_remap[cc](client, header, raw_response_handler);
-    }
-    break;
-  default:
-    /* Unknown interface.
-     * It should be impossible to get here so I'll just call abort
-     * to avoid getting a compiler warning :-)
-     */
-    abort();
-  }
-
-
-  if (rval == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND &&
-      client->root->callback->unknown != NULL)
-  {
-    rval= client->root->callback->unknown(client, header, raw_response_handler);
-  }
-
-  if (rval != PROTOCOL_BINARY_RESPONSE_SUCCESS &&
-      rval != PROTOCOL_BINARY_RESPONSE_EINTERNAL &&
-      rval != PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED)
-  {
-    protocol_binary_response_no_extras response= {
-      .message= {
-        .header.response= {
-          .magic= PROTOCOL_BINARY_RES,
-          .opcode= cc,
-          .status= htons(rval),
-          .opaque= header->request.opaque,
-        },
-      }
-    };
-    rval= raw_response_handler(client, header, (void*)&response);
-  }
-
-  if (client->root->callback->post_execute != NULL)
-  {
-    client->root->callback->post_execute(client, header);
-  }
-
-  return rval;
-}
-
-/*
-** **********************************************************************
-** "PROTOECTED" INTERFACE
-** **********************************************************************
-*/
-memcached_protocol_event_t memcached_binary_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr)
-{
-  /* try to parse all of the received packets */
-  protocol_binary_request_header *header;
-  header= (void*)client->root->input_buffer;
-  if (header->request.magic != (uint8_t)PROTOCOL_BINARY_REQ)
-  {
-    client->error= EINVAL;
-    return MEMCACHED_PROTOCOL_ERROR_EVENT;
-  }
-  ssize_t len= *length;
-
-  while (len >= (ssize_t)sizeof(*header) &&
-         (len >= (ssize_t)(sizeof(*header) + ntohl(header->request.bodylen))))
-  {
-    /* I have the complete package */
-    client->current_command= header;
-    protocol_binary_response_status rv= execute_command(client, header);
-
-    if (rv == PROTOCOL_BINARY_RESPONSE_EINTERNAL)
-    {
-      *length= len;
-      *endptr= (void*)header;
-      return MEMCACHED_PROTOCOL_ERROR_EVENT;
-    } else if (rv == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED)
-      return MEMCACHED_PROTOCOL_PAUSE_EVENT;
-
-    ssize_t total= (ssize_t)(sizeof(*header) + ntohl(header->request.bodylen));
-    len -= total;
-    if (len > 0)
-    {
-      intptr_t ptr= (intptr_t)header;
-      ptr += total;
-      if ((ptr % 8) == 0)
-      {
-        header= (void*)ptr;
-      }
-      else
-      {
-        /* Fix alignment */
-        memmove(client->root->input_buffer, (void*)ptr, (size_t)len);
-        header= (void*)client->root->input_buffer;
-      }
-    }
-    *length= len;
-    *endptr= (void*)header;
-  }
-
-  return MEMCACHED_PROTOCOL_READ_EVENT;
-}
-
-/*
-** **********************************************************************
-** PUBLIC INTERFACE
-** **********************************************************************
-*/
-memcached_binary_protocol_callback_st *memcached_binary_protocol_get_callbacks(memcached_protocol_st *instance)
-{
-  return instance->callback;
-}
-
-void memcached_binary_protocol_set_callbacks(memcached_protocol_st *instance, memcached_binary_protocol_callback_st *callback)
-{
-  instance->callback= callback;
-}
-
-memcached_binary_protocol_raw_response_handler memcached_binary_protocol_get_raw_response_handler(const void *cookie)
-{
-  (void)cookie;
-  return raw_response_handler;
-}
-
-void memcached_binary_protocol_set_pedantic(memcached_protocol_st *instance, bool enable)
-{
-  instance->pedantic= enable;
-}
-
-bool memcached_binary_protocol_get_pedantic(memcached_protocol_st *instance)
-{
-  return instance->pedantic;
-}
-
diff --git a/libmemcached/protocol/binary_handler.h b/libmemcached/protocol/binary_handler.h
deleted file mode 100644 (file)
index d5a74e7..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-LIBMEMCACHED_LOCAL
-bool memcached_binary_protocol_pedantic_check_request(const protocol_binary_request_header *request);
-
-LIBMEMCACHED_LOCAL
-bool memcached_binary_protocol_pedantic_check_response(const protocol_binary_request_header *request,
-                                                       const protocol_binary_response_header *response);
-
-LIBMEMCACHED_LOCAL
-memcached_protocol_event_t memcached_binary_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr);
diff --git a/libmemcached/protocol/cache.c b/libmemcached/protocol/cache.c
deleted file mode 100644 (file)
index f92fdec..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-
-#ifndef NDEBUG
-#include <signal.h>
-#endif
-
-#include "cache.h"
-
-#ifndef NDEBUG
-const uint64_t redzone_pattern = 0xdeadbeefcafebabe;
-int cache_error = 0;
-#endif
-
-const size_t initial_pool_size = 64;
-
-cache_t* cache_create(const char *name, size_t bufsize, size_t align,
-                      cache_constructor_t* constructor,
-                      cache_destructor_t* destructor) {
-    cache_t* ret = calloc(1, sizeof(cache_t));
-    size_t name_length= strlen(name);
-    char* nm= calloc(1, (sizeof(char) * name_length) +1);
-    memcpy(nm, name, name_length);
-    void** ptr = calloc(initial_pool_size, bufsize);
-    if (ret == NULL || nm == NULL || ptr == NULL ||
-        pthread_mutex_init(&ret->mutex, NULL) == -1) {
-        free(ret);
-        free(nm);
-        free(ptr);
-        return NULL;
-    }
-
-    ret->name = nm;
-    ret->ptr = ptr;
-    ret->freetotal = initial_pool_size;
-    ret->constructor = constructor;
-    ret->destructor = destructor;
-
-#ifndef NDEBUG
-    ret->bufsize = bufsize + 2 * sizeof(redzone_pattern);
-#else
-    ret->bufsize = bufsize;
-#endif
-
-    (void)align;
-
-    return ret;
-}
-
-static inline void* get_object(void *ptr) {
-#ifndef NDEBUG
-    uint64_t *pre = ptr;
-    return pre + 1;
-#else
-    return ptr;
-#endif
-}
-
-void cache_destroy(cache_t *cache) {
-    while (cache->freecurr > 0) {
-        void *ptr = cache->ptr[--cache->freecurr];
-        if (cache->destructor) {
-            cache->destructor(get_object(ptr), NULL);
-        }
-        free(ptr);
-    }
-    free(cache->name);
-    free(cache->ptr);
-    pthread_mutex_destroy(&cache->mutex);
-}
-
-void* cache_alloc(cache_t *cache) {
-    void *ret;
-    void *object;
-    pthread_mutex_lock(&cache->mutex);
-    if (cache->freecurr > 0) {
-        ret = cache->ptr[--cache->freecurr];
-        object = get_object(ret);
-    } else {
-        object = ret = malloc(cache->bufsize);
-        if (ret != NULL) {
-            object = get_object(ret);
-
-            if (cache->constructor != NULL &&
-                cache->constructor(object, NULL, 0) != 0) {
-                free(ret);
-                object = NULL;
-            }
-        }
-    }
-    pthread_mutex_unlock(&cache->mutex);
-
-#ifndef NDEBUG
-    if (object != NULL) {
-        /* add a simple form of buffer-check */
-        uint64_t *pre = ret;
-        *pre = redzone_pattern;
-        ret = pre+1;
-        memcpy(((char*)ret) + cache->bufsize - (2 * sizeof(redzone_pattern)),
-               &redzone_pattern, sizeof(redzone_pattern));
-    }
-#endif
-
-    return object;
-}
-
-void cache_free(cache_t *cache, void *ptr) {
-    pthread_mutex_lock(&cache->mutex);
-
-#ifndef NDEBUG
-    /* validate redzone... */
-    if (memcmp(((char*)ptr) + cache->bufsize - (2 * sizeof(redzone_pattern)),
-               &redzone_pattern, sizeof(redzone_pattern)) != 0) {
-        raise(SIGABRT);
-        cache_error = 1;
-        pthread_mutex_unlock(&cache->mutex);
-        return;
-    }
-    uint64_t *pre = ptr;
-    --pre;
-    if (*pre != redzone_pattern) {
-        raise(SIGABRT);
-        cache_error = -1;
-        pthread_mutex_unlock(&cache->mutex);
-        return;
-    }
-    ptr = pre;
-#endif
-    if (cache->freecurr < cache->freetotal) {
-        cache->ptr[cache->freecurr++] = ptr;
-    } else {
-        /* try to enlarge free connections array */
-        size_t newtotal = cache->freetotal * 2;
-        void **new_free = realloc(cache->ptr, sizeof(char *) * newtotal);
-        if (new_free) {
-            cache->freetotal = newtotal;
-            cache->ptr = new_free;
-            cache->ptr[cache->freecurr++] = ptr;
-        } else {
-            if (cache->destructor) {
-                cache->destructor(ptr, NULL);
-            }
-            free(ptr);
-
-        }
-    }
-    pthread_mutex_unlock(&cache->mutex);
-}
-
diff --git a/libmemcached/protocol/cache.h b/libmemcached/protocol/cache.h
deleted file mode 100644 (file)
index 6f84fea..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-#pragma once
-
-#include <pthread.h>
-
-#ifdef HAVE_UMEM_H
-# include <umem.h>
-# define cache_t umem_cache_t
-# define cache_alloc(a) umem_cache_alloc(a, UMEM_DEFAULT)
-# define cache_free(a, b) umem_cache_free(a, b)
-# define cache_create(a,b,c,d,e) umem_cache_create((char*)a, b, c, d, e, NULL, NULL, NULL, 0)
-# define cache_destroy(a) umem_cache_destroy(a);
-#else
-# ifndef NDEBUG
-/* may be used for debug purposes */
-extern int cache_error;
-# endif
-
-/**
- * Constructor used to initialize allocated objects
- *
- * @param obj pointer to the object to initialized.
- * @param notused1 This parameter is currently not used.
- * @param notused2 This parameter is currently not used.
- * @return you should return 0, but currently this is not checked
- */
-typedef int cache_constructor_t(void* obj, void* notused1, int notused2);
-/**
- * Destructor used to clean up allocated objects before they are
- * returned to the operating system.
- *
- * @param obj pointer to the object to initialized.
- * @param notused1 This parameter is currently not used.
- * @param notused2 This parameter is currently not used.
- * @return you should return 0, but currently this is not checked
- */
-typedef void cache_destructor_t(void* obj, void* notused);
-
-/**
- * Definition of the structure to keep track of the internal details of
- * the cache allocator. Touching any of these variables results in
- * undefined behavior.
- */
-typedef struct {
-    /** Mutex to protect access to the structure */
-    pthread_mutex_t mutex;
-    /** Name of the cache objects in this cache (provided by the caller) */
-    char *name;
-    /** List of pointers to available buffers in this cache */
-    void **ptr;
-    /** The size of each element in this cache */
-    size_t bufsize;
-    /** The capacity of the list of elements */
-    size_t freetotal;
-    /** The current number of free elements */
-    size_t freecurr;
-    /** The constructor to be called each time we allocate more memory */
-    cache_constructor_t* constructor;
-    /** The destructor to be called each time before we release memory */
-    cache_destructor_t* destructor;
-} cache_t;
-
-/**
- * Create an object cache.
- *
- * The object cache will let you allocate objects of the same size. It is fully
- * MT safe, so you may allocate objects from multiple threads without having to
- * do any syncrhonization in the application code.
- *
- * @param name the name of the object cache. This name may be used for debug purposes
- *             and may help you track down what kind of object you have problems with
- *             (buffer overruns, leakage etc)
- * @param bufsize the size of each object in the cache
- * @param align the alignment requirements of the objects in the cache.
- * @param constructor the function to be called to initialize memory when we need
- *                    to allocate more memory from the os.
- * @param destructor the function to be called before we release the memory back
- *                   to the os.
- * @return a handle to an object cache if successful, NULL otherwise.
- */
-cache_t* cache_create(const char* name, size_t bufsize, size_t align,
-                      cache_constructor_t* constructor,
-                      cache_destructor_t* destructor);
-/**
- * Destroy an object cache.
- *
- * Destroy and invalidate an object cache. You should return all buffers allocated
- * with cache_alloc by using cache_free before calling this function. Not doing
- * so results in undefined behavior (the buffers may or may not be invalidated)
- *
- * @param handle the handle to the object cache to destroy.
- */
-void cache_destroy(cache_t* handle);
-/**
- * Allocate an object from the cache.
- *
- * @param handle the handle to the object cache to allocate from
- * @return a pointer to an initialized object from the cache, or NULL if
- *         the allocation cannot be satisfied.
- */
-void* cache_alloc(cache_t* handle);
-/**
- * Return an object back to the cache.
- *
- * The caller should return the object in an initialized state so that
- * the object may be returned in an expected state from cache_alloc.
- *
- * @param handle handle to the object cache to return the object to
- * @param ptr pointer to the object to return.
- */
-void cache_free(cache_t* handle, void* ptr);
-#endif //  HAVE_UMEM_H
diff --git a/libmemcached/protocol/callback.h b/libmemcached/protocol/callback.h
deleted file mode 100644 (file)
index e7efaad..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Summary: Definition of the callback interface
- *
- * Copy: See Copyright for the status of this software.
- *
- * Author: Trond Norbye
- */
-#ifndef LIBMEMCACHEDPROTOCOL_CALLBACK_H
-#define LIBMEMCACHEDPROTOCOL_CALLBACK_H
-
-/**
- * Callback to send data back from a successful GET/GETQ/GETK/GETKQ command
- *
- * @param cookie Just pass along the cookie supplied in the callback
- * @param key What to insert as key in the reply
- * @param keylen The length of the key
- * @param body What to store in the body of the package
- * @param bodylen The number of bytes of the body
- * @param flags The flags stored with the item
- * @param cas The CAS value to insert into the response (should be 0
- *            if you don't care)
- */
-typedef protocol_binary_response_status
-(*memcached_binary_protocol_get_response_handler)(const void *cookie,
-                                                  const void *key,
-                                                  uint16_t keylen,
-                                                  const void *body,
-                                                  uint32_t bodylen,
-                                                  uint32_t flags,
-                                                  uint64_t cas);
-/**
- * Callback to send data back from a STAT command
- *
- * @param cookie Just pass along the cookie supplied in the callback
- * @param key What to insert as key in the reply
- * @param keylen The length of the key
- * @param body What to store in the body of the package
- * @param bodylen The number of bytes of the body
- */
-typedef protocol_binary_response_status
-(*memcached_binary_protocol_stat_response_handler)(const void *cookie,
-                                                   const void *key,
-                                                   uint16_t keylen,
-                                                   const void *body,
-                                                   uint32_t bodylen);
-/**
- * Callback to send data back from a VERSION command
- *
- * @param cookie Just pass along the cookie supplied in the callback
- * @param text The version string
- * @param length The number of bytes in the version string
- */
-typedef protocol_binary_response_status
-(*memcached_binary_protocol_version_response_handler)(const void *cookie,
-                                                      const void *text,
-                                                      uint32_t length);
-
-
-/**
- * In the low level interface you need to format the response
- * packet yourself (giving you complete freedom :-)
- *
- * @param cookie Just pass along the cookie supplied in the callback
- * @param request Pointer to the request packet you are sending a reply to
- * @param response Pointer to the response packet to send
- *
- */
-typedef protocol_binary_response_status (*memcached_binary_protocol_raw_response_handler)(const void *cookie,
-                                                               protocol_binary_request_header *request,
-                                                               protocol_binary_response_header *response);
-
-/**
- * In the low lever interface you have to do most of the work by
- * yourself, but it also gives you a lot of freedom :-)
- * @param cookie identification for this connection, just pass it along to
- *               the response handler
- * @param header the command received over the wire. Never try to access
- *               <u>anything</u> outside the command.
- * @param resonse_handler call this function to send data back to the client
- */
-typedef protocol_binary_response_status (*memcached_binary_protocol_command_handler)(const void *cookie,
-                                                   protocol_binary_request_header *header,
-                                                   memcached_binary_protocol_raw_response_handler response_handler);
-
-/**
- * The raw interface to the packets is implemented in version 0. It contains
- * just an array with command handlers. The inxed in the array is the
- * com code.
- */
-typedef struct {
-   memcached_binary_protocol_command_handler comcode[256];
-} memcached_binary_protocol_callback_v0_st;
-
-
-/**
- * The first version of the callback struct containing all of the
- * documented commands in the initial release of the binary protocol
- * (aka. memcached 1.4.0).
- *
- * You might miss the Q commands (addq etc) but the response function
- * knows how to deal with them so you don't need to worry about that :-)
- */
-typedef struct {
-   /**
-    * Add an item to the cache
-    * @param cookie id of the client receiving the command
-    * @param key the key to add
-    * @param len the length of the key
-    * @param val the value to store for the key (may be NIL)
-    * @param vallen the length of the data
-    * @param flags the flags to store with the key
-    * @param exptime the expiry time for the key-value pair
-    * @param cas the resulting cas for the add operation (if success)
-    */
-   protocol_binary_response_status (*add)(const void *cookie,
-                                          const void *key,
-                                          uint16_t keylen,
-                                          const void* val,
-                                          uint32_t vallen,
-                                          uint32_t flags,
-                                          uint32_t exptime,
-                                          uint64_t *cas);
-
-   /**
-    * Append data to an <b>existing</b> key-value pair.
-    *
-    * @param cookie id of the client receiving the command
-    * @param key the key to add data to
-    * @param len the length of the key
-    * @param val the value to append to the value
-    * @param vallen the length of the data
-    * @param cas the CAS in the request
-    * @param result_cas the resulting cas for the append operation
-    *
-    */
-   protocol_binary_response_status (*append)(const void *cookie,
-                                             const void *key,
-                                             uint16_t keylen,
-                                             const void* val,
-                                             uint32_t vallen,
-                                             uint64_t cas,
-                                             uint64_t *result_cas);
-
-   /**
-    * Decrement the value for a key
-    *
-    * @param cookie id of the client receiving the command
-    * @param key the key to decrement the value for
-    * @param len the length of the key
-    * @param delta the amount to decrement
-    * @param initial initial value to store (if the key doesn't exist)
-    * @param expiration expiration time for the object (if the key doesn't exist)
-    * @param cas the CAS in the request
-    * @param result the result from the decrement
-    * @param result_cas the cas of the item
-    *
-    */
-   protocol_binary_response_status (*decrement)(const void *cookie,
-                                                const void *key,
-                                                uint16_t keylen,
-                                                uint64_t delta,
-                                                uint64_t initial,
-                                                uint32_t expiration,
-                                                uint64_t *result,
-                                                uint64_t *result_cas);
-
-   /**
-    * Delete an existing key
-    *
-    * @param cookie id of the client receiving the command
-    * @param key the key to delete
-    * @param len the length of the key
-    * @param cas the CAS in the request
-    */
-   protocol_binary_response_status (*delete)(const void *cookie,
-                                             const void *key,
-                                             uint16_t keylen,
-                                             uint64_t cas);
-
-
-   /**
-    * Flush the cache
-    *
-    * @param cookie id of the client receiving the command
-    * @param when when the cache should be flushed (0 == immediately)
-    */
-   protocol_binary_response_status (*flush)(const void *cookie,
-                                            uint32_t when);
-
-
-
-   /**
-    * Get a key-value pair
-    *
-    * @param cookie id of the client receiving the command
-    * @param key the key to get
-    * @param len the length of the key
-    * @param response_handler to send the result back to the client
-    */
-   protocol_binary_response_status (*get)(const void *cookie,
-                                          const void *key,
-                                          uint16_t keylen,
-                                          memcached_binary_protocol_get_response_handler response_handler);
-
-   /**
-    * Increment the value for a key
-    *
-    * @param cookie id of the client receiving the command
-    * @param key the key to increment the value on
-    * @param len the length of the key
-    * @param delta the amount to increment
-    * @param initial initial value to store (if the key doesn't exist)
-    * @param expiration expiration time for the object (if the key doesn't exist)
-    * @param cas the CAS in the request
-    * @param result the result from the decrement
-    * @param result_cas the cas of the item
-    *
-    */
-   protocol_binary_response_status (*increment)(const void *cookie,
-                                                const void *key,
-                                                uint16_t keylen,
-                                                uint64_t delta,
-                                                uint64_t initial,
-                                                uint32_t expiration,
-                                                uint64_t *result,
-                                                uint64_t *result_cas);
-
-   /**
-    * The noop command was received. This is just a notification callback (the
-    * response is automatically created).
-    *
-    * @param cookie id of the client receiving the command
-    */
-   protocol_binary_response_status (*noop)(const void *cookie);
-
-   /**
-    * Prepend data to an <b>existing</b> key-value pair.
-    *
-    * @param cookie id of the client receiving the command
-    * @param key the key to prepend data to
-    * @param len the length of the key
-    * @param val the value to prepend to the value
-    * @param vallen the length of the data
-    * @param cas the CAS in the request
-    * @param result-cas the cas id of the item
-    *
-    */
-   protocol_binary_response_status (*prepend)(const void *cookie,
-                                              const void *key,
-                                              uint16_t keylen,
-                                              const void* val,
-                                              uint32_t vallen,
-                                              uint64_t cas,
-                                              uint64_t *result_cas);
-
-   /**
-    * The quit command was received. This is just a notification callback (the
-    * response is automatically created).
-    *
-    * @param cookie id of the client receiving the command
-    */
-   protocol_binary_response_status (*quit)(const void *cookie);
-
-
-   /**
-    * Replace an <b>existing</b> item to the cache
-    *
-    * @param cookie id of the client receiving the command
-    * @param key the key to replace the content for
-    * @param len the length of the key
-    * @param val the value to store for the key (may be NIL)
-    * @param vallen the length of the data
-    * @param flags the flags to store with the key
-    * @param exptime the expiry time for the key-value pair
-    * @param cas the cas id in the request
-    * @param result_cas the cas id of the item
-    */
-   protocol_binary_response_status (*replace)(const void *cookie,
-                                              const void *key,
-                                              uint16_t keylen,
-                                              const void* val,
-                                              uint32_t vallen,
-                                              uint32_t flags,
-                                              uint32_t exptime,
-                                              uint64_t cas,
-                                              uint64_t *result_cas);
-
-
-   /**
-    * Set a key-value pair in the cache
-    *
-    * @param cookie id of the client receiving the command
-    * @param key the key to insert
-    * @param len the length of the key
-    * @param val the value to store for the key (may be NIL)
-    * @param vallen the length of the data
-    * @param flags the flags to store with the key
-    * @param exptime the expiry time for the key-value pair
-    * @param cas the cas id in the request
-    * @param result_cas the cas id of the new item
-    */
-   protocol_binary_response_status (*set)(const void *cookie,
-                                          const void *key,
-                                          uint16_t keylen,
-                                          const void* val,
-                                          uint32_t vallen,
-                                          uint32_t flags,
-                                          uint32_t exptime,
-                                          uint64_t cas,
-                                          uint64_t *result_cas);
-
-   /**
-    * Get status information
-    *
-    * @param cookie id of the client receiving the command
-    * @param key the key to get status for (or NIL to request all status).
-    *            Remember to insert the terminating packet if multiple
-    *            packets should be returned.
-    * @param keylen the length of the key
-    * @param response_handler to send the result back to the client, but
-    *                         don't send reply on success!
-    *
-    */
-   protocol_binary_response_status (*stat)(const void *cookie,
-                                           const void *key,
-                                           uint16_t keylen,
-                                           memcached_binary_protocol_stat_response_handler response_handler);
-
-   /**
-    * Get the version information
-    *
-    * @param cookie id of the client receiving the command
-    * @param response_handler to send the result back to the client, but
-    *                         don't send reply on success!
-    *
-    */
-   protocol_binary_response_status (*version)(const void *cookie,
-                                              memcached_binary_protocol_version_response_handler response_handler);
-} memcached_binary_protocol_callback_v1_st;
-
-
-/**
- * The version numbers for the different callback structures.
- */
-typedef enum {
-   /** Version 0 is a lowlevel interface that tries to maximize your freedom */
-   MEMCACHED_PROTOCOL_HANDLER_V0= 0,
-   /**
-    * Version 1 abstracts more of the protocol details, and let you work at
-    * a logical level
-    */
-   MEMCACHED_PROTOCOL_HANDLER_V1= 1,
-} memcached_protocol_interface_version_t;
-
-/**
- * Definition of the protocol callback structure.
- */
-typedef struct {
-   /**
-    * The interface version you provide callbacks for.
-    */
-   memcached_protocol_interface_version_t interface_version;
-
-   /**
-    * Callback fired just before the command will be executed.
-    *
-    * @param cookie id of the client receiving the command
-    * @param header the command header as received on the wire. If you look
-    *               at the content you <b>must</b> ensure that you don't
-    *               try to access beyond the end of the message.
-    */
-   void (*pre_execute)(const void *cookie,
-                       protocol_binary_request_header *header);
-   /**
-    * Callback fired just after the command was exected (please note
-    * that the data transfer back to the client is not finished at this
-    * time).
-    *
-    * @param cookie id of the client receiving the command
-    * @param header the command header as received on the wire. If you look
-    *               at the content you <b>must</b> ensure that you don't
-    *               try to access beyond the end of the message.
-    */
-   void (*post_execute)(const void *cookie,
-                        protocol_binary_request_header *header);
-
-   /**
-    * Callback fired if no specialized callback is registered for this
-    * specific command code.
-    *
-    * @param cookie id of the client receiving the command
-    * @param header the command header as received on the wire. You <b>must</b>
-    *               ensure that you don't try to access beyond the end of the
-    *               message.
-    * @param response_handler The response handler to send data back.
-    */
-   protocol_binary_response_status (*unknown)(const void *cookie,
-                                              protocol_binary_request_header *header,
-                                              memcached_binary_protocol_raw_response_handler response_handler);
-
-   /**
-    * The different interface levels we support. A pointer is used so the
-    * size of the structure is fixed. You must ensure that the memory area
-    * passed as the pointer is valid as long as you use the protocol handler.
-    */
-   union {
-      memcached_binary_protocol_callback_v0_st v0;
-
-      /**
-       * The first version of the callback struct containing all of the
-       * documented commands in the initial release of the binary protocol
-       * (aka. memcached 1.4.0).
-       */
-      memcached_binary_protocol_callback_v1_st v1;
-   } interface;
-} memcached_binary_protocol_callback_st;
-
-#endif
diff --git a/libmemcached/protocol/common.h b/libmemcached/protocol/common.h
deleted file mode 100644 (file)
index 808a608..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#include "config.h"
-#if !defined(__cplusplus)
-# include <stdbool.h>
-#endif
-#include <assert.h>
-
-#include <libmemcached/visibility.h>
-#include <libmemcached/protocol_handler.h>
-#include <libmemcached/protocol/cache.h>
-
-/*
- * I don't really need the following two functions as function pointers
- * in the instance handle, but I don't want to put them in the global
- * namespace for those linking statically (personally I don't like that,
- * but some people still do). If it ever shows up as a performance thing
- * I'll look into optimizing this ;-)
- */
-typedef bool (*drain_func)(memcached_protocol_client_st *client);
-typedef protocol_binary_response_status (*spool_func)(memcached_protocol_client_st *client,
-                                                      const void *data,
-                                                      size_t length);
-
-/**
- * Definition of the per instance structure.
- */
-struct memcached_protocol_st {
-  memcached_binary_protocol_callback_st *callback;
-  memcached_protocol_recv_func recv;
-  memcached_protocol_send_func send;
-
-  /*
-   * I really don't need these as funciton pointers, but I don't want
-   * to clutter the namespace if someone links statically.
-   */
-  drain_func drain;
-  spool_func spool;
-
-  /*
-   * To avoid keeping a buffer in each client all the time I have a
-   * bigger buffer in the instance that I read to initially, and then
-   * I try to parse and execute as much from the buffer. If I wasn't able
-   * to process all data I'll keep that in a per-connection buffer until
-   * the next time I can read from the socket.
-   */
-  uint8_t *input_buffer;
-  size_t input_buffer_size;
-
-  bool pedantic;
-  /* @todo use multiple sized buffers */
-  cache_t *buffer_cache;
-};
-
-struct chunk_st {
-  /* Pointer to the data */
-  char *data;
-  /* The offset to the first byte into the buffer that is used */
-  size_t offset;
-  /* The offset into the buffer for the first free byte */
-  size_t nbytes;
-  /* The number of bytes in the buffer */
-  size_t size;
-  /* Pointer to the next buffer in the chain */
-  struct chunk_st *next;
-};
-
-#define CHUNK_BUFFERSIZE 2048
-
-typedef memcached_protocol_event_t (*process_data)(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr);
-
-enum ascii_cmd {
-  GET_CMD,
-  GETS_CMD,
-  SET_CMD,
-  ADD_CMD,
-  REPLACE_CMD,
-  CAS_CMD,
-  APPEND_CMD,
-  PREPEND_CMD,
-  DELETE_CMD,
-  INCR_CMD,
-  DECR_CMD,
-  STATS_CMD,
-  FLUSH_ALL_CMD,
-  VERSION_CMD,
-  QUIT_CMD,
-  VERBOSITY_CMD,
-  UNKNOWN_CMD
-};
-
-struct memcached_protocol_client_st {
-  memcached_protocol_st *root;
-  memcached_socket_t sock;
-  int error;
-
-  /* Linked list of data to send */
-  struct chunk_st *output;
-  struct chunk_st *output_tail;
-
-  /*
-   * While we process input data, this is where we spool incomplete commands
-   * if we need to receive more data....
-   * @todo use the buffercace
-   */
-  uint8_t *input_buffer;
-  size_t input_buffer_size;
-  size_t input_buffer_offset;
-
-  /* The callback to the protocol handler to use (ascii or binary) */
-  process_data work;
-
-  /*
-   * Should the spool data discard the data to send or not? (aka noreply in
-   * the ascii protocol..
-   */
-  bool mute;
-
-  /* Members used by the binary protocol */
-  protocol_binary_request_header *current_command;
-
-  /* Members used by the ascii protocol */
-  enum ascii_cmd ascii_command;
-};
-
-#include "ascii_handler.h"
-#include "binary_handler.h"
diff --git a/libmemcached/protocol/include.am b/libmemcached/protocol/include.am
deleted file mode 100644 (file)
index d5bd9c4..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# vim:ft=automake
-# included from Top Level Makefile.am
-# All paths should be given relative to the root
-
-
-lib_LTLIBRARIES+= libmemcached/libmemcachedprotocol.la
-libmemcached_libmemcachedprotocol_la_SOURCES=  \
-                                              libmemcached/byteorder.cc \
-                                              libmemcached/protocol/ascii_handler.c \
-                                              libmemcached/protocol/binary_handler.c \
-                                              libmemcached/protocol/cache.c \
-                                              libmemcached/protocol/pedantic.c \
-                                              libmemcached/protocol/protocol_handler.c
-
-libmemcached_libmemcachedprotocol_la_CFLAGS= \
-                                            ${AM_CFLAGS} \
-                                            ${NO_CONVERSION} \
-                                            -DBUILDING_LIBMEMCACHED
-libmemcached_libmemcachedprotocol_la_CFLAGS+= ${PTHREAD_CFLAGS}
-
-libmemcached_libmemcachedprotocol_la_CXXFLAGS= \
-                                              ${AM_CXXFLAGS} \
-                                              -DBUILDING_LIBMEMCACHED
-libmemcached_libmemcachedprotocol_la_CXXFLAGS+= ${PTHREAD_CFLAGS}
-
-libmemcached_libmemcachedprotocol_la_LIBADD= ${PTHREAD_LIBS}
-libmemcached_libmemcachedprotocol_la_LDFLAGS= ${AM_LDFLAGS}
-libmemcached_libmemcachedprotocol_la_LDFLAGS+= -version-info ${MEMCACHED_PROTOCAL_LIBRARY_VERSION}
diff --git a/libmemcached/protocol/pedantic.c b/libmemcached/protocol/pedantic.c
deleted file mode 100644 (file)
index f275b39..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#include <libmemcached/protocol/common.h>
-
-#include <sys/types.h>
-#include <inttypes.h>
-
-#define ensure(a) if (!(a)) { return false; }
-
-bool memcached_binary_protocol_pedantic_check_request(const protocol_binary_request_header *request)
-{
-  ensure(request->request.magic == PROTOCOL_BINARY_REQ);
-  ensure(request->request.datatype == PROTOCOL_BINARY_RAW_BYTES);
-
-  ensure(request->bytes[6] == 0);
-  ensure(request->bytes[7] == 0);
-
-  uint8_t opcode= request->request.opcode;
-  uint16_t keylen= ntohs(request->request.keylen);
-  uint8_t extlen= request->request.extlen;
-  uint32_t bodylen= ntohl(request->request.bodylen);
-
-  ensure(bodylen >= (keylen + extlen));
-
-  switch (opcode) {
-  case PROTOCOL_BINARY_CMD_GET:
-  case PROTOCOL_BINARY_CMD_GETK:
-  case PROTOCOL_BINARY_CMD_GETKQ:
-  case PROTOCOL_BINARY_CMD_GETQ:
-    ensure(extlen == 0);
-    ensure(keylen > 0);
-    ensure(keylen == bodylen);
-    ensure(request->request.cas == 0);
-    break;
-
-  case PROTOCOL_BINARY_CMD_ADD:
-  case PROTOCOL_BINARY_CMD_ADDQ:
-    /* it makes no sense to run add with a cas value */
-    ensure(request->request.cas == 0);
-    /* FALLTHROUGH */
-  case PROTOCOL_BINARY_CMD_SET:
-  case PROTOCOL_BINARY_CMD_SETQ:
-  case PROTOCOL_BINARY_CMD_REPLACE:
-  case PROTOCOL_BINARY_CMD_REPLACEQ:
-    ensure(keylen > 0);
-    ensure(extlen == 8);
-    break;
-
-  case PROTOCOL_BINARY_CMD_DELETE:
-  case PROTOCOL_BINARY_CMD_DELETEQ:
-    ensure(extlen == 0);
-    ensure(keylen > 0);
-    ensure(keylen == bodylen);
-    break;
-
-  case PROTOCOL_BINARY_CMD_INCREMENT:
-  case PROTOCOL_BINARY_CMD_INCREMENTQ:
-  case PROTOCOL_BINARY_CMD_DECREMENT:
-  case PROTOCOL_BINARY_CMD_DECREMENTQ:
-    ensure(extlen == 20);
-    ensure(keylen > 0);
-    ensure(keylen + extlen == bodylen);
-    break;
-
-  case PROTOCOL_BINARY_CMD_QUIT:
-  case PROTOCOL_BINARY_CMD_QUITQ:
-  case PROTOCOL_BINARY_CMD_NOOP:
-  case PROTOCOL_BINARY_CMD_VERSION:
-    ensure(extlen == 0);
-    ensure(keylen == 0);
-    ensure(bodylen == 0);
-    break;
-
-  case PROTOCOL_BINARY_CMD_FLUSH:
-  case PROTOCOL_BINARY_CMD_FLUSHQ:
-    ensure(extlen == 0 || extlen == 4);
-    ensure(keylen == 0);
-    ensure(bodylen == extlen);
-    break;
-
-  case PROTOCOL_BINARY_CMD_STAT:
-    ensure(extlen == 0);
-    /* May have key, but not value */
-    ensure(keylen == bodylen);
-    break;
-
-  case PROTOCOL_BINARY_CMD_APPEND:
-  case PROTOCOL_BINARY_CMD_APPENDQ:
-  case PROTOCOL_BINARY_CMD_PREPEND:
-  case PROTOCOL_BINARY_CMD_PREPENDQ:
-    ensure(extlen == 0);
-    ensure(keylen > 0);
-    break;
-  default:
-    /* Unknown command */
-    ;
-  }
-
-  return true;
-}
-
-bool memcached_binary_protocol_pedantic_check_response(const protocol_binary_request_header *request,
-                                                       const protocol_binary_response_header *response)
-{
-  ensure(response->response.magic == PROTOCOL_BINARY_RES);
-  ensure(response->response.datatype == PROTOCOL_BINARY_RAW_BYTES);
-  ensure(response->response.opaque == request->request.opaque);
-
-  uint16_t status= ntohs(response->response.status);
-  uint8_t opcode= response->response.opcode;
-
-  if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS)
-  {
-    switch (opcode) {
-    case PROTOCOL_BINARY_CMD_ADDQ:
-    case PROTOCOL_BINARY_CMD_APPENDQ:
-    case PROTOCOL_BINARY_CMD_DECREMENTQ:
-    case PROTOCOL_BINARY_CMD_DELETEQ:
-    case PROTOCOL_BINARY_CMD_FLUSHQ:
-    case PROTOCOL_BINARY_CMD_INCREMENTQ:
-    case PROTOCOL_BINARY_CMD_PREPENDQ:
-    case PROTOCOL_BINARY_CMD_QUITQ:
-    case PROTOCOL_BINARY_CMD_REPLACEQ:
-    case PROTOCOL_BINARY_CMD_SETQ:
-      /* Quiet command shouldn't return on success */
-      return false;
-    default:
-      break;
-    }
-
-    switch (opcode) {
-    case PROTOCOL_BINARY_CMD_ADD:
-    case PROTOCOL_BINARY_CMD_REPLACE:
-    case PROTOCOL_BINARY_CMD_SET:
-    case PROTOCOL_BINARY_CMD_APPEND:
-    case PROTOCOL_BINARY_CMD_PREPEND:
-      ensure(response->response.keylen == 0);
-      ensure(response->response.extlen == 0);
-      ensure(response->response.bodylen == 0);
-      ensure(response->response.cas != 0);
-      break;
-    case PROTOCOL_BINARY_CMD_FLUSH:
-    case PROTOCOL_BINARY_CMD_NOOP:
-    case PROTOCOL_BINARY_CMD_QUIT:
-    case PROTOCOL_BINARY_CMD_DELETE:
-      ensure(response->response.keylen == 0);
-      ensure(response->response.extlen == 0);
-      ensure(response->response.bodylen == 0);
-      ensure(response->response.cas == 0);
-      break;
-
-    case PROTOCOL_BINARY_CMD_DECREMENT:
-    case PROTOCOL_BINARY_CMD_INCREMENT:
-      ensure(response->response.keylen == 0);
-      ensure(response->response.extlen == 0);
-      ensure(ntohl(response->response.bodylen) == 8);
-      ensure(response->response.cas != 0);
-      break;
-
-    case PROTOCOL_BINARY_CMD_STAT:
-      ensure(response->response.extlen == 0);
-      /* key and value exists in all packets except in the terminating */
-      ensure(response->response.cas == 0);
-      break;
-
-    case PROTOCOL_BINARY_CMD_VERSION:
-      ensure(response->response.keylen == 0);
-      ensure(response->response.extlen == 0);
-      ensure(response->response.bodylen != 0);
-      ensure(response->response.cas == 0);
-      break;
-
-    case PROTOCOL_BINARY_CMD_GET:
-    case PROTOCOL_BINARY_CMD_GETQ:
-      ensure(response->response.keylen == 0);
-      ensure(response->response.extlen == 4);
-      ensure(response->response.cas != 0);
-      break;
-
-    case PROTOCOL_BINARY_CMD_GETK:
-    case PROTOCOL_BINARY_CMD_GETKQ:
-      ensure(response->response.keylen != 0);
-      ensure(response->response.extlen == 4);
-      ensure(response->response.cas != 0);
-      break;
-
-    default:
-      /* Undefined command code */
-      break;
-    }
-  }
-  else
-  {
-    ensure(response->response.cas == 0);
-    ensure(response->response.extlen == 0);
-    if (opcode != PROTOCOL_BINARY_CMD_GETK)
-    {
-      ensure(response->response.keylen == 0);
-    }
-  }
-
-  return true;
-}
diff --git a/libmemcached/protocol/protocol_handler.c b/libmemcached/protocol/protocol_handler.c
deleted file mode 100644 (file)
index 99b4ff2..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#include <libmemcached/protocol/common.h>
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <string.h>
-#include <strings.h>
-#include <ctype.h>
-#include <stdio.h>
-
-/*
-** **********************************************************************
-** INTERNAL INTERFACE
-** **********************************************************************
-*/
-
-/**
- * The default function to receive data from the client. This function
- * just wraps the recv function to receive from a socket.
- * See man -s3socket recv for more information.
- *
- * @param cookie cookie indentifying a client, not used
- * @param sock socket to read from
- * @param buf the destination buffer
- * @param nbytes the number of bytes to read
- * @return the number of bytes transferred of -1 upon error
- */
-static ssize_t default_recv(const void *cookie,
-                            memcached_socket_t sock,
-                            void *buf,
-                            size_t nbytes)
-{
-  (void)cookie;
-  return recv(sock, buf, nbytes, 0);
-}
-
-/**
- * The default function to send data to the server. This function
- * just wraps the send function to send through a socket.
- * See man -s3socket send for more information.
- *
- * @param cookie cookie indentifying a client, not used
- * @param sock socket to send to
- * @param buf the source buffer
- * @param nbytes the number of bytes to send
- * @return the number of bytes transferred of -1 upon error
- */
-static ssize_t default_send(const void *cookie,
-                            memcached_socket_t fd,
-                            const void *buf,
-                            size_t nbytes)
-{
-  (void)cookie;
-  return send(fd, buf, nbytes, 0);
-}
-
-/**
- * Try to drain the output buffers without blocking
- *
- * @param client the client to drain
- * @return false if an error occured (connection should be shut down)
- *         true otherwise (please note that there may be more data to
- *              left in the buffer to send)
- */
-static bool drain_output(struct memcached_protocol_client_st *client)
-{
-  ssize_t len;
-
-  /* Do we have pending data to send? */
-  while (client->output != NULL)
-  {
-    len= client->root->send(client,
-                            client->sock,
-                            client->output->data + client->output->offset,
-                            client->output->nbytes - client->output->offset);
-
-    if (len == -1)
-    {
-      if (get_socket_errno() == EWOULDBLOCK)
-      {
-        return true;
-      }
-      else if (get_socket_errno() != EINTR)
-      {
-        client->error= get_socket_errno();
-        return false;
-      }
-    }
-    else
-    {
-      client->output->offset += (size_t)len;
-      if (client->output->offset == client->output->nbytes)
-      {
-        /* This was the complete buffer */
-        struct chunk_st *old= client->output;
-        client->output= client->output->next;
-        if (client->output == NULL)
-        {
-          client->output_tail= NULL;
-        }
-        cache_free(client->root->buffer_cache, old);
-      }
-    }
-  }
-
-  return true;
-}
-
-/**
- * Allocate an output buffer and chain it into the output list
- *
- * @param client the client that needs the buffer
- * @return pointer to the new chunk if the allocation succeeds, NULL otherwise
- */
-static struct chunk_st *allocate_output_chunk(struct memcached_protocol_client_st *client)
-{
-  struct chunk_st *ret= cache_alloc(client->root->buffer_cache);
-
-  if (ret == NULL)
-  {
-    return NULL;
-  }
-
-  ret->offset= ret->nbytes= 0;
-  ret->next= NULL;
-  ret->size= CHUNK_BUFFERSIZE;
-  ret->data= (void*)(ret + 1);
-  if (client->output == NULL)
-  {
-    client->output= client->output_tail= ret;
-  }
-  else
-  {
-    client->output_tail->next= ret;
-    client->output_tail= ret;
-  }
-
-  return ret;
-}
-
-/**
- * Spool data into the send-buffer for a client.
- *
- * @param client the client to spool the data for
- * @param data the data to spool
- * @param length the number of bytes of data to spool
- * @return PROTOCOL_BINARY_RESPONSE_SUCCESS if success,
- *         PROTOCOL_BINARY_RESPONSE_ENOMEM if we failed to allocate memory
- */
-static protocol_binary_response_status spool_output(struct memcached_protocol_client_st *client,
-                                                    const void *data,
-                                                    size_t length)
-{
-  if (client->mute)
-  {
-    return PROTOCOL_BINARY_RESPONSE_SUCCESS;
-  }
-
-  size_t offset= 0;
-
-  struct chunk_st *chunk= client->output;
-  while (offset < length)
-  {
-    if (chunk == NULL || (chunk->size - chunk->nbytes) == 0)
-    {
-      if ((chunk= allocate_output_chunk(client)) == NULL)
-      {
-        return PROTOCOL_BINARY_RESPONSE_ENOMEM;
-      }
-    }
-
-    size_t bulk= length - offset;
-    if (bulk > chunk->size - chunk->nbytes)
-    {
-      bulk= chunk->size - chunk->nbytes;
-    }
-
-    memcpy(chunk->data + chunk->nbytes, data, bulk);
-    chunk->nbytes += bulk;
-    offset += bulk;
-  }
-
-  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
-}
-
-/**
- * Try to determine the protocol used on this connection.
- * If the first byte contains the magic byte PROTOCOL_BINARY_REQ we should
- * be using the binary protocol on the connection. I implemented the support
- * for the ASCII protocol by wrapping into the simple interface (aka v1),
- * so the implementors needs to provide an implementation of that interface
- *
- */
-static memcached_protocol_event_t determine_protocol(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr)
-{
-  if (*client->root->input_buffer == (uint8_t)PROTOCOL_BINARY_REQ)
-  {
-    client->work= memcached_binary_protocol_process_data;
-  }
-  else if (client->root->callback->interface_version == 1)
-  {
-    /*
-     * The ASCII protocol can only be used if the implementors provide
-     * an implementation for the version 1 of the interface..
-     *
-     * @todo I should allow the implementors to provide an implementation
-     *       for version 0 and 1 at the same time and set the preferred
-     *       interface to use...
-     */
-    client->work= memcached_ascii_protocol_process_data;
-  }
-  else
-  {
-    /* Let's just output a warning the way it is supposed to look like
-     * in the ASCII protocol...
-     */
-    const char *err= "CLIENT_ERROR: Unsupported protocol\r\n";
-    client->root->spool(client, err, strlen(err));
-    client->root->drain(client);
-    return MEMCACHED_PROTOCOL_ERROR_EVENT; /* Unsupported protocol */
-  }
-
-  return client->work(client, length, endptr);
-}
-
-/*
-** **********************************************************************
-** * PUBLIC INTERFACE
-** * See protocol_handler.h for function description
-** **********************************************************************
-*/
-struct memcached_protocol_st *memcached_protocol_create_instance(void)
-{
-  struct memcached_protocol_st *ret= calloc(1, sizeof(*ret));
-  if (ret != NULL)
-  {
-    ret->recv= default_recv;
-    ret->send= default_send;
-    ret->drain= drain_output;
-    ret->spool= spool_output;
-    ret->input_buffer_size= 1 * 1024 * 1024;
-    ret->input_buffer= malloc(ret->input_buffer_size);
-    if (ret->input_buffer == NULL)
-    {
-      free(ret);
-      ret= NULL;
-      return NULL;
-    }
-
-    ret->buffer_cache= cache_create("protocol_handler",
-                                     CHUNK_BUFFERSIZE + sizeof(struct chunk_st),
-                                     0, NULL, NULL);
-    if (ret->buffer_cache == NULL)
-    {
-      free(ret->input_buffer);
-      free(ret);
-    }
-  }
-
-  return ret;
-}
-
-void memcached_protocol_destroy_instance(struct memcached_protocol_st *instance)
-{
-  cache_destroy(instance->buffer_cache);
-  free(instance->input_buffer);
-  free(instance);
-}
-
-struct memcached_protocol_client_st *memcached_protocol_create_client(struct memcached_protocol_st *instance, memcached_socket_t sock)
-{
-  struct memcached_protocol_client_st *ret= calloc(1, sizeof(*ret));
-  if (ret != NULL)
-  {
-    ret->root= instance;
-    ret->sock= sock;
-    ret->work= determine_protocol;
-  }
-
-  return ret;
-}
-
-void memcached_protocol_client_destroy(struct memcached_protocol_client_st *client)
-{
-  free(client);
-}
-
-memcached_protocol_event_t memcached_protocol_client_work(struct memcached_protocol_client_st *client)
-{
-  /* Try to send data and read from the socket */
-  bool more_data= true;
-  do
-  {
-    ssize_t len= client->root->recv(client,
-                                    client->sock,
-                                    client->root->input_buffer + client->input_buffer_offset,
-                                    client->root->input_buffer_size - client->input_buffer_offset);
-
-    if (len > 0)
-    {
-      /* Do we have the complete packet? */
-      if (client->input_buffer_offset > 0)
-      {
-        memcpy(client->root->input_buffer, client->input_buffer,
-               client->input_buffer_offset);
-        len += (ssize_t)client->input_buffer_offset;
-
-        /* @todo use buffer-cache! */
-        free(client->input_buffer);
-        client->input_buffer_offset= 0;
-      }
-
-      void *endptr;
-      memcached_protocol_event_t events= client->work(client, &len, &endptr);
-      if (events == MEMCACHED_PROTOCOL_ERROR_EVENT)
-      {
-        return MEMCACHED_PROTOCOL_ERROR_EVENT;
-      }
-
-      if (len > 0)
-      {
-        /* save the data for later on */
-        /* @todo use buffer-cache */
-        client->input_buffer= malloc((size_t)len);
-        if (client->input_buffer == NULL)
-        {
-          client->error= ENOMEM;
-          return MEMCACHED_PROTOCOL_ERROR_EVENT;
-        }
-        memcpy(client->input_buffer, endptr, (size_t)len);
-        client->input_buffer_offset= (size_t)len;
-        more_data= false;
-      }
-    }
-    else if (len == 0)
-    {
-      /* Connection closed */
-      drain_output(client);
-      return MEMCACHED_PROTOCOL_ERROR_EVENT;
-    }
-    else
-    {
-      if (get_socket_errno() != EWOULDBLOCK)
-      {
-        client->error= get_socket_errno();
-        /* mark this client as terminated! */
-        return MEMCACHED_PROTOCOL_ERROR_EVENT;
-      }
-      more_data= false;
-    }
-  } while (more_data);
-
-  if (!drain_output(client))
-  {
-    return MEMCACHED_PROTOCOL_ERROR_EVENT;
-  }
-
-  memcached_protocol_event_t ret= MEMCACHED_PROTOCOL_READ_EVENT;
-  if (client->output)
-    ret|= MEMCACHED_PROTOCOL_READ_EVENT;
-
-  return ret;
-}
diff --git a/libmemcached/protocol_handler.h b/libmemcached/protocol_handler.h
deleted file mode 100644 (file)
index 1eee5ca..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/* LibMemcached
- * Copyright (C) 2006-2009 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- *
- * Summary: Definition of the callback interface to the protocol handler
- *
- * Author: Trond Norbye
- *
- */
-
-#pragma once
-
-#include <sys/types.h>
-#if !defined(__cplusplus)
-# include <stdbool.h>
-#endif
-
-#include <libmemcached/platform.h>
-#include <libmemcached/memcached/protocol_binary.h>
-#include <libmemcached/visibility.h>
-#include <libmemcached/protocol/callback.h>
-
-/* Forward declarations */
-/*
- * You should only access memcached_protocol_st from one thread!,
- * and never assume anything about the internal layout / sizes of the
- * structures.
- */
-typedef struct memcached_protocol_st memcached_protocol_st;
-typedef struct memcached_protocol_client_st memcached_protocol_client_st;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Function the protocol handler should call to receive data.
- * This function should behave exactly like read(2)
- *
- * @param cookie a cookie used to represent a given client
- * @param fd the filedescriptor associated with the client
- * @param buf destination buffer
- * @param nbuf number of bytes to receive
- * @return the number of bytes copied into buf
- *         or -1 upon error (errno should contain more information)
- */
-typedef ssize_t (*memcached_protocol_recv_func)(const void *cookie,
-                                                memcached_socket_t fd,
-                                                void *buf,
-                                                size_t nbuf);
-
-/**
- * Function the protocol handler should call to send data.
- * This function should behave exactly like write(2)
- *
- * @param cookie a cookie used to represent a given client
- * @param fd the filedescriptor associated with the client
- * @param buf the source buffer
- * @param nbuf number of bytes to send
- * @return the number of bytes sent
- *         or -1 upon error (errno should contain more information)
- */
-typedef ssize_t (*memcached_protocol_send_func)(const void *cookie,
-                                                memcached_socket_t fd,
-                                                const void *buf,
-                                                size_t nbuf);
-
-/**
- * Create an instance of the protocol handler
- *
- * @return NULL if allocation of an instance fails
- */
-LIBMEMCACHED_API
-memcached_protocol_st *memcached_protocol_create_instance(void);
-
-/**
- * Get the callbacks associated with a protocol handler instance
- * @return the callbacks currently used
- */
-LIBMEMCACHED_API
-memcached_binary_protocol_callback_st *memcached_binary_protocol_get_callbacks(memcached_protocol_st *instance);
-
-/**
- * Set the callbacks to be used by the given protocol handler instance
- * @param instance the instance to update
- * @param callback the callbacks to use
- */
-LIBMEMCACHED_API
-void memcached_binary_protocol_set_callbacks(memcached_protocol_st *instance, memcached_binary_protocol_callback_st *callback);
-
-/**
- * Should the library inspect the packages being sent and received and verify
- * that they are according to the specification? If it encounters an invalid
- * packet, it will return an EINVAL packet.
- *
- * @param instance the instance to update
- * @param enable true if you want the library to check packages, false otherwise
- */
-LIBMEMCACHED_API
-void memcached_binary_protocol_set_pedantic(memcached_protocol_st *instance, bool enable);
-
-/**
- * Is the library inpecting each package?
- * @param instance the instance to check
- * @return true it the library is inspecting each package, false otherwise
- */
-LIBMEMCACHED_API
-bool memcached_binary_protocol_get_pedantic(memcached_protocol_st *instance);
-
-/**
- * Destroy an instance of the protocol handler
- *
- * @param instance The instance to destroy
- */
-LIBMEMCACHED_API
-void memcached_protocol_destroy_instance(memcached_protocol_st *instance);
-
-/**
- * Set the IO functions used by the instance to send and receive data. The
- * functions should behave like recv(3socket) and send(3socket).
- *
- * @param instance the instance to specify the IO functions for
- * @param recv the function to call for reciving data
- * @param send the function to call for sending data
- */
-LIBMEMCACHED_API
-void memached_protocol_set_io_functions(memcached_protocol_st *instance,
-                                        memcached_protocol_recv_func recv,
-                                        memcached_protocol_send_func send);
-
-
-/**
- * Create a new client instance and associate it with a socket
- * @param instance the protocol instance to bind the client to
- * @param sock the client socket
- * @return NULL if allocation fails, otherwise an instance
- */
-LIBMEMCACHED_API
-memcached_protocol_client_st *memcached_protocol_create_client(memcached_protocol_st *instance, memcached_socket_t sock);
-
-/**
- * Destroy a client handle.
- * The caller needs to close the socket accociated with the client
- * <b>before</b> calling this function. This function invalidates the
- * client memory area.
- *
- * @param client the client to destroy
- */
-LIBMEMCACHED_API
-void memcached_protocol_client_destroy(memcached_protocol_client_st *client);
-
-/**
- * Error event means that the client encountered an error with the
- * connection so you should shut it down
- */
-#define MEMCACHED_PROTOCOL_ERROR_EVENT 1
-/**
- * Please notify when there is more data available to read
- */
-#define MEMCACHED_PROTOCOL_READ_EVENT 2
-/**
- * Please notify when it is possible to send more data
- */
-#define MEMCACHED_PROTOCOL_WRITE_EVENT 4
-/**
- * Backed paused the execution for this client
- */
-#define MEMCACHED_PROTOCOL_PAUSE_EVENT 8
-
-/**
- * The different events the client is interested in. This is a bitmask of
- * the constants defined above.
- */
-typedef uint32_t memcached_protocol_event_t;
-
-/**
- * Let the client do some work. This might involve reading / sending data
- * to/from the client, or perform callbacks to execute a command.
- * @param client the client structure to work on
- * @return The next event the protocol handler will be notified for
- */
-LIBMEMCACHED_API
-memcached_protocol_event_t memcached_protocol_client_work(memcached_protocol_client_st *client);
-
-/**
- * Get the socket attached to a client handle
- * @param client the client to query
- * @return the socket handle
- */
-LIBMEMCACHED_API
-memcached_socket_t memcached_protocol_client_get_socket(memcached_protocol_client_st *client);
-
-/**
- * Get the error id socket attached to a client handle
- * @param client the client to query for an error code
- * @return the OS error code from the client
- */
-LIBMEMCACHED_API
-int memcached_protocol_client_get_errno(memcached_protocol_client_st *client);
-
-/**
- * Get a raw response handler for the given cookie
- * @param cookie the cookie passed along into the callback
- * @return the raw reponse handler you may use if you find
- *         the generic callback too limiting
- */
-LIBMEMCACHED_API
-memcached_binary_protocol_raw_response_handler memcached_binary_protocol_get_raw_response_handler(const void *cookie);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/quit.h b/libmemcached/quit.h
deleted file mode 100644 (file)
index 0338eaf..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-void memcached_quit(memcached_st *ptr);
-
-LIBMEMCACHED_LOCAL
-void memcached_quit_server(memcached_server_st *ptr, bool io_death);
-
-LIBMEMCACHED_LOCAL
-void send_quit(memcached_st *ptr);
-
-#ifdef __cplusplus
-}
-#endif
index adecd6e1c38475d6f2dab01a3a82dd66f9f083ca..061f7401fee84a19dbd462a0564601ebce5a7276 100644 (file)
@@ -1,5 +1,5 @@
 /*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
+ *
  *  Libmemcached library
  *
  *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
@@ -71,7 +71,9 @@ memcached_return_t memcached_read_one_response(memcached_server_write_instance_s
            rc == MEMCACHED_PROTOCOL_ERROR or
            rc == MEMCACHED_CLIENT_ERROR or
            rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE)
+  {
     memcached_io_reset(ptr);
+  }
 
   return rc;
 }
@@ -124,7 +126,9 @@ static memcached_return_t textual_value_fetch(memcached_server_write_instance_st
   ssize_t read_length= 0;
 
   if (ptr->root->flags.use_udp)
+  {
     return memcached_set_error(*ptr, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT);
+  }
 
   WATCHPOINT_ASSERT(ptr->root);
   end_ptr= buffer + MEMCACHED_DEFAULT_COMMAND_SIZE;
@@ -280,6 +284,7 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta
     }
   case 'O': /* OK */
     return MEMCACHED_SUCCESS;
+
   case 'S': /* STORED STATS SERVER_ERROR */
     {
       if (buffer[2] == 'A') /* STORED STATS */
@@ -328,9 +333,13 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta
   case 'N': /* NOT_FOUND */
     {
       if (buffer[4] == 'F')
+      {
         return MEMCACHED_NOTFOUND;
+      }
       else if (buffer[4] == 'S')
+      {
         return MEMCACHED_NOTSTORED;
+      }
       else
       {
         WATCHPOINT_STRING(buffer);
@@ -340,11 +349,17 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta
   case 'E': /* PROTOCOL ERROR or END */
     {
       if (buffer[1] == 'N')
+      {
         return MEMCACHED_END;
+      }
       else if (buffer[1] == 'R')
+      {
         return MEMCACHED_PROTOCOL_ERROR;
+      }
       else if (buffer[1] == 'X')
+      {
         return MEMCACHED_DATA_EXISTS;
+      }
       else
       {
         WATCHPOINT_STRING(buffer);
@@ -352,12 +367,25 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta
       }
 
     }
+  case 'T': /* TOUCHED */
+    {
+      if (buffer[1] == 'O' and buffer[2] == 'U' 
+          and buffer[3] == 'C' and buffer[4] == 'H' 
+          and buffer[5] == 'E' and buffer[6] == 'D')
+      {
+        return MEMCACHED_SUCCESS;
+      }
+    }
+    return MEMCACHED_UNKNOWN_READ_FAILURE;
+
   case 'I': /* CLIENT ERROR */
     /* We add back in one because we will need to search for END */
     memcached_server_response_increment(ptr);
     return MEMCACHED_ITEM;
+
   case 'C': /* CLIENT ERROR */
     return MEMCACHED_CLIENT_ERROR;
+
   default:
     {
       unsigned long long auto_return_value;
@@ -511,15 +539,18 @@ static memcached_return_t binary_read_one_response(memcached_server_write_instan
     case PROTOCOL_BINARY_CMD_APPEND:
     case PROTOCOL_BINARY_CMD_PREPEND:
     case PROTOCOL_BINARY_CMD_DELETE:
+    case PROTOCOL_BINARY_CMD_TOUCH:
       {
         WATCHPOINT_ASSERT(bodylen == 0);
         return MEMCACHED_SUCCESS;
       }
+
     case PROTOCOL_BINARY_CMD_NOOP:
       {
         WATCHPOINT_ASSERT(bodylen == 0);
         return MEMCACHED_END;
       }
+
     case PROTOCOL_BINARY_CMD_STAT:
       {
         if (bodylen == 0)
diff --git a/libmemcached/result.h b/libmemcached/result.h
deleted file mode 100644 (file)
index 41608b5..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-struct memcached_result_st {
-  uint32_t item_flags;
-  time_t item_expiration;
-  size_t key_length;
-  uint64_t item_cas;
-  memcached_st *root;
-  memcached_string_st value;
-  uint64_t count;
-  char item_key[MEMCACHED_MAX_KEY];
-  struct {
-    bool is_allocated:1;
-    bool is_initialized:1;
-  } options;
-  /* Add result callback function */
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Result Struct */
-LIBMEMCACHED_API
-void memcached_result_free(memcached_result_st *result);
-
-LIBMEMCACHED_API
-void memcached_result_reset(memcached_result_st *ptr);
-
-LIBMEMCACHED_API
-memcached_result_st *memcached_result_create(const memcached_st *ptr,
-                                             memcached_result_st *result);
-
-LIBMEMCACHED_API
-const char *memcached_result_key_value(const memcached_result_st *self);
-
-LIBMEMCACHED_API
-size_t memcached_result_key_length(const memcached_result_st *self);
-
-LIBMEMCACHED_API
-const char *memcached_result_value(const memcached_result_st *self);
-
-LIBMEMCACHED_API
-size_t memcached_result_length(const memcached_result_st *self);
-
-LIBMEMCACHED_API
-uint32_t memcached_result_flags(const memcached_result_st *self);
-
-LIBMEMCACHED_API
-uint64_t memcached_result_cas(const memcached_result_st *self);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_result_set_value(memcached_result_st *ptr, const char *value, size_t length);
-
-LIBMEMCACHED_API
-void memcached_result_set_flags(memcached_result_st *self, uint32_t flags);
-
-LIBMEMCACHED_API
-void memcached_result_set_expiration(memcached_result_st *self, time_t expiration);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/libmemcached/return.h b/libmemcached/return.h
deleted file mode 100644 (file)
index fa36243..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-enum memcached_return_t {
-  MEMCACHED_SUCCESS,
-  MEMCACHED_FAILURE,
-  MEMCACHED_HOST_LOOKUP_FAILURE, // getaddrinfo() and getnameinfo() only
-  MEMCACHED_CONNECTION_FAILURE,
-  MEMCACHED_CONNECTION_BIND_FAILURE,  // DEPRECATED, see MEMCACHED_HOST_LOOKUP_FAILURE
-  MEMCACHED_WRITE_FAILURE,
-  MEMCACHED_READ_FAILURE,
-  MEMCACHED_UNKNOWN_READ_FAILURE,
-  MEMCACHED_PROTOCOL_ERROR,
-  MEMCACHED_CLIENT_ERROR,
-  MEMCACHED_SERVER_ERROR,
-  MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE, // DEPRECATED
-  MEMCACHED_DATA_EXISTS,
-  MEMCACHED_DATA_DOES_NOT_EXIST,
-  MEMCACHED_NOTSTORED,
-  MEMCACHED_STORED,
-  MEMCACHED_NOTFOUND,
-  MEMCACHED_MEMORY_ALLOCATION_FAILURE,
-  MEMCACHED_PARTIAL_READ,
-  MEMCACHED_SOME_ERRORS,
-  MEMCACHED_NO_SERVERS,
-  MEMCACHED_END,
-  MEMCACHED_DELETED,
-  MEMCACHED_VALUE,
-  MEMCACHED_STAT,
-  MEMCACHED_ITEM,
-  MEMCACHED_ERRNO,
-  MEMCACHED_FAIL_UNIX_SOCKET, // DEPRECATED
-  MEMCACHED_NOT_SUPPORTED,
-  MEMCACHED_NO_KEY_PROVIDED, /* Deprecated. Use MEMCACHED_BAD_KEY_PROVIDED! */
-  MEMCACHED_FETCH_NOTFINISHED,
-  MEMCACHED_TIMEOUT,
-  MEMCACHED_BUFFERED,
-  MEMCACHED_BAD_KEY_PROVIDED,
-  MEMCACHED_INVALID_HOST_PROTOCOL,
-  MEMCACHED_SERVER_MARKED_DEAD,
-  MEMCACHED_UNKNOWN_STAT_KEY,
-  MEMCACHED_E2BIG,
-  MEMCACHED_INVALID_ARGUMENTS,
-  MEMCACHED_KEY_TOO_BIG,
-  MEMCACHED_AUTH_PROBLEM,
-  MEMCACHED_AUTH_FAILURE,
-  MEMCACHED_AUTH_CONTINUE,
-  MEMCACHED_PARSE_ERROR,
-  MEMCACHED_PARSE_USER_ERROR,
-  MEMCACHED_DEPRECATED,
-  MEMCACHED_IN_PROGRESS,
-  MEMCACHED_SERVER_TEMPORARILY_DISABLED,
-  MEMCACHED_MAXIMUM_RETURN /* Always add new error code before */
-};
-
-#ifndef __cplusplus
-typedef enum memcached_return_t memcached_return_t;
-#endif
-
-static inline bool memcached_success(memcached_return_t rc)
-{
-  return (rc == MEMCACHED_BUFFERED ||
-          rc == MEMCACHED_DELETED ||
-          rc == MEMCACHED_END || 
-          rc == MEMCACHED_ITEM || 
-          rc == MEMCACHED_STAT || 
-          rc == MEMCACHED_STORED || 
-          rc == MEMCACHED_SUCCESS || 
-          rc == MEMCACHED_VALUE);
-}
-
-static inline bool memcached_failed(memcached_return_t rc)
-{
-  return (rc != MEMCACHED_SUCCESS && 
-          rc != MEMCACHED_END && 
-          rc != MEMCACHED_STORED && 
-          rc != MEMCACHED_STAT && 
-          rc != MEMCACHED_DELETED &&
-          rc != MEMCACHED_BUFFERED &&
-          rc != MEMCACHED_VALUE);
-}
-
-static inline bool memcached_fatal(memcached_return_t rc)
-{
-  return (rc != MEMCACHED_SUCCESS && 
-          rc != MEMCACHED_END && 
-          rc != MEMCACHED_STORED && 
-          rc != MEMCACHED_STAT && 
-          rc != MEMCACHED_DELETED &&
-          rc != MEMCACHED_BUFFERED &&
-          rc != MEMCACHED_VALUE);
-}
-
-#define memcached_continue(__memcached_return_t) ((__memcached_return_t) == MEMCACHED_IN_PROGRESS)
index 3aefb701f9bfd93cb0fa343f3cf7feeff5752f4c..32906cc8a8858e82056d8b87c822afd53147be0f 100644 (file)
@@ -231,9 +231,9 @@ memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *s
 
     struct libmemcached_io_vector_st vector[]=
     {
-      { sizeof(request.bytes), request.bytes },
-      { keylen, chosenmech },
-      { len, data }
+      { request.bytes, sizeof(request.bytes) },
+      { chosenmech, keylen },
+      { data, len }
     };
 
     if (memcached_io_writev(server, vector, 3, true) == -1)
diff --git a/libmemcached/sasl.h b/libmemcached/sasl.h
deleted file mode 100644 (file)
index 8602246..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT
-#include <sasl/sasl.h>
-#else
-#define sasl_callback_t void
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-void memcached_set_sasl_callbacks(memcached_st *ptr,
-                                  const sasl_callback_t *callbacks);
-
-LIBMEMCACHED_API
-memcached_return_t  memcached_set_sasl_auth_data(memcached_st *ptr,
-                                                 const char *username,
-                                                 const char *password);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_destroy_sasl_auth_data(memcached_st *ptr);
-
-
-LIBMEMCACHED_API
-sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *ptr);
-
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_clone_sasl(memcached_st *clone, const  memcached_st *source);
-
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *server);
-
-#ifdef __cplusplus
-}
-#endif
-
-struct memcached_sasl_st {
-  sasl_callback_t *callbacks;
-  /*
-   ** Did we allocate data inside the callbacks, or did the user
-   ** supply that.
- */
-  bool is_allocated;
-};
index 669979ef1cd154cec31587ccececd6bf94b34634..c9c5ffca6b3a9269ca3782d3f1e68fe3f4151375 100644 (file)
@@ -124,7 +124,7 @@ memcached_server_st *__server_create_with(memcached_st *memc,
 
   self= _server_create(self, memc);
 
-  if (not self)
+  if (self == NULL)
   {
     return NULL;
   }
@@ -166,8 +166,10 @@ void __server_free(memcached_server_st *self)
 
 void memcached_server_free(memcached_server_st *self)
 {
-  if (not self)
+  if (self == NULL)
+  {
     return;
+  }
 
   if (memcached_server_list_count(self))
   {
@@ -185,7 +187,7 @@ memcached_server_st *memcached_server_clone(memcached_server_st *destination,
                                             memcached_server_st *source)
 {
   /* We just do a normal create if source is missing */
-  if (not source)
+  if (source == NULL)
   {
     return NULL;
   }
@@ -258,17 +260,19 @@ memcached_return_t memcached_server_execute(memcached_st *ptr,
   return MEMCACHED_SUCCESS;
 }
 
-memcached_server_instance_st memcached_server_by_key(const memcached_st *ptr,
+memcached_server_instance_st memcached_server_by_key(memcached_st *ptr,
                                                      const char *key,
                                                      size_t key_length,
                                                      memcached_return_t *error)
 {
-  memcached_return_t rc;
   memcached_return_t unused;
-
   if (not error)
+  {
     error= &unused;
+  }
 
+
+  memcached_return_t rc;
   if (memcached_failed(rc= initialize_const_query(ptr)))
   {
     *error= rc;
diff --git a/libmemcached/server.h b/libmemcached/server.h
deleted file mode 100644 (file)
index 3ca1df3..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#pragma once
-
-#ifndef WIN32
-#include <netdb.h>
-#endif
-
-#ifdef NI_MAXHOST
-#define MEMCACHED_NI_MAXHOST NI_MAXHOST
-#else
-#define MEMCACHED_NI_MAXHOST 1025
-#endif
-
-enum memcached_server_state_t {
-  MEMCACHED_SERVER_STATE_NEW, // fd == -1, no address lookup has been done
-  MEMCACHED_SERVER_STATE_ADDRINFO, // ADDRRESS information has been gathered
-  MEMCACHED_SERVER_STATE_IN_PROGRESS,
-  MEMCACHED_SERVER_STATE_CONNECTED,
-  MEMCACHED_SERVER_STATE_IN_TIMEOUT
-};
-
-struct memcached_server_st {
-  struct {
-    bool is_allocated:1;
-    bool is_initialized:1;
-    bool is_shutting_down:1;
-    bool is_dead:1;
-  } options;
-  uint32_t number_of_hosts;
-  uint32_t cursor_active;
-  in_port_t port;
-  memcached_socket_t fd;
-  uint32_t io_bytes_sent; /* # bytes sent since last read */
-  uint32_t server_failure_counter;
-  uint64_t server_failure_counter_query_id;
-  uint32_t weight;
-  uint32_t version;
-  enum memcached_server_state_t state;
-  struct {
-    uint32_t read;
-    uint32_t write;
-  } io_wait_count;
-  uint8_t major_version; // Default definition of UINT8_MAX means that it has not been set.
-  uint8_t micro_version; // ditto
-  uint8_t minor_version; // ditto
-  memcached_connection_t type;
-  char *read_ptr;
-  size_t read_buffer_length;
-  size_t read_data_length;
-  size_t write_buffer_offset;
-  struct addrinfo *address_info;
-  struct addrinfo *address_info_next;
-  time_t next_retry;
-  memcached_st *root;
-  uint64_t limit_maxbytes;
-  struct memcached_error_t *error_messages;
-  char read_buffer[MEMCACHED_MAX_BUFFER];
-  char write_buffer[MEMCACHED_MAX_BUFFER];
-  char hostname[MEMCACHED_NI_MAXHOST];
-};
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_server_cursor(const memcached_st *ptr,
-                                           const memcached_server_fn *callback,
-                                           void *context,
-                                           uint32_t number_of_callbacks);
-
-LIBMEMCACHED_API
-  memcached_server_instance_st memcached_server_by_key(const memcached_st *ptr,
-                                                        const char *key,
-                                                        size_t key_length,
-                                                        memcached_return_t *error);
-
-LIBMEMCACHED_API
-void memcached_server_error_reset(memcached_server_st *ptr);
-
-LIBMEMCACHED_API
-void memcached_server_free(memcached_server_st *ptr);
-
-LIBMEMCACHED_LOCAL
-memcached_server_st *memcached_server_clone(memcached_server_st *destination,
-                                            memcached_server_st *source);
-
-LIBMEMCACHED_API
-memcached_server_instance_st memcached_server_get_last_disconnect(const memcached_st *ptr);
-
-
-LIBMEMCACHED_API
-memcached_return_t memcached_server_add_udp(memcached_st *ptr,
-                                            const char *hostname,
-                                            in_port_t port);
-LIBMEMCACHED_API
-memcached_return_t memcached_server_add_unix_socket(memcached_st *ptr,
-                                                    const char *filename);
-LIBMEMCACHED_API
-memcached_return_t memcached_server_add(memcached_st *ptr,
-                                        const char *hostname, in_port_t port);
-
-LIBMEMCACHED_LOCAL
-  memcached_return_t memcached_server_add_parsed(memcached_st *ptr,
-                                                 const char *hostname,
-                                                 size_t hostname_length,
-                                                 in_port_t port,
-                                                 uint32_t weight);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_server_add_udp_with_weight(memcached_st *ptr,
-                                                        const char *hostname,
-                                                        in_port_t port,
-                                                        uint32_t weight);
-LIBMEMCACHED_API
-memcached_return_t memcached_server_add_unix_socket_with_weight(memcached_st *ptr,
-                                                                const char *filename,
-                                                                uint32_t weight);
-LIBMEMCACHED_API
-memcached_return_t memcached_server_add_with_weight(memcached_st *ptr, const char *hostname,
-                                                    in_port_t port,
-                                                    uint32_t weight);
-
-/**
-  Operations on Single Servers.
-*/
-LIBMEMCACHED_API
-uint32_t memcached_server_response_count(const memcached_server_instance_st self);
-
-LIBMEMCACHED_API
-const char *memcached_server_name(const memcached_server_instance_st self);
-
-LIBMEMCACHED_API
-in_port_t memcached_server_port(const memcached_server_instance_st self);
-
-LIBMEMCACHED_API
-const char *memcached_server_type(const memcached_server_instance_st ptr);
-
-
-LIBMEMCACHED_LOCAL
-void __server_free(memcached_server_st *);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
index 8cfcbdba229fa75112d9acd83a3953e8fa869ef8..b5f31f6676191585cd9f8bf8bbc5b89072bf1dd3 100644 (file)
@@ -37,8 +37,6 @@
 
 #pragma once
 
-#include <libmemcached/basic_string.h>
-
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
diff --git a/libmemcached/server_list.h b/libmemcached/server_list.h
deleted file mode 100644 (file)
index 8fe6dc7..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Server List Public functions */
-LIBMEMCACHED_API
-  void memcached_server_list_free(memcached_server_list_st ptr);
-
-LIBMEMCACHED_API
-  memcached_return_t memcached_server_push(memcached_st *ptr, const memcached_server_list_st list);
-
-LIBMEMCACHED_API
-  memcached_server_list_st memcached_server_list_append(memcached_server_list_st ptr,
-                                                        const char *hostname,
-                                                        in_port_t port,
-                                                        memcached_return_t *error);
-LIBMEMCACHED_API
-  memcached_server_list_st memcached_server_list_append_with_weight(memcached_server_list_st ptr,
-                                                                    const char *hostname,
-                                                                    in_port_t port,
-                                                                    uint32_t weight,
-                                                                    memcached_return_t *error);
-LIBMEMCACHED_API
-  uint32_t memcached_server_list_count(const memcached_server_list_st ptr);
-
-LIBMEMCACHED_LOCAL
-  uint32_t memcached_servers_set_count(memcached_server_list_st servers, uint32_t count);
-
-LIBMEMCACHED_LOCAL
-  memcached_server_st *memcached_server_list(const memcached_st *);
-
-LIBMEMCACHED_LOCAL
-  void memcached_server_list_set(memcached_st *self, memcached_server_list_st list);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
index 515adeeb8daeb735c30d0d1b31a63b3e187a1fee..3b664802de20142d93254133ee01609ad827e593 100644 (file)
@@ -323,16 +323,18 @@ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat,
     size_t len= strlen(args);
 
     memcached_return_t rc= memcached_validate_key_length(len, true);
-    unlikely (rc != MEMCACHED_SUCCESS)
+    if (rc != MEMCACHED_SUCCESS)
+    {
       return rc;
+    }
 
     request.message.header.request.keylen= htons((uint16_t)len);
     request.message.header.request.bodylen= htonl((uint32_t) len);
 
     struct libmemcached_io_vector_st vector[]=
     {
-      { sizeof(request.bytes), request.bytes },
-      { len, args }
+      { request.bytes, sizeof(request.bytes) },
+      { args, len }
     };
 
     if (memcached_vdo(instance, vector, 2, true) != MEMCACHED_SUCCESS)
diff --git a/libmemcached/stats.h b/libmemcached/stats.h
deleted file mode 100644 (file)
index f2d064a..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-struct memcached_stat_st {
-  unsigned long connection_structures;
-  unsigned long curr_connections;
-  unsigned long curr_items;
-  pid_t pid;
-  unsigned long pointer_size;
-  unsigned long rusage_system_microseconds;
-  unsigned long rusage_system_seconds;
-  unsigned long rusage_user_microseconds;
-  unsigned long rusage_user_seconds;
-  unsigned long threads;
-  unsigned long time;
-  unsigned long total_connections;
-  unsigned long total_items;
-  unsigned long uptime;
-  unsigned long long bytes;
-  unsigned long long bytes_read;
-  unsigned long long bytes_written;
-  unsigned long long cmd_get;
-  unsigned long long cmd_set;
-  unsigned long long evictions;
-  unsigned long long get_hits;
-  unsigned long long get_misses;
-  unsigned long long limit_maxbytes;
-  char version[MEMCACHED_VERSION_STRING_LENGTH];
-  void *__future; // @todo create a new structure to place here for future usage
-  memcached_st *root;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-void memcached_stat_free(const memcached_st *, memcached_stat_st *);
-
-LIBMEMCACHED_API
-memcached_stat_st *memcached_stat(memcached_st *ptr, char *args, memcached_return_t *error);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_stat_servername(memcached_stat_st *memc_stat, char *args,
-                                             const char *hostname, in_port_t port);
-
-LIBMEMCACHED_API
-char *memcached_stat_get_value(const memcached_st *ptr, memcached_stat_st *memc_stat,
-                               const char *key, memcached_return_t *error);
-
-LIBMEMCACHED_API
-char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *memc_stat,
-                                memcached_return_t *error);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_stat_execute(memcached_st *memc, const char *args,  memcached_stat_fn func, void *context);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
index 703b0e3081da635fcb58490e6e32ced7bdd86d1a..12c292758cdd8fd609afb76e5fd891ceccab86c8 100644 (file)
@@ -162,10 +162,10 @@ static memcached_return_t memcached_send_binary(memcached_st *ptr,
 
   struct libmemcached_io_vector_st vector[]=
   {
-    { send_length, request.bytes },
-    { memcached_array_size(ptr->_namespace), memcached_array_string(ptr->_namespace) },
-    { key_length, key },
-    { value_length, value }
+    { request.bytes, send_length },
+    { memcached_array_string(ptr->_namespace),  memcached_array_size(ptr->_namespace) },
+    { key, key_length },
+    { value, value_length }
   };
 
   /* write the header */
@@ -307,9 +307,9 @@ static memcached_return_t memcached_send_ascii(memcached_st *ptr,
   {
     struct libmemcached_io_vector_st vector[]=
     {
-      { write_length, buffer },
-      { value_length, value },
-      { 2, "\r\n" }
+      { buffer, write_length },
+      { value, value_length },
+      { memcached_literal_param("\r\n") }
     };
 
     if (ptr->flags.buffer_requests && verb == SET_OP)
diff --git a/libmemcached/storage.h b/libmemcached/storage.h
deleted file mode 100644 (file)
index 0854f16..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#include "libmemcached/memcached.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* All of the functions for adding data to the server */
-LIBMEMCACHED_API
-memcached_return_t memcached_set(memcached_st *ptr, const char *key, size_t key_length,
-                                 const char *value, size_t value_length,
-                                 time_t expiration,
-                                 uint32_t  flags);
-LIBMEMCACHED_API
-memcached_return_t memcached_add(memcached_st *ptr, const char *key, size_t key_length,
-                                 const char *value, size_t value_length,
-                                 time_t expiration,
-                                 uint32_t  flags);
-LIBMEMCACHED_API
-memcached_return_t memcached_replace(memcached_st *ptr, const char *key, size_t key_length,
-                                     const char *value, size_t value_length,
-                                     time_t expiration,
-                                     uint32_t  flags);
-LIBMEMCACHED_API
-memcached_return_t memcached_append(memcached_st *ptr,
-                                    const char *key, size_t key_length,
-                                    const char *value, size_t value_length,
-                                    time_t expiration,
-                                    uint32_t flags);
-LIBMEMCACHED_API
-memcached_return_t memcached_prepend(memcached_st *ptr,
-                                     const char *key, size_t key_length,
-                                     const char *value, size_t value_length,
-                                     time_t expiration,
-                                     uint32_t flags);
-LIBMEMCACHED_API
-memcached_return_t memcached_cas(memcached_st *ptr,
-                                 const char *key, size_t key_length,
-                                 const char *value, size_t value_length,
-                                 time_t expiration,
-                                 uint32_t flags,
-                                 uint64_t cas);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_set_by_key(memcached_st *ptr,
-                                        const char *group_key, size_t group_key_length,
-                                        const char *key, size_t key_length,
-                                        const char *value, size_t value_length,
-                                        time_t expiration,
-                                        uint32_t flags);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_add_by_key(memcached_st *ptr,
-                                        const char *group_key, size_t group_key_length,
-                                        const char *key, size_t key_length,
-                                        const char *value, size_t value_length,
-                                        time_t expiration,
-                                        uint32_t flags);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_replace_by_key(memcached_st *ptr,
-                                            const char *group_key, size_t group_key_length,
-                                            const char *key, size_t key_length,
-                                            const char *value, size_t value_length,
-                                            time_t expiration,
-                                            uint32_t flags);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_prepend_by_key(memcached_st *ptr,
-                                            const char *group_key, size_t group_key_length,
-                                            const char *key, size_t key_length,
-                                            const char *value, size_t value_length,
-                                            time_t expiration,
-                                            uint32_t flags);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_append_by_key(memcached_st *ptr,
-                                           const char *group_key, size_t group_key_length,
-                                           const char *key, size_t key_length,
-                                           const char *value, size_t value_length,
-                                           time_t expiration,
-                                           uint32_t flags);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_cas_by_key(memcached_st *ptr,
-                                        const char *group_key, size_t group_key_length,
-                                        const char *key, size_t key_length,
-                                        const char *value, size_t value_length,
-                                        time_t expiration,
-                                        uint32_t flags,
-                                        uint64_t cas);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/strerror.h b/libmemcached/strerror.h
deleted file mode 100644 (file)
index 8e1e0fa..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-const char *memcached_strerror(memcached_st *ptr, memcached_return_t rc);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/string.h b/libmemcached/string.h
deleted file mode 100644 (file)
index 01097a6..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#include <libmemcached/basic_string.h>
-
-/**
-  Strings are always under our control so we make some assumptions
-  about them.
-
-  1) is_initialized is always valid.
-  2) A string once intialized will always be, until free where we
-     unset this flag.
-  3) A string always has a root.
-*/
-
-struct memcached_string_st {
-  char *end;
-  char *string;
-  size_t current_size;
-  memcached_st *root;
-  struct {
-    bool is_allocated:1;
-    bool is_initialized:1;
-  } options;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_LOCAL
-memcached_string_st *memcached_string_create(memcached_st *ptr,
-                                             memcached_string_st *string,
-                                             size_t initial_size);
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_string_check(memcached_string_st *string, size_t need);
-
-LIBMEMCACHED_LOCAL
-char *memcached_string_c_copy(memcached_string_st *string);
-
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_string_append_character(memcached_string_st *string,
-                                                     char character);
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_string_append(memcached_string_st *string,
-                                           const char *value, size_t length);
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_string_reset(memcached_string_st *string);
-
-LIBMEMCACHED_LOCAL
-void memcached_string_free(memcached_string_st *string);
-
-LIBMEMCACHED_LOCAL
-size_t memcached_string_length(const memcached_string_st *self);
-
-LIBMEMCACHED_LOCAL
-size_t memcached_string_size(const memcached_string_st *self);
-
-LIBMEMCACHED_LOCAL
-const char *memcached_string_value(const memcached_string_st *self);
-
-LIBMEMCACHED_LOCAL
-char *memcached_string_take_value(memcached_string_st *self);
-
-LIBMEMCACHED_LOCAL
-char *memcached_string_value_mutable(const memcached_string_st *self);
-
-LIBMEMCACHED_LOCAL
-void memcached_string_set_length(memcached_string_st *self, size_t length);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/touch.cc b/libmemcached/touch.cc
new file mode 100644 (file)
index 0000000..1107139
--- /dev/null
@@ -0,0 +1,148 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <libmemcached/common.h>
+#include <libmemcached/memcached/protocol_binary.h>
+
+static memcached_return_t ascii_touch(memcached_server_write_instance_st instance,
+                                      const char *key, size_t key_length,
+                                      time_t expiration)
+{
+  char buffer[21];
+
+  int buffer_length= snprintf(buffer, sizeof(buffer), " %u", uint32_t(expiration));
+  struct libmemcached_io_vector_st vector[]=
+  {
+    { memcached_literal_param("touch ") },
+    { memcached_array_string(instance->root->_namespace), memcached_array_size(instance->root->_namespace) },
+    { key, key_length },
+    { buffer, buffer_length },
+    { memcached_literal_param("\r\n") }
+  };
+
+  memcached_return_t rc;
+  if (memcached_failed(rc= memcached_vdo(instance, vector, 5, true)))
+  {
+    memcached_io_reset(instance);
+    return memcached_set_error(*instance, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
+  }
+
+  return rc;
+}
+
+static memcached_return_t binary_touch(memcached_server_write_instance_st instance,
+                                       const char *key, size_t key_length,
+                                       time_t expiration)
+{
+  protocol_binary_request_touch request= {}; //{.bytes= {0}};
+  request.message.header.request.magic= PROTOCOL_BINARY_REQ;
+  request.message.header.request.opcode= PROTOCOL_BINARY_CMD_TOUCH;
+  request.message.header.request.extlen= 4;
+  request.message.header.request.keylen= htons((uint16_t)(key_length +memcached_array_size(instance->root->_namespace)));
+  request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
+  request.message.header.request.bodylen= htonl((uint32_t)(key_length +memcached_array_size(instance->root->_namespace) +request.message.header.request.extlen));
+  request.message.body.expiration= htonl((uint32_t) expiration);
+
+  struct libmemcached_io_vector_st vector[]=
+  {
+    { request.bytes, sizeof(request.bytes) },
+    { memcached_array_string(instance->root->_namespace), memcached_array_size(instance->root->_namespace) },
+    { key, key_length }
+  };
+
+  memcached_return_t rc;
+  if (memcached_failed(rc= memcached_vdo(instance, vector, 3, true)))
+  {
+    memcached_io_reset(instance);
+    return memcached_set_error(*instance, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
+  }
+
+  return rc;
+}
+
+memcached_return_t memcached_touch(memcached_st *ptr,
+                                   const char *key, size_t key_length,
+                                   time_t expiration)
+{
+  return memcached_touch_by_key(ptr, key, key_length, key, key_length, expiration);
+}
+
+memcached_return_t memcached_touch_by_key(memcached_st *ptr,
+                                          const char *group_key, size_t group_key_length,
+                                          const char *key, size_t key_length,
+                                          time_t expiration)
+{
+  LIBMEMCACHED_MEMCACHED_TOUCH_START();
+
+  memcached_return_t rc;
+  if (memcached_failed(rc= initialize_query(ptr)))
+  {
+    return rc;
+  }
+
+  if (memcached_failed(rc= memcached_validate_key_length(key_length, ptr->flags.binary_protocol)))
+  {
+    return memcached_set_error(*ptr, rc, MEMCACHED_AT);
+  }
+
+  uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
+  memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
+
+  if (ptr->flags.binary_protocol)
+  {
+    rc= binary_touch(instance, key, key_length, expiration);
+  }
+  else
+  {
+    rc= ascii_touch(instance, key, key_length, expiration);
+  }
+
+  if (memcached_failed(rc))
+  {
+    return memcached_set_error(*instance, rc, MEMCACHED_AT, memcached_literal_param("Error occcured while writing touch command to server"));
+  }
+
+  char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+  rc= memcached_read_one_response(instance, buffer, sizeof(buffer), NULL);
+
+  if (rc == MEMCACHED_SUCCESS or rc == MEMCACHED_NOTFOUND)
+  {
+    return rc;
+  }
+
+  return memcached_set_error(*instance, rc, MEMCACHED_AT, memcached_literal_param("Error occcured while reading response"));
+}
diff --git a/libmemcached/types.h b/libmemcached/types.h
deleted file mode 100644 (file)
index 3a4ae3b..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#pragma once
-
-typedef struct memcached_st memcached_st;
-typedef struct memcached_stat_st memcached_stat_st;
-typedef struct memcached_analysis_st memcached_analysis_st;
-typedef struct memcached_result_st memcached_result_st;
-typedef struct memcached_array_st memcached_array_st;
-typedef struct memcached_error_t memcached_error_t;
-
-// All of the flavors of memcache_server_st
-typedef struct memcached_server_st memcached_server_st;
-typedef const struct memcached_server_st *memcached_server_instance_st;
-typedef struct memcached_server_st *memcached_server_list_st;
-
-typedef struct memcached_callback_st memcached_callback_st;
-
-// The following two structures are internal, and never exposed to users.
-typedef struct memcached_string_st memcached_string_st;
-typedef struct memcached_string_t memcached_string_t;
-typedef struct memcached_continuum_item_st memcached_continuum_item_st;
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef memcached_return_t (*memcached_clone_fn)(memcached_st *destination, const memcached_st *source);
-typedef memcached_return_t (*memcached_cleanup_fn)(const memcached_st *ptr);
-
-/**
-  Memory allocation functions.
-*/
-typedef void (*memcached_free_fn)(const memcached_st *ptr, void *mem, void *context);
-typedef void *(*memcached_malloc_fn)(const memcached_st *ptr, const size_t size, void *context);
-typedef void *(*memcached_realloc_fn)(const memcached_st *ptr, void *mem, const size_t size, void *context);
-typedef void *(*memcached_calloc_fn)(const memcached_st *ptr, size_t nelem, const size_t elsize, void *context);
-
-
-typedef memcached_return_t (*memcached_execute_fn)(const memcached_st *ptr, memcached_result_st *result, void *context);
-typedef memcached_return_t (*memcached_server_fn)(const memcached_st *ptr, memcached_server_instance_st server, void *context);
-typedef memcached_return_t (*memcached_stat_fn)(memcached_server_instance_st server,
-                                                const char *key, size_t key_length,
-                                                const char *value, size_t value_length,
-                                                void *context);
-
-/**
-  Trigger functions.
-*/
-typedef memcached_return_t (*memcached_trigger_key_fn)(const memcached_st *ptr,
-                                                       const char *key, size_t key_length,
-                                                       memcached_result_st *result);
-typedef memcached_return_t (*memcached_trigger_delete_key_fn)(const memcached_st *ptr,
-                                                              const char *key, size_t key_length);
-
-typedef memcached_return_t (*memcached_dump_fn)(const memcached_st *ptr,
-                                                const char *key,
-                                                size_t key_length,
-                                                void *context);
-
-#ifdef __cplusplus
-}
-#endif
-
-/**
-  @note The following definitions are just here for backwards compatibility.
-*/
-typedef memcached_return_t memcached_return;
-typedef memcached_server_distribution_t memcached_server_distribution;
-typedef memcached_behavior_t memcached_behavior;
-typedef memcached_callback_t memcached_callback;
-typedef memcached_hash_t memcached_hash;
-typedef memcached_connection_t memcached_connection;
-typedef memcached_clone_fn memcached_clone_func;
-typedef memcached_cleanup_fn memcached_cleanup_func;
-typedef memcached_execute_fn memcached_execute_function;
-typedef memcached_server_fn memcached_server_function;
-typedef memcached_trigger_key_fn memcached_trigger_key;
-typedef memcached_trigger_delete_key_fn memcached_trigger_delete_key;
-typedef memcached_dump_fn memcached_dump_func;
index d771d241ad08dfedfeb9c06baa8a384d86e68211..03ed6da569f31e5d08f8eabcfa4a8e1d0296d1ee 100644 (file)
@@ -3,7 +3,6 @@
  *  Libmemcached library
  *
  *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that the following conditions are
@@ -37,4 +36,5 @@
 
 #pragma once
 
-#include <libmemcached/memcached_util.h>
+#include <libmemcachedutil-1.0/util.h>
+
diff --git a/libmemcached/util/flush.cc b/libmemcached/util/flush.cc
deleted file mode 100644 (file)
index 17131f7..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Summary: connects to a host, and then flushes it (memcached_flush(3)).
- *
- */
-
-#include <libmemcached/common.h>
-#include <libmemcached/memcached_util.h>
-
-
-bool libmemcached_util_flush(const char *hostname, in_port_t port, memcached_return_t *ret)
-{
-  memcached_st *memc_ptr= memcached_create(NULL);
-
-  memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
-  if (memcached_success(rc))
-  {
-    rc= memcached_flush(memc_ptr, 0);
-  }
-
-  memcached_free(memc_ptr);
-
-  if (ret)
-  {
-    *ret= rc;
-  }
-
-  return memcached_success(rc);
-}
diff --git a/libmemcached/util/flush.h b/libmemcached/util/flush.h
deleted file mode 100644 (file)
index dd7e779..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-bool libmemcached_util_flush(const char *hostname, in_port_t port, memcached_return_t *ret);
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/libmemcached/util/include.am b/libmemcached/util/include.am
deleted file mode 100644 (file)
index 10f3b94..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-# vim:ft=automake
-# included from Top Level Makefile.am
-# All paths should be given relative to the root
-
-nobase_include_HEADERS+= \
-                        libmemcached/memcached_util.h \
-                        libmemcached/util.h \
-                        libmemcached/util/flush.h \
-                        libmemcached/util/pid.h \
-                        libmemcached/util/ping.h \
-                        libmemcached/util/pool.h \
-                        libmemcached/util/version.h
-lib_LTLIBRARIES+= libmemcached/libmemcachedutil.la
-
-libmemcached_libmemcachedutil_la_SOURCES= \
-                                         libmemcached/backtrace.cc \
-                                         libmemcached/util/flush.cc \
-                                         libmemcached/util/pid.cc \
-                                         libmemcached/util/ping.cc \
-                                         libmemcached/util/pool.cc \
-                                         libmemcached/util/version.cc
-libmemcached_libmemcachedutil_la_CXXFLAGS= \
-                                          ${AM_CXXFLAGS} \
-                                          ${NO_CONVERSION} \
-                                          -DBUILDING_LIBMEMCACHED
-libmemcached_libmemcachedutil_la_CXXFLAGS+= ${PTHREAD_CFLAGS}
-libmemcached_libmemcachedutil_la_LIBADD= libmemcached/libmemcached.la
-libmemcached_libmemcachedutil_la_LIBADD+= ${PTHREAD_LIBS}
-libmemcached_libmemcachedutil_la_LDFLAGS= ${AM_LDFLAGS} -version-info ${MEMCACHED_UTIL_LIBRARY_VERSION}
-libmemcached_libmemcachedutil_la_DEPENDENCIES= libmemcached/libmemcached.la
-
diff --git a/libmemcached/util/pid.cc b/libmemcached/util/pid.cc
deleted file mode 100644 (file)
index 0ac3d4f..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Summary: connects to a host, and determines what its pid is
- *
- */
-
-#include <libmemcached/common.h>
-#include <libmemcached/memcached_util.h>
-
-
-// Never look at the stat object directly.
-
-
-pid_t libmemcached_util_getpid(const char *hostname, in_port_t port, memcached_return_t *ret)
-{
-  pid_t pid= -1;
-
-  memcached_return_t unused;
-  if (not ret)
-    ret= &unused;
-
-  memcached_st *memc_ptr= memcached_create(NULL);
-  if (not memc_ptr)
-  {
-    *ret= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
-    return -1;
-  }
-
-  memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
-  if (memcached_success(rc))
-  {
-    memcached_stat_st *stat= memcached_stat(memc_ptr, NULL, &rc);
-    if (memcached_success(rc) and stat and stat->pid != -1)
-    {
-      pid= stat->pid;
-    }
-    else if (memcached_success(rc))
-    {
-      rc= MEMCACHED_UNKNOWN_STAT_KEY; // Something went wrong if this happens
-    }
-    else if (rc == MEMCACHED_SOME_ERRORS) // Generic answer, we will now find the specific reason (if one exists)
-    {
-      memcached_server_instance_st instance=
-        memcached_server_instance_by_position(memc_ptr, 0);
-
-      assert_msg(instance and instance->error_messages, " ");
-      if (instance and instance->error_messages)
-      {
-        rc= memcached_server_error_return(instance);
-      }
-    }
-
-    memcached_stat_free(memc_ptr, stat);
-  }
-  memcached_free(memc_ptr);
-
-  *ret= rc;
-
-  return pid;
-}
-
-pid_t libmemcached_util_getpid2(const char *hostname, in_port_t port, const char *username, const char *password,  memcached_return_t *ret)
-{
-  if (username == NULL)
-  {
-    return libmemcached_util_getpid(hostname, port, ret);
-  }
-
-  pid_t pid= -1;
-
-  memcached_return_t unused;
-  if (not ret)
-    ret= &unused;
-
-  if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
-  {
-    *ret= MEMCACHED_NOT_SUPPORTED;
-    return pid;
-  }
-
-  memcached_st *memc_ptr= memcached_create(NULL);
-  if (not memc_ptr)
-  {
-    *ret= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
-    return -1;
-  }
-
-  if (memcached_failed(*ret= memcached_set_sasl_auth_data(memc_ptr, username, password)))
-  {
-    memcached_free(memc_ptr);
-    return false;
-  }
-
-
-  memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
-  if (memcached_success(rc))
-  {
-    memcached_stat_st *stat= memcached_stat(memc_ptr, NULL, &rc);
-    if (memcached_success(rc) and stat and stat->pid != -1)
-    {
-      pid= stat->pid;
-    }
-    else if (memcached_success(rc))
-    {
-      rc= MEMCACHED_UNKNOWN_STAT_KEY; // Something went wrong if this happens
-    }
-    else if (rc == MEMCACHED_SOME_ERRORS) // Generic answer, we will now find the specific reason (if one exists)
-    {
-      memcached_server_instance_st instance=
-        memcached_server_instance_by_position(memc_ptr, 0);
-
-#if 0
-      assert_msg(instance and instance->error_messages, " ");
-#endif
-      if (instance and instance->error_messages)
-      {
-        rc= memcached_server_error_return(instance);
-      }
-    }
-
-    memcached_stat_free(memc_ptr, stat);
-  }
-  memcached_free(memc_ptr);
-
-  *ret= rc;
-
-  return pid;
-}
diff --git a/libmemcached/util/pid.h b/libmemcached/util/pid.h
deleted file mode 100644 (file)
index 4101c11..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-pid_t libmemcached_util_getpid(const char *hostname, in_port_t port, memcached_return_t *ret);
-
-LIBMEMCACHED_API
-pid_t libmemcached_util_getpid2(const char *hostname, in_port_t port, const char *username, const char *password,  memcached_return_t *ret);
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/libmemcached/util/ping.cc b/libmemcached/util/ping.cc
deleted file mode 100644 (file)
index 66b1df7..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Summary: connects to a host, and makes sure it is alive.
- *
- */
-
-#include <libmemcached/common.h>
-#include <libmemcached/memcached_util.h>
-
-bool libmemcached_util_ping(const char *hostname, in_port_t port, memcached_return_t *ret)
-{
-  memcached_return_t unused;
-  if (not ret)
-    ret= &unused;
-
-  memcached_st *memc_ptr= memcached_create(NULL);
-  if (not memc_ptr)
-  {
-    *ret= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
-    return false;
-  }
-
-  memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
-  if (memcached_success(rc))
-  {
-    rc= memcached_version(memc_ptr);
-  }
-
-  if (memcached_failed(rc) and rc == MEMCACHED_SOME_ERRORS)
-  {
-    memcached_server_instance_st instance=
-      memcached_server_instance_by_position(memc_ptr, 0);
-
-    assert_msg(instance and instance->error_messages, " ");
-    if (instance and instance->error_messages)
-    {
-      rc= memcached_server_error_return(instance);
-    }
-  }
-  memcached_free(memc_ptr);
-
-  *ret= rc;
-
-  return memcached_success(rc);
-}
-
-bool libmemcached_util_ping2(const char *hostname, in_port_t port, const char *username, const char *password,  memcached_return_t *ret)
-{
-  if (username == NULL)
-  {
-    return libmemcached_util_ping(hostname, port, ret);
-  }
-
-  memcached_return_t unused;
-  if (not ret)
-    ret= &unused;
-
-  if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
-  {
-    *ret= MEMCACHED_NOT_SUPPORTED;
-    return false;
-  }
-
-  memcached_st *memc_ptr= memcached_create(NULL);
-  if (not memc_ptr)
-  {
-    *ret= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
-    return false;
-  }
-
-  if (memcached_failed(*ret= memcached_set_sasl_auth_data(memc_ptr, username, password)))
-  {
-    memcached_free(memc_ptr);
-    return false;
-  }
-
-  memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
-  if (memcached_success(rc))
-  {
-    rc= memcached_version(memc_ptr);
-  }
-
-  if (memcached_failed(rc) and rc == MEMCACHED_SOME_ERRORS)
-  {
-    memcached_server_instance_st instance=
-      memcached_server_instance_by_position(memc_ptr, 0);
-
-    assert_msg(instance and instance->error_messages, " ");
-    if (instance and instance->error_messages)
-    {
-      rc= memcached_server_error_return(instance);
-    }
-  }
-  memcached_free(memc_ptr);
-
-  *ret= rc;
-
-  return memcached_success(rc);
-}
diff --git a/libmemcached/util/ping.h b/libmemcached/util/ping.h
deleted file mode 100644 (file)
index faea8b2..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-bool libmemcached_util_ping(const char *hostname, in_port_t port, memcached_return_t *ret);
-
-LIBMEMCACHED_API
-bool libmemcached_util_ping2(const char *hostname, in_port_t port, const char *username, const char *password,  memcached_return_t *ret);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libmemcached/util/pool.cc b/libmemcached/util/pool.cc
deleted file mode 100644 (file)
index 47f46ee..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include <libmemcached/common.h>
-#include <libmemcached/memcached_util.h>
-
-#include <libmemcached/error.hpp>
-
-#include <cassert>
-#include <cerrno>
-#include <pthread.h>
-#include <memory>
-
-struct memcached_pool_st
-{
-  pthread_mutex_t mutex;
-  pthread_cond_t cond;
-  memcached_st *master;
-  memcached_st **server_pool;
-  int firstfree;
-  const uint32_t size;
-  uint32_t current_size;
-  bool _owns_master;
-  struct timespec _timeout;
-
-  memcached_pool_st(memcached_st *master_arg, size_t max_arg) :
-    master(master_arg),
-    server_pool(NULL),
-    firstfree(-1),
-    size(max_arg),
-    current_size(0),
-    _owns_master(false)
-  {
-    pthread_mutex_init(&mutex, NULL);
-    pthread_cond_init(&cond, NULL);
-    _timeout.tv_sec= 5;
-    _timeout.tv_nsec= 0;
-  }
-
-  const struct timespec& timeout() const
-  {
-    return _timeout;
-  }
-
-  bool release(memcached_st*, memcached_return_t& rc);
-
-  memcached_st *fetch(memcached_return_t& rc);
-  memcached_st *fetch(const struct timespec&, memcached_return_t& rc);
-
-  bool init(uint32_t initial);
-
-  ~memcached_pool_st()
-  {
-    for (int x= 0; x <= firstfree; ++x)
-    {
-      memcached_free(server_pool[x]);
-      server_pool[x] = NULL;
-    }
-
-    pthread_mutex_destroy(&mutex);
-    pthread_cond_destroy(&cond);
-    delete [] server_pool;
-    if (_owns_master)
-    {
-      memcached_free(master);
-    }
-  }
-
-  void increment_version()
-  {
-    ++master->configure.version;
-  }
-
-  bool compare_version(const memcached_st *arg) const
-  {
-    return (arg->configure.version == version());
-  }
-
-  int32_t version() const
-  {
-    return master->configure.version;
-  }
-};
-
-
-/**
- * Grow the connection pool by creating a connection structure and clone the
- * original memcached handle.
- */
-static bool grow_pool(memcached_pool_st* pool)
-{
-  assert(pool);
-
-  memcached_st *obj;
-  if (not (obj= memcached_clone(NULL, pool->master)))
-  {
-    return false;
-  }
-
-  pool->server_pool[++pool->firstfree]= obj;
-  pool->current_size++;
-  obj->configure.version= pool->version();
-
-  return true;
-}
-
-bool memcached_pool_st::init(uint32_t initial)
-{
-  server_pool= new (std::nothrow) memcached_st *[size];
-  if (not server_pool)
-    return false;
-
-  /*
-    Try to create the initial size of the pool. An allocation failure at
-    this time is not fatal..
-  */
-  for (unsigned int x= 0; x < initial; ++x)
-  {
-    if (grow_pool(this) == false)
-    {
-      break;
-    }
-  }
-
-  return true;
-}
-
-
-static inline memcached_pool_st *_pool_create(memcached_st* master, uint32_t initial, uint32_t max)
-{
-  if (initial == 0 or max == 0 or (initial > max))
-  {
-    return NULL;
-  }
-
-  memcached_pool_st *object= new (std::nothrow) memcached_pool_st(master, max);
-  if (object == NULL)
-  {
-    return NULL;
-  }
-
-  /*
-    Try to create the initial size of the pool. An allocation failure at
-    this time is not fatal..
-  */
-  if (not object->init(initial))
-  {
-    delete object;
-    return NULL;
-  }
-
-  return object;
-}
-
-memcached_pool_st *memcached_pool_create(memcached_st* master, uint32_t initial, uint32_t max)
-{
-  return _pool_create(master, initial, max);
-}
-
-memcached_pool_st * memcached_pool(const char *option_string, size_t option_string_length)
-{
-  memcached_st *memc= memcached(option_string, option_string_length);
-
-  if (memc == NULL)
-  {
-    return NULL;
-  }
-
-  memcached_pool_st *self= memcached_pool_create(memc, memc->configure.initial_pool_size, memc->configure.max_pool_size);
-  if (self == NULL)
-  {
-    memcached_free(memc);
-    return NULL;
-  }
-
-  self->_owns_master= true;
-
-  return self;
-}
-
-memcached_st*  memcached_pool_destroy(memcached_pool_st* pool)
-{
-  if (pool == NULL)
-  {
-    return NULL;
-  }
-
-  // Legacy that we return the original structure
-  memcached_st *ret= NULL;
-  if (pool->_owns_master)
-  { }
-  else
-  {
-    ret= pool->master;
-  }
-
-  delete pool;
-
-  return ret;
-}
-
-memcached_st* memcached_pool_st::fetch(memcached_return_t& rc)
-{
-  static struct timespec relative_time= { 0, 0 };
-  return fetch(relative_time, rc);
-}
-
-memcached_st* memcached_pool_st::fetch(const struct timespec& relative_time, memcached_return_t& rc)
-{
-  rc= MEMCACHED_SUCCESS;
-
-  if (pthread_mutex_lock(&mutex))
-  {
-    rc= MEMCACHED_IN_PROGRESS;
-    return NULL;
-  }
-
-  memcached_st *ret= NULL;
-  do
-  {
-    if (firstfree > -1)
-    {
-      ret= server_pool[firstfree--];
-    }
-    else if (current_size == size)
-    {
-      if (relative_time.tv_sec == 0 and relative_time.tv_nsec == 0)
-      {
-        pthread_mutex_unlock(&mutex);
-        rc= MEMCACHED_NOTFOUND;
-
-        return NULL;
-      }
-
-      struct timespec time_to_wait= {0, 0};
-      time_to_wait.tv_sec= time(NULL) +relative_time.tv_sec;
-      time_to_wait.tv_nsec= relative_time.tv_nsec;
-
-      int thread_ret;
-      if ((thread_ret= pthread_cond_timedwait(&cond, &mutex, &time_to_wait)) != 0)
-      {
-        pthread_mutex_unlock(&mutex);
-
-        if (thread_ret == ETIMEDOUT)
-        {
-          rc= MEMCACHED_TIMEOUT;
-        }
-        else
-        {
-          errno= thread_ret;
-          rc= MEMCACHED_ERRNO;
-        }
-
-        return NULL;
-      }
-    }
-    else if (grow_pool(this) == false)
-    {
-      (void)pthread_mutex_unlock(&mutex);
-      return NULL;
-    }
-  } while (ret == NULL);
-
-  pthread_mutex_unlock(&mutex);
-
-  return ret;
-}
-
-bool memcached_pool_st::release(memcached_st *released, memcached_return_t& rc)
-{
-  rc= MEMCACHED_SUCCESS;
-  if (released == NULL)
-  {
-    rc= MEMCACHED_INVALID_ARGUMENTS;
-    return false;
-  }
-
-  if (pthread_mutex_lock(&mutex))
-  {
-    rc= MEMCACHED_IN_PROGRESS;
-    return false;
-  }
-
-  /* 
-    Someone updated the behavior on the object, so we clone a new memcached_st with the new settings. If we fail to clone, we keep the old one around.
-  */
-  if (compare_version(released) == false)
-  {
-    memcached_st *memc;
-    if ((memc= memcached_clone(NULL, master)))
-    {
-      memcached_free(released);
-      released= memc;
-    }
-  }
-
-  server_pool[++firstfree]= released;
-
-  if (firstfree == 0 and current_size == size)
-  {
-    /* we might have people waiting for a connection.. wake them up :-) */
-    pthread_cond_broadcast(&cond);
-  }
-
-  (void)pthread_mutex_unlock(&mutex);
-
-  return true;
-}
-
-memcached_st* memcached_pool_fetch(memcached_pool_st* pool, struct timespec* relative_time, memcached_return_t* rc)
-{
-  if (pool == NULL)
-  {
-    return NULL;
-  }
-
-  memcached_return_t unused;
-  if (rc == NULL)
-  {
-    rc= &unused;
-  }
-
-  if (relative_time == NULL)
-  {
-    return pool->fetch(*rc);
-  }
-
-  return pool->fetch(*relative_time, *rc);
-}
-
-memcached_st* memcached_pool_pop(memcached_pool_st* pool,
-                                 bool block,
-                                 memcached_return_t *rc)
-{
-  if (pool == NULL)
-  {
-    return NULL;
-  }
-
-  memcached_return_t unused;
-  if (rc == NULL)
-  {
-    rc= &unused;
-  }
-
-  memcached_st *memc;
-  if (block)
-  {
-    memc= pool->fetch(pool->timeout(), *rc);
-  }
-  else
-  {
-    memc= pool->fetch(*rc);
-  }
-
-  return memc;
-}
-
-memcached_return_t memcached_pool_release(memcached_pool_st* pool, memcached_st *released)
-{
-  if (pool == NULL)
-  {
-    return MEMCACHED_INVALID_ARGUMENTS;
-  }
-
-  memcached_return_t rc;
-
-  (void) pool->release(released, rc);
-
-  return rc;
-}
-
-memcached_return_t memcached_pool_push(memcached_pool_st* pool, memcached_st *released)
-{
-  return memcached_pool_release(pool, released);
-}
-
-
-memcached_return_t memcached_pool_behavior_set(memcached_pool_st *pool,
-                                               memcached_behavior_t flag,
-                                               uint64_t data)
-{
-  if (pool == NULL)
-  {
-    return MEMCACHED_INVALID_ARGUMENTS;
-  }
-
-  if (pthread_mutex_lock(&pool->mutex))
-  {
-    return MEMCACHED_IN_PROGRESS;
-  }
-
-  /* update the master */
-  memcached_return_t rc= memcached_behavior_set(pool->master, flag, data);
-  if (memcached_failed(rc))
-  {
-    (void)pthread_mutex_unlock(&pool->mutex);
-    return rc;
-  }
-
-  pool->increment_version();
-  /* update the clones */
-  for (int xx= 0; xx <= pool->firstfree; ++xx)
-  {
-    if (memcached_success(memcached_behavior_set(pool->server_pool[xx], flag, data)))
-    {
-      pool->server_pool[xx]->configure.version= pool->version();
-    }
-    else
-    {
-      memcached_st *memc;
-      if ((memc= memcached_clone(NULL, pool->master)))
-      {
-        memcached_free(pool->server_pool[xx]);
-        pool->server_pool[xx]= memc;
-        /* I'm not sure what to do in this case.. this would happen
-          if we fail to push the server list inside the client..
-          I should add a testcase for this, but I believe the following
-          would work, except that you would add a hole in the pool list..
-          in theory you could end up with an empty pool....
-        */
-      }
-    }
-  }
-
-  (void)pthread_mutex_unlock(&pool->mutex);
-
-  return rc;
-}
-
-memcached_return_t memcached_pool_behavior_get(memcached_pool_st *pool,
-                                               memcached_behavior_t flag,
-                                               uint64_t *value)
-{
-  if (pool == NULL)
-  {
-    return MEMCACHED_INVALID_ARGUMENTS;
-  }
-
-  if (pthread_mutex_lock(&pool->mutex))
-  {
-    return MEMCACHED_IN_PROGRESS;
-  }
-
-  *value= memcached_behavior_get(pool->master, flag);
-
-  (void)pthread_mutex_unlock(&pool->mutex);
-
-  return MEMCACHED_SUCCESS;
-}
diff --git a/libmemcached/util/pool.h b/libmemcached/util/pool.h
deleted file mode 100644 (file)
index eba97ec..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-
-#include <libmemcached/memcached.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct memcached_pool_st;
-typedef struct memcached_pool_st memcached_pool_st;
-
-LIBMEMCACHED_API
-memcached_pool_st *memcached_pool_create(memcached_st* mmc, uint32_t initial, uint32_t max);
-
-LIBMEMCACHED_API
-memcached_pool_st *memcached_pool(const char *option_string, size_t option_string_length);
-
-LIBMEMCACHED_API
-memcached_st* memcached_pool_destroy(memcached_pool_st* pool);
-
-LIBMEMCACHED_API
-memcached_st* memcached_pool_pop(memcached_pool_st* pool,
-                                 bool block,
-                                 memcached_return_t* rc);
-LIBMEMCACHED_API
-memcached_return_t memcached_pool_push(memcached_pool_st* pool,
-                                       memcached_st* mmc);
-LIBMEMCACHED_API
-  memcached_return_t memcached_pool_release(memcached_pool_st* pool, memcached_st* mmc);
-
-LIBMEMCACHED_API
-memcached_st* memcached_pool_fetch(memcached_pool_st*, struct timespec* relative_time, memcached_return_t* rc);
-
-LIBMEMCACHED_API
-memcached_return_t memcached_pool_behavior_set(memcached_pool_st *ptr,
-                                               memcached_behavior_t flag,
-                                               uint64_t data);
-LIBMEMCACHED_API
-memcached_return_t memcached_pool_behavior_get(memcached_pool_st *ptr,
-                                               memcached_behavior_t flag,
-                                               uint64_t *value);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/libmemcached/util/version.cc b/libmemcached/util/version.cc
deleted file mode 100644 (file)
index a820829..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include <libmemcached/common.h>
-#include <libmemcached/memcached_util.h>
-
-struct local_context
-{
-  uint8_t major_version;
-  uint8_t minor_version;
-  uint8_t micro_version;
-
-  bool truth;
-};
-
-static memcached_return_t check_server_version(const memcached_st *ptr,
-                                               const memcached_server_st *instance,
-                                               void *context)
-{
-  /* Do Nothing */
-  struct local_context *check= (struct local_context *)context;
-  (void)ptr;
-
-  if (instance->major_version != UINT8_MAX &&
-      instance->major_version >= check->major_version &&
-      instance->minor_version >= check->minor_version &&
-      instance->micro_version >= check->micro_version )
-  {
-    return MEMCACHED_SUCCESS;
-  }
-
-  check->truth= false;
-
-  return MEMCACHED_FAILURE;
-}
-
-bool libmemcached_util_version_check(memcached_st *memc,
-                                     uint8_t major_version,
-                                     uint8_t minor_version,
-                                     uint8_t micro_version)
-{
-  if (memcached_version(memc) != MEMCACHED_SUCCESS)
-    return false;
-
-  struct local_context check= { major_version, minor_version, micro_version, true };
-
-  memcached_server_fn callbacks[1];
-  callbacks[0]= check_server_version;
-  memcached_server_cursor(memc, callbacks, (void *)&check,  1);
-
-  return check.truth;
-}
diff --git a/libmemcached/util/version.h b/libmemcached/util/version.h
deleted file mode 100644 (file)
index 372283a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-  bool libmemcached_util_version_check(memcached_st *memc, 
-                                       uint8_t major_version,
-                                       uint8_t minor_version,
-                                       uint8_t micro_version);
-
-#ifdef __cplusplus
-}
-#endif
index c4231719df0b0ac168472702ff544d7fa373c16d..5564c7a90f7b894cb88b8349749daf9ddcbd40fa 100644 (file)
@@ -43,26 +43,23 @@ struct context_st
   const char *buffer;
 };
 
-static memcached_return_t _set_verbosity(const memcached_st *ptr,
+static memcached_return_t _set_verbosity(const memcached_st *,
                                          const memcached_server_st *server,
                                          void *context)
 {
-  memcached_return_t rc;
-  memcached_st local_memc;
-  memcached_st *memc_ptr;
-  char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-
   struct context_st *execute= (struct context_st *)context;
-  (void)ptr;
 
-  memc_ptr= memcached_create(&local_memc);
+  memcached_st local_memc;
+  memcached_st *memc_ptr= memcached_create(&local_memc);
 
-  rc= memcached_server_add(memc_ptr, memcached_server_name(server), memcached_server_port(server));
+  memcached_return_t rc= memcached_server_add(memc_ptr, memcached_server_name(server), memcached_server_port(server));
 
   if (rc == MEMCACHED_SUCCESS)
   {
-    memcached_server_write_instance_st instance=
-      memcached_server_instance_fetch(memc_ptr, 0);
+    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+
+    memcached_server_write_instance_st instance= memcached_server_instance_fetch(memc_ptr, 0);
+
 
     rc= memcached_do(instance, execute->buffer, execute->length, true);
 
diff --git a/libmemcached/verbosity.h b/libmemcached/verbosity.h
deleted file mode 100644 (file)
index 2994648..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_verbosity(memcached_st *ptr, uint32_t verbosity);
-
-
-#ifdef __cplusplus
-}
-#endif
index abb720054545177ba929e3342c24675bafba8da0..b70cf672278c7421257ab9cacdd3269e071454bd 100644 (file)
@@ -46,88 +46,100 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr);
 
 memcached_return_t memcached_version(memcached_st *ptr)
 {
+  memcached_return_t rc;
+  if (memcached_failed(rc= initialize_query(ptr)))
+  {
+    return rc;
+  }
+
   if (ptr->flags.use_udp)
+  {
     return MEMCACHED_NOT_SUPPORTED;
-
-  memcached_return_t rc;
+  }
 
   if (ptr->flags.binary_protocol)
+  {
     rc= memcached_version_binary(ptr);
+  }
   else
+  {
     rc= memcached_version_textual(ptr);      
+  }
 
   return rc;
 }
 
 static inline memcached_return_t memcached_version_textual(memcached_st *ptr)
 {
-  size_t send_length;
-  memcached_return_t rc;
-  char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-  char *response_ptr;
-  const char *command= "version\r\n";
-
-  send_length= sizeof("version\r\n") -1;
-
-  rc= MEMCACHED_SUCCESS;
+  memcached_return_t rc= MEMCACHED_SUCCESS;
   for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
   {
-    memcached_return_t rrc;
-    memcached_server_write_instance_st instance=
-      memcached_server_instance_fetch(ptr, x);
+    memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x);
 
     // Optimization, we only fetch version once.
     if (instance->major_version != UINT8_MAX)
+    {
       continue;
+    }
 
-    rrc= memcached_do(instance, command, send_length, true);
-    if (rrc != MEMCACHED_SUCCESS)
+    memcached_return_t rrc= memcached_do(instance, memcached_literal_param("version\r\n"), true);
+    if (memcached_failed(rrc))
     {
+      (void)memcached_set_error(*instance, rrc, MEMCACHED_AT);
       instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
       rc= MEMCACHED_SOME_ERRORS;
       continue;
     }
 
+    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
     rrc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
-    if (rrc != MEMCACHED_SUCCESS)
+    if (memcached_failed(rrc))
     {
+      memcached_set_error(*instance, rrc, MEMCACHED_AT);
       instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
       rc= MEMCACHED_SOME_ERRORS;
       continue;
     }
 
     /* Find the space, and then move one past it to copy version */
-    response_ptr= index(buffer, ' ');
+    char *response_ptr= index(buffer, ' ');
     response_ptr++;
 
-    instance->major_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
-    if (errno == ERANGE)
+    long int version= strtol(response_ptr, (char **)NULL, 10);
+    if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
     {
+      memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version"));
       instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
       rc= MEMCACHED_SOME_ERRORS;
       continue;
     }
+    instance->major_version= uint8_t(version);
 
     response_ptr= index(response_ptr, '.');
     response_ptr++;
 
-    instance->minor_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
-    if (errno == ERANGE)
+    version= strtol(response_ptr, (char **)NULL, 10);
+    if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
     {
+      memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version"));
       instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
       rc= MEMCACHED_SOME_ERRORS;
       continue;
     }
+    instance->minor_version= uint8_t(version);
 
     response_ptr= index(response_ptr, '.');
     response_ptr++;
-    instance->micro_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10);
-    if (errno == ERANGE)
+
+    version= strtol(response_ptr, (char **)NULL, 10);
+    if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
     {
+      memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
       instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
       rc= MEMCACHED_SOME_ERRORS;
       continue;
     }
+    instance->micro_version= uint8_t(version);
   }
 
   return rc;
@@ -135,25 +147,23 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr)
 
 static inline memcached_return_t memcached_version_binary(memcached_st *ptr)
 {
-  memcached_return_t rc;
   protocol_binary_request_version request= {};
   request.message.header.request.magic= PROTOCOL_BINARY_REQ;
   request.message.header.request.opcode= PROTOCOL_BINARY_CMD_VERSION;
   request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
 
-  rc= MEMCACHED_SUCCESS;
+  memcached_return_t rc= MEMCACHED_SUCCESS;
   for (uint32_t x= 0; x < memcached_server_count(ptr); x++) 
   {
-    memcached_return_t rrc;
-
-    memcached_server_write_instance_st instance=
-      memcached_server_instance_fetch(ptr, x);
+    memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x);
 
     if (instance->major_version != UINT8_MAX)
+    {
       continue;
+    }
 
-    rrc= memcached_do(instance, request.bytes, sizeof(request.bytes), true);
-    if (rrc != MEMCACHED_SUCCESS) 
+    memcached_return_t rrc= memcached_do(instance, request.bytes, sizeof(request.bytes), true);
+    if (memcached_failed(rrc))
     {
       memcached_io_reset(instance);
       rc= MEMCACHED_SOME_ERRORS;
@@ -167,46 +177,52 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr)
       memcached_server_instance_fetch(ptr, x);
 
     if (instance->major_version != UINT8_MAX)
+    {
       continue;
+    }
 
     if (memcached_server_response_count(instance) > 0) 
     {
-      memcached_return_t rrc;
       char buffer[32];
       char *p;
 
-      rrc= memcached_response(instance, buffer, sizeof(buffer), NULL);
-      if (rrc != MEMCACHED_SUCCESS) 
+      memcached_return_t rrc= memcached_response(instance, buffer, sizeof(buffer), NULL);
+      if (memcached_failed(rrc))
       {
         memcached_io_reset(instance);
         rc= MEMCACHED_SOME_ERRORS;
         continue;
       }
 
-      instance->major_version= (uint8_t)strtol(buffer, &p, 10);
-      if (errno == ERANGE)
+      long int version= strtol(buffer, &p, 10);
+      if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
       {
+        memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version"));
         instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
         rc= MEMCACHED_SOME_ERRORS;
         continue;
       }
+      instance->major_version= uint8_t(version);
 
-      instance->minor_version= (uint8_t)strtol(p + 1, &p, 10);
-      if (errno == ERANGE)
+      version= strtol(p +1, &p, 10);
+      if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
       {
+        memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
         instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
         rc= MEMCACHED_SOME_ERRORS;
         continue;
       }
+      instance->minor_version= uint8_t(version);
 
-      instance->micro_version= (uint8_t)strtol(p + 1, NULL, 10);
+      version= strtol(p + 1, NULL, 10);
       if (errno == ERANGE)
       {
+        memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
         instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
         rc= MEMCACHED_SOME_ERRORS;
         continue;
       }
-
+      instance->micro_version= uint8_t(version);
     }
   }
 
diff --git a/libmemcached/version.h b/libmemcached/version.h
deleted file mode 100644 (file)
index c443acc..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- * 
- *  Libmemcached library
- *
- *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
- *  Copyright (C) 2010 Brian Aker All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBMEMCACHED_API
-memcached_return_t memcached_version(memcached_st *ptr);
-
-LIBMEMCACHED_API
-const char * memcached_lib_version(void);
-
-#ifdef __cplusplus
-}
-#endif
index 74ec10ef63f2149ab3186d8e0b35fd23f247a5d4..f91bf4549f089ec887312d186cb54ab9f0d96a7a 100644 (file)
@@ -36,8 +36,7 @@
  */
 
 #include <config.h>
-#include <libmemcached/memcached.h>
-#include <libmemcached/virtual_bucket.h>
+#include <libmemcached/common.h>
 
 struct bucket_t {
   uint32_t master;
@@ -58,7 +57,9 @@ memcached_return_t memcached_virtual_bucket_create(memcached_st *self,
                                                    const uint32_t replicas)
 {
   if (! self || ! host_map || ! buckets)
+  {
     return MEMCACHED_INVALID_ARGUMENTS;
+  }
 
   memcached_virtual_bucket_free(self);
 
diff --git a/libmemcached/visibility.h b/libmemcached/visibility.h
deleted file mode 100644 (file)
index d4e4eea..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* LibMemcached
- * Copyright (C) 2006-2009 Brian Aker 
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- *
- * Summary: Interface for memcached server.
- *
- * Author: Trond Norbye
- *
- */
-
-/**
- * @file
- * @brief Visibility control macros
- */
-
-#pragma once
-
-/**
- *
- * LIBMEMCACHED_API is used for the public API symbols. It either DLL imports or
- * DLL exports (or does nothing for static build).
- *
- * LIBMEMCACHED_LOCAL is used for non-api symbols.
- */
-
-#if defined(BUILDING_LIBMEMCACHEDINTERNAL)
-# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
-#  define LIBMEMCACHED_API __attribute__ ((visibility("default")))
-#  define LIBMEMCACHED_LOCAL  __attribute__ ((visibility("default")))
-# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
-#  define LIBMEMCACHED_API __global
-#  define LIBMEMCACHED_LOCAL __global
-# elif defined(_MSC_VER)
-#  define LIBMEMCACHED_API extern __declspec(dllexport) 
-#  define LIBMEMCACHED_LOCAL extern __declspec(dllexport)
-# else
-#  define LIBMEMCACHED_API
-#  define LIBMEMCACHED_LOCAL
-# endif
-#else
-# if defined(BUILDING_LIBMEMCACHED)
-#  if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
-#   define LIBMEMCACHED_API __attribute__ ((visibility("default")))
-#   define LIBMEMCACHED_LOCAL  __attribute__ ((visibility("hidden")))
-#  elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
-#   define LIBMEMCACHED_API __global
-#   define LIBMEMCACHED_LOCAL __hidden
-#  elif defined(_MSC_VER)
-#   define LIBMEMCACHED_API extern __declspec(dllexport) 
-#   define LIBMEMCACHED_LOCAL
-#  else
-#   define LIBMEMCACHED_API
-#   define LIBMEMCACHED_LOCAL
-#  endif /* defined(HAVE_VISIBILITY) */
-# else  /* defined(BUILDING_LIBMEMCACHED) */
-#  if defined(_MSC_VER)
-#   define LIBMEMCACHED_API extern __declspec(dllimport) 
-#   define LIBMEMCACHED_LOCAL
-#  else
-#   define LIBMEMCACHED_API
-#   define LIBMEMCACHED_LOCAL
-#  endif /* defined(_MSC_VER) */
-# endif /* defined(BUILDING_LIBMEMCACHED) */
-#endif /* defined(BUILDING_LIBMEMCACHEDINTERNAL) */
diff --git a/libmemcachedprotocol-0.0/binary.h b/libmemcachedprotocol-0.0/binary.h
new file mode 100644 (file)
index 0000000..73cd35b
--- /dev/null
@@ -0,0 +1,726 @@
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (c) <2008>, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the  nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SUN MICROSYSTEMS, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Summary: Constants used by to implement the binary protocol.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Trond Norbye <trond.norbye@sun.com>
+ */
+
+#ifndef PROTOCOL_BINARY_H
+#define PROTOCOL_BINARY_H
+
+#include <libmemcachedprotocol-0.0/vbucket.h>
+
+/**
+ * \addtogroup Protocol
+ * @{
+ */
+
+/**
+ * This file contains definitions of the constants and packet formats
+ * defined in the binary specification. Please note that you _MUST_ remember
+ * to convert each multibyte field to / from network byte order to / from
+ * host order.
+ */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    /**
+     * Definition of the legal "magic" values used in a packet.
+     * See section 3.1 Magic byte
+     */
+    typedef enum {
+        PROTOCOL_BINARY_REQ = 0x80,
+        PROTOCOL_BINARY_RES = 0x81
+    } protocol_binary_magic;
+
+    /**
+     * Definition of the valid response status numbers.
+     * See section 3.2 Response Status
+     */
+    typedef enum {
+        PROTOCOL_BINARY_RESPONSE_SUCCESS = 0x00,
+        PROTOCOL_BINARY_RESPONSE_KEY_ENOENT = 0x01,
+        PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS = 0x02,
+        PROTOCOL_BINARY_RESPONSE_E2BIG = 0x03,
+        PROTOCOL_BINARY_RESPONSE_EINVAL = 0x04,
+        PROTOCOL_BINARY_RESPONSE_NOT_STORED = 0x05,
+        PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL = 0x06,
+        PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET = 0x07,
+        PROTOCOL_BINARY_RESPONSE_AUTH_ERROR = 0x20,
+        PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE = 0x21,
+        PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND = 0x81,
+        PROTOCOL_BINARY_RESPONSE_ENOMEM = 0x82,
+        PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED = 0x83,
+        PROTOCOL_BINARY_RESPONSE_EINTERNAL = 0x84,
+        PROTOCOL_BINARY_RESPONSE_EBUSY = 0x85,
+        PROTOCOL_BINARY_RESPONSE_ETMPFAIL = 0x86
+    } protocol_binary_response_status;
+
+    /**
+     * Defintion of the different command opcodes.
+     * See section 3.3 Command Opcodes
+     */
+    typedef enum {
+        PROTOCOL_BINARY_CMD_GET = 0x00,
+        PROTOCOL_BINARY_CMD_SET = 0x01,
+        PROTOCOL_BINARY_CMD_ADD = 0x02,
+        PROTOCOL_BINARY_CMD_REPLACE = 0x03,
+        PROTOCOL_BINARY_CMD_DELETE = 0x04,
+        PROTOCOL_BINARY_CMD_INCREMENT = 0x05,
+        PROTOCOL_BINARY_CMD_DECREMENT = 0x06,
+        PROTOCOL_BINARY_CMD_QUIT = 0x07,
+        PROTOCOL_BINARY_CMD_FLUSH = 0x08,
+        PROTOCOL_BINARY_CMD_GETQ = 0x09,
+        PROTOCOL_BINARY_CMD_NOOP = 0x0a,
+        PROTOCOL_BINARY_CMD_VERSION = 0x0b,
+        PROTOCOL_BINARY_CMD_GETK = 0x0c,
+        PROTOCOL_BINARY_CMD_GETKQ = 0x0d,
+        PROTOCOL_BINARY_CMD_APPEND = 0x0e,
+        PROTOCOL_BINARY_CMD_PREPEND = 0x0f,
+        PROTOCOL_BINARY_CMD_STAT = 0x10,
+        PROTOCOL_BINARY_CMD_SETQ = 0x11,
+        PROTOCOL_BINARY_CMD_ADDQ = 0x12,
+        PROTOCOL_BINARY_CMD_REPLACEQ = 0x13,
+        PROTOCOL_BINARY_CMD_DELETEQ = 0x14,
+        PROTOCOL_BINARY_CMD_INCREMENTQ = 0x15,
+        PROTOCOL_BINARY_CMD_DECREMENTQ = 0x16,
+        PROTOCOL_BINARY_CMD_QUITQ = 0x17,
+        PROTOCOL_BINARY_CMD_FLUSHQ = 0x18,
+        PROTOCOL_BINARY_CMD_APPENDQ = 0x19,
+        PROTOCOL_BINARY_CMD_PREPENDQ = 0x1a,
+        PROTOCOL_BINARY_CMD_VERBOSITY = 0x1b,
+        PROTOCOL_BINARY_CMD_TOUCH = 0x1c,
+        PROTOCOL_BINARY_CMD_GAT = 0x1d,
+        PROTOCOL_BINARY_CMD_GATQ = 0x1e,
+
+        PROTOCOL_BINARY_CMD_SASL_LIST_MECHS = 0x20,
+        PROTOCOL_BINARY_CMD_SASL_AUTH = 0x21,
+        PROTOCOL_BINARY_CMD_SASL_STEP = 0x22,
+
+        /* These commands are used for range operations and exist within
+         * this header for use in other projects.  Range operations are
+         * not expected to be implemented in the memcached server itself.
+         */
+        PROTOCOL_BINARY_CMD_RGET      = 0x30,
+        PROTOCOL_BINARY_CMD_RSET      = 0x31,
+        PROTOCOL_BINARY_CMD_RSETQ     = 0x32,
+        PROTOCOL_BINARY_CMD_RAPPEND   = 0x33,
+        PROTOCOL_BINARY_CMD_RAPPENDQ  = 0x34,
+        PROTOCOL_BINARY_CMD_RPREPEND  = 0x35,
+        PROTOCOL_BINARY_CMD_RPREPENDQ = 0x36,
+        PROTOCOL_BINARY_CMD_RDELETE   = 0x37,
+        PROTOCOL_BINARY_CMD_RDELETEQ  = 0x38,
+        PROTOCOL_BINARY_CMD_RINCR     = 0x39,
+        PROTOCOL_BINARY_CMD_RINCRQ    = 0x3a,
+        PROTOCOL_BINARY_CMD_RDECR     = 0x3b,
+        PROTOCOL_BINARY_CMD_RDECRQ    = 0x3c,
+        /* End Range operations */
+
+        /* VBucket commands */
+        PROTOCOL_BINARY_CMD_SET_VBUCKET = 0x3d,
+        PROTOCOL_BINARY_CMD_GET_VBUCKET = 0x3e,
+        PROTOCOL_BINARY_CMD_DEL_VBUCKET = 0x3f,
+        /* End VBucket commands */
+
+        /* TAP commands */
+        PROTOCOL_BINARY_CMD_TAP_CONNECT = 0x40,
+        PROTOCOL_BINARY_CMD_TAP_MUTATION = 0x41,
+        PROTOCOL_BINARY_CMD_TAP_DELETE = 0x42,
+        PROTOCOL_BINARY_CMD_TAP_FLUSH = 0x43,
+        PROTOCOL_BINARY_CMD_TAP_OPAQUE = 0x44,
+        PROTOCOL_BINARY_CMD_TAP_VBUCKET_SET = 0x45,
+        PROTOCOL_BINARY_CMD_TAP_CHECKPOINT_START = 0x46,
+        PROTOCOL_BINARY_CMD_TAP_CHECKPOINT_END = 0x47,
+        /* End TAP */
+
+        PROTOCOL_BINARY_CMD_LAST_RESERVED = 0xef,
+
+        /* Scrub the data */
+        PROTOCOL_BINARY_CMD_SCRUB = 0xf0
+    } protocol_binary_command;
+
+    /**
+     * Definition of the data types in the packet
+     * See section 3.4 Data Types
+     */
+    typedef enum {
+        PROTOCOL_BINARY_RAW_BYTES = 0x00
+    } protocol_binary_datatypes;
+
+    /**
+     * Definition of the header structure for a request packet.
+     * See section 2
+     */
+    typedef union {
+        struct {
+            uint8_t magic;
+            uint8_t opcode;
+            uint16_t keylen;
+            uint8_t extlen;
+            uint8_t datatype;
+            uint16_t vbucket;
+            uint32_t bodylen;
+            uint32_t opaque;
+            uint64_t cas;
+        } request;
+        uint8_t bytes[24];
+    } protocol_binary_request_header;
+
+    /**
+     * Definition of the header structure for a response packet.
+     * See section 2
+     */
+    typedef union {
+        struct {
+            uint8_t magic;
+            uint8_t opcode;
+            uint16_t keylen;
+            uint8_t extlen;
+            uint8_t datatype;
+            uint16_t status;
+            uint32_t bodylen;
+            uint32_t opaque;
+            uint64_t cas;
+        } response;
+        uint8_t bytes[24];
+    } protocol_binary_response_header;
+
+    /**
+     * Definition of a request-packet containing no extras
+     */
+    union protocol_binary_request_no_extras {
+        struct {
+            protocol_binary_request_header header;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header)];
+    };
+    typedef union protocol_binary_request_no_extras protocol_binary_request_no_extras;
+
+    /**
+     * Definition of a response-packet containing no extras
+     */
+    typedef union {
+        struct {
+            protocol_binary_response_header header;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_response_header)];
+    } protocol_binary_response_no_extras;
+
+    /**
+     * Definition of the packet used by the get, getq, getk and getkq command.
+     * See section 4
+     */
+    typedef protocol_binary_request_no_extras protocol_binary_request_get;
+    typedef protocol_binary_request_no_extras protocol_binary_request_getq;
+    typedef protocol_binary_request_no_extras protocol_binary_request_getk;
+    typedef protocol_binary_request_no_extras protocol_binary_request_getkq;
+
+    /**
+     * Definition of the packet returned from a successful get, getq, getk and
+     * getkq.
+     * See section 4
+     */
+    typedef union {
+        struct {
+            protocol_binary_response_header header;
+            struct {
+                uint32_t flags;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_response_header) + 4];
+    } protocol_binary_response_get;
+
+    typedef protocol_binary_response_get protocol_binary_response_getq;
+    typedef protocol_binary_response_get protocol_binary_response_getk;
+    typedef protocol_binary_response_get protocol_binary_response_getkq;
+
+    /**
+     * Definition of the packet used by the delete command
+     * See section 4
+     */
+    typedef protocol_binary_request_no_extras protocol_binary_request_delete;
+
+    /**
+     * Definition of the packet returned by the delete command
+     * See section 4
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_delete;
+
+    /**
+     * Definition of the packet used by the flush command
+     * See section 4
+     * Please note that the expiration field is optional, so remember to see
+     * check the header.bodysize to see if it is present.
+     */
+    typedef union {
+        struct {
+            protocol_binary_request_header header;
+            struct {
+                uint32_t expiration;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + 4];
+    } protocol_binary_request_flush;
+
+    /**
+     * Definition of the packet returned by the flush command
+     * See section 4
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_flush;
+
+    /**
+     * Definition of the packet used by set, add and replace
+     * See section 4
+     */
+    typedef union {
+        struct {
+            protocol_binary_request_header header;
+            struct {
+                uint32_t flags;
+                uint32_t expiration;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + 8];
+    } protocol_binary_request_set;
+    typedef protocol_binary_request_set protocol_binary_request_add;
+    typedef protocol_binary_request_set protocol_binary_request_replace;
+
+    /**
+     * Definition of the packet returned by set, add and replace
+     * See section 4
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_set;
+    typedef protocol_binary_response_no_extras protocol_binary_response_add;
+    typedef protocol_binary_response_no_extras protocol_binary_response_replace;
+
+    /**
+     * Definition of the noop packet
+     * See section 4
+     */
+    typedef protocol_binary_request_no_extras protocol_binary_request_noop;
+
+    /**
+     * Definition of the packet returned by the noop command
+     * See section 4
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_noop;
+
+    /**
+     * Definition of the structure used by the increment and decrement
+     * command.
+     * See section 4
+     */
+    typedef union {
+        struct {
+            protocol_binary_request_header header;
+            struct {
+                uint64_t delta;
+                uint64_t initial;
+                uint32_t expiration;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + 20];
+    } protocol_binary_request_incr;
+    typedef protocol_binary_request_incr protocol_binary_request_decr;
+
+    /**
+     * Definition of the response from an incr or decr command
+     * command.
+     * See section 4
+     */
+    typedef union {
+        struct {
+            protocol_binary_response_header header;
+            struct {
+                uint64_t value;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_response_header) + 8];
+    } protocol_binary_response_incr;
+    typedef protocol_binary_response_incr protocol_binary_response_decr;
+
+    /**
+     * Definition of the quit
+     * See section 4
+     */
+    typedef protocol_binary_request_no_extras protocol_binary_request_quit;
+
+    /**
+     * Definition of the packet returned by the quit command
+     * See section 4
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_quit;
+
+    /**
+     * Definition of the packet used by append and prepend command
+     * See section 4
+     */
+    typedef protocol_binary_request_no_extras protocol_binary_request_append;
+    typedef protocol_binary_request_no_extras protocol_binary_request_prepend;
+
+    /**
+     * Definition of the packet returned from a successful append or prepend
+     * See section 4
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_append;
+    typedef protocol_binary_response_no_extras protocol_binary_response_prepend;
+
+    /**
+     * Definition of the packet used by the version command
+     * See section 4
+     */
+    typedef protocol_binary_request_no_extras protocol_binary_request_version;
+
+    /**
+     * Definition of the packet returned from a successful version command
+     * See section 4
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_version;
+
+
+    /**
+     * Definition of the packet used by the stats command.
+     * See section 4
+     */
+    typedef protocol_binary_request_no_extras protocol_binary_request_stats;
+
+    /**
+     * Definition of the packet returned from a successful stats command
+     * See section 4
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_stats;
+
+    /**
+     * Definition of the packet used by the verbosity command
+     */
+    typedef union {
+        struct {
+            protocol_binary_request_header header;
+            struct {
+                uint32_t level;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + 4];
+    } protocol_binary_request_verbosity;
+
+    /**
+     * Definition of the packet returned from the verbosity command
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_verbosity;
+
+    /**
+     * Definition of the packet used by the touch command.
+     */
+    typedef union {
+        struct {
+            protocol_binary_request_header header;
+            struct {
+                uint32_t expiration;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + 4];
+    } protocol_binary_request_touch;
+
+    /**
+     * Definition of the packet returned from the touch command
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_touch;
+
+    /**
+     * Definition of the packet used by the GAT(Q) command.
+     */
+    typedef union {
+        struct {
+            protocol_binary_request_header header;
+            struct {
+                uint32_t expiration;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + 4];
+    } protocol_binary_request_gat;
+
+    typedef protocol_binary_request_gat protocol_binary_request_gatq;
+
+    /**
+     * Definition of the packet returned from the GAT(Q)
+     */
+    typedef protocol_binary_response_get protocol_binary_response_gat;
+    typedef protocol_binary_response_get protocol_binary_response_gatq;
+
+
+    /**
+     * Definition of a request for a range operation.
+     * See http://code.google.com/p/memcached/wiki/RangeOps
+     *
+     * These types are used for range operations and exist within
+     * this header for use in other projects.  Range operations are
+     * not expected to be implemented in the memcached server itself.
+     */
+    typedef union {
+        struct {
+            protocol_binary_response_header header;
+            struct {
+                uint16_t size;
+                uint8_t  reserved;
+                uint8_t  flags;
+                uint32_t max_results;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + 4];
+    } protocol_binary_request_rangeop;
+
+    typedef protocol_binary_request_rangeop protocol_binary_request_rget;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rset;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rsetq;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rappend;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rappendq;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rprepend;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rprependq;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rdelete;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rdeleteq;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rincr;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rincrq;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rdecr;
+    typedef protocol_binary_request_rangeop protocol_binary_request_rdecrq;
+
+
+    /**
+     * Definition of tap commands
+     * See To be written
+     *
+     */
+
+    typedef union {
+        struct {
+            protocol_binary_request_header header;
+            struct {
+                /**
+                 * flags is a bitmask used to set properties for the
+                 * the connection. Please In order to be forward compatible
+                 * you should set all undefined bits to 0.
+                 *
+                 * If the bit require extra userdata, it will be stored
+                 * in the user-data field of the body (passed to the engine
+                 * as enginespeciffic). That means that when you parse the
+                 * flags and the engine-specific data, you have to work your
+                 * way from bit 0 and upwards to find the correct offset for
+                 * the data.
+                 *
+                 */
+                uint32_t flags;
+
+                /**
+                 * Backfill age
+                 *
+                 * By using this flag you can limit the amount of data being
+                 * transmitted. If you don't specify a backfill age, the
+                 * server will transmit everything it contains.
+                 *
+                 * The first 8 bytes in the engine specific data contains
+                 * the oldest entry (from epoc) you're interested in.
+                 * Specifying a time in the future (for the server you are
+                 * connecting to), will cause it to start streaming current
+                 * changes.
+                 */
+#define TAP_CONNECT_FLAG_BACKFILL 0x01
+                /**
+                 * Dump will cause the server to send the data stored on the
+                 * server, but disconnect when the keys stored in the server
+                 * are transmitted.
+                 */
+#define TAP_CONNECT_FLAG_DUMP 0x02
+                /**
+                 * The body contains a list of 16 bits words in network byte
+                 * order specifying the vbucket ids to monitor. The first 16
+                 * bit word contains the number of buckets. The number of 0
+                 * means "all buckets"
+                 */
+#define TAP_CONNECT_FLAG_LIST_VBUCKETS 0x04
+                /**
+                 * The responsibility of the vbuckets is to be transferred
+                 * over to the caller when all items are transferred.
+                 */
+#define TAP_CONNECT_FLAG_TAKEOVER_VBUCKETS 0x08
+                /**
+                 * The tap consumer supports ack'ing of tap messages
+                 */
+#define TAP_CONNECT_SUPPORT_ACK 0x10
+                /**
+                 * The tap consumer would prefer to just get the keys
+                 * back. If the engine supports this it will set
+                 * the TAP_FLAG_NO_VALUE flag in each of the
+                 * tap packets returned.
+                 */
+#define TAP_CONNECT_REQUEST_KEYS_ONLY 0x20
+                /**
+                 * The body contains a list of (vbucket_id, last_checkpoint_id)
+                 * pairs. This provides the checkpoint support in TAP streams.
+                 * The last checkpoint id represents the last checkpoint that
+                 * was successfully persisted.
+                 */
+#define TAP_CONNECT_CHECKPOINT 0x40
+                /**
+                 * The tap consumer is a registered tap client, which means that
+                 * the tap server will maintain its checkpoint cursor permanently.
+                 */
+#define TAP_CONNECT_REGISTERED_CLIENT 0x80
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + 4];
+    } protocol_binary_request_tap_connect;
+
+    typedef union {
+        struct {
+            protocol_binary_request_header header;
+            struct {
+                struct {
+                    uint16_t enginespecific_length;
+                    /*
+                     * The flag section support the following flags
+                     */
+                    /**
+                     * Request that the consumer send a response packet
+                     * for this packet. The opaque field must be preserved
+                     * in the response.
+                     */
+#define TAP_FLAG_ACK 0x01
+                    /**
+                     * The value for the key is not included in the packet
+                     */
+#define TAP_FLAG_NO_VALUE 0x02
+                    uint16_t flags;
+                    uint8_t  ttl;
+                    uint8_t  res1;
+                    uint8_t  res2;
+                    uint8_t  res3;
+                } tap;
+                struct {
+                    uint32_t flags;
+                    uint32_t expiration;
+                } item;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + 16];
+    } protocol_binary_request_tap_mutation;
+
+    typedef union {
+        struct {
+            protocol_binary_request_header header;
+            struct {
+                struct {
+                    uint16_t enginespecific_length;
+                    /**
+                     * See the definition of the flags for
+                     * protocol_binary_request_tap_mutation for a description
+                     * of the available flags.
+                     */
+                    uint16_t flags;
+                    uint8_t  ttl;
+                    uint8_t  res1;
+                    uint8_t  res2;
+                    uint8_t  res3;
+                } tap;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + 8];
+    } protocol_binary_request_tap_no_extras;
+
+    typedef protocol_binary_request_tap_no_extras protocol_binary_request_tap_delete;
+    typedef protocol_binary_request_tap_no_extras protocol_binary_request_tap_flush;
+    typedef protocol_binary_request_tap_no_extras protocol_binary_request_tap_opaque;
+    typedef protocol_binary_request_tap_no_extras protocol_binary_request_tap_vbucket_set;
+
+
+    /**
+     * Definition of the packet used by the scrub.
+     */
+    typedef protocol_binary_request_no_extras protocol_binary_request_scrub;
+
+    /**
+     * Definition of the packet returned from scrub.
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_scrub;
+
+
+    /**
+     * Definition of the packet used by set vbucket
+     */
+    typedef union {
+        struct {
+            protocol_binary_request_header header;
+            struct {
+                vbucket_state_t state;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_request_header) + sizeof(vbucket_state_t)];
+    } protocol_binary_request_set_vbucket;
+    /**
+     * Definition of the packet returned from set vbucket
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_set_vbucket;
+    /**
+     * Definition of the packet used by del vbucket
+     */
+    typedef protocol_binary_request_no_extras protocol_binary_request_del_vbucket;
+    /**
+     * Definition of the packet returned from del vbucket
+     */
+    typedef protocol_binary_response_no_extras protocol_binary_response_del_vbucket;
+
+    /**
+     * Definition of the packet used by get vbucket
+     */
+    typedef protocol_binary_request_no_extras protocol_binary_request_get_vbucket;
+
+    /**
+     * Definition of the packet returned from get vbucket
+     */
+    typedef union {
+        struct {
+            protocol_binary_response_header header;
+            struct {
+                vbucket_state_t state;
+            } body;
+        } message;
+        uint8_t bytes[sizeof(protocol_binary_response_header) + sizeof(vbucket_state_t)];
+    } protocol_binary_response_get_vbucket;
+
+
+    /**
+     * @}
+     */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* PROTOCOL_BINARY_H */
diff --git a/libmemcachedprotocol-0.0/callback.h b/libmemcachedprotocol-0.0/callback.h
new file mode 100644 (file)
index 0000000..9020411
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * Summary: Definition of the callback interface
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Trond Norbye
+ */
+
+#pragma once
+
+/**
+ * Callback to send data back from a successful GET/GETQ/GETK/GETKQ command
+ *
+ * @param cookie Just pass along the cookie supplied in the callback
+ * @param key What to insert as key in the reply
+ * @param keylen The length of the key
+ * @param body What to store in the body of the package
+ * @param bodylen The number of bytes of the body
+ * @param flags The flags stored with the item
+ * @param cas The CAS value to insert into the response (should be 0
+ *            if you don't care)
+ */
+typedef protocol_binary_response_status
+(*memcached_binary_protocol_get_response_handler)(const void *cookie,
+                                                  const void *key,
+                                                  uint16_t keylen,
+                                                  const void *body,
+                                                  uint32_t bodylen,
+                                                  uint32_t flags,
+                                                  uint64_t cas);
+/**
+ * Callback to send data back from a STAT command
+ *
+ * @param cookie Just pass along the cookie supplied in the callback
+ * @param key What to insert as key in the reply
+ * @param keylen The length of the key
+ * @param body What to store in the body of the package
+ * @param bodylen The number of bytes of the body
+ */
+typedef protocol_binary_response_status
+(*memcached_binary_protocol_stat_response_handler)(const void *cookie,
+                                                   const void *key,
+                                                   uint16_t keylen,
+                                                   const void *body,
+                                                   uint32_t bodylen);
+/**
+ * Callback to send data back from a VERSION command
+ *
+ * @param cookie Just pass along the cookie supplied in the callback
+ * @param text The version string
+ * @param length The number of bytes in the version string
+ */
+typedef protocol_binary_response_status
+(*memcached_binary_protocol_version_response_handler)(const void *cookie,
+                                                      const void *text,
+                                                      uint32_t length);
+
+
+/**
+ * In the low level interface you need to format the response
+ * packet yourself (giving you complete freedom :-)
+ *
+ * @param cookie Just pass along the cookie supplied in the callback
+ * @param request Pointer to the request packet you are sending a reply to
+ * @param response Pointer to the response packet to send
+ *
+ */
+typedef protocol_binary_response_status (*memcached_binary_protocol_raw_response_handler)(const void *cookie,
+                                                               protocol_binary_request_header *request,
+                                                               protocol_binary_response_header *response);
+
+/**
+ * In the low lever interface you have to do most of the work by
+ * yourself, but it also gives you a lot of freedom :-)
+ * @param cookie identification for this connection, just pass it along to
+ *               the response handler
+ * @param header the command received over the wire. Never try to access
+ *               <u>anything</u> outside the command.
+ * @param resonse_handler call this function to send data back to the client
+ */
+typedef protocol_binary_response_status (*memcached_binary_protocol_command_handler)(const void *cookie,
+                                                   protocol_binary_request_header *header,
+                                                   memcached_binary_protocol_raw_response_handler response_handler);
+
+/**
+ * The raw interface to the packets is implemented in version 0. It contains
+ * just an array with command handlers. The inxed in the array is the
+ * com code.
+ */
+typedef struct {
+   memcached_binary_protocol_command_handler comcode[256];
+} memcached_binary_protocol_callback_v0_st;
+
+
+/**
+ * The first version of the callback struct containing all of the
+ * documented commands in the initial release of the binary protocol
+ * (aka. memcached 1.4.0).
+ *
+ * You might miss the Q commands (addq etc) but the response function
+ * knows how to deal with them so you don't need to worry about that :-)
+ */
+typedef struct {
+   /**
+    * Add an item to the cache
+    * @param cookie id of the client receiving the command
+    * @param key the key to add
+    * @param len the length of the key
+    * @param val the value to store for the key (may be NIL)
+    * @param vallen the length of the data
+    * @param flags the flags to store with the key
+    * @param exptime the expiry time for the key-value pair
+    * @param cas the resulting cas for the add operation (if success)
+    */
+   protocol_binary_response_status (*add)(const void *cookie,
+                                          const void *key,
+                                          uint16_t keylen,
+                                          const void* val,
+                                          uint32_t vallen,
+                                          uint32_t flags,
+                                          uint32_t exptime,
+                                          uint64_t *cas);
+
+   /**
+    * Append data to an <b>existing</b> key-value pair.
+    *
+    * @param cookie id of the client receiving the command
+    * @param key the key to add data to
+    * @param len the length of the key
+    * @param val the value to append to the value
+    * @param vallen the length of the data
+    * @param cas the CAS in the request
+    * @param result_cas the resulting cas for the append operation
+    *
+    */
+   protocol_binary_response_status (*append)(const void *cookie,
+                                             const void *key,
+                                             uint16_t keylen,
+                                             const void* val,
+                                             uint32_t vallen,
+                                             uint64_t cas,
+                                             uint64_t *result_cas);
+
+   /**
+    * Decrement the value for a key
+    *
+    * @param cookie id of the client receiving the command
+    * @param key the key to decrement the value for
+    * @param len the length of the key
+    * @param delta the amount to decrement
+    * @param initial initial value to store (if the key doesn't exist)
+    * @param expiration expiration time for the object (if the key doesn't exist)
+    * @param cas the CAS in the request
+    * @param result the result from the decrement
+    * @param result_cas the cas of the item
+    *
+    */
+   protocol_binary_response_status (*decrement)(const void *cookie,
+                                                const void *key,
+                                                uint16_t keylen,
+                                                uint64_t delta,
+                                                uint64_t initial,
+                                                uint32_t expiration,
+                                                uint64_t *result,
+                                                uint64_t *result_cas);
+
+   /**
+    * Delete an existing key
+    *
+    * @param cookie id of the client receiving the command
+    * @param key the key to delete
+    * @param len the length of the key
+    * @param cas the CAS in the request
+    */
+   protocol_binary_response_status (*delete)(const void *cookie,
+                                             const void *key,
+                                             uint16_t keylen,
+                                             uint64_t cas);
+
+
+   /**
+    * Flush the cache
+    *
+    * @param cookie id of the client receiving the command
+    * @param when when the cache should be flushed (0 == immediately)
+    */
+   protocol_binary_response_status (*flush)(const void *cookie,
+                                            uint32_t when);
+
+
+
+   /**
+    * Get a key-value pair
+    *
+    * @param cookie id of the client receiving the command
+    * @param key the key to get
+    * @param len the length of the key
+    * @param response_handler to send the result back to the client
+    */
+   protocol_binary_response_status (*get)(const void *cookie,
+                                          const void *key,
+                                          uint16_t keylen,
+                                          memcached_binary_protocol_get_response_handler response_handler);
+
+   /**
+    * Increment the value for a key
+    *
+    * @param cookie id of the client receiving the command
+    * @param key the key to increment the value on
+    * @param len the length of the key
+    * @param delta the amount to increment
+    * @param initial initial value to store (if the key doesn't exist)
+    * @param expiration expiration time for the object (if the key doesn't exist)
+    * @param cas the CAS in the request
+    * @param result the result from the decrement
+    * @param result_cas the cas of the item
+    *
+    */
+   protocol_binary_response_status (*increment)(const void *cookie,
+                                                const void *key,
+                                                uint16_t keylen,
+                                                uint64_t delta,
+                                                uint64_t initial,
+                                                uint32_t expiration,
+                                                uint64_t *result,
+                                                uint64_t *result_cas);
+
+   /**
+    * The noop command was received. This is just a notification callback (the
+    * response is automatically created).
+    *
+    * @param cookie id of the client receiving the command
+    */
+   protocol_binary_response_status (*noop)(const void *cookie);
+
+   /**
+    * Prepend data to an <b>existing</b> key-value pair.
+    *
+    * @param cookie id of the client receiving the command
+    * @param key the key to prepend data to
+    * @param len the length of the key
+    * @param val the value to prepend to the value
+    * @param vallen the length of the data
+    * @param cas the CAS in the request
+    * @param result-cas the cas id of the item
+    *
+    */
+   protocol_binary_response_status (*prepend)(const void *cookie,
+                                              const void *key,
+                                              uint16_t keylen,
+                                              const void* val,
+                                              uint32_t vallen,
+                                              uint64_t cas,
+                                              uint64_t *result_cas);
+
+   /**
+    * The quit command was received. This is just a notification callback (the
+    * response is automatically created).
+    *
+    * @param cookie id of the client receiving the command
+    */
+   protocol_binary_response_status (*quit)(const void *cookie);
+
+
+   /**
+    * Replace an <b>existing</b> item to the cache
+    *
+    * @param cookie id of the client receiving the command
+    * @param key the key to replace the content for
+    * @param len the length of the key
+    * @param val the value to store for the key (may be NIL)
+    * @param vallen the length of the data
+    * @param flags the flags to store with the key
+    * @param exptime the expiry time for the key-value pair
+    * @param cas the cas id in the request
+    * @param result_cas the cas id of the item
+    */
+   protocol_binary_response_status (*replace)(const void *cookie,
+                                              const void *key,
+                                              uint16_t keylen,
+                                              const void* val,
+                                              uint32_t vallen,
+                                              uint32_t flags,
+                                              uint32_t exptime,
+                                              uint64_t cas,
+                                              uint64_t *result_cas);
+
+
+   /**
+    * Set a key-value pair in the cache
+    *
+    * @param cookie id of the client receiving the command
+    * @param key the key to insert
+    * @param len the length of the key
+    * @param val the value to store for the key (may be NIL)
+    * @param vallen the length of the data
+    * @param flags the flags to store with the key
+    * @param exptime the expiry time for the key-value pair
+    * @param cas the cas id in the request
+    * @param result_cas the cas id of the new item
+    */
+   protocol_binary_response_status (*set)(const void *cookie,
+                                          const void *key,
+                                          uint16_t keylen,
+                                          const void* val,
+                                          uint32_t vallen,
+                                          uint32_t flags,
+                                          uint32_t exptime,
+                                          uint64_t cas,
+                                          uint64_t *result_cas);
+
+   /**
+    * Get status information
+    *
+    * @param cookie id of the client receiving the command
+    * @param key the key to get status for (or NIL to request all status).
+    *            Remember to insert the terminating packet if multiple
+    *            packets should be returned.
+    * @param keylen the length of the key
+    * @param response_handler to send the result back to the client, but
+    *                         don't send reply on success!
+    *
+    */
+   protocol_binary_response_status (*stat)(const void *cookie,
+                                           const void *key,
+                                           uint16_t keylen,
+                                           memcached_binary_protocol_stat_response_handler response_handler);
+
+   /**
+    * Get the version information
+    *
+    * @param cookie id of the client receiving the command
+    * @param response_handler to send the result back to the client, but
+    *                         don't send reply on success!
+    *
+    */
+   protocol_binary_response_status (*version)(const void *cookie,
+                                              memcached_binary_protocol_version_response_handler response_handler);
+} memcached_binary_protocol_callback_v1_st;
+
+
+/**
+ * The version numbers for the different callback structures.
+ */
+typedef enum {
+   /** Version 0 is a lowlevel interface that tries to maximize your freedom */
+   MEMCACHED_PROTOCOL_HANDLER_V0= 0,
+   /**
+    * Version 1 abstracts more of the protocol details, and let you work at
+    * a logical level
+    */
+   MEMCACHED_PROTOCOL_HANDLER_V1= 1,
+} memcached_protocol_interface_version_t;
+
+/**
+ * Definition of the protocol callback structure.
+ */
+typedef struct {
+   /**
+    * The interface version you provide callbacks for.
+    */
+   memcached_protocol_interface_version_t interface_version;
+
+   /**
+    * Callback fired just before the command will be executed.
+    *
+    * @param cookie id of the client receiving the command
+    * @param header the command header as received on the wire. If you look
+    *               at the content you <b>must</b> ensure that you don't
+    *               try to access beyond the end of the message.
+    */
+   void (*pre_execute)(const void *cookie,
+                       protocol_binary_request_header *header);
+   /**
+    * Callback fired just after the command was exected (please note
+    * that the data transfer back to the client is not finished at this
+    * time).
+    *
+    * @param cookie id of the client receiving the command
+    * @param header the command header as received on the wire. If you look
+    *               at the content you <b>must</b> ensure that you don't
+    *               try to access beyond the end of the message.
+    */
+   void (*post_execute)(const void *cookie,
+                        protocol_binary_request_header *header);
+
+   /**
+    * Callback fired if no specialized callback is registered for this
+    * specific command code.
+    *
+    * @param cookie id of the client receiving the command
+    * @param header the command header as received on the wire. You <b>must</b>
+    *               ensure that you don't try to access beyond the end of the
+    *               message.
+    * @param response_handler The response handler to send data back.
+    */
+   protocol_binary_response_status (*unknown)(const void *cookie,
+                                              protocol_binary_request_header *header,
+                                              memcached_binary_protocol_raw_response_handler response_handler);
+
+   /**
+    * The different interface levels we support. A pointer is used so the
+    * size of the structure is fixed. You must ensure that the memory area
+    * passed as the pointer is valid as long as you use the protocol handler.
+    */
+   union {
+      memcached_binary_protocol_callback_v0_st v0;
+
+      /**
+       * The first version of the callback struct containing all of the
+       * documented commands in the initial release of the binary protocol
+       * (aka. memcached 1.4.0).
+       */
+      memcached_binary_protocol_callback_v1_st v1;
+   } interface;
+} memcached_binary_protocol_callback_st;
diff --git a/libmemcachedprotocol-0.0/handler.h b/libmemcachedprotocol-0.0/handler.h
new file mode 100644 (file)
index 0000000..f1cfdc0
--- /dev/null
@@ -0,0 +1,215 @@
+/* LibMemcached
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ *
+ * Summary: Definition of the callback interface to the protocol handler
+ *
+ * Author: Trond Norbye
+ *
+ */
+
+#pragma once
+
+#include <sys/types.h>
+#if !defined(__cplusplus)
+# include <stdbool.h>
+#endif
+
+#include <libmemcached-1.0/visibility.h>
+#include <libmemcached-1.0/platform.h>
+#include <libmemcachedprotocol-0.0/binary.h>
+#include <libmemcachedprotocol-0.0/callback.h>
+
+/* Forward declarations */
+/*
+ * You should only access memcached_protocol_st from one thread!,
+ * and never assume anything about the internal layout / sizes of the
+ * structures.
+ */
+typedef struct memcached_protocol_st memcached_protocol_st;
+typedef struct memcached_protocol_client_st memcached_protocol_client_st;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Function the protocol handler should call to receive data.
+ * This function should behave exactly like read(2)
+ *
+ * @param cookie a cookie used to represent a given client
+ * @param fd the filedescriptor associated with the client
+ * @param buf destination buffer
+ * @param nbuf number of bytes to receive
+ * @return the number of bytes copied into buf
+ *         or -1 upon error (errno should contain more information)
+ */
+typedef ssize_t (*memcached_protocol_recv_func)(const void *cookie,
+                                                memcached_socket_t fd,
+                                                void *buf,
+                                                size_t nbuf);
+
+/**
+ * Function the protocol handler should call to send data.
+ * This function should behave exactly like write(2)
+ *
+ * @param cookie a cookie used to represent a given client
+ * @param fd the filedescriptor associated with the client
+ * @param buf the source buffer
+ * @param nbuf number of bytes to send
+ * @return the number of bytes sent
+ *         or -1 upon error (errno should contain more information)
+ */
+typedef ssize_t (*memcached_protocol_send_func)(const void *cookie,
+                                                memcached_socket_t fd,
+                                                const void *buf,
+                                                size_t nbuf);
+
+/**
+ * Create an instance of the protocol handler
+ *
+ * @return NULL if allocation of an instance fails
+ */
+LIBMEMCACHED_API
+memcached_protocol_st *memcached_protocol_create_instance(void);
+
+/**
+ * Get the callbacks associated with a protocol handler instance
+ * @return the callbacks currently used
+ */
+LIBMEMCACHED_API
+memcached_binary_protocol_callback_st *memcached_binary_protocol_get_callbacks(memcached_protocol_st *instance);
+
+/**
+ * Set the callbacks to be used by the given protocol handler instance
+ * @param instance the instance to update
+ * @param callback the callbacks to use
+ */
+LIBMEMCACHED_API
+void memcached_binary_protocol_set_callbacks(memcached_protocol_st *instance, memcached_binary_protocol_callback_st *callback);
+
+/**
+ * Should the library inspect the packages being sent and received and verify
+ * that they are according to the specification? If it encounters an invalid
+ * packet, it will return an EINVAL packet.
+ *
+ * @param instance the instance to update
+ * @param enable true if you want the library to check packages, false otherwise
+ */
+LIBMEMCACHED_API
+void memcached_binary_protocol_set_pedantic(memcached_protocol_st *instance, bool enable);
+
+/**
+ * Is the library inpecting each package?
+ * @param instance the instance to check
+ * @return true it the library is inspecting each package, false otherwise
+ */
+LIBMEMCACHED_API
+bool memcached_binary_protocol_get_pedantic(memcached_protocol_st *instance);
+
+/**
+ * Destroy an instance of the protocol handler
+ *
+ * @param instance The instance to destroy
+ */
+LIBMEMCACHED_API
+void memcached_protocol_destroy_instance(memcached_protocol_st *instance);
+
+/**
+ * Set the IO functions used by the instance to send and receive data. The
+ * functions should behave like recv(3socket) and send(3socket).
+ *
+ * @param instance the instance to specify the IO functions for
+ * @param recv the function to call for reciving data
+ * @param send the function to call for sending data
+ */
+LIBMEMCACHED_API
+void memached_protocol_set_io_functions(memcached_protocol_st *instance,
+                                        memcached_protocol_recv_func recv,
+                                        memcached_protocol_send_func send);
+
+
+/**
+ * Create a new client instance and associate it with a socket
+ * @param instance the protocol instance to bind the client to
+ * @param sock the client socket
+ * @return NULL if allocation fails, otherwise an instance
+ */
+LIBMEMCACHED_API
+memcached_protocol_client_st *memcached_protocol_create_client(memcached_protocol_st *instance, memcached_socket_t sock);
+
+/**
+ * Destroy a client handle.
+ * The caller needs to close the socket accociated with the client
+ * <b>before</b> calling this function. This function invalidates the
+ * client memory area.
+ *
+ * @param client the client to destroy
+ */
+LIBMEMCACHED_API
+void memcached_protocol_client_destroy(memcached_protocol_client_st *client);
+
+/**
+ * Error event means that the client encountered an error with the
+ * connection so you should shut it down
+ */
+#define MEMCACHED_PROTOCOL_ERROR_EVENT 1
+/**
+ * Please notify when there is more data available to read
+ */
+#define MEMCACHED_PROTOCOL_READ_EVENT 2
+/**
+ * Please notify when it is possible to send more data
+ */
+#define MEMCACHED_PROTOCOL_WRITE_EVENT 4
+/**
+ * Backed paused the execution for this client
+ */
+#define MEMCACHED_PROTOCOL_PAUSE_EVENT 8
+
+/**
+ * The different events the client is interested in. This is a bitmask of
+ * the constants defined above.
+ */
+typedef uint32_t memcached_protocol_event_t;
+
+/**
+ * Let the client do some work. This might involve reading / sending data
+ * to/from the client, or perform callbacks to execute a command.
+ * @param client the client structure to work on
+ * @return The next event the protocol handler will be notified for
+ */
+LIBMEMCACHED_API
+memcached_protocol_event_t memcached_protocol_client_work(memcached_protocol_client_st *client);
+
+/**
+ * Get the socket attached to a client handle
+ * @param client the client to query
+ * @return the socket handle
+ */
+LIBMEMCACHED_API
+memcached_socket_t memcached_protocol_client_get_socket(memcached_protocol_client_st *client);
+
+/**
+ * Get the error id socket attached to a client handle
+ * @param client the client to query for an error code
+ * @return the OS error code from the client
+ */
+LIBMEMCACHED_API
+int memcached_protocol_client_get_errno(memcached_protocol_client_st *client);
+
+/**
+ * Get a raw response handler for the given cookie
+ * @param cookie the cookie passed along into the callback
+ * @return the raw reponse handler you may use if you find
+ *         the generic callback too limiting
+ */
+LIBMEMCACHED_API
+memcached_binary_protocol_raw_response_handler memcached_binary_protocol_get_raw_response_handler(const void *cookie);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcachedprotocol-0.0/include.am b/libmemcachedprotocol-0.0/include.am
new file mode 100644 (file)
index 0000000..3683c0f
--- /dev/null
@@ -0,0 +1,9 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+nobase_include_HEADERS+= \
+                        libmemcachedprotocol-0.0/binary.h \
+                        libmemcachedprotocol-0.0/callback.h \
+                        libmemcachedprotocol-0.0/handler.h \
+                        libmemcachedprotocol-0.0/vbucket.h
diff --git a/libmemcachedprotocol-0.0/vbucket.h b/libmemcachedprotocol-0.0/vbucket.h
new file mode 100644 (file)
index 0000000..e2cc563
--- /dev/null
@@ -0,0 +1,59 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef enum {
+    vbucket_state_active = 1, /**< Actively servicing a vbucket. */
+    vbucket_state_replica, /**< Servicing a vbucket as a replica only. */
+    vbucket_state_pending, /**< Pending active. */
+    vbucket_state_dead /**< Not in use, pending deletion. */
+} vbucket_state_t;
+
+#define is_valid_vbucket_state_t(state) \
+    (state == vbucket_state_active || \
+     state == vbucket_state_replica || \
+     state == vbucket_state_pending || \
+     state == vbucket_state_dead)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcachedprotocol/ascii_handler.c b/libmemcachedprotocol/ascii_handler.c
new file mode 100644 (file)
index 0000000..f6134b3
--- /dev/null
@@ -0,0 +1,960 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <libmemcachedprotocol/common.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * Try to parse a key from the string.
+ * @pointer start pointer to a pointer to the string (IN and OUT)
+ * @return length of the string of -1 if this was an illegal key (invalid
+ *         characters or invalid length)
+ * @todo add length!
+ */
+static uint16_t parse_ascii_key(char **start)
+{
+  uint16_t len= 0;
+  char *c= *start;
+  /* Strip leading whitespaces */
+  while (isspace(*c))
+  {
+    ++c;
+  }
+
+  *start= c;
+
+  while (*c != '\0' && !isspace(*c) && !iscntrl(*c))
+  {
+    ++c;
+    ++len;
+  }
+
+
+  if (len == 0 || len > 240 || (*c != '\0' && *c != '\r' && iscntrl(*c)))
+  {
+    return 0;
+  }
+
+  return len;
+}
+
+/**
+ * Spool a zero-terminated string
+ * @param client destination
+ * @param text the text to spool
+ * @return status of the spool operation
+ */
+static protocol_binary_response_status
+spool_string(memcached_protocol_client_st *client, const char *text)
+{
+  return client->root->spool(client, text, strlen(text));
+}
+
+/**
+ * Send a "CLIENT_ERROR" message back to the client with the correct
+ * format of the command being sent
+ * @param client the client to send the message to
+ */
+static void send_command_usage(memcached_protocol_client_st *client)
+{
+  const char *errmsg[]= {
+    [GET_CMD]= "CLIENT_ERROR: Syntax error: get <key>*\r\n",
+    [GETS_CMD]= "CLIENT_ERROR: Syntax error: gets <key>*\r\n",
+    [SET_CMD]= "CLIENT_ERROR: Syntax error: set <key> <flags> <exptime> <bytes> [noreply]\r\n",
+    [ADD_CMD]= "CLIENT_ERROR: Syntax error: add <key> <flags> <exptime> <bytes> [noreply]\r\n",
+    [REPLACE_CMD]= "CLIENT_ERROR: Syntax error: replace <key> <flags> <exptime> <bytes> [noreply]\r\n",
+    [CAS_CMD]= "CLIENT_ERROR: Syntax error: cas <key> <flags> <exptime> <bytes> <casid> [noreply]\r\n",
+    [APPEND_CMD]= "CLIENT_ERROR: Syntax error: append <key> <flags> <exptime> <bytes> [noreply]\r\n",
+    [PREPEND_CMD]= "CLIENT_ERROR: Syntax error: prepend <key> <flags> <exptime> <bytes> [noreply]\r\n",
+    [DELETE_CMD]= "CLIENT_ERROR: Syntax error: delete <key> [noreply]\r\n",
+    [INCR_CMD]= "CLIENT_ERROR: Syntax error: incr <key> <value> [noreply]\r\n",
+    [DECR_CMD]= "CLIENT_ERROR: Syntax error: decr <key> <value> [noreply]\r\n",
+    [STATS_CMD]= "CLIENT_ERROR: Syntax error: stats [key]\r\n",
+    [FLUSH_ALL_CMD]= "CLIENT_ERROR: Syntax error: flush_all [timeout] [noreply]\r\n",
+    [VERSION_CMD]= "CLIENT_ERROR: Syntax error: version\r\n",
+    [QUIT_CMD]="CLIENT_ERROR: Syntax error: quit\r\n",
+
+    [VERBOSITY_CMD]= "CLIENT_ERROR: Syntax error: verbosity <num>\r\n",
+    [UNKNOWN_CMD]= "CLIENT_ERROR: Unknown command\r\n",
+  };
+
+  client->mute = false;
+  spool_string(client, errmsg[client->ascii_command]);
+}
+
+/**
+ * Callback for the VERSION responses
+ * @param cookie client identifier
+ * @param text the length of the body
+ * @param textlen the length of the body
+ */
+static protocol_binary_response_status
+ascii_version_response_handler(const void *cookie,
+                               const void *text,
+                               uint32_t textlen)
+{
+  memcached_protocol_client_st *client= (memcached_protocol_client_st*)cookie;
+  spool_string(client, "VERSION ");
+  client->root->spool(client, text, textlen);
+  spool_string(client, "\r\n");
+  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
+}
+
+/**
+ * Callback for the GET/GETQ/GETK and GETKQ responses
+ * @param cookie client identifier
+ * @param key the key for the item
+ * @param keylen the length of the key
+ * @param body the length of the body
+ * @param bodylen the length of the body
+ * @param flags the flags for the item
+ * @param cas the CAS id for the item
+ */
+static protocol_binary_response_status
+ascii_get_response_handler(const void *cookie,
+                           const void *key,
+                           uint16_t keylen,
+                           const void *body,
+                           uint32_t bodylen,
+                           uint32_t flags,
+                           uint64_t cas)
+{
+  memcached_protocol_client_st *client= (void*)cookie;
+  char buffer[300];
+  strcpy(buffer, "VALUE ");
+  const char *source= key;
+  char *dest= buffer + 6;
+
+  for (int x= 0; x < keylen; ++x)
+  {
+    if (*source != '\0' && !isspace(*source) && !iscntrl(*source))
+    {
+      *dest= *source;
+    }
+    else
+    {
+      return PROTOCOL_BINARY_RESPONSE_EINVAL; /* key constraints in ascii */
+    }
+
+    ++dest;
+    ++source;
+  }
+
+  size_t used= (size_t)(dest - buffer);
+
+  if (client->ascii_command == GETS_CMD)
+  {
+    snprintf(dest, sizeof(buffer) - used, " %u %u %" PRIu64 "\r\n", flags,
+             bodylen, cas);
+  }
+  else
+  {
+    snprintf(dest, sizeof(buffer) - used, " %u %u\r\n", flags, bodylen);
+  }
+
+  client->root->spool(client, buffer, strlen(buffer));
+  client->root->spool(client, body, bodylen);
+  client->root->spool(client, "\r\n", 2);
+
+  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
+}
+
+/**
+ * Callback for the STAT responses
+ * @param cookie client identifier
+ * @param key the key for the item
+ * @param keylen the length of the key
+ * @param body the length of the body
+ * @param bodylen the length of the body
+ */
+static protocol_binary_response_status
+ascii_stat_response_handler(const void *cookie,
+                     const void *key,
+                     uint16_t keylen,
+                     const void *body,
+                     uint32_t bodylen)
+{
+
+  memcached_protocol_client_st *client= (void*)cookie;
+
+  if (key != NULL)
+  {
+    spool_string(client, "STAT ");
+    client->root->spool(client, key, keylen);
+    spool_string(client, " ");
+    client->root->spool(client, body, bodylen);
+    spool_string(client, "\r\n");
+  }
+  else
+  {
+    spool_string(client, "END\r\n");
+  }
+
+  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
+}
+
+/**
+ * Process a get or a gets request.
+ * @param client the client handle
+ * @param buffer the complete get(s) command
+ * @param end the last character in the command
+ */
+static void ascii_process_gets(memcached_protocol_client_st *client,
+                               char *buffer, char *end)
+{
+  char *key= buffer;
+
+  /* Skip command */
+  key += (client->ascii_command == GETS_CMD) ? 5 : 4;
+
+  int num_keys= 0;
+  while (key < end)
+  {
+    uint16_t nkey= parse_ascii_key(&key);
+    if (nkey == 0) /* Invalid key... stop processing this line */
+    {
+      break;
+    }
+
+    (void)client->root->callback->interface.v1.get(client, key, nkey,
+                                                   ascii_get_response_handler);
+    key += nkey;
+    ++num_keys;
+  }
+
+  if (num_keys == 0)
+  {
+    send_command_usage(client);
+  }
+  else
+    client->root->spool(client, "END\r\n", 5);
+}
+
+/**
+ * Try to split up the command line "asdf asdf asdf asdf\n" into an
+ * argument vector for easier parsing.
+ * @param start the first character in the command line
+ * @param end the last character in the command line ("\n")
+ * @param vec the vector to insert the pointers into
+ * @size the number of elements in the vector
+ * @return the number of tokens in the vector
+ */
+static int ascii_tokenize_command(char *str, char *end, char **vec, int size)
+{
+  int elem= 0;
+
+  while (str < end)
+  {
+    /* Skip leading blanks */
+    while (str < end && isspace(*str))
+    {
+      ++str;
+    }
+
+    if (str == end)
+    {
+      return elem;
+    }
+
+    vec[elem++]= str;
+    /* find the next non-blank field */
+    while (str < end && !isspace(*str))
+    {
+      ++str;
+    }
+
+    /* zero-terminate it for easier parsing later on */
+    *str= '\0';
+    ++str;
+
+    /* Is the vector full? */
+    if (elem == size)
+    {
+      break;
+    }
+  }
+
+  return elem;
+}
+
+/**
+ * If we for some reasons needs to push the line back to read more
+ * data we have to reverse the tokenization. Just do the brain-dead replace
+ * of all '\0' to ' ' and set the last character to '\n'. We could have used
+ * the vector we created, but then we would have to search for all of the
+ * spaces we ignored...
+ * @param start pointer to the first character in the buffer to recover
+ * @param end pointer to the last character in the buffer to recover
+ */
+static void recover_tokenize_command(char *start, char *end)
+{
+  while (start < end)
+  {
+    if (*start == '\0')
+      *start= ' ';
+    ++start;
+  }
+
+  *end= '\n';
+}
+
+/**
+ * Convert the textual command into a comcode
+ */
+static enum ascii_cmd ascii_to_cmd(char *start, size_t length)
+{
+  struct {
+    const char *cmd;
+    size_t len;
+    enum ascii_cmd cc;
+  } commands[]= {
+    { .cmd= "get", .len= 3, .cc= GET_CMD },
+    { .cmd= "gets", .len= 4, .cc= GETS_CMD },
+    { .cmd= "set", .len= 3, .cc= SET_CMD },
+    { .cmd= "add", .len= 3, .cc= ADD_CMD },
+    { .cmd= "replace", .len= 7, .cc= REPLACE_CMD },
+    { .cmd= "cas", .len= 3, .cc= CAS_CMD },
+    { .cmd= "append", .len= 6, .cc= APPEND_CMD },
+    { .cmd= "prepend", .len= 7, .cc= PREPEND_CMD },
+    { .cmd= "delete", .len= 6, .cc= DELETE_CMD },
+    { .cmd= "incr", .len= 4, .cc= INCR_CMD },
+    { .cmd= "decr", .len= 4, .cc= DECR_CMD },
+    { .cmd= "stats", .len= 5, .cc= STATS_CMD },
+    { .cmd= "flush_all", .len= 9, .cc= FLUSH_ALL_CMD },
+    { .cmd= "version", .len= 7, .cc= VERSION_CMD },
+    { .cmd= "quit", .len= 4, .cc= QUIT_CMD },
+    { .cmd= "verbosity", .len= 9, .cc= VERBOSITY_CMD },
+    { .cmd= NULL, .len= 0, .cc= UNKNOWN_CMD }};
+
+  int x= 0;
+  while (commands[x].len > 0) {
+    if (length >= commands[x].len)
+    {
+      if (strncmp(start, commands[x].cmd, commands[x].len) == 0)
+      {
+        /* Potential hit */
+        if (length == commands[x].len || isspace(*(start + commands[x].len)))
+        {
+          return commands[x].cc;
+        }
+      }
+    }
+    ++x;
+  }
+
+  return UNKNOWN_CMD;
+}
+
+/**
+ * Perform a delete operation.
+ *
+ * @param client client requesting the deletion
+ * @param tokens the command as a vector
+ * @param ntokens the number of items in the vector
+ */
+static void process_delete(memcached_protocol_client_st *client,
+                           char **tokens, int ntokens)
+{
+  char *key= tokens[1];
+  uint16_t nkey;
+
+  if (ntokens != 2 || (nkey= parse_ascii_key(&key)) == 0)
+  {
+    send_command_usage(client);
+    return;
+  }
+
+  if (client->root->callback->interface.v1.delete == NULL)
+  {
+    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+    return;
+  }
+
+  protocol_binary_response_status rval;
+  rval= client->root->callback->interface.v1.delete(client, key, nkey, 0);
+
+  if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
+  {
+    spool_string(client, "DELETED\r\n");
+  }
+  else if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT)
+  {
+    spool_string(client, "NOT_FOUND\r\n");
+  }
+  else
+  {
+    char msg[80];
+    snprintf(msg, sizeof(msg), "SERVER_ERROR: delete failed %u\r\n",(uint32_t)rval);
+    spool_string(client, msg);
+  }
+}
+
+static void process_arithmetic(memcached_protocol_client_st *client,
+                               char **tokens, int ntokens)
+{
+  char *key= tokens[1];
+  uint16_t nkey;
+
+  if (ntokens != 3 || (nkey= parse_ascii_key(&key)) == 0)
+  {
+    send_command_usage(client);
+    return;
+  }
+
+  uint64_t cas;
+  uint64_t result;
+  uint64_t delta= strtoull(tokens[2], NULL, 10);
+
+  protocol_binary_response_status rval;
+  if (client->ascii_command == INCR_CMD)
+  {
+    if (client->root->callback->interface.v1.increment == NULL)
+    {
+      spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+      return;
+    }
+    rval= client->root->callback->interface.v1.increment(client,
+                                                         key, nkey,
+                                                         delta, 0,
+                                                         0,
+                                                         &result,
+                                                         &cas);
+  }
+  else
+  {
+    if (client->root->callback->interface.v1.decrement == NULL)
+    {
+      spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+      return;
+    }
+    rval= client->root->callback->interface.v1.decrement(client,
+                                                         key, nkey,
+                                                         delta, 0,
+                                                         0,
+                                                         &result,
+                                                         &cas);
+  }
+
+  if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
+  {
+    char buffer[80];
+    snprintf(buffer, sizeof(buffer), "%"PRIu64"\r\n", result);
+    spool_string(client, buffer);
+  }
+  else
+  {
+    spool_string(client, "NOT_FOUND\r\n");
+  }
+}
+
+/**
+ * Process the stats command (with or without a key specified)
+ * @param key pointer to the first character after "stats"
+ * @param end pointer to the "\n"
+ */
+static void process_stats(memcached_protocol_client_st *client,
+                          char *key, char *end)
+{
+  if (client->root->callback->interface.v1.stat == NULL)
+  {
+    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+    return;
+  }
+
+  while (isspace(*key))
+    key++;
+
+  uint16_t nkey= (uint16_t)(end - key);
+  (void)client->root->callback->interface.v1.stat(client, key, nkey,
+                                                  ascii_stat_response_handler);
+}
+
+static void process_version(memcached_protocol_client_st *client,
+                            char **tokens, int ntokens)
+{
+  (void)tokens;
+  if (ntokens != 1)
+  {
+    send_command_usage(client);
+    return;
+  }
+
+  if (client->root->callback->interface.v1.version == NULL)
+  {
+    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+    return;
+  }
+
+ client->root->callback->interface.v1.version(client,
+                                              ascii_version_response_handler);
+}
+
+static void process_flush(memcached_protocol_client_st *client,
+                          char **tokens, int ntokens)
+{
+  if (ntokens > 2)
+  {
+    send_command_usage(client);
+    return;
+  }
+
+  if (client->root->callback->interface.v1.flush == NULL)
+  {
+    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+    return;
+  }
+
+  uint32_t timeout= 0;
+  if (ntokens == 2)
+  {
+    timeout= (uint32_t)strtoul(tokens[1], NULL, 10);
+  }
+
+  protocol_binary_response_status rval;
+  rval= client->root->callback->interface.v1.flush(client, timeout);
+  if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
+    spool_string(client, "OK\r\n");
+  else
+    spool_string(client, "SERVER_ERROR: internal error\r\n");
+}
+
+/**
+ * Process one of the storage commands
+ * @param client the client performing the operation
+ * @param tokens the command tokens
+ * @param ntokens the number of tokens
+ * @param start pointer to the first character in the line
+ * @param end pointer to the pointer where the last character of this
+ *            command is (IN and OUT)
+ * @param length the number of bytes available
+ * @return -1 if an error occurs (and we should just terminate the connection
+ *            because we are out of sync)
+ *         0 storage command completed, continue processing
+ *         1 We need more data, so just go ahead and wait for more!
+ */
+static inline int process_storage_command(memcached_protocol_client_st *client,
+                                     char **tokens, int ntokens, char *start,
+                                     char **end, ssize_t length)
+{
+  (void)ntokens; /* already checked */
+  char *key= tokens[1];
+  uint16_t nkey= parse_ascii_key(&key);
+  if (nkey == 0)
+  {
+    /* return error */
+    spool_string(client, "CLIENT_ERROR: bad key\r\n");
+    return -1;
+  }
+
+  uint32_t flags= (uint32_t)strtoul(tokens[2], NULL, 10);
+  uint32_t timeout= (uint32_t)strtoul(tokens[3], NULL, 10);
+  unsigned long nbytes= strtoul(tokens[4], NULL, 10);
+
+  /* Do we have all data? */
+  unsigned long need= nbytes + (unsigned long)((*end - start) + 1) + 2; /* \n\r\n */
+  if ((ssize_t)need > length)
+  {
+    /* Keep on reading */
+    recover_tokenize_command(start, *end);
+    return 1;
+  }
+
+  void *data= (*end) + 1;
+  uint64_t cas= 0;
+  uint64_t result_cas;
+  protocol_binary_response_status rval;
+  switch (client->ascii_command)
+  {
+  case SET_CMD:
+    rval= client->root->callback->interface.v1.set(client, key,
+                                                   (uint16_t)nkey,
+                                                   data,
+                                                   (uint32_t)nbytes,
+                                                   flags,
+                                                   timeout, cas,
+                                                   &result_cas);
+    break;
+  case ADD_CMD:
+    rval= client->root->callback->interface.v1.add(client, key,
+                                                   (uint16_t)nkey,
+                                                   data,
+                                                   (uint32_t)nbytes,
+                                                   flags,
+                                                   timeout, &result_cas);
+    break;
+  case CAS_CMD:
+    cas= strtoull(tokens[5], NULL, 10);
+    /* FALLTHROUGH */
+  case REPLACE_CMD:
+    rval= client->root->callback->interface.v1.replace(client, key,
+                                                       (uint16_t)nkey,
+                                                       data,
+                                                       (uint32_t)nbytes,
+                                                       flags,
+                                                       timeout, cas,
+                                                       &result_cas);
+    break;
+  case APPEND_CMD:
+    rval= client->root->callback->interface.v1.append(client, key,
+                                                      (uint16_t)nkey,
+                                                      data,
+                                                      (uint32_t)nbytes,
+                                                      cas,
+                                                      &result_cas);
+    break;
+  case PREPEND_CMD:
+    rval= client->root->callback->interface.v1.prepend(client, key,
+                                                       (uint16_t)nkey,
+                                                       data,
+                                                       (uint32_t)nbytes,
+                                                       cas,
+                                                       &result_cas);
+    break;
+
+    /* gcc complains if I don't put all of the enums in here.. */
+  case GET_CMD:
+  case GETS_CMD:
+  case DELETE_CMD:
+  case DECR_CMD:
+  case INCR_CMD:
+  case STATS_CMD:
+  case FLUSH_ALL_CMD:
+  case VERSION_CMD:
+  case QUIT_CMD:
+  case VERBOSITY_CMD:
+  case UNKNOWN_CMD:
+  default:
+    abort(); /* impossible */
+  }
+
+  if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
+  {
+    spool_string(client, "STORED\r\n");
+  }
+  else
+  {
+    if (client->ascii_command == CAS_CMD)
+    {
+      if (rval == PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS)
+      {
+        spool_string(client, "EXISTS\r\n");
+      }
+      else if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT)
+      {
+        spool_string(client, "NOT_FOUND\r\n");
+      }
+      else
+      {
+        spool_string(client, "NOT_STORED\r\n");
+      }
+    }
+    else
+    {
+      spool_string(client, "NOT_STORED\r\n");
+    }
+  }
+
+  *end += nbytes + 2;
+
+  return 0;
+}
+
+static int process_cas_command(memcached_protocol_client_st *client,
+                                char **tokens, int ntokens, char *start,
+                                char **end, ssize_t length)
+{
+  if (ntokens != 6)
+  {
+    send_command_usage(client);
+    return false;
+  }
+
+  if (client->root->callback->interface.v1.replace == NULL)
+  {
+    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+    return false;
+  }
+
+  return process_storage_command(client, tokens, ntokens, start, end, length);
+}
+
+static int process_set_command(memcached_protocol_client_st *client,
+                                char **tokens, int ntokens, char *start,
+                                char **end, ssize_t length)
+{
+  if (ntokens != 5)
+  {
+    send_command_usage(client);
+    return false;
+  }
+
+  if (client->root->callback->interface.v1.set == NULL)
+  {
+    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+    return false;
+  }
+
+  return process_storage_command(client, tokens, ntokens, start, end, length);
+}
+
+static int process_add_command(memcached_protocol_client_st *client,
+                                char **tokens, int ntokens, char *start,
+                                char **end, ssize_t length)
+{
+  if (ntokens != 5)
+  {
+    send_command_usage(client);
+    return false;
+  }
+
+  if (client->root->callback->interface.v1.add == NULL)
+  {
+    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+    return false;
+  }
+
+  return process_storage_command(client, tokens, ntokens, start, end, length);
+}
+
+static int process_replace_command(memcached_protocol_client_st *client,
+                                    char **tokens, int ntokens, char *start,
+                                    char **end, ssize_t length)
+{
+  if (ntokens != 5)
+  {
+    send_command_usage(client);
+    return false;
+  }
+
+  if (client->root->callback->interface.v1.replace == NULL)
+  {
+    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+    return false;
+  }
+
+  return process_storage_command(client, tokens, ntokens, start, end, length);
+}
+
+static int process_append_command(memcached_protocol_client_st *client,
+                                   char **tokens, int ntokens, char *start,
+                                   char **end, ssize_t length)
+{
+  if (ntokens != 5)
+  {
+    send_command_usage(client);
+    return false;
+  }
+
+  if (client->root->callback->interface.v1.append == NULL)
+  {
+    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+    return false;
+  }
+
+  return process_storage_command(client, tokens, ntokens, start, end, length);
+}
+
+static int process_prepend_command(memcached_protocol_client_st *client,
+                                    char **tokens, int ntokens, char *start,
+                                    char **end, ssize_t length)
+{
+  if (ntokens != 5)
+  {
+    send_command_usage(client);
+    return false;
+  }
+
+  if (client->root->callback->interface.v1.prepend == NULL)
+  {
+    spool_string(client, "SERVER_ERROR: callback not implemented\r\n");
+    return false;
+  }
+
+  return process_storage_command(client, tokens, ntokens, start, end, length);
+}
+
+/**
+ * The ASCII protocol support is just one giant big hack. Instead of adding
+ * a optimal ascii support, I just convert the ASCII commands to the binary
+ * protocol and calls back into the command handlers for the binary protocol ;)
+ */
+memcached_protocol_event_t memcached_ascii_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr)
+{
+  char *ptr= (char*)client->root->input_buffer;
+  *endptr= ptr;
+
+  do {
+    /* Do we have \n (indicating the command preamble)*/
+    char *end= memchr(ptr, '\n', (size_t)*length);
+    if (end == NULL)
+    {
+      *endptr= ptr;
+      return MEMCACHED_PROTOCOL_READ_EVENT;
+    }
+
+    client->ascii_command= ascii_to_cmd(ptr, (size_t)(*length));
+
+    /* A multiget lists all of the keys, and I don't want to have an
+     * avector of let's say 512 pointers to tokenize all of them, so let's
+     * just handle them immediately
+     */
+    if (client->ascii_command == GET_CMD ||
+        client->ascii_command == GETS_CMD) {
+      if (client->root->callback->interface.v1.get != NULL)
+        ascii_process_gets(client, ptr, end);
+      else
+        spool_string(client, "SERVER_ERROR: Command not implemented\n");
+    } else {
+      /* None of the defined commands takes 10 parameters, so lets just use
+       * that as a maximum limit.
+       */
+      char *tokens[10];
+      int ntokens= ascii_tokenize_command(ptr, end, tokens, 10);
+
+      if (ntokens < 10)
+      {
+        client->mute= strcmp(tokens[ntokens - 1], "noreply") == 0;
+        if (client->mute)
+          --ntokens; /* processed noreply token*/
+      }
+
+      int error= 0;
+
+      switch (client->ascii_command) {
+      case SET_CMD:
+        error= process_set_command(client, tokens, ntokens, ptr, &end, *length);
+        break;
+      case ADD_CMD:
+        error= process_add_command(client, tokens, ntokens, ptr, &end, *length);
+        break;
+      case REPLACE_CMD:
+        error= process_replace_command(client, tokens, ntokens,
+                                       ptr, &end, *length);
+        break;
+      case CAS_CMD:
+        error= process_cas_command(client, tokens, ntokens, ptr, &end, *length);
+        break;
+      case APPEND_CMD:
+        error= process_append_command(client, tokens, ntokens,
+                                      ptr, &end, *length);
+        break;
+      case PREPEND_CMD:
+        error= process_prepend_command(client, tokens, ntokens,
+                                       ptr, &end, *length);
+       break;
+      case DELETE_CMD:
+        process_delete(client, tokens, ntokens);
+        break;
+
+      case INCR_CMD: /* FALLTHROUGH */
+      case DECR_CMD:
+        process_arithmetic(client, tokens, ntokens);
+        break;
+      case STATS_CMD:
+        if (client->mute)
+        {
+          send_command_usage(client);
+        }
+        else
+        {
+          recover_tokenize_command(ptr, end);
+          process_stats(client, ptr + 6, end);
+        }
+        break;
+      case FLUSH_ALL_CMD:
+        process_flush(client, tokens, ntokens);
+        break;
+      case VERSION_CMD:
+        if (client->mute)
+        {
+          send_command_usage(client);
+        }
+        else
+        {
+          process_version(client, tokens, ntokens);
+        }
+        break;
+      case QUIT_CMD:
+        if (ntokens != 1 || client->mute)
+        {
+          send_command_usage(client);
+        }
+        else
+        {
+          if (client->root->callback->interface.v1.quit != NULL)
+            client->root->callback->interface.v1.quit(client);
+
+          return MEMCACHED_PROTOCOL_ERROR_EVENT;
+        }
+        break;
+
+      case VERBOSITY_CMD:
+        if (ntokens != 2)
+          send_command_usage(client);
+        else
+          spool_string(client, "OK\r\n");
+        break;
+
+      case UNKNOWN_CMD:
+        send_command_usage(client);
+        break;
+
+      case GET_CMD:
+      case GETS_CMD:
+      default:
+        /* Should already be handled */
+        abort();
+      }
+
+      if (error == -1)
+        return MEMCACHED_PROTOCOL_ERROR_EVENT;
+      else if (error == 1)
+        return MEMCACHED_PROTOCOL_READ_EVENT;
+    }
+
+    /* Move past \n */
+    ++end;
+    *length -= end - ptr;
+    ptr= end;
+  } while (*length > 0);
+
+  *endptr= ptr;
+  return MEMCACHED_PROTOCOL_READ_EVENT;
+}
diff --git a/libmemcachedprotocol/ascii_handler.h b/libmemcachedprotocol/ascii_handler.h
new file mode 100644 (file)
index 0000000..02f8831
--- /dev/null
@@ -0,0 +1,40 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+LIBMEMCACHED_LOCAL
+memcached_protocol_event_t memcached_ascii_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr);
diff --git a/libmemcachedprotocol/binary_handler.c b/libmemcachedprotocol/binary_handler.c
new file mode 100644 (file)
index 0000000..c2fd441
--- /dev/null
@@ -0,0 +1,1120 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <libmemcachedprotocol/common.h>
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+
+/*
+** **********************************************************************
+** INTERNAL INTERFACE
+** **********************************************************************
+*/
+
+/**
+ * Send a preformatted packet back to the client. If the connection is in
+ * pedantic mode, it will validate the packet and refuse to send it if it
+ * breaks the specification.
+ *
+ * @param cookie client identification
+ * @param request the original request packet
+ * @param response the packet to send
+ * @return The status of the operation
+ */
+static protocol_binary_response_status
+raw_response_handler(const void *cookie,
+                     protocol_binary_request_header *request,
+                     protocol_binary_response_header *response)
+{
+  memcached_protocol_client_st *client= (void*)cookie;
+
+  if (client->root->pedantic &&
+      !memcached_binary_protocol_pedantic_check_response(request, response))
+  {
+    return PROTOCOL_BINARY_RESPONSE_EINVAL;
+  }
+
+  if (!client->root->drain(client))
+  {
+    return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
+  }
+
+  size_t len= sizeof(*response) + htonl(response->response.bodylen);
+  size_t offset= 0;
+  char *ptr= (void*)response;
+
+  if (client->output == NULL)
+  {
+    /* I can write directly to the socket.... */
+    do
+    {
+      size_t num_bytes= len - offset;
+      ssize_t nw= client->root->send(client,
+                                     client->sock,
+                                     ptr + offset,
+                                     num_bytes);
+      if (nw == -1)
+      {
+        if (get_socket_errno() == EWOULDBLOCK)
+        {
+          break;
+        }
+        else if (get_socket_errno() != EINTR)
+        {
+          client->error= errno;
+          return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
+        }
+      }
+      else
+      {
+        offset += (size_t)nw;
+      }
+    } while (offset < len);
+  }
+
+  return client->root->spool(client, ptr, len - offset);
+}
+
+/*
+ * Version 0 of the interface is really low level and protocol specific,
+ * while the version 1 of the interface is more API focused. We need a
+ * way to translate between the command codes on the wire and the
+ * application level interface in V1, so let's just use the V0 of the
+ * interface as a map instead of creating a huuuge switch :-)
+ */
+
+/**
+ * Callback for the GET/GETQ/GETK and GETKQ responses
+ * @param cookie client identifier
+ * @param key the key for the item
+ * @param keylen the length of the key
+ * @param body the length of the body
+ * @param bodylen the length of the body
+ * @param flags the flags for the item
+ * @param cas the CAS id for the item
+ */
+static protocol_binary_response_status
+get_response_handler(const void *cookie,
+                     const void *key,
+                     uint16_t keylen,
+                     const void *body,
+                     uint32_t bodylen,
+                     uint32_t flags,
+                     uint64_t cas) {
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  uint8_t opcode= client->current_command->request.opcode;
+
+  if (opcode == PROTOCOL_BINARY_CMD_GET || opcode == PROTOCOL_BINARY_CMD_GETQ)
+  {
+    keylen= 0;
+  }
+
+  protocol_binary_response_get response= {
+    .message.header.response= {
+      .magic= PROTOCOL_BINARY_RES,
+      .opcode= opcode,
+      .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+      .opaque= client->current_command->request.opaque,
+      .cas= memcached_htonll(cas),
+      .keylen= htons(keylen),
+      .extlen= 4,
+      .bodylen= htonl(bodylen + keylen + 4),
+    },
+  };
+
+  response.message.body.flags= htonl(flags);
+
+  protocol_binary_response_status rval;
+  const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS;
+  if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success ||
+      (rval= client->root->spool(client, key, keylen)) != success ||
+      (rval= client->root->spool(client, body, bodylen)) != success)
+  {
+    return rval;
+  }
+
+  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
+}
+
+/**
+ * Callback for the STAT responses
+ * @param cookie client identifier
+ * @param key the key for the item
+ * @param keylen the length of the key
+ * @param body the length of the body
+ * @param bodylen the length of the body
+ */
+static protocol_binary_response_status stat_response_handler(const void *cookie,
+                                                             const void *key,
+                                                             uint16_t keylen,
+                                                             const void *body,
+                                                             uint32_t bodylen)
+{
+
+  memcached_protocol_client_st *client= (void*)cookie;
+
+  protocol_binary_response_no_extras response= {
+    .message.header.response= {
+      .magic= PROTOCOL_BINARY_RES,
+      .opcode= client->current_command->request.opcode,
+      .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+      .opaque= client->current_command->request.opaque,
+      .keylen= htons(keylen),
+      .bodylen= htonl(bodylen + keylen),
+      .cas= 0
+    },
+  };
+
+  protocol_binary_response_status rval;
+  const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS;
+  if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success ||
+      (rval= client->root->spool(client, key, keylen)) != success ||
+      (rval= client->root->spool(client, body, bodylen)) != success)
+  {
+    return rval;
+  }
+
+  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
+}
+
+/**
+ * Callback for the VERSION responses
+ * @param cookie client identifier
+ * @param text the length of the body
+ * @param textlen the length of the body
+ */
+static protocol_binary_response_status
+version_response_handler(const void *cookie,
+                         const void *text,
+                         uint32_t textlen) {
+
+  memcached_protocol_client_st *client= (void*)cookie;
+
+  protocol_binary_response_no_extras response= {
+    .message.header.response= {
+      .magic= PROTOCOL_BINARY_RES,
+      .opcode= client->current_command->request.opcode,
+      .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+      .opaque= client->current_command->request.opaque,
+      .bodylen= htonl(textlen),
+      .cas= 0
+    },
+  };
+
+  protocol_binary_response_status rval;
+  const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS;
+  if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success ||
+      (rval= client->root->spool(client, text, textlen)) != success)
+  {
+    return rval;
+  }
+
+  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
+}
+
+/**
+ * Callback for ADD and ADDQ
+ * @param cookie the calling client
+ * @param header the add/addq command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+add_command_handler(const void *cookie,
+                    protocol_binary_request_header *header,
+                    memcached_binary_protocol_raw_response_handler response_handler)
+{
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.add != NULL)
+  {
+    uint16_t keylen= ntohs(header->request.keylen);
+    uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
+    protocol_binary_request_add *request= (void*)header;
+    uint32_t flags= ntohl(request->message.body.flags);
+    uint32_t timeout= ntohl(request->message.body.expiration);
+    char *key= ((char*)header) + sizeof(*header) + 8;
+    char *data= key + keylen;
+    uint64_t cas;
+
+    rval= client->root->callback->interface.v1.add(cookie, key, keylen,
+                                                   data, datalen, flags,
+                                                   timeout, &cas);
+
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
+        header->request.opcode == PROTOCOL_BINARY_CMD_ADD)
+    {
+      /* Send a positive request */
+      protocol_binary_response_no_extras response= {
+        .message= {
+          .header.response= {
+            .magic= PROTOCOL_BINARY_RES,
+            .opcode= PROTOCOL_BINARY_CMD_ADD,
+            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+            .opaque= header->request.opaque,
+            .cas= memcached_ntohll(cas)
+          }
+        }
+      };
+      rval= response_handler(cookie, header, (void*)&response);
+    }
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for DECREMENT and DECREMENTQ
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+decrement_command_handler(const void *cookie,
+                          protocol_binary_request_header *header,
+                          memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.decrement != NULL)
+  {
+    uint16_t keylen= ntohs(header->request.keylen);
+    protocol_binary_request_decr *request= (void*)header;
+    uint64_t init= memcached_ntohll(request->message.body.initial);
+    uint64_t delta= memcached_ntohll(request->message.body.delta);
+    uint32_t timeout= ntohl(request->message.body.expiration);
+    void *key= request->bytes + sizeof(request->bytes);
+    uint64_t result;
+    uint64_t cas;
+
+    rval= client->root->callback->interface.v1.decrement(cookie, key, keylen,
+                                                         delta, init, timeout,
+                                                         &result, &cas);
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
+        header->request.opcode == PROTOCOL_BINARY_CMD_DECREMENT)
+    {
+      /* Send a positive request */
+      protocol_binary_response_decr response= {
+        .message= {
+          .header.response= {
+            .magic= PROTOCOL_BINARY_RES,
+            .opcode= PROTOCOL_BINARY_CMD_DECREMENT,
+            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+            .opaque= header->request.opaque,
+            .cas= memcached_ntohll(cas),
+            .bodylen= htonl(8)
+          },
+          .body.value= memcached_htonll(result)
+        }
+      };
+      rval= response_handler(cookie, header, (void*)&response);
+    }
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for DELETE and DELETEQ
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+delete_command_handler(const void *cookie,
+                       protocol_binary_request_header *header,
+                       memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.delete != NULL)
+  {
+    uint16_t keylen= ntohs(header->request.keylen);
+    void *key= (header +1);
+    uint64_t cas= memcached_ntohll(header->request.cas);
+    rval= client->root->callback->interface.v1.delete(cookie, key, keylen, cas);
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
+        header->request.opcode == PROTOCOL_BINARY_CMD_DELETE)
+    {
+      /* Send a positive request */
+      protocol_binary_response_no_extras response= {
+        .message= {
+          .header.response= {
+            .magic= PROTOCOL_BINARY_RES,
+            .opcode= PROTOCOL_BINARY_CMD_DELETE,
+            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+            .opaque= header->request.opaque,
+          }
+        }
+      };
+      rval= response_handler(cookie, header, (void*)&response);
+    }
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for FLUSH and FLUSHQ
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+flush_command_handler(const void *cookie,
+                      protocol_binary_request_header *header,
+                      memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.flush != NULL)
+  {
+    protocol_binary_request_flush *flush= (void*)header;
+    uint32_t timeout= 0;
+    if (htonl(header->request.bodylen) == 4)
+    {
+      timeout= ntohl(flush->message.body.expiration);
+    }
+
+    rval= client->root->callback->interface.v1.flush(cookie, timeout);
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
+        header->request.opcode == PROTOCOL_BINARY_CMD_FLUSH)
+    {
+      /* Send a positive request */
+      protocol_binary_response_no_extras response= {
+        .message= {
+          .header.response= {
+            .magic= PROTOCOL_BINARY_RES,
+            .opcode= PROTOCOL_BINARY_CMD_FLUSH,
+            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+            .opaque= header->request.opaque,
+          }
+        }
+      };
+      rval= response_handler(cookie, header, (void*)&response);
+    }
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for GET, GETK, GETQ, GETKQ
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+get_command_handler(const void *cookie,
+                    protocol_binary_request_header *header,
+                    memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.get != NULL)
+  {
+    uint16_t keylen= ntohs(header->request.keylen);
+    void *key= (header + 1);
+    rval= client->root->callback->interface.v1.get(cookie, key, keylen,
+                                                   get_response_handler);
+
+    if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT &&
+        (header->request.opcode == PROTOCOL_BINARY_CMD_GETQ ||
+         header->request.opcode == PROTOCOL_BINARY_CMD_GETKQ))
+    {
+      /* Quiet commands shouldn't respond on cache misses */
+      rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
+    }
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for INCREMENT and INCREMENTQ
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+increment_command_handler(const void *cookie,
+                          protocol_binary_request_header *header,
+                          memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.increment != NULL)
+  {
+    uint16_t keylen= ntohs(header->request.keylen);
+    protocol_binary_request_incr *request= (void*)header;
+    uint64_t init= memcached_ntohll(request->message.body.initial);
+    uint64_t delta= memcached_ntohll(request->message.body.delta);
+    uint32_t timeout= ntohl(request->message.body.expiration);
+    void *key= request->bytes + sizeof(request->bytes);
+    uint64_t cas;
+    uint64_t result;
+
+    rval= client->root->callback->interface.v1.increment(cookie, key, keylen,
+                                                         delta, init, timeout,
+                                                         &result, &cas);
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
+        header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENT)
+    {
+      /* Send a positive request */
+      protocol_binary_response_incr response= {
+        .message= {
+          .header.response= {
+            .magic= PROTOCOL_BINARY_RES,
+            .opcode= PROTOCOL_BINARY_CMD_INCREMENT,
+            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+            .opaque= header->request.opaque,
+            .cas= memcached_ntohll(cas),
+            .bodylen= htonl(8)
+          },
+          .body.value= memcached_htonll(result)
+        }
+      };
+
+      rval= response_handler(cookie, header, (void*)&response);
+    }
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for noop. Inform the v1 interface about the noop packet, and
+ * create and send a packet back to the client
+ *
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler the response handler
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+noop_command_handler(const void *cookie,
+                     protocol_binary_request_header *header,
+                     memcached_binary_protocol_raw_response_handler response_handler)
+{
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.noop != NULL)
+  {
+    client->root->callback->interface.v1.noop(cookie);
+  }
+
+  protocol_binary_response_no_extras response= {
+    .message= {
+      .header.response= {
+        .magic= PROTOCOL_BINARY_RES,
+        .opcode= PROTOCOL_BINARY_CMD_NOOP,
+        .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+        .opaque= header->request.opaque,
+      }
+    }
+  };
+
+  return response_handler(cookie, header, (void*)&response);
+}
+
+/**
+ * Callback for APPEND and APPENDQ
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+append_command_handler(const void *cookie,
+                       protocol_binary_request_header *header,
+                       memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.append != NULL)
+  {
+    uint16_t keylen= ntohs(header->request.keylen);
+    uint32_t datalen= ntohl(header->request.bodylen) - keylen;
+    char *key= (void*)(header +1);
+    char *data= key +keylen;
+    uint64_t cas= memcached_ntohll(header->request.cas);
+    uint64_t result_cas;
+
+    rval= client->root->callback->interface.v1.append(cookie, key, keylen,
+                                                      data, datalen, cas,
+                                                      &result_cas);
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
+        header->request.opcode == PROTOCOL_BINARY_CMD_APPEND)
+    {
+      /* Send a positive request */
+      protocol_binary_response_no_extras response= {
+        .message= {
+          .header.response= {
+            .magic= PROTOCOL_BINARY_RES,
+            .opcode= PROTOCOL_BINARY_CMD_APPEND,
+            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+            .opaque= header->request.opaque,
+            .cas= memcached_ntohll(result_cas),
+          },
+        }
+      };
+      rval= response_handler(cookie, header, (void*)&response);
+    }
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for PREPEND and PREPENDQ
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+prepend_command_handler(const void *cookie,
+                        protocol_binary_request_header *header,
+                        memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.prepend != NULL)
+  {
+    uint16_t keylen= ntohs(header->request.keylen);
+    uint32_t datalen= ntohl(header->request.bodylen) - keylen;
+    char *key= (char*)(header + 1);
+    char *data= key + keylen;
+    uint64_t cas= memcached_ntohll(header->request.cas);
+    uint64_t result_cas;
+    rval= client->root->callback->interface.v1.prepend(cookie, key, keylen,
+                                                       data, datalen, cas,
+                                                       &result_cas);
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
+        header->request.opcode == PROTOCOL_BINARY_CMD_PREPEND)
+    {
+      /* Send a positive request */
+      protocol_binary_response_no_extras response= {
+        .message= {
+          .header.response= {
+            .magic= PROTOCOL_BINARY_RES,
+            .opcode= PROTOCOL_BINARY_CMD_PREPEND,
+            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+            .opaque= header->request.opaque,
+            .cas= memcached_ntohll(result_cas),
+          },
+        }
+      };
+      rval= response_handler(cookie, header, (void*)&response);
+    }
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for QUIT and QUITQ. Notify the client and shut down the connection
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+quit_command_handler(const void *cookie,
+                     protocol_binary_request_header *header,
+                     memcached_binary_protocol_raw_response_handler response_handler)
+{
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.quit != NULL)
+  {
+    client->root->callback->interface.v1.quit(cookie);
+  }
+
+  protocol_binary_response_no_extras response= {
+    .message= {
+      .header.response= {
+        .magic= PROTOCOL_BINARY_RES,
+        .opcode= PROTOCOL_BINARY_CMD_QUIT,
+        .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+        .opaque= header->request.opaque
+      }
+    }
+  };
+
+  if (header->request.opcode == PROTOCOL_BINARY_CMD_QUIT)
+  {
+    response_handler(cookie, header, (void*)&response);
+  }
+
+  /* I need a better way to signal to close the connection */
+  return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
+}
+
+/**
+ * Callback for REPLACE and REPLACEQ
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+replace_command_handler(const void *cookie,
+                        protocol_binary_request_header *header,
+                        memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.replace != NULL)
+  {
+    uint16_t keylen= ntohs(header->request.keylen);
+    uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
+    protocol_binary_request_replace *request= (void*)header;
+    uint32_t flags= ntohl(request->message.body.flags);
+    uint32_t timeout= ntohl(request->message.body.expiration);
+    char *key= ((char*)header) + sizeof(*header) + 8;
+    char *data= key + keylen;
+    uint64_t cas= memcached_ntohll(header->request.cas);
+    uint64_t result_cas;
+
+    rval= client->root->callback->interface.v1.replace(cookie, key, keylen,
+                                                       data, datalen, flags,
+                                                       timeout, cas,
+                                                       &result_cas);
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
+        header->request.opcode == PROTOCOL_BINARY_CMD_REPLACE)
+    {
+      /* Send a positive request */
+      protocol_binary_response_no_extras response= {
+        .message= {
+          .header.response= {
+            .magic= PROTOCOL_BINARY_RES,
+            .opcode= PROTOCOL_BINARY_CMD_REPLACE,
+            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+            .opaque= header->request.opaque,
+            .cas= memcached_ntohll(result_cas),
+          },
+        }
+      };
+      rval= response_handler(cookie, header, (void*)&response);
+    }
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for SET and SETQ
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+set_command_handler(const void *cookie,
+                    protocol_binary_request_header *header,
+                    memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.set != NULL)
+  {
+    uint16_t keylen= ntohs(header->request.keylen);
+    uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
+    protocol_binary_request_replace *request= (void*)header;
+    uint32_t flags= ntohl(request->message.body.flags);
+    uint32_t timeout= ntohl(request->message.body.expiration);
+    char *key= ((char*)header) + sizeof(*header) + 8;
+    char *data= key + keylen;
+    uint64_t cas= memcached_ntohll(header->request.cas);
+    uint64_t result_cas;
+
+
+    rval= client->root->callback->interface.v1.set(cookie, key, keylen,
+                                                   data, datalen, flags,
+                                                   timeout, cas, &result_cas);
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
+        header->request.opcode == PROTOCOL_BINARY_CMD_SET)
+    {
+      /* Send a positive request */
+      protocol_binary_response_no_extras response= {
+        .message= {
+          .header.response= {
+            .magic= PROTOCOL_BINARY_RES,
+            .opcode= PROTOCOL_BINARY_CMD_SET,
+            .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+            .opaque= header->request.opaque,
+            .cas= memcached_ntohll(result_cas),
+          },
+        }
+      };
+      rval= response_handler(cookie, header, (void*)&response);
+    }
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for STAT
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+stat_command_handler(const void *cookie,
+                     protocol_binary_request_header *header,
+                     memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.stat != NULL)
+  {
+    uint16_t keylen= ntohs(header->request.keylen);
+
+    rval= client->root->callback->interface.v1.stat(cookie,
+                                                    (void*)(header + 1),
+                                                    keylen,
+                                                    stat_response_handler);
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * Callback for VERSION
+ * @param cookie the calling client
+ * @param header the command
+ * @param response_handler not used
+ * @return the result of the operation
+ */
+static protocol_binary_response_status
+version_command_handler(const void *cookie,
+                        protocol_binary_request_header *header,
+                        memcached_binary_protocol_raw_response_handler response_handler)
+{
+  (void)response_handler;
+  (void)header;
+  protocol_binary_response_status rval;
+
+  memcached_protocol_client_st *client= (void*)cookie;
+  if (client->root->callback->interface.v1.version != NULL)
+  {
+    rval= client->root->callback->interface.v1.version(cookie,
+                                                       version_response_handler);
+  }
+  else
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  }
+
+  return rval;
+}
+
+/**
+ * The map to remap between the com codes and the v1 logical setting
+ */
+static memcached_binary_protocol_command_handler comcode_v0_v1_remap[256]= {
+  [PROTOCOL_BINARY_CMD_ADDQ]= add_command_handler,
+  [PROTOCOL_BINARY_CMD_ADD]= add_command_handler,
+  [PROTOCOL_BINARY_CMD_APPENDQ]= append_command_handler,
+  [PROTOCOL_BINARY_CMD_APPEND]= append_command_handler,
+  [PROTOCOL_BINARY_CMD_DECREMENTQ]= decrement_command_handler,
+  [PROTOCOL_BINARY_CMD_DECREMENT]= decrement_command_handler,
+  [PROTOCOL_BINARY_CMD_DELETEQ]= delete_command_handler,
+  [PROTOCOL_BINARY_CMD_DELETE]= delete_command_handler,
+  [PROTOCOL_BINARY_CMD_FLUSHQ]= flush_command_handler,
+  [PROTOCOL_BINARY_CMD_FLUSH]= flush_command_handler,
+  [PROTOCOL_BINARY_CMD_GETKQ]= get_command_handler,
+  [PROTOCOL_BINARY_CMD_GETK]= get_command_handler,
+  [PROTOCOL_BINARY_CMD_GETQ]= get_command_handler,
+  [PROTOCOL_BINARY_CMD_GET]= get_command_handler,
+  [PROTOCOL_BINARY_CMD_INCREMENTQ]= increment_command_handler,
+  [PROTOCOL_BINARY_CMD_INCREMENT]= increment_command_handler,
+  [PROTOCOL_BINARY_CMD_NOOP]= noop_command_handler,
+  [PROTOCOL_BINARY_CMD_PREPENDQ]= prepend_command_handler,
+  [PROTOCOL_BINARY_CMD_PREPEND]= prepend_command_handler,
+  [PROTOCOL_BINARY_CMD_QUITQ]= quit_command_handler,
+  [PROTOCOL_BINARY_CMD_QUIT]= quit_command_handler,
+  [PROTOCOL_BINARY_CMD_REPLACEQ]= replace_command_handler,
+  [PROTOCOL_BINARY_CMD_REPLACE]= replace_command_handler,
+  [PROTOCOL_BINARY_CMD_SETQ]= set_command_handler,
+  [PROTOCOL_BINARY_CMD_SET]= set_command_handler,
+  [PROTOCOL_BINARY_CMD_STAT]= stat_command_handler,
+  [PROTOCOL_BINARY_CMD_VERSION]= version_command_handler,
+};
+
+/**
+ * Try to execute a command. Fire the pre/post functions and the specialized
+ * handler function if it's set. If not, the unknown probe should be fired
+ * if it's present.
+ * @param client the client connection to operate on
+ * @param header the command to execute
+ * @return true if success or false if a fatal error occured so that the
+ *         connection should be shut down.
+ */
+static protocol_binary_response_status execute_command(memcached_protocol_client_st *client, protocol_binary_request_header *header)
+{
+  if (client->root->pedantic &&
+      memcached_binary_protocol_pedantic_check_request(header))
+  {
+      /* @todo return invalid command packet */
+  }
+
+  /* we got all data available, execute the callback! */
+  if (client->root->callback->pre_execute != NULL)
+  {
+    client->root->callback->pre_execute(client, header);
+  }
+
+  protocol_binary_response_status rval;
+  rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
+  uint8_t cc= header->request.opcode;
+
+  switch (client->root->callback->interface_version)
+  {
+  case 0:
+    if (client->root->callback->interface.v0.comcode[cc] != NULL) {
+      rval= client->root->callback->interface.v0.comcode[cc](client, header, raw_response_handler);
+    }
+    break;
+  case 1:
+    if (comcode_v0_v1_remap[cc] != NULL) {
+      rval= comcode_v0_v1_remap[cc](client, header, raw_response_handler);
+    }
+    break;
+  default:
+    /* Unknown interface.
+     * It should be impossible to get here so I'll just call abort
+     * to avoid getting a compiler warning :-)
+     */
+    abort();
+  }
+
+
+  if (rval == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND &&
+      client->root->callback->unknown != NULL)
+  {
+    rval= client->root->callback->unknown(client, header, raw_response_handler);
+  }
+
+  if (rval != PROTOCOL_BINARY_RESPONSE_SUCCESS &&
+      rval != PROTOCOL_BINARY_RESPONSE_EINTERNAL &&
+      rval != PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED)
+  {
+    protocol_binary_response_no_extras response= {
+      .message= {
+        .header.response= {
+          .magic= PROTOCOL_BINARY_RES,
+          .opcode= cc,
+          .status= htons(rval),
+          .opaque= header->request.opaque,
+        },
+      }
+    };
+    rval= raw_response_handler(client, header, (void*)&response);
+  }
+
+  if (client->root->callback->post_execute != NULL)
+  {
+    client->root->callback->post_execute(client, header);
+  }
+
+  return rval;
+}
+
+/*
+** **********************************************************************
+** "PROTOECTED" INTERFACE
+** **********************************************************************
+*/
+memcached_protocol_event_t memcached_binary_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr)
+{
+  /* try to parse all of the received packets */
+  protocol_binary_request_header *header;
+  header= (void*)client->root->input_buffer;
+  if (header->request.magic != (uint8_t)PROTOCOL_BINARY_REQ)
+  {
+    client->error= EINVAL;
+    return MEMCACHED_PROTOCOL_ERROR_EVENT;
+  }
+  ssize_t len= *length;
+
+  while (len >= (ssize_t)sizeof(*header) &&
+         (len >= (ssize_t)(sizeof(*header) + ntohl(header->request.bodylen))))
+  {
+    /* I have the complete package */
+    client->current_command= header;
+    protocol_binary_response_status rv= execute_command(client, header);
+
+    if (rv == PROTOCOL_BINARY_RESPONSE_EINTERNAL)
+    {
+      *length= len;
+      *endptr= (void*)header;
+      return MEMCACHED_PROTOCOL_ERROR_EVENT;
+    } else if (rv == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED)
+      return MEMCACHED_PROTOCOL_PAUSE_EVENT;
+
+    ssize_t total= (ssize_t)(sizeof(*header) + ntohl(header->request.bodylen));
+    len -= total;
+    if (len > 0)
+    {
+      intptr_t ptr= (intptr_t)header;
+      ptr += total;
+      if ((ptr % 8) == 0)
+      {
+        header= (void*)ptr;
+      }
+      else
+      {
+        /* Fix alignment */
+        memmove(client->root->input_buffer, (void*)ptr, (size_t)len);
+        header= (void*)client->root->input_buffer;
+      }
+    }
+    *length= len;
+    *endptr= (void*)header;
+  }
+
+  return MEMCACHED_PROTOCOL_READ_EVENT;
+}
+
+/*
+** **********************************************************************
+** PUBLIC INTERFACE
+** **********************************************************************
+*/
+memcached_binary_protocol_callback_st *memcached_binary_protocol_get_callbacks(memcached_protocol_st *instance)
+{
+  return instance->callback;
+}
+
+void memcached_binary_protocol_set_callbacks(memcached_protocol_st *instance, memcached_binary_protocol_callback_st *callback)
+{
+  instance->callback= callback;
+}
+
+memcached_binary_protocol_raw_response_handler memcached_binary_protocol_get_raw_response_handler(const void *cookie)
+{
+  (void)cookie;
+  return raw_response_handler;
+}
+
+void memcached_binary_protocol_set_pedantic(memcached_protocol_st *instance, bool enable)
+{
+  instance->pedantic= enable;
+}
+
+bool memcached_binary_protocol_get_pedantic(memcached_protocol_st *instance)
+{
+  return instance->pedantic;
+}
+
diff --git a/libmemcachedprotocol/binary_handler.h b/libmemcachedprotocol/binary_handler.h
new file mode 100644 (file)
index 0000000..d5a74e7
--- /dev/null
@@ -0,0 +1,47 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+LIBMEMCACHED_LOCAL
+bool memcached_binary_protocol_pedantic_check_request(const protocol_binary_request_header *request);
+
+LIBMEMCACHED_LOCAL
+bool memcached_binary_protocol_pedantic_check_response(const protocol_binary_request_header *request,
+                                                       const protocol_binary_response_header *response);
+
+LIBMEMCACHED_LOCAL
+memcached_protocol_event_t memcached_binary_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr);
diff --git a/libmemcachedprotocol/cache.c b/libmemcachedprotocol/cache.c
new file mode 100644 (file)
index 0000000..ed669f4
--- /dev/null
@@ -0,0 +1,187 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#ifndef NDEBUG
+#include <signal.h>
+#endif
+
+#include <libmemcachedprotocol/common.h>
+
+#ifndef NDEBUG
+const uint64_t redzone_pattern = 0xdeadbeefcafebabe;
+int cache_error = 0;
+#endif
+
+const size_t initial_pool_size = 64;
+
+cache_t* cache_create(const char *name, size_t bufsize, size_t align,
+                      cache_constructor_t* constructor,
+                      cache_destructor_t* destructor) {
+    cache_t* ret = calloc(1, sizeof(cache_t));
+    size_t name_length= strlen(name);
+    char* nm= calloc(1, (sizeof(char) * name_length) +1);
+    memcpy(nm, name, name_length);
+    void** ptr = calloc(initial_pool_size, bufsize);
+    if (ret == NULL || nm == NULL || ptr == NULL ||
+        pthread_mutex_init(&ret->mutex, NULL) == -1) {
+        free(ret);
+        free(nm);
+        free(ptr);
+        return NULL;
+    }
+
+    ret->name = nm;
+    ret->ptr = ptr;
+    ret->freetotal = initial_pool_size;
+    ret->constructor = constructor;
+    ret->destructor = destructor;
+
+#ifndef NDEBUG
+    ret->bufsize = bufsize + 2 * sizeof(redzone_pattern);
+#else
+    ret->bufsize = bufsize;
+#endif
+
+    (void)align;
+
+    return ret;
+}
+
+static inline void* get_object(void *ptr) {
+#ifndef NDEBUG
+    uint64_t *pre = ptr;
+    return pre + 1;
+#else
+    return ptr;
+#endif
+}
+
+void cache_destroy(cache_t *cache) {
+    while (cache->freecurr > 0) {
+        void *ptr = cache->ptr[--cache->freecurr];
+        if (cache->destructor) {
+            cache->destructor(get_object(ptr), NULL);
+        }
+        free(ptr);
+    }
+    free(cache->name);
+    free(cache->ptr);
+    pthread_mutex_destroy(&cache->mutex);
+}
+
+void* cache_alloc(cache_t *cache) {
+    void *ret;
+    void *object;
+    pthread_mutex_lock(&cache->mutex);
+    if (cache->freecurr > 0) {
+        ret = cache->ptr[--cache->freecurr];
+        object = get_object(ret);
+    } else {
+        object = ret = malloc(cache->bufsize);
+        if (ret != NULL) {
+            object = get_object(ret);
+
+            if (cache->constructor != NULL &&
+                cache->constructor(object, NULL, 0) != 0) {
+                free(ret);
+                object = NULL;
+            }
+        }
+    }
+    pthread_mutex_unlock(&cache->mutex);
+
+#ifndef NDEBUG
+    if (object != NULL) {
+        /* add a simple form of buffer-check */
+        uint64_t *pre = ret;
+        *pre = redzone_pattern;
+        ret = pre+1;
+        memcpy(((char*)ret) + cache->bufsize - (2 * sizeof(redzone_pattern)),
+               &redzone_pattern, sizeof(redzone_pattern));
+    }
+#endif
+
+    return object;
+}
+
+void cache_free(cache_t *cache, void *ptr) {
+    pthread_mutex_lock(&cache->mutex);
+
+#ifndef NDEBUG
+    /* validate redzone... */
+    if (memcmp(((char*)ptr) + cache->bufsize - (2 * sizeof(redzone_pattern)),
+               &redzone_pattern, sizeof(redzone_pattern)) != 0) {
+        raise(SIGABRT);
+        cache_error = 1;
+        pthread_mutex_unlock(&cache->mutex);
+        return;
+    }
+    uint64_t *pre = ptr;
+    --pre;
+    if (*pre != redzone_pattern) {
+        raise(SIGABRT);
+        cache_error = -1;
+        pthread_mutex_unlock(&cache->mutex);
+        return;
+    }
+    ptr = pre;
+#endif
+    if (cache->freecurr < cache->freetotal) {
+        cache->ptr[cache->freecurr++] = ptr;
+    } else {
+        /* try to enlarge free connections array */
+        size_t newtotal = cache->freetotal * 2;
+        void **new_free = realloc(cache->ptr, sizeof(char *) * newtotal);
+        if (new_free) {
+            cache->freetotal = newtotal;
+            cache->ptr = new_free;
+            cache->ptr[cache->freecurr++] = ptr;
+        } else {
+            if (cache->destructor) {
+                cache->destructor(ptr, NULL);
+            }
+            free(ptr);
+
+        }
+    }
+    pthread_mutex_unlock(&cache->mutex);
+}
+
diff --git a/libmemcachedprotocol/cache.h b/libmemcachedprotocol/cache.h
new file mode 100644 (file)
index 0000000..6f84fea
--- /dev/null
@@ -0,0 +1,148 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+#pragma once
+
+#include <pthread.h>
+
+#ifdef HAVE_UMEM_H
+# include <umem.h>
+# define cache_t umem_cache_t
+# define cache_alloc(a) umem_cache_alloc(a, UMEM_DEFAULT)
+# define cache_free(a, b) umem_cache_free(a, b)
+# define cache_create(a,b,c,d,e) umem_cache_create((char*)a, b, c, d, e, NULL, NULL, NULL, 0)
+# define cache_destroy(a) umem_cache_destroy(a);
+#else
+# ifndef NDEBUG
+/* may be used for debug purposes */
+extern int cache_error;
+# endif
+
+/**
+ * Constructor used to initialize allocated objects
+ *
+ * @param obj pointer to the object to initialized.
+ * @param notused1 This parameter is currently not used.
+ * @param notused2 This parameter is currently not used.
+ * @return you should return 0, but currently this is not checked
+ */
+typedef int cache_constructor_t(void* obj, void* notused1, int notused2);
+/**
+ * Destructor used to clean up allocated objects before they are
+ * returned to the operating system.
+ *
+ * @param obj pointer to the object to initialized.
+ * @param notused1 This parameter is currently not used.
+ * @param notused2 This parameter is currently not used.
+ * @return you should return 0, but currently this is not checked
+ */
+typedef void cache_destructor_t(void* obj, void* notused);
+
+/**
+ * Definition of the structure to keep track of the internal details of
+ * the cache allocator. Touching any of these variables results in
+ * undefined behavior.
+ */
+typedef struct {
+    /** Mutex to protect access to the structure */
+    pthread_mutex_t mutex;
+    /** Name of the cache objects in this cache (provided by the caller) */
+    char *name;
+    /** List of pointers to available buffers in this cache */
+    void **ptr;
+    /** The size of each element in this cache */
+    size_t bufsize;
+    /** The capacity of the list of elements */
+    size_t freetotal;
+    /** The current number of free elements */
+    size_t freecurr;
+    /** The constructor to be called each time we allocate more memory */
+    cache_constructor_t* constructor;
+    /** The destructor to be called each time before we release memory */
+    cache_destructor_t* destructor;
+} cache_t;
+
+/**
+ * Create an object cache.
+ *
+ * The object cache will let you allocate objects of the same size. It is fully
+ * MT safe, so you may allocate objects from multiple threads without having to
+ * do any syncrhonization in the application code.
+ *
+ * @param name the name of the object cache. This name may be used for debug purposes
+ *             and may help you track down what kind of object you have problems with
+ *             (buffer overruns, leakage etc)
+ * @param bufsize the size of each object in the cache
+ * @param align the alignment requirements of the objects in the cache.
+ * @param constructor the function to be called to initialize memory when we need
+ *                    to allocate more memory from the os.
+ * @param destructor the function to be called before we release the memory back
+ *                   to the os.
+ * @return a handle to an object cache if successful, NULL otherwise.
+ */
+cache_t* cache_create(const char* name, size_t bufsize, size_t align,
+                      cache_constructor_t* constructor,
+                      cache_destructor_t* destructor);
+/**
+ * Destroy an object cache.
+ *
+ * Destroy and invalidate an object cache. You should return all buffers allocated
+ * with cache_alloc by using cache_free before calling this function. Not doing
+ * so results in undefined behavior (the buffers may or may not be invalidated)
+ *
+ * @param handle the handle to the object cache to destroy.
+ */
+void cache_destroy(cache_t* handle);
+/**
+ * Allocate an object from the cache.
+ *
+ * @param handle the handle to the object cache to allocate from
+ * @return a pointer to an initialized object from the cache, or NULL if
+ *         the allocation cannot be satisfied.
+ */
+void* cache_alloc(cache_t* handle);
+/**
+ * Return an object back to the cache.
+ *
+ * The caller should return the object in an initialized state so that
+ * the object may be returned in an expected state from cache_alloc.
+ *
+ * @param handle handle to the object cache to return the object to
+ * @param ptr pointer to the object to return.
+ */
+void cache_free(cache_t* handle, void* ptr);
+#endif //  HAVE_UMEM_H
diff --git a/libmemcachedprotocol/common.h b/libmemcachedprotocol/common.h
new file mode 100644 (file)
index 0000000..398e7ee
--- /dev/null
@@ -0,0 +1,163 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#include "config.h"
+#if !defined(__cplusplus)
+# include <stdbool.h>
+#endif
+#include <assert.h>
+
+#include <libmemcachedprotocol-0.0/handler.h>
+#include <libmemcachedprotocol/cache.h>
+#include <libmemcached/byteorder.h>
+
+/*
+ * I don't really need the following two functions as function pointers
+ * in the instance handle, but I don't want to put them in the global
+ * namespace for those linking statically (personally I don't like that,
+ * but some people still do). If it ever shows up as a performance thing
+ * I'll look into optimizing this ;-)
+ */
+typedef bool (*drain_func)(memcached_protocol_client_st *client);
+typedef protocol_binary_response_status (*spool_func)(memcached_protocol_client_st *client,
+                                                      const void *data,
+                                                      size_t length);
+
+/**
+ * Definition of the per instance structure.
+ */
+struct memcached_protocol_st {
+  memcached_binary_protocol_callback_st *callback;
+  memcached_protocol_recv_func recv;
+  memcached_protocol_send_func send;
+
+  /*
+   * I really don't need these as funciton pointers, but I don't want
+   * to clutter the namespace if someone links statically.
+   */
+  drain_func drain;
+  spool_func spool;
+
+  /*
+   * To avoid keeping a buffer in each client all the time I have a
+   * bigger buffer in the instance that I read to initially, and then
+   * I try to parse and execute as much from the buffer. If I wasn't able
+   * to process all data I'll keep that in a per-connection buffer until
+   * the next time I can read from the socket.
+   */
+  uint8_t *input_buffer;
+  size_t input_buffer_size;
+
+  bool pedantic;
+  /* @todo use multiple sized buffers */
+  cache_t *buffer_cache;
+};
+
+struct chunk_st {
+  /* Pointer to the data */
+  char *data;
+  /* The offset to the first byte into the buffer that is used */
+  size_t offset;
+  /* The offset into the buffer for the first free byte */
+  size_t nbytes;
+  /* The number of bytes in the buffer */
+  size_t size;
+  /* Pointer to the next buffer in the chain */
+  struct chunk_st *next;
+};
+
+#define CHUNK_BUFFERSIZE 2048
+
+typedef memcached_protocol_event_t (*process_data)(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr);
+
+enum ascii_cmd {
+  GET_CMD,
+  GETS_CMD,
+  SET_CMD,
+  ADD_CMD,
+  REPLACE_CMD,
+  CAS_CMD,
+  APPEND_CMD,
+  PREPEND_CMD,
+  DELETE_CMD,
+  INCR_CMD,
+  DECR_CMD,
+  STATS_CMD,
+  FLUSH_ALL_CMD,
+  VERSION_CMD,
+  QUIT_CMD,
+  VERBOSITY_CMD,
+  UNKNOWN_CMD
+};
+
+struct memcached_protocol_client_st {
+  memcached_protocol_st *root;
+  memcached_socket_t sock;
+  int error;
+
+  /* Linked list of data to send */
+  struct chunk_st *output;
+  struct chunk_st *output_tail;
+
+  /*
+   * While we process input data, this is where we spool incomplete commands
+   * if we need to receive more data....
+   * @todo use the buffercace
+   */
+  uint8_t *input_buffer;
+  size_t input_buffer_size;
+  size_t input_buffer_offset;
+
+  /* The callback to the protocol handler to use (ascii or binary) */
+  process_data work;
+
+  /*
+   * Should the spool data discard the data to send or not? (aka noreply in
+   * the ascii protocol..
+   */
+  bool mute;
+
+  /* Members used by the binary protocol */
+  protocol_binary_request_header *current_command;
+
+  /* Members used by the ascii protocol */
+  enum ascii_cmd ascii_command;
+};
+
+#include "ascii_handler.h"
+#include "binary_handler.h"
diff --git a/libmemcachedprotocol/handler.c b/libmemcachedprotocol/handler.c
new file mode 100644 (file)
index 0000000..9ce927a
--- /dev/null
@@ -0,0 +1,401 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+#include <libmemcachedprotocol/common.h>
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <stdio.h>
+
+/*
+** **********************************************************************
+** INTERNAL INTERFACE
+** **********************************************************************
+*/
+
+/**
+ * The default function to receive data from the client. This function
+ * just wraps the recv function to receive from a socket.
+ * See man -s3socket recv for more information.
+ *
+ * @param cookie cookie indentifying a client, not used
+ * @param sock socket to read from
+ * @param buf the destination buffer
+ * @param nbytes the number of bytes to read
+ * @return the number of bytes transferred of -1 upon error
+ */
+static ssize_t default_recv(const void *cookie,
+                            memcached_socket_t sock,
+                            void *buf,
+                            size_t nbytes)
+{
+  (void)cookie;
+  return recv(sock, buf, nbytes, 0);
+}
+
+/**
+ * The default function to send data to the server. This function
+ * just wraps the send function to send through a socket.
+ * See man -s3socket send for more information.
+ *
+ * @param cookie cookie indentifying a client, not used
+ * @param sock socket to send to
+ * @param buf the source buffer
+ * @param nbytes the number of bytes to send
+ * @return the number of bytes transferred of -1 upon error
+ */
+static ssize_t default_send(const void *cookie,
+                            memcached_socket_t fd,
+                            const void *buf,
+                            size_t nbytes)
+{
+  (void)cookie;
+  return send(fd, buf, nbytes, 0);
+}
+
+/**
+ * Try to drain the output buffers without blocking
+ *
+ * @param client the client to drain
+ * @return false if an error occured (connection should be shut down)
+ *         true otherwise (please note that there may be more data to
+ *              left in the buffer to send)
+ */
+static bool drain_output(struct memcached_protocol_client_st *client)
+{
+  ssize_t len;
+
+  /* Do we have pending data to send? */
+  while (client->output != NULL)
+  {
+    len= client->root->send(client,
+                            client->sock,
+                            client->output->data + client->output->offset,
+                            client->output->nbytes - client->output->offset);
+
+    if (len == -1)
+    {
+      if (get_socket_errno() == EWOULDBLOCK)
+      {
+        return true;
+      }
+      else if (get_socket_errno() != EINTR)
+      {
+        client->error= get_socket_errno();
+        return false;
+      }
+    }
+    else
+    {
+      client->output->offset += (size_t)len;
+      if (client->output->offset == client->output->nbytes)
+      {
+        /* This was the complete buffer */
+        struct chunk_st *old= client->output;
+        client->output= client->output->next;
+        if (client->output == NULL)
+        {
+          client->output_tail= NULL;
+        }
+        cache_free(client->root->buffer_cache, old);
+      }
+    }
+  }
+
+  return true;
+}
+
+/**
+ * Allocate an output buffer and chain it into the output list
+ *
+ * @param client the client that needs the buffer
+ * @return pointer to the new chunk if the allocation succeeds, NULL otherwise
+ */
+static struct chunk_st *allocate_output_chunk(struct memcached_protocol_client_st *client)
+{
+  struct chunk_st *ret= cache_alloc(client->root->buffer_cache);
+
+  if (ret == NULL)
+  {
+    return NULL;
+  }
+
+  ret->offset= ret->nbytes= 0;
+  ret->next= NULL;
+  ret->size= CHUNK_BUFFERSIZE;
+  ret->data= (void*)(ret + 1);
+  if (client->output == NULL)
+  {
+    client->output= client->output_tail= ret;
+  }
+  else
+  {
+    client->output_tail->next= ret;
+    client->output_tail= ret;
+  }
+
+  return ret;
+}
+
+/**
+ * Spool data into the send-buffer for a client.
+ *
+ * @param client the client to spool the data for
+ * @param data the data to spool
+ * @param length the number of bytes of data to spool
+ * @return PROTOCOL_BINARY_RESPONSE_SUCCESS if success,
+ *         PROTOCOL_BINARY_RESPONSE_ENOMEM if we failed to allocate memory
+ */
+static protocol_binary_response_status spool_output(struct memcached_protocol_client_st *client,
+                                                    const void *data,
+                                                    size_t length)
+{
+  if (client->mute)
+  {
+    return PROTOCOL_BINARY_RESPONSE_SUCCESS;
+  }
+
+  size_t offset= 0;
+
+  struct chunk_st *chunk= client->output;
+  while (offset < length)
+  {
+    if (chunk == NULL || (chunk->size - chunk->nbytes) == 0)
+    {
+      if ((chunk= allocate_output_chunk(client)) == NULL)
+      {
+        return PROTOCOL_BINARY_RESPONSE_ENOMEM;
+      }
+    }
+
+    size_t bulk= length - offset;
+    if (bulk > chunk->size - chunk->nbytes)
+    {
+      bulk= chunk->size - chunk->nbytes;
+    }
+
+    memcpy(chunk->data + chunk->nbytes, data, bulk);
+    chunk->nbytes += bulk;
+    offset += bulk;
+  }
+
+  return PROTOCOL_BINARY_RESPONSE_SUCCESS;
+}
+
+/**
+ * Try to determine the protocol used on this connection.
+ * If the first byte contains the magic byte PROTOCOL_BINARY_REQ we should
+ * be using the binary protocol on the connection. I implemented the support
+ * for the ASCII protocol by wrapping into the simple interface (aka v1),
+ * so the implementors needs to provide an implementation of that interface
+ *
+ */
+static memcached_protocol_event_t determine_protocol(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr)
+{
+  if (*client->root->input_buffer == (uint8_t)PROTOCOL_BINARY_REQ)
+  {
+    client->work= memcached_binary_protocol_process_data;
+  }
+  else if (client->root->callback->interface_version == 1)
+  {
+    /*
+     * The ASCII protocol can only be used if the implementors provide
+     * an implementation for the version 1 of the interface..
+     *
+     * @todo I should allow the implementors to provide an implementation
+     *       for version 0 and 1 at the same time and set the preferred
+     *       interface to use...
+     */
+    client->work= memcached_ascii_protocol_process_data;
+  }
+  else
+  {
+    /* Let's just output a warning the way it is supposed to look like
+     * in the ASCII protocol...
+     */
+    const char *err= "CLIENT_ERROR: Unsupported protocol\r\n";
+    client->root->spool(client, err, strlen(err));
+    client->root->drain(client);
+    return MEMCACHED_PROTOCOL_ERROR_EVENT; /* Unsupported protocol */
+  }
+
+  return client->work(client, length, endptr);
+}
+
+/*
+** **********************************************************************
+** * PUBLIC INTERFACE
+** * See protocol_handler.h for function description
+** **********************************************************************
+*/
+struct memcached_protocol_st *memcached_protocol_create_instance(void)
+{
+  struct memcached_protocol_st *ret= calloc(1, sizeof(*ret));
+  if (ret != NULL)
+  {
+    ret->recv= default_recv;
+    ret->send= default_send;
+    ret->drain= drain_output;
+    ret->spool= spool_output;
+    ret->input_buffer_size= 1 * 1024 * 1024;
+    ret->input_buffer= malloc(ret->input_buffer_size);
+    if (ret->input_buffer == NULL)
+    {
+      free(ret);
+      ret= NULL;
+      return NULL;
+    }
+
+    ret->buffer_cache= cache_create("protocol_handler",
+                                     CHUNK_BUFFERSIZE + sizeof(struct chunk_st),
+                                     0, NULL, NULL);
+    if (ret->buffer_cache == NULL)
+    {
+      free(ret->input_buffer);
+      free(ret);
+    }
+  }
+
+  return ret;
+}
+
+void memcached_protocol_destroy_instance(struct memcached_protocol_st *instance)
+{
+  cache_destroy(instance->buffer_cache);
+  free(instance->input_buffer);
+  free(instance);
+}
+
+struct memcached_protocol_client_st *memcached_protocol_create_client(struct memcached_protocol_st *instance, memcached_socket_t sock)
+{
+  struct memcached_protocol_client_st *ret= calloc(1, sizeof(*ret));
+  if (ret != NULL)
+  {
+    ret->root= instance;
+    ret->sock= sock;
+    ret->work= determine_protocol;
+  }
+
+  return ret;
+}
+
+void memcached_protocol_client_destroy(struct memcached_protocol_client_st *client)
+{
+  free(client);
+}
+
+memcached_protocol_event_t memcached_protocol_client_work(struct memcached_protocol_client_st *client)
+{
+  /* Try to send data and read from the socket */
+  bool more_data= true;
+  do
+  {
+    ssize_t len= client->root->recv(client,
+                                    client->sock,
+                                    client->root->input_buffer + client->input_buffer_offset,
+                                    client->root->input_buffer_size - client->input_buffer_offset);
+
+    if (len > 0)
+    {
+      /* Do we have the complete packet? */
+      if (client->input_buffer_offset > 0)
+      {
+        memcpy(client->root->input_buffer, client->input_buffer,
+               client->input_buffer_offset);
+        len += (ssize_t)client->input_buffer_offset;
+
+        /* @todo use buffer-cache! */
+        free(client->input_buffer);
+        client->input_buffer_offset= 0;
+      }
+
+      void *endptr;
+      memcached_protocol_event_t events= client->work(client, &len, &endptr);
+      if (events == MEMCACHED_PROTOCOL_ERROR_EVENT)
+      {
+        return MEMCACHED_PROTOCOL_ERROR_EVENT;
+      }
+
+      if (len > 0)
+      {
+        /* save the data for later on */
+        /* @todo use buffer-cache */
+        client->input_buffer= malloc((size_t)len);
+        if (client->input_buffer == NULL)
+        {
+          client->error= ENOMEM;
+          return MEMCACHED_PROTOCOL_ERROR_EVENT;
+        }
+        memcpy(client->input_buffer, endptr, (size_t)len);
+        client->input_buffer_offset= (size_t)len;
+        more_data= false;
+      }
+    }
+    else if (len == 0)
+    {
+      /* Connection closed */
+      drain_output(client);
+      return MEMCACHED_PROTOCOL_ERROR_EVENT;
+    }
+    else
+    {
+      if (get_socket_errno() != EWOULDBLOCK)
+      {
+        client->error= get_socket_errno();
+        /* mark this client as terminated! */
+        return MEMCACHED_PROTOCOL_ERROR_EVENT;
+      }
+      more_data= false;
+    }
+  } while (more_data);
+
+  if (!drain_output(client))
+  {
+    return MEMCACHED_PROTOCOL_ERROR_EVENT;
+  }
+
+  memcached_protocol_event_t ret= MEMCACHED_PROTOCOL_READ_EVENT;
+  if (client->output)
+    ret|= MEMCACHED_PROTOCOL_READ_EVENT;
+
+  return ret;
+}
diff --git a/libmemcachedprotocol/include.am b/libmemcachedprotocol/include.am
new file mode 100644 (file)
index 0000000..58aed62
--- /dev/null
@@ -0,0 +1,35 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+
+lib_LTLIBRARIES+= libmemcached/libmemcachedprotocol.la
+
+noinst_HEADERS+= \
+                libmemcachedprotocol/ascii_handler.h \
+                libmemcachedprotocol/binary_handler.h \
+                libmemcachedprotocol/cache.h \
+                libmemcachedprotocol/common.h
+
+libmemcached_libmemcachedprotocol_la_SOURCES=  \
+                                              libmemcached/byteorder.cc \
+                                              libmemcachedprotocol/ascii_handler.c \
+                                              libmemcachedprotocol/binary_handler.c \
+                                              libmemcachedprotocol/cache.c \
+                                              libmemcachedprotocol/handler.c \
+                                              libmemcachedprotocol/pedantic.c
+
+libmemcached_libmemcachedprotocol_la_CFLAGS= \
+                                            ${AM_CFLAGS} \
+                                            ${NO_CONVERSION} \
+                                            -DBUILDING_LIBMEMCACHED
+libmemcached_libmemcachedprotocol_la_CFLAGS+= ${PTHREAD_CFLAGS}
+
+libmemcached_libmemcachedprotocol_la_CXXFLAGS= \
+                                              ${AM_CXXFLAGS} \
+                                              -DBUILDING_LIBMEMCACHED
+libmemcached_libmemcachedprotocol_la_CXXFLAGS+= ${PTHREAD_CFLAGS}
+
+libmemcached_libmemcachedprotocol_la_LIBADD= ${PTHREAD_LIBS}
+libmemcached_libmemcachedprotocol_la_LDFLAGS= ${AM_LDFLAGS}
+libmemcached_libmemcachedprotocol_la_LDFLAGS+= -version-info ${MEMCACHED_PROTOCAL_LIBRARY_VERSION}
diff --git a/libmemcachedprotocol/pedantic.c b/libmemcachedprotocol/pedantic.c
new file mode 100644 (file)
index 0000000..54a2add
--- /dev/null
@@ -0,0 +1,237 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+#include <libmemcachedprotocol/common.h>
+
+#include <sys/types.h>
+
+#define ensure(a) if (!(a)) { return false; }
+
+bool memcached_binary_protocol_pedantic_check_request(const protocol_binary_request_header *request)
+{
+  ensure(request->request.magic == PROTOCOL_BINARY_REQ);
+  ensure(request->request.datatype == PROTOCOL_BINARY_RAW_BYTES);
+
+  ensure(request->bytes[6] == 0);
+  ensure(request->bytes[7] == 0);
+
+  uint8_t opcode= request->request.opcode;
+  uint16_t keylen= ntohs(request->request.keylen);
+  uint8_t extlen= request->request.extlen;
+  uint32_t bodylen= ntohl(request->request.bodylen);
+
+  ensure(bodylen >= (keylen + extlen));
+
+  switch (opcode) {
+  case PROTOCOL_BINARY_CMD_GET:
+  case PROTOCOL_BINARY_CMD_GETK:
+  case PROTOCOL_BINARY_CMD_GETKQ:
+  case PROTOCOL_BINARY_CMD_GETQ:
+    ensure(extlen == 0);
+    ensure(keylen > 0);
+    ensure(keylen == bodylen);
+    ensure(request->request.cas == 0);
+    break;
+
+  case PROTOCOL_BINARY_CMD_ADD:
+  case PROTOCOL_BINARY_CMD_ADDQ:
+    /* it makes no sense to run add with a cas value */
+    ensure(request->request.cas == 0);
+    /* FALLTHROUGH */
+  case PROTOCOL_BINARY_CMD_SET:
+  case PROTOCOL_BINARY_CMD_SETQ:
+  case PROTOCOL_BINARY_CMD_REPLACE:
+  case PROTOCOL_BINARY_CMD_REPLACEQ:
+    ensure(keylen > 0);
+    ensure(extlen == 8);
+    break;
+
+  case PROTOCOL_BINARY_CMD_DELETE:
+  case PROTOCOL_BINARY_CMD_DELETEQ:
+    ensure(extlen == 0);
+    ensure(keylen > 0);
+    ensure(keylen == bodylen);
+    break;
+
+  case PROTOCOL_BINARY_CMD_INCREMENT:
+  case PROTOCOL_BINARY_CMD_INCREMENTQ:
+  case PROTOCOL_BINARY_CMD_DECREMENT:
+  case PROTOCOL_BINARY_CMD_DECREMENTQ:
+    ensure(extlen == 20);
+    ensure(keylen > 0);
+    ensure(keylen + extlen == bodylen);
+    break;
+
+  case PROTOCOL_BINARY_CMD_QUIT:
+  case PROTOCOL_BINARY_CMD_QUITQ:
+  case PROTOCOL_BINARY_CMD_NOOP:
+  case PROTOCOL_BINARY_CMD_VERSION:
+    ensure(extlen == 0);
+    ensure(keylen == 0);
+    ensure(bodylen == 0);
+    break;
+
+  case PROTOCOL_BINARY_CMD_FLUSH:
+  case PROTOCOL_BINARY_CMD_FLUSHQ:
+    ensure(extlen == 0 || extlen == 4);
+    ensure(keylen == 0);
+    ensure(bodylen == extlen);
+    break;
+
+  case PROTOCOL_BINARY_CMD_STAT:
+    ensure(extlen == 0);
+    /* May have key, but not value */
+    ensure(keylen == bodylen);
+    break;
+
+  case PROTOCOL_BINARY_CMD_APPEND:
+  case PROTOCOL_BINARY_CMD_APPENDQ:
+  case PROTOCOL_BINARY_CMD_PREPEND:
+  case PROTOCOL_BINARY_CMD_PREPENDQ:
+    ensure(extlen == 0);
+    ensure(keylen > 0);
+    break;
+  default:
+    /* Unknown command */
+    ;
+  }
+
+  return true;
+}
+
+bool memcached_binary_protocol_pedantic_check_response(const protocol_binary_request_header *request,
+                                                       const protocol_binary_response_header *response)
+{
+  ensure(response->response.magic == PROTOCOL_BINARY_RES);
+  ensure(response->response.datatype == PROTOCOL_BINARY_RAW_BYTES);
+  ensure(response->response.opaque == request->request.opaque);
+
+  uint16_t status= ntohs(response->response.status);
+  uint8_t opcode= response->response.opcode;
+
+  if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS)
+  {
+    switch (opcode) {
+    case PROTOCOL_BINARY_CMD_ADDQ:
+    case PROTOCOL_BINARY_CMD_APPENDQ:
+    case PROTOCOL_BINARY_CMD_DECREMENTQ:
+    case PROTOCOL_BINARY_CMD_DELETEQ:
+    case PROTOCOL_BINARY_CMD_FLUSHQ:
+    case PROTOCOL_BINARY_CMD_INCREMENTQ:
+    case PROTOCOL_BINARY_CMD_PREPENDQ:
+    case PROTOCOL_BINARY_CMD_QUITQ:
+    case PROTOCOL_BINARY_CMD_REPLACEQ:
+    case PROTOCOL_BINARY_CMD_SETQ:
+      /* Quiet command shouldn't return on success */
+      return false;
+    default:
+      break;
+    }
+
+    switch (opcode) {
+    case PROTOCOL_BINARY_CMD_ADD:
+    case PROTOCOL_BINARY_CMD_REPLACE:
+    case PROTOCOL_BINARY_CMD_SET:
+    case PROTOCOL_BINARY_CMD_APPEND:
+    case PROTOCOL_BINARY_CMD_PREPEND:
+      ensure(response->response.keylen == 0);
+      ensure(response->response.extlen == 0);
+      ensure(response->response.bodylen == 0);
+      ensure(response->response.cas != 0);
+      break;
+    case PROTOCOL_BINARY_CMD_FLUSH:
+    case PROTOCOL_BINARY_CMD_NOOP:
+    case PROTOCOL_BINARY_CMD_QUIT:
+    case PROTOCOL_BINARY_CMD_DELETE:
+      ensure(response->response.keylen == 0);
+      ensure(response->response.extlen == 0);
+      ensure(response->response.bodylen == 0);
+      ensure(response->response.cas == 0);
+      break;
+
+    case PROTOCOL_BINARY_CMD_DECREMENT:
+    case PROTOCOL_BINARY_CMD_INCREMENT:
+      ensure(response->response.keylen == 0);
+      ensure(response->response.extlen == 0);
+      ensure(ntohl(response->response.bodylen) == 8);
+      ensure(response->response.cas != 0);
+      break;
+
+    case PROTOCOL_BINARY_CMD_STAT:
+      ensure(response->response.extlen == 0);
+      /* key and value exists in all packets except in the terminating */
+      ensure(response->response.cas == 0);
+      break;
+
+    case PROTOCOL_BINARY_CMD_VERSION:
+      ensure(response->response.keylen == 0);
+      ensure(response->response.extlen == 0);
+      ensure(response->response.bodylen != 0);
+      ensure(response->response.cas == 0);
+      break;
+
+    case PROTOCOL_BINARY_CMD_GET:
+    case PROTOCOL_BINARY_CMD_GETQ:
+      ensure(response->response.keylen == 0);
+      ensure(response->response.extlen == 4);
+      ensure(response->response.cas != 0);
+      break;
+
+    case PROTOCOL_BINARY_CMD_GETK:
+    case PROTOCOL_BINARY_CMD_GETKQ:
+      ensure(response->response.keylen != 0);
+      ensure(response->response.extlen == 4);
+      ensure(response->response.cas != 0);
+      break;
+
+    default:
+      /* Undefined command code */
+      break;
+    }
+  }
+  else
+  {
+    ensure(response->response.cas == 0);
+    ensure(response->response.extlen == 0);
+    if (opcode != PROTOCOL_BINARY_CMD_GETK)
+    {
+      ensure(response->response.keylen == 0);
+    }
+  }
+
+  return true;
+}
diff --git a/libmemcachedutil-1.0/flush.h b/libmemcachedutil-1.0/flush.h
new file mode 100644 (file)
index 0000000..dd7e779
--- /dev/null
@@ -0,0 +1,50 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+bool libmemcached_util_flush(const char *hostname, in_port_t port, memcached_return_t *ret);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/libmemcachedutil-1.0/include.am b/libmemcachedutil-1.0/include.am
new file mode 100644 (file)
index 0000000..c557605
--- /dev/null
@@ -0,0 +1,12 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+
+nobase_include_HEADERS+= \
+                        libmemcachedutil-1.0/flush.h \
+                        libmemcachedutil-1.0/pid.h \
+                        libmemcachedutil-1.0/ping.h \
+                        libmemcachedutil-1.0/pool.h \
+                        libmemcachedutil-1.0/util.h \
+                        libmemcachedutil-1.0/version.h
diff --git a/libmemcachedutil-1.0/pid.h b/libmemcachedutil-1.0/pid.h
new file mode 100644 (file)
index 0000000..01738ac
--- /dev/null
@@ -0,0 +1,58 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifndef WIN32
+#include <netdb.h>
+#endif
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+pid_t libmemcached_util_getpid(const char *hostname, in_port_t port, memcached_return_t *ret);
+
+LIBMEMCACHED_API
+pid_t libmemcached_util_getpid2(const char *hostname, in_port_t port, const char *username, const char *password,  memcached_return_t *ret);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/libmemcachedutil-1.0/ping.h b/libmemcachedutil-1.0/ping.h
new file mode 100644 (file)
index 0000000..faea8b2
--- /dev/null
@@ -0,0 +1,52 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+bool libmemcached_util_ping(const char *hostname, in_port_t port, memcached_return_t *ret);
+
+LIBMEMCACHED_API
+bool libmemcached_util_ping2(const char *hostname, in_port_t port, const char *username, const char *password,  memcached_return_t *ret);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcachedutil-1.0/pool.h b/libmemcachedutil-1.0/pool.h
new file mode 100644 (file)
index 0000000..682aed5
--- /dev/null
@@ -0,0 +1,83 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+
+#include <libmemcached-1.0/memcached.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct memcached_pool_st;
+typedef struct memcached_pool_st memcached_pool_st;
+
+LIBMEMCACHED_API
+memcached_pool_st *memcached_pool_create(memcached_st* mmc, uint32_t initial, uint32_t max);
+
+LIBMEMCACHED_API
+memcached_pool_st *memcached_pool(const char *option_string, size_t option_string_length);
+
+LIBMEMCACHED_API
+memcached_st* memcached_pool_destroy(memcached_pool_st* pool);
+
+LIBMEMCACHED_API
+memcached_st* memcached_pool_pop(memcached_pool_st* pool,
+                                 bool block,
+                                 memcached_return_t* rc);
+LIBMEMCACHED_API
+memcached_return_t memcached_pool_push(memcached_pool_st* pool,
+                                       memcached_st* mmc);
+LIBMEMCACHED_API
+  memcached_return_t memcached_pool_release(memcached_pool_st* pool, memcached_st* mmc);
+
+LIBMEMCACHED_API
+memcached_st* memcached_pool_fetch(memcached_pool_st*, struct timespec* relative_time, memcached_return_t* rc);
+
+LIBMEMCACHED_API
+memcached_return_t memcached_pool_behavior_set(memcached_pool_st *ptr,
+                                               memcached_behavior_t flag,
+                                               uint64_t data);
+LIBMEMCACHED_API
+memcached_return_t memcached_pool_behavior_get(memcached_pool_st *ptr,
+                                               memcached_behavior_t flag,
+                                               uint64_t *value);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/libmemcachedutil-1.0/util.h b/libmemcachedutil-1.0/util.h
new file mode 100644 (file)
index 0000000..d362098
--- /dev/null
@@ -0,0 +1,46 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#include <libmemcached-1.0/memcached.h>
+
+#include <libmemcachedutil-1.0/pid.h>
+#include <libmemcachedutil-1.0/flush.h>
+#include <libmemcachedutil-1.0/ping.h>
+#include <libmemcachedutil-1.0/pool.h>
+#include <libmemcachedutil-1.0/version.h>
diff --git a/libmemcachedutil-1.0/version.h b/libmemcachedutil-1.0/version.h
new file mode 100644 (file)
index 0000000..372283a
--- /dev/null
@@ -0,0 +1,53 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_API
+  bool libmemcached_util_version_check(memcached_st *memc, 
+                                       uint8_t major_version,
+                                       uint8_t minor_version,
+                                       uint8_t micro_version);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libmemcachedutil/common.h b/libmemcachedutil/common.h
new file mode 100644 (file)
index 0000000..5c7b59f
--- /dev/null
@@ -0,0 +1,45 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached Utility library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Summary: connects to a host, and then flushes it (memcached_flush(3)).
+ *
+ */
+
+#pragma once
+
+#include <config.h>
+
+#include <libmemcachedutil-1.0/util.h>
+#include <libmemcached/assert.hpp>
+#include <libmemcached/backtrace.hpp>
diff --git a/libmemcachedutil/flush.cc b/libmemcachedutil/flush.cc
new file mode 100644 (file)
index 0000000..6a99603
--- /dev/null
@@ -0,0 +1,60 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Summary: connects to a host, and then flushes it (memcached_flush(3)).
+ *
+ */
+
+#include <libmemcachedutil/common.h>
+
+
+bool libmemcached_util_flush(const char *hostname, in_port_t port, memcached_return_t *ret)
+{
+  memcached_st *memc_ptr= memcached_create(NULL);
+
+  memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
+  if (memcached_success(rc))
+  {
+    rc= memcached_flush(memc_ptr, 0);
+  }
+
+  memcached_free(memc_ptr);
+
+  if (ret)
+  {
+    *ret= rc;
+  }
+
+  return memcached_success(rc);
+}
diff --git a/libmemcachedutil/include.am b/libmemcachedutil/include.am
new file mode 100644 (file)
index 0000000..8c9b7a5
--- /dev/null
@@ -0,0 +1,26 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+lib_LTLIBRARIES+= libmemcached/libmemcachedutil.la
+
+noinst_HEADERS+= \
+                libmemcachedutil/common.h
+
+libmemcached_libmemcachedutil_la_SOURCES= \
+                                         libmemcached/backtrace.cc \
+                                         libmemcachedutil/flush.cc \
+                                         libmemcachedutil/pid.cc \
+                                         libmemcachedutil/ping.cc \
+                                         libmemcachedutil/pool.cc \
+                                         libmemcachedutil/version.cc
+libmemcached_libmemcachedutil_la_CXXFLAGS= \
+                                          ${AM_CXXFLAGS} \
+                                          ${NO_CONVERSION} \
+                                          -DBUILDING_LIBMEMCACHED
+libmemcached_libmemcachedutil_la_CXXFLAGS+= ${PTHREAD_CFLAGS}
+libmemcached_libmemcachedutil_la_LIBADD= libmemcached/libmemcached.la
+libmemcached_libmemcachedutil_la_LIBADD+= ${PTHREAD_LIBS}
+libmemcached_libmemcachedutil_la_LDFLAGS= ${AM_LDFLAGS} -version-info ${MEMCACHED_UTIL_LIBRARY_VERSION}
+libmemcached_libmemcachedutil_la_DEPENDENCIES= libmemcached/libmemcached.la
+
diff --git a/libmemcachedutil/pid.cc b/libmemcachedutil/pid.cc
new file mode 100644 (file)
index 0000000..7ff665b
--- /dev/null
@@ -0,0 +1,160 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Summary: connects to a host, and determines what its pid is
+ *
+ */
+
+#include <libmemcachedutil/common.h>
+
+
+// Never look at the stat object directly.
+
+
+pid_t libmemcached_util_getpid(const char *hostname, in_port_t port, memcached_return_t *ret)
+{
+  pid_t pid= -1;
+
+  memcached_return_t unused;
+  if (not ret)
+    ret= &unused;
+
+  memcached_st *memc_ptr= memcached_create(NULL);
+  if (not memc_ptr)
+  {
+    *ret= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+    return -1;
+  }
+
+  memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
+  if (memcached_success(rc))
+  {
+    memcached_stat_st *stat= memcached_stat(memc_ptr, NULL, &rc);
+    if (memcached_success(rc) and stat and stat->pid != -1)
+    {
+      pid= stat->pid;
+    }
+    else if (memcached_success(rc))
+    {
+      rc= MEMCACHED_UNKNOWN_STAT_KEY; // Something went wrong if this happens
+    }
+    else if (rc == MEMCACHED_SOME_ERRORS) // Generic answer, we will now find the specific reason (if one exists)
+    {
+      memcached_server_instance_st instance=
+        memcached_server_instance_by_position(memc_ptr, 0);
+
+      assert_msg(instance and instance->error_messages, " ");
+      if (instance and instance->error_messages)
+      {
+        rc= memcached_server_error_return(instance);
+      }
+    }
+
+    memcached_stat_free(memc_ptr, stat);
+  }
+  memcached_free(memc_ptr);
+
+  *ret= rc;
+
+  return pid;
+}
+
+pid_t libmemcached_util_getpid2(const char *hostname, in_port_t port, const char *username, const char *password,  memcached_return_t *ret)
+{
+  if (username == NULL)
+  {
+    return libmemcached_util_getpid(hostname, port, ret);
+  }
+
+  pid_t pid= -1;
+
+  memcached_return_t unused;
+  if (not ret)
+    ret= &unused;
+
+  if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+  {
+    *ret= MEMCACHED_NOT_SUPPORTED;
+    return pid;
+  }
+
+  memcached_st *memc_ptr= memcached_create(NULL);
+  if (not memc_ptr)
+  {
+    *ret= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+    return -1;
+  }
+
+  if (memcached_failed(*ret= memcached_set_sasl_auth_data(memc_ptr, username, password)))
+  {
+    memcached_free(memc_ptr);
+    return false;
+  }
+
+
+  memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
+  if (memcached_success(rc))
+  {
+    memcached_stat_st *stat= memcached_stat(memc_ptr, NULL, &rc);
+    if (memcached_success(rc) and stat and stat->pid != -1)
+    {
+      pid= stat->pid;
+    }
+    else if (memcached_success(rc))
+    {
+      rc= MEMCACHED_UNKNOWN_STAT_KEY; // Something went wrong if this happens
+    }
+    else if (rc == MEMCACHED_SOME_ERRORS) // Generic answer, we will now find the specific reason (if one exists)
+    {
+      memcached_server_instance_st instance=
+        memcached_server_instance_by_position(memc_ptr, 0);
+
+#if 0
+      assert_msg(instance and instance->error_messages, " ");
+#endif
+      if (instance and instance->error_messages)
+      {
+        rc= memcached_server_error_return(instance);
+      }
+    }
+
+    memcached_stat_free(memc_ptr, stat);
+  }
+  memcached_free(memc_ptr);
+
+  *ret= rc;
+
+  return pid;
+}
diff --git a/libmemcachedutil/ping.cc b/libmemcachedutil/ping.cc
new file mode 100644 (file)
index 0000000..82d891a
--- /dev/null
@@ -0,0 +1,131 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Summary: connects to a host, and makes sure it is alive.
+ *
+ */
+
+#include <libmemcachedutil/common.h>
+
+bool libmemcached_util_ping(const char *hostname, in_port_t port, memcached_return_t *ret)
+{
+  memcached_return_t unused;
+  if (not ret)
+    ret= &unused;
+
+  memcached_st *memc_ptr= memcached_create(NULL);
+  if (not memc_ptr)
+  {
+    *ret= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+    return false;
+  }
+
+  memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
+  if (memcached_success(rc))
+  {
+    rc= memcached_version(memc_ptr);
+  }
+
+  if (memcached_failed(rc) and rc == MEMCACHED_SOME_ERRORS)
+  {
+    memcached_server_instance_st instance=
+      memcached_server_instance_by_position(memc_ptr, 0);
+
+    assert_msg(instance and instance->error_messages, " ");
+    if (instance and instance->error_messages)
+    {
+      rc= memcached_server_error_return(instance);
+    }
+  }
+  memcached_free(memc_ptr);
+
+  *ret= rc;
+
+  return memcached_success(rc);
+}
+
+bool libmemcached_util_ping2(const char *hostname, in_port_t port, const char *username, const char *password,  memcached_return_t *ret)
+{
+  if (username == NULL)
+  {
+    return libmemcached_util_ping(hostname, port, ret);
+  }
+
+  memcached_return_t unused;
+  if (not ret)
+    ret= &unused;
+
+  if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+  {
+    *ret= MEMCACHED_NOT_SUPPORTED;
+    return false;
+  }
+
+  memcached_st *memc_ptr= memcached_create(NULL);
+  if (not memc_ptr)
+  {
+    *ret= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+    return false;
+  }
+
+  if (memcached_failed(*ret= memcached_set_sasl_auth_data(memc_ptr, username, password)))
+  {
+    memcached_free(memc_ptr);
+    return false;
+  }
+
+  memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
+  if (memcached_success(rc))
+  {
+    rc= memcached_version(memc_ptr);
+  }
+
+  if (memcached_failed(rc) and rc == MEMCACHED_SOME_ERRORS)
+  {
+    memcached_server_instance_st instance=
+      memcached_server_instance_by_position(memc_ptr, 0);
+
+    assert_msg(instance and instance->error_messages, " ");
+    if (instance and instance->error_messages)
+    {
+      rc= memcached_server_error_return(instance);
+    }
+  }
+  memcached_free(memc_ptr);
+
+  *ret= rc;
+
+  return memcached_success(rc);
+}
diff --git a/libmemcachedutil/pool.cc b/libmemcachedutil/pool.cc
new file mode 100644 (file)
index 0000000..a0f30c5
--- /dev/null
@@ -0,0 +1,482 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include <libmemcachedutil/common.h>
+
+#include <cassert>
+#include <cerrno>
+#include <pthread.h>
+#include <memory>
+
+struct memcached_pool_st
+{
+  pthread_mutex_t mutex;
+  pthread_cond_t cond;
+  memcached_st *master;
+  memcached_st **server_pool;
+  int firstfree;
+  const uint32_t size;
+  uint32_t current_size;
+  bool _owns_master;
+  struct timespec _timeout;
+
+  memcached_pool_st(memcached_st *master_arg, size_t max_arg) :
+    master(master_arg),
+    server_pool(NULL),
+    firstfree(-1),
+    size(max_arg),
+    current_size(0),
+    _owns_master(false)
+  {
+    pthread_mutex_init(&mutex, NULL);
+    pthread_cond_init(&cond, NULL);
+    _timeout.tv_sec= 5;
+    _timeout.tv_nsec= 0;
+  }
+
+  const struct timespec& timeout() const
+  {
+    return _timeout;
+  }
+
+  bool release(memcached_st*, memcached_return_t& rc);
+
+  memcached_st *fetch(memcached_return_t& rc);
+  memcached_st *fetch(const struct timespec&, memcached_return_t& rc);
+
+  bool init(uint32_t initial);
+
+  ~memcached_pool_st()
+  {
+    for (int x= 0; x <= firstfree; ++x)
+    {
+      memcached_free(server_pool[x]);
+      server_pool[x] = NULL;
+    }
+
+    pthread_mutex_destroy(&mutex);
+    pthread_cond_destroy(&cond);
+    delete [] server_pool;
+    if (_owns_master)
+    {
+      memcached_free(master);
+    }
+  }
+
+  void increment_version()
+  {
+    ++master->configure.version;
+  }
+
+  bool compare_version(const memcached_st *arg) const
+  {
+    return (arg->configure.version == version());
+  }
+
+  int32_t version() const
+  {
+    return master->configure.version;
+  }
+};
+
+
+/**
+ * Grow the connection pool by creating a connection structure and clone the
+ * original memcached handle.
+ */
+static bool grow_pool(memcached_pool_st* pool)
+{
+  assert(pool);
+
+  memcached_st *obj;
+  if (not (obj= memcached_clone(NULL, pool->master)))
+  {
+    return false;
+  }
+
+  pool->server_pool[++pool->firstfree]= obj;
+  pool->current_size++;
+  obj->configure.version= pool->version();
+
+  return true;
+}
+
+bool memcached_pool_st::init(uint32_t initial)
+{
+  server_pool= new (std::nothrow) memcached_st *[size];
+  if (not server_pool)
+    return false;
+
+  /*
+    Try to create the initial size of the pool. An allocation failure at
+    this time is not fatal..
+  */
+  for (unsigned int x= 0; x < initial; ++x)
+  {
+    if (grow_pool(this) == false)
+    {
+      break;
+    }
+  }
+
+  return true;
+}
+
+
+static inline memcached_pool_st *_pool_create(memcached_st* master, uint32_t initial, uint32_t max)
+{
+  if (initial == 0 or max == 0 or (initial > max))
+  {
+    return NULL;
+  }
+
+  memcached_pool_st *object= new (std::nothrow) memcached_pool_st(master, max);
+  if (object == NULL)
+  {
+    return NULL;
+  }
+
+  /*
+    Try to create the initial size of the pool. An allocation failure at
+    this time is not fatal..
+  */
+  if (not object->init(initial))
+  {
+    delete object;
+    return NULL;
+  }
+
+  return object;
+}
+
+memcached_pool_st *memcached_pool_create(memcached_st* master, uint32_t initial, uint32_t max)
+{
+  return _pool_create(master, initial, max);
+}
+
+memcached_pool_st * memcached_pool(const char *option_string, size_t option_string_length)
+{
+  memcached_st *memc= memcached(option_string, option_string_length);
+
+  if (memc == NULL)
+  {
+    return NULL;
+  }
+
+  memcached_pool_st *self= memcached_pool_create(memc, memc->configure.initial_pool_size, memc->configure.max_pool_size);
+  if (self == NULL)
+  {
+    memcached_free(memc);
+    return NULL;
+  }
+
+  self->_owns_master= true;
+
+  return self;
+}
+
+memcached_st*  memcached_pool_destroy(memcached_pool_st* pool)
+{
+  if (pool == NULL)
+  {
+    return NULL;
+  }
+
+  // Legacy that we return the original structure
+  memcached_st *ret= NULL;
+  if (pool->_owns_master)
+  { }
+  else
+  {
+    ret= pool->master;
+  }
+
+  delete pool;
+
+  return ret;
+}
+
+memcached_st* memcached_pool_st::fetch(memcached_return_t& rc)
+{
+  static struct timespec relative_time= { 0, 0 };
+  return fetch(relative_time, rc);
+}
+
+memcached_st* memcached_pool_st::fetch(const struct timespec& relative_time, memcached_return_t& rc)
+{
+  rc= MEMCACHED_SUCCESS;
+
+  if (pthread_mutex_lock(&mutex))
+  {
+    rc= MEMCACHED_IN_PROGRESS;
+    return NULL;
+  }
+
+  memcached_st *ret= NULL;
+  do
+  {
+    if (firstfree > -1)
+    {
+      ret= server_pool[firstfree--];
+    }
+    else if (current_size == size)
+    {
+      if (relative_time.tv_sec == 0 and relative_time.tv_nsec == 0)
+      {
+        pthread_mutex_unlock(&mutex);
+        rc= MEMCACHED_NOTFOUND;
+
+        return NULL;
+      }
+
+      struct timespec time_to_wait= {0, 0};
+      time_to_wait.tv_sec= time(NULL) +relative_time.tv_sec;
+      time_to_wait.tv_nsec= relative_time.tv_nsec;
+
+      int thread_ret;
+      if ((thread_ret= pthread_cond_timedwait(&cond, &mutex, &time_to_wait)) != 0)
+      {
+        pthread_mutex_unlock(&mutex);
+
+        if (thread_ret == ETIMEDOUT)
+        {
+          rc= MEMCACHED_TIMEOUT;
+        }
+        else
+        {
+          errno= thread_ret;
+          rc= MEMCACHED_ERRNO;
+        }
+
+        return NULL;
+      }
+    }
+    else if (grow_pool(this) == false)
+    {
+      (void)pthread_mutex_unlock(&mutex);
+      return NULL;
+    }
+  } while (ret == NULL);
+
+  pthread_mutex_unlock(&mutex);
+
+  return ret;
+}
+
+bool memcached_pool_st::release(memcached_st *released, memcached_return_t& rc)
+{
+  rc= MEMCACHED_SUCCESS;
+  if (released == NULL)
+  {
+    rc= MEMCACHED_INVALID_ARGUMENTS;
+    return false;
+  }
+
+  if (pthread_mutex_lock(&mutex))
+  {
+    rc= MEMCACHED_IN_PROGRESS;
+    return false;
+  }
+
+  /* 
+    Someone updated the behavior on the object, so we clone a new memcached_st with the new settings. If we fail to clone, we keep the old one around.
+  */
+  if (compare_version(released) == false)
+  {
+    memcached_st *memc;
+    if ((memc= memcached_clone(NULL, master)))
+    {
+      memcached_free(released);
+      released= memc;
+    }
+  }
+
+  server_pool[++firstfree]= released;
+
+  if (firstfree == 0 and current_size == size)
+  {
+    /* we might have people waiting for a connection.. wake them up :-) */
+    pthread_cond_broadcast(&cond);
+  }
+
+  (void)pthread_mutex_unlock(&mutex);
+
+  return true;
+}
+
+memcached_st* memcached_pool_fetch(memcached_pool_st* pool, struct timespec* relative_time, memcached_return_t* rc)
+{
+  if (pool == NULL)
+  {
+    return NULL;
+  }
+
+  memcached_return_t unused;
+  if (rc == NULL)
+  {
+    rc= &unused;
+  }
+
+  if (relative_time == NULL)
+  {
+    return pool->fetch(*rc);
+  }
+
+  return pool->fetch(*relative_time, *rc);
+}
+
+memcached_st* memcached_pool_pop(memcached_pool_st* pool,
+                                 bool block,
+                                 memcached_return_t *rc)
+{
+  if (pool == NULL)
+  {
+    return NULL;
+  }
+
+  memcached_return_t unused;
+  if (rc == NULL)
+  {
+    rc= &unused;
+  }
+
+  memcached_st *memc;
+  if (block)
+  {
+    memc= pool->fetch(pool->timeout(), *rc);
+  }
+  else
+  {
+    memc= pool->fetch(*rc);
+  }
+
+  return memc;
+}
+
+memcached_return_t memcached_pool_release(memcached_pool_st* pool, memcached_st *released)
+{
+  if (pool == NULL)
+  {
+    return MEMCACHED_INVALID_ARGUMENTS;
+  }
+
+  memcached_return_t rc;
+
+  (void) pool->release(released, rc);
+
+  return rc;
+}
+
+memcached_return_t memcached_pool_push(memcached_pool_st* pool, memcached_st *released)
+{
+  return memcached_pool_release(pool, released);
+}
+
+
+memcached_return_t memcached_pool_behavior_set(memcached_pool_st *pool,
+                                               memcached_behavior_t flag,
+                                               uint64_t data)
+{
+  if (pool == NULL)
+  {
+    return MEMCACHED_INVALID_ARGUMENTS;
+  }
+
+  if (pthread_mutex_lock(&pool->mutex))
+  {
+    return MEMCACHED_IN_PROGRESS;
+  }
+
+  /* update the master */
+  memcached_return_t rc= memcached_behavior_set(pool->master, flag, data);
+  if (memcached_failed(rc))
+  {
+    (void)pthread_mutex_unlock(&pool->mutex);
+    return rc;
+  }
+
+  pool->increment_version();
+  /* update the clones */
+  for (int xx= 0; xx <= pool->firstfree; ++xx)
+  {
+    if (memcached_success(memcached_behavior_set(pool->server_pool[xx], flag, data)))
+    {
+      pool->server_pool[xx]->configure.version= pool->version();
+    }
+    else
+    {
+      memcached_st *memc;
+      if ((memc= memcached_clone(NULL, pool->master)))
+      {
+        memcached_free(pool->server_pool[xx]);
+        pool->server_pool[xx]= memc;
+        /* I'm not sure what to do in this case.. this would happen
+          if we fail to push the server list inside the client..
+          I should add a testcase for this, but I believe the following
+          would work, except that you would add a hole in the pool list..
+          in theory you could end up with an empty pool....
+        */
+      }
+    }
+  }
+
+  (void)pthread_mutex_unlock(&pool->mutex);
+
+  return rc;
+}
+
+memcached_return_t memcached_pool_behavior_get(memcached_pool_st *pool,
+                                               memcached_behavior_t flag,
+                                               uint64_t *value)
+{
+  if (pool == NULL)
+  {
+    return MEMCACHED_INVALID_ARGUMENTS;
+  }
+
+  if (pthread_mutex_lock(&pool->mutex))
+  {
+    return MEMCACHED_IN_PROGRESS;
+  }
+
+  *value= memcached_behavior_get(pool->master, flag);
+
+  (void)pthread_mutex_unlock(&pool->mutex);
+
+  return MEMCACHED_SUCCESS;
+}
diff --git a/libmemcachedutil/version.cc b/libmemcachedutil/version.cc
new file mode 100644 (file)
index 0000000..15f888b
--- /dev/null
@@ -0,0 +1,88 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2010 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include <libmemcachedutil/common.h>
+#include <cassert>
+
+struct local_context
+{
+  uint8_t major_version;
+  uint8_t minor_version;
+  uint8_t micro_version;
+
+  bool truth;
+};
+
+static memcached_return_t check_server_version(const memcached_st *,
+                                               const memcached_server_st *instance,
+                                               void *context)
+{
+  /* Do Nothing */
+  struct local_context *check= (struct local_context *)context;
+
+  if (instance->major_version != UINT8_MAX &&
+      instance->major_version >= check->major_version and
+      instance->minor_version >= check->minor_version and
+      instance->micro_version >= check->micro_version )
+  {
+    return MEMCACHED_SUCCESS;
+  }
+
+  check->truth= false;
+
+  return MEMCACHED_FAILURE;
+}
+
+bool libmemcached_util_version_check(memcached_st *memc,
+                                     uint8_t major_version,
+                                     uint8_t minor_version,
+                                     uint8_t micro_version)
+{
+  if (memcached_failed(memcached_version(memc)))
+  {
+    return false;
+  }
+
+  struct local_context check= { major_version, minor_version, micro_version, true };
+
+  memcached_server_fn callbacks[1];
+  callbacks[0]= check_server_version;
+  memcached_server_cursor(memc, callbacks, (void *)&check,  1);
+
+  return check.truth;
+}
index 0f1e1e0ad7044846d0f1a60b99077e407850ade7..74a20e05e8d3df44ebdd70584c155ad9a63d7c28 100644 (file)
@@ -160,6 +160,8 @@ do \
   } \
 } while (0)
 
+#define test_compare_hint test_compare_got
+
 #define test_compare_warn(__expected, __actual) \
 do \
 { \
diff --git a/m4/progtest.m4 b/m4/progtest.m4
deleted file mode 100644 (file)
index 2d804ac..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-# progtest.m4 serial 6 (gettext-0.18)
-dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl   Ulrich Drepper <drepper@cygnus.com>, 1996.
-
-AC_PREREQ([2.50])
-
-# Search path for a program which passes the given test.
-
-dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
-dnl   TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
-AC_DEFUN([AM_PATH_PROG_WITH_TEST],
-[
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
-# Find out how to test for executable files. Don't use a zero-byte file,
-# as systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  ac_executable_p="test -x"
-else
-  ac_executable_p="test -f"
-fi
-rm -f conf$$.file
-
-# Extract the first word of "$2", so it can be a program name with args.
-set dummy $2; ac_word=[$]2
-AC_MSG_CHECKING([for $ac_word])
-AC_CACHE_VAL([ac_cv_path_$1],
-[case "[$]$1" in
-  [[\\/]]* | ?:[[\\/]]*)
-    ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
-    ;;
-  *)
-    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
-    for ac_dir in ifelse([$5], , $PATH, [$5]); do
-      IFS="$ac_save_IFS"
-      test -z "$ac_dir" && ac_dir=.
-      for ac_exec_ext in '' $ac_executable_extensions; do
-        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
-          echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
-          if [$3]; then
-            ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
-            break 2
-          fi
-        fi
-      done
-    done
-    IFS="$ac_save_IFS"
-dnl If no 4th arg is given, leave the cache variable unset,
-dnl so AC_PATH_PROGS will keep looking.
-ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
-])dnl
-    ;;
-esac])dnl
-$1="$ac_cv_path_$1"
-if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
-  AC_MSG_RESULT([$][$1])
-else
-  AC_MSG_RESULT([no])
-fi
-AC_SUBST([$1])dnl
-])
index 64abfc3234c2538871303c6a5f021fc3cbaed252..449ee0b30732a1f0f571be2bd96a5606c80cff9e 100644 (file)
@@ -28,6 +28,8 @@ memslap - Generate testing loads on a memcached cluster.
 memcp - Copy files to memcached servers.
 memerror - Creates human readable messages from libmemecached error codes.
 memcapable - Verify a memcached server for protocol behavior.
+memexist - Check for the existance of a key.
+memtouch - Update the expiration value of a key.
 
 
 %package devel
@@ -109,71 +111,75 @@ you will need to install %{name}-devel.
 %files devel
 %defattr (-,root,root,-) 
 %doc examples
-%{_includedir}/libhashkit/algorithm.h
-%{_includedir}/libhashkit/behavior.h
-%{_includedir}/libhashkit/configure.h
-%{_includedir}/libhashkit/digest.h
-%{_includedir}/libhashkit/function.h
-%{_includedir}/libhashkit/has.h
 %{_includedir}/libhashkit/hashkit.h
-%{_includedir}/libhashkit/hashkit.hpp
-%{_includedir}/libhashkit/str_algorithm.h
-%{_includedir}/libhashkit/strerror.h
-%{_includedir}/libhashkit/types.h
-%{_includedir}/libhashkit/visibility.h
-
-%{_includedir}/libmemcached/allocators.h
-%{_includedir}/libmemcached/analyze.h
-%{_includedir}/libmemcached/array.h
-%{_includedir}/libmemcached/auto.h
-%{_includedir}/libmemcached/basic_string.h
-%{_includedir}/libmemcached/behavior.h
-%{_includedir}/libmemcached/callback.h
-%{_includedir}/libmemcached/configure.h
-%{_includedir}/libmemcached/constants.h
-%{_includedir}/libmemcached/delete.h
-%{_includedir}/libmemcached/dump.h
-%{_includedir}/libmemcached/error.h
-%{_includedir}/libmemcached/exist.h
-%{_includedir}/libmemcached/exception.hpp
-%{_includedir}/libmemcached/fetch.h
-%{_includedir}/libmemcached/flush.h
-%{_includedir}/libmemcached/flush_buffers.h
-%{_includedir}/libmemcached/get.h
-%{_includedir}/libmemcached/hash.h
+%{_includedir}/libhashkit-1.0/algorithm.h
+%{_includedir}/libhashkit-1.0/behavior.h
+%{_includedir}/libhashkit-1.0/configure.h
+%{_includedir}/libhashkit-1.0/digest.h
+%{_includedir}/libhashkit-1.0/function.h
+%{_includedir}/libhashkit-1.0/has.h
+%{_includedir}/libhashkit-1.0/hashkit.h
+%{_includedir}/libhashkit-1.0/hashkit.hpp
+%{_includedir}/libhashkit-1.0/str_algorithm.h
+%{_includedir}/libhashkit-1.0/strerror.h
+%{_includedir}/libhashkit-1.0/types.h
+%{_includedir}/libhashkit-1.0/visibility.h
+
+%{_includedir}/libmemcachedprotocol-0.0/binary.h
+%{_includedir}/libmemcachedprotocol-0.0/callback.h
+%{_includedir}/libmemcachedprotocol-0.0/handler.h
+%{_includedir}/libmemcachedprotocol-0.0/vbucket.h
+
+%{_includedir}/libmemcachedutil-1.0/util.h
+%{_includedir}/libmemcachedutil-1.0/flush.h
+%{_includedir}/libmemcachedutil-1.0/pid.h
+%{_includedir}/libmemcachedutil-1.0/ping.h
+%{_includedir}/libmemcachedutil-1.0/pool.h
+%{_includedir}/libmemcachedutil-1.0/version.h
+
 %{_includedir}/libmemcached/memcached.h
 %{_includedir}/libmemcached/memcached.hpp
-%{_includedir}/libmemcached/memcached/protocol_binary.h
-%{_includedir}/libmemcached/memcached/vbucket.h
-%{_includedir}/libmemcached/memcached_util.h
-%{_includedir}/libmemcached/namespace.h
-%{_includedir}/libmemcached/options.h
-%{_includedir}/libmemcached/parse.h
-%{_includedir}/libmemcached/platform.h
-%{_includedir}/libmemcached/protocol/cache.h
-%{_includedir}/libmemcached/protocol/callback.h
-%{_includedir}/libmemcached/protocol_handler.h
-%{_includedir}/libmemcached/quit.h
-%{_includedir}/libmemcached/result.h
-%{_includedir}/libmemcached/return.h
-%{_includedir}/libmemcached/sasl.h
-%{_includedir}/libmemcached/server.h
-%{_includedir}/libmemcached/server_list.h
-%{_includedir}/libmemcached/stats.h
-%{_includedir}/libmemcached/storage.h
-%{_includedir}/libmemcached/strerror.h
-%{_includedir}/libmemcached/string.h
-%{_includedir}/libmemcached/types.h
 %{_includedir}/libmemcached/util.h
-%{_includedir}/libmemcached/util/flush.h
-%{_includedir}/libmemcached/util/pid.h
-%{_includedir}/libmemcached/util/ping.h
-%{_includedir}/libmemcached/util/pool.h
-%{_includedir}/libmemcached/util/version.h
-%{_includedir}/libmemcached/verbosity.h
-%{_includedir}/libmemcached/version.h
-%{_includedir}/libmemcached/visibility.h
-%{_includedir}/libmemcached/watchpoint.h
+
+%{_includedir}/libmemcached-1.0/allocators.h
+%{_includedir}/libmemcached-1.0/analyze.h
+%{_includedir}/libmemcached-1.0/auto.h
+%{_includedir}/libmemcached-1.0/basic_string.h
+%{_includedir}/libmemcached-1.0/behavior.h
+%{_includedir}/libmemcached-1.0/callback.h
+%{_includedir}/libmemcached-1.0/configure.h
+%{_includedir}/libmemcached-1.0/constants.h
+%{_includedir}/libmemcached-1.0/delete.h
+%{_includedir}/libmemcached-1.0/dump.h
+%{_includedir}/libmemcached-1.0/error.h
+%{_includedir}/libmemcached-1.0/exist.h
+%{_includedir}/libmemcached-1.0/touch.h
+%{_includedir}/libmemcached-1.0/exception.hpp
+%{_includedir}/libmemcached-1.0/fetch.h
+%{_includedir}/libmemcached-1.0/flush.h
+%{_includedir}/libmemcached-1.0/flush_buffers.h
+%{_includedir}/libmemcached-1.0/get.h
+%{_includedir}/libmemcached-1.0/hash.h
+%{_includedir}/libmemcached-1.0/memcached.h
+%{_includedir}/libmemcached-1.0/memcached.hpp
+%{_includedir}/libmemcached-1.0/options.h
+%{_includedir}/libmemcached-1.0/parse.h
+%{_includedir}/libmemcached-1.0/platform.h
+%{_includedir}/libmemcached-1.0/quit.h
+%{_includedir}/libmemcached-1.0/result.h
+%{_includedir}/libmemcached-1.0/return.h
+%{_includedir}/libmemcached-1.0/sasl.h
+%{_includedir}/libmemcached-1.0/server.h
+%{_includedir}/libmemcached-1.0/server_list.h
+%{_includedir}/libmemcached-1.0/stats.h
+%{_includedir}/libmemcached-1.0/storage.h
+%{_includedir}/libmemcached-1.0/strerror.h
+%{_includedir}/libmemcached-1.0/string.h
+%{_includedir}/libmemcached-1.0/types.h
+%{_includedir}/libmemcached-1.0/verbosity.h
+%{_includedir}/libmemcached-1.0/version.h
+%{_includedir}/libmemcached-1.0/visibility.h
+
 %{_libdir}/libhashkit.so
 %{_libdir}/libmemcached.so
 %{_libdir}/libmemcachedprotocol.so
@@ -278,6 +284,8 @@ you will need to install %{name}-devel.
 %{_mandir}/man3/memcached_strerror.3.gz
 %{_mandir}/man3/memcached_exist.3.gz
 %{_mandir}/man3/memcached_exist_by_key.3.gz
+%{_mandir}/man3/memcached_touch.3.gz
+%{_mandir}/man3/memcached_touch_by_key.3.gz
 %{_mandir}/man3/memcached_verbosity.3.gz
 %{_mandir}/man3/memcached_version.3.gz
 
index eebe0f38311162ed75bd847a1c32370183d41f07..981819d20c0c75ea03b6fafde11cd20b97e5ad26 100644 (file)
@@ -17,7 +17,6 @@
 #include <libtest/test.hpp>
 
 #include <libmemcached/memcached.h>
-#include <libmemcached/watchpoint.h>
 
 #include <cstdio>
 #include <cstdlib>
@@ -99,8 +98,7 @@ infinite:
       }
       else
       {
-        WATCHPOINT_ERROR(rc);
-        WATCHPOINT_ASSERT(rc);
+        test_compare(MEMCACHED_SUCCESS, rc);
       }
     }
     else
@@ -112,8 +110,7 @@ infinite:
                         0, 0);
       if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
       {
-        WATCHPOINT_ERROR(rc);
-        WATCHPOINT_ASSERT(0);
+        test_compare(MEMCACHED_SUCCESS, rc);
       }
     }
   }
diff --git a/tests/callbacks.cc b/tests/callbacks.cc
new file mode 100644 (file)
index 0000000..c490e00
--- /dev/null
@@ -0,0 +1,83 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached Client and Server 
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include <libtest/test.hpp>
+
+#include <tests/callbacks.h>
+
+using namespace libtest;
+
+static memcached_return_t delete_trigger(memcached_st *,
+                                         const char *key,
+                                         size_t key_length)
+{
+  assert(key);
+  assert(key_length);
+
+  return MEMCACHED_SUCCESS;
+}
+
+
+test_return_t test_MEMCACHED_CALLBACK_DELETE_TRIGGER_and_MEMCACHED_BEHAVIOR_NOREPLY(memcached_st *)
+{
+  memcached_st *memc= memcached(test_literal_param("--NOREPLY"));
+  test_true(memc);
+
+  memcached_trigger_delete_key_fn callback;
+
+  callback= (memcached_trigger_delete_key_fn)delete_trigger;
+
+  test_compare(MEMCACHED_INVALID_ARGUMENTS, 
+               memcached_callback_set(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, *(void**)&callback));
+
+  memcached_free(memc);
+
+  return TEST_SUCCESS;
+}
+
+test_return_t test_MEMCACHED_CALLBACK_DELETE_TRIGGER(memcached_st *memc)
+{
+  memcached_trigger_delete_key_fn callback;
+
+  callback= (memcached_trigger_delete_key_fn)delete_trigger;
+
+  test_compare(MEMCACHED_SUCCESS, 
+               memcached_callback_set(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, *(void**)&callback));
+
+  return TEST_SUCCESS;
+}
diff --git a/tests/callbacks.h b/tests/callbacks.h
new file mode 100644 (file)
index 0000000..070670c
--- /dev/null
@@ -0,0 +1,41 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached Client and Server 
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+test_return_t test_MEMCACHED_CALLBACK_DELETE_TRIGGER_and_MEMCACHED_BEHAVIOR_NOREPLY(memcached_st *);
+test_return_t test_MEMCACHED_CALLBACK_DELETE_TRIGGER(memcached_st *);
index c616a262d794f52253e8779f875effb7afff3220..cbc165e0c7d1a2b3f1d0210425cdb203b3205c47 100644 (file)
@@ -39,7 +39,7 @@
 /*
   C++ interface test
 */
-#include <libmemcached/memcached.hpp>
+#include <libmemcached-1.0/memcached.hpp>
 #include <libmemcached/server_instance.h>
 #include <libtest/test.hpp>
 
index 3d2545ab66e9987dcad260ddc74468459b57bc8b..fada2a6f8c0772ce36de93353aaca22a2a4055f3 100644 (file)
@@ -10,7 +10,7 @@
 #include <cstdlib>
 #include <cstring>
 
-#include <libhashkit/hashkit.hpp>
+#include <libhashkit-1.0/hashkit.hpp>
 
 using namespace libtest;
 
index 2d664e7c64e3fb629c07608b15547ee9473b2659..908ad9605cc247ddc75f302654875b6fed3cd9f9 100644 (file)
@@ -45,9 +45,10 @@ using namespace libtest;
 #include <cstdlib>
 #include <cstring>
 
-#include <libhashkit/hashkit.h>
+#include <libhashkit-1.0/hashkit.h>
+#include <libhashkit/is.h>
 
-#include "hash_results.h"
+#include "tests/hash_results.h"
 
 static hashkit_st global_hashk;
 
index 8e173d88a331f2a63ade91bc8abf520f66bb15ee..b51dc2c3c74a640fef288b1bc6a11d6e83094a4f 100644 (file)
@@ -23,6 +23,7 @@ EXTRA_DIST+= \
 
 noinst_HEADERS+= \
                 tests/basic.h \
+                tests/callbacks.h \
                 tests/debug.h \
                 tests/error_conditions.h \
                 tests/exist.h \
@@ -33,6 +34,7 @@ noinst_HEADERS+= \
                 tests/libmemcached_world.h \
                 tests/namespace.h \
                 tests/parser.h \
+                tests/touch.h \
                 tests/deprecated.h \
                 tests/pool.h \
                 tests/print.h \
@@ -77,6 +79,8 @@ tests_testapp_SOURCES= \
                       tests/mem_functions.cc \
                       tests/namespace.cc \
                       tests/parser.cc \
+                      tests/touch.cc \
+                      tests/callbacks.cc \
                       tests/pool.cc \
                       tests/print.cc \
                       tests/replication.cc \
@@ -171,71 +175,78 @@ noinst_PROGRAMS+= tests/hash_plus
 
 tests_memcapable_SOURCES= tests/memcapable.cc
 tests_memcapable_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memcapable_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
-tests_memcapable_LDADD=  $(tests_memcapable_DEPENDENCIES)
+tests_memcapable_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memcapable
+tests_memcapable_LDADD=  libtest/libtest.la $(TESTS_LDADDS)
 check_PROGRAMS+= tests/memcapable
 noinst_PROGRAMS+= tests/memcapable
 
 tests_memstat_SOURCES= tests/memstat.cc
 tests_memstat_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memstat_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
-tests_memstat_LDADD=  $(tests_memstat_DEPENDENCIES)
+tests_memstat_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memstat
+tests_memstat_LDADD=  libtest/libtest.la $(TESTS_LDADDS)
 check_PROGRAMS+= tests/memstat
 noinst_PROGRAMS+= tests/memstat
 
 tests_memcp_SOURCES= tests/memcp.cc
 tests_memcp_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memcp_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
-tests_memcp_LDADD=  $(tests_memcp_DEPENDENCIES)
+tests_memcp_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memcp
+tests_memcp_LDADD=  libtest/libtest.la $(TESTS_LDADDS)
 check_PROGRAMS+= tests/memcp
 noinst_PROGRAMS+= tests/memcp
 
 tests_memflush_SOURCES= tests/memflush.cc
 tests_memflush_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memflush_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
-tests_memflush_LDADD=  $(tests_memflush_DEPENDENCIES)
+tests_memflush_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memflush
+tests_memflush_LDADD= libtest/libtest.la $(TESTS_LDADDS)
 check_PROGRAMS+= tests/memflush
 noinst_PROGRAMS+= tests/memflush
 
 tests_memrm_SOURCES= tests/memrm.cc
 tests_memrm_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memrm_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
-tests_memrm_LDADD=  $(tests_memrm_DEPENDENCIES)
+tests_memrm_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memrm
+tests_memrm_LDADD= libtest/libtest.la $(TESTS_LDADDS)
 check_PROGRAMS+= tests/memrm
 noinst_PROGRAMS+= tests/memrm
 
 tests_memexist_SOURCES= tests/memexist.cc
 tests_memexist_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memexist_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
-tests_memexist_LDADD=  $(tests_memexist_DEPENDENCIES)
+tests_memexist_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memexist
+tests_memexist_LDADD= libtest/libtest.la $(TESTS_LDADDS)
 check_PROGRAMS+= tests/memexist
 noinst_PROGRAMS+= tests/memexist
 
+tests_memtouch_SOURCES= tests/memtouch.cc
+tests_memtouch_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
+tests_memtouch_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memtouch
+tests_memtouch_LDADD=  libtest/libtest.la $(TESTS_LDADDS)
+check_PROGRAMS+= tests/memtouch
+noinst_PROGRAMS+= tests/memtouch
+
 tests_memcat_SOURCES= tests/memcat.cc
 tests_memcat_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memcat_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
-tests_memcat_LDADD=  $(tests_memcat_DEPENDENCIES)
+tests_memcat_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memcat
+tests_memcat_LDADD= libtest/libtest.la $(TESTS_LDADDS)
 check_PROGRAMS+= tests/memcat
 noinst_PROGRAMS+= tests/memcat
 
 tests_memerror_SOURCES= tests/memerror.cc
 tests_memerror_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memerror_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
-tests_memerror_LDADD=  $(tests_memerror_DEPENDENCIES)
+tests_memerror_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memerror
+tests_memerror_LDADD= libtest/libtest.la $(TESTS_LDADDS)
 check_PROGRAMS+= tests/memerror
 noinst_PROGRAMS+= tests/memerror
 
 tests_memslap_SOURCES= tests/memslap.cc
 tests_memslap_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memslap_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
-tests_memslap_LDADD=  $(tests_memslap_DEPENDENCIES)
+tests_memslap_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memslap
+tests_memslap_LDADD= libtest/libtest.la $(TESTS_LDADDS)
 check_PROGRAMS+= tests/memslap
 noinst_PROGRAMS+= tests/memslap
 
 tests_memdump_SOURCES= tests/memdump.cc
 tests_memdump_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memdump_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
-tests_memdump_LDADD=  $(tests_memdump_DEPENDENCIES)
+tests_memdump_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS) clients/memdump
+tests_memdump_LDADD=  libtest/libtest.la $(TESTS_LDADDS)
 check_PROGRAMS+= tests/memdump
 noinst_PROGRAMS+= tests/memdump
  
index ecbb489efbc036b1e938ae69aefd07109ba2b402..7936a524826818b009cbbe5e6ac67b7506071203 100644 (file)
@@ -131,9 +131,10 @@ static test_return_t world_container_startup(libmemcached_test_container_st *con
                                                     buffer, sizeof(buffer)),
                    container->construct.option_string().c_str());
 
-  test_true(not container->parent);
+  test_null(container->parent);
   container->parent= memcached(container->construct.option_string().c_str(), container->construct.option_string().size());
   test_true(container->parent);
+  test_compare(MEMCACHED_SUCCESS, memcached_version(container->parent));
 
   if (container->construct.sasl())
   {
@@ -175,7 +176,7 @@ static test_return_t world_container_shutdown(libmemcached_test_container_st *co
 static test_return_t world_test_startup(libmemcached_test_container_st *container)
 {
   test_true(container);
-  test_true(not container->memc);
+  test_null(container->memc);
   test_true(container->parent);
   container->memc= memcached_clone(NULL, container->parent);
   test_true(container->memc);
@@ -216,9 +217,8 @@ static test_return_t world_post_run(libmemcached_test_container_st *container)
   return TEST_SUCCESS;
 }
 
-static test_return_t world_on_error(test_return_t test_state, libmemcached_test_container_st *container)
+static test_return_t world_on_error(test_return_t , libmemcached_test_container_st *container)
 {
-  (void)test_state;
   test_true(container->memc);
   memcached_free(container->memc);
   container->memc= NULL;
index cca23464e01ac16d9b63aa21e2c5cdef6ca3395d..b9acb87ef882a7c03504765aeb4921be715bf216 100644 (file)
   Test cases
 */
 
-#include <libmemcached/memcached.h>
+#include <libmemcached-1.0/memcached.h>
 #include <libmemcached/is.h>
 #include <libmemcached/server_instance.h>
 
-#include <libhashkit/hashkit.h>
+#include <libhashkit-1.0/hashkit.h>
 
 #include <cassert>
 #include <cerrno>
@@ -78,6 +78,8 @@
 #include "tests/ketama.h"
 #include "tests/namespace.h"
 #include "tests/parser.h"
+#include "tests/touch.h"
+#include "tests/callbacks.h"
 #include "tests/pool.h"
 #include "tests/print.h"
 #include "tests/replication.h"
@@ -86,7 +88,7 @@
 
 using namespace libtest;
 
-#include <libmemcached/memcached_util.h>
+#include <libmemcached/util.h>
 
 #include "hash_results.h"
 
@@ -99,8 +101,22 @@ static pairs_st *global_pairs;
 static const char *global_keys[GLOBAL_COUNT];
 static size_t global_keys_length[GLOBAL_COUNT];
 
-// Prototype
-static test_return_t pre_binary(memcached_st *memc);
+/**
+  @note This should be testing to see if the server really supports the binary protocol.
+*/
+static test_return_t pre_binary(memcached_st *memc)
+{
+  memcached_return_t rc= MEMCACHED_FAILURE;
+
+  if (libmemcached_util_version_check(memc, 1, 4, 4))
+  {
+    rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
+    test_compare(MEMCACHED_SUCCESS, rc);
+    test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
+  }
+
+  return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
+}
 
 
 static test_return_t init_test(memcached_st *not_used)
@@ -981,28 +997,6 @@ static test_return_t read_through(memcached_st *memc)
   return TEST_SUCCESS;
 }
 
-static memcached_return_t delete_trigger(memcached_st *,
-                                         const char *key,
-                                         size_t key_length)
-{
-  assert(key);
-  assert(key_length);
-
-  return MEMCACHED_SUCCESS;
-}
-
-static test_return_t delete_through(memcached_st *memc)
-{
-  memcached_trigger_delete_key_fn callback;
-
-  callback= (memcached_trigger_delete_key_fn)delete_trigger;
-
-  test_compare(MEMCACHED_SUCCESS, 
-               memcached_callback_set(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, *(void**)&callback));
-
-  return TEST_SUCCESS;
-}
-
 static test_return_t get_test(memcached_st *memc)
 {
   memcached_return_t rc;
@@ -2281,9 +2275,8 @@ static test_return_t user_supplied_bug2(memcached_st *memc)
 /* Do a large mget() over all the keys we think exist */
 static test_return_t user_supplied_bug3(memcached_st *memc)
 {
-  unsigned int setter= 1;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
+  test_compare(true, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1));
+  test_compare(true, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
 #ifdef NOT_YET
   setter = 20 * 1024576;
   memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
@@ -2300,6 +2293,7 @@ static test_return_t user_supplied_bug3(memcached_st *memc)
   {
     char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
     int key_length= snprintf(key, sizeof(key), "%u", x);
+    test_true(key_length);
     keys[x]= strdup(key);
     test_true(keys[x]);
     key_lengths[x]= key_length;
@@ -2397,7 +2391,7 @@ static test_return_t user_supplied_bug5(memcached_st *memc)
 
   memcached_return_t rc;
   value= memcached_get(memc, keys[0], key_length[0],
-                        &value_length, &flags, &rc);
+                       &value_length, &flags, &rc);
   test_false(value);
   test_compare(MEMCACHED_SUCCESS,
                memcached_mget(memc, keys, key_length, 4));
@@ -2461,7 +2455,7 @@ static test_return_t user_supplied_bug6(memcached_st *memc)
   memcached_return_t rc;
   uint32_t count= 0;
   while ((value= memcached_fetch(memc, return_key, &return_key_length,
-                                        &value_length, &flags, &rc)))
+                                 &value_length, &flags, &rc)))
   {
     count++;
   }
@@ -2557,7 +2551,7 @@ static test_return_t user_supplied_bug7(memcached_st *memc)
 
   flags= 0;
   value= memcached_get(memc, keys, key_length,
-                        &value_length, &flags, &rc);
+                       &value_length, &flags, &rc);
   test_true(flags == 245);
   test_true(value);
   free(value);
@@ -2643,7 +2637,7 @@ static test_return_t user_supplied_bug10(memcached_st *memc)
                                          value, value_length, 0, 0);
 
     test_true_got((rc == MEMCACHED_SUCCESS or rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_BUFFERED or rc == MEMCACHED_TIMEOUT or rc == MEMCACHED_CONNECTION_FAILURE 
-                  or rc == MEMCACHED_SERVER_TEMPORARILY_DISABLED), 
+                   or rc == MEMCACHED_SERVER_TEMPORARILY_DISABLED), 
                   memcached_strerror(NULL, rc));
 
     if (rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_TIMEOUT)
@@ -2709,7 +2703,7 @@ static test_return_t user_supplied_bug12(memcached_st *memc)
   uint64_t number_value;
 
   value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
-                        &value_length, &flags, &rc);
+                       &value_length, &flags, &rc);
   test_true(value == NULL);
   test_compare(MEMCACHED_NOTFOUND, rc);
 
@@ -2730,7 +2724,7 @@ static test_return_t user_supplied_bug12(memcached_st *memc)
   rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
 
   value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
-                        &value_length, &flags, &rc);
+                       &value_length, &flags, &rc);
   test_true(value);
   test_compare(MEMCACHED_SUCCESS, rc);
   free(value);
@@ -2746,7 +2740,7 @@ static test_return_t user_supplied_bug12(memcached_st *memc)
 /*
   Bug found where command total one more than MEMCACHED_MAX_BUFFER
   set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
- */
+*/
 static test_return_t user_supplied_bug13(memcached_st *memc)
 {
   char key[] = "key34567890";
@@ -2783,7 +2777,7 @@ static test_return_t user_supplied_bug13(memcached_st *memc)
   Bug found where command total one more than MEMCACHED_MAX_BUFFER
   set key34567890 0 0 8169 \r\n
   is sent followed by buffer of size 8169, followed by 8169
- */
+*/
 static test_return_t user_supplied_bug14(memcached_st *memc)
 {
   memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
@@ -2818,7 +2812,7 @@ static test_return_t user_supplied_bug14(memcached_st *memc)
 
 /*
   Look for zero length value problems
-  */
+*/
 static test_return_t user_supplied_bug15(memcached_st *memc)
 {
   for (uint32_t x= 0; x < 2; x++)
@@ -2863,7 +2857,7 @@ static test_return_t user_supplied_bug16(memcached_st *memc)
   size_t length;
   uint32_t flags;
   char *value= memcached_get(memc, test_literal_param("mykey"),
-                       &length, &flags, &rc);
+                             &length, &flags, &rc);
 
   test_compare(MEMCACHED_SUCCESS, rc);
   test_true(value == NULL);
@@ -2877,25 +2871,25 @@ static test_return_t user_supplied_bug16(memcached_st *memc)
 /* Check the validity of chinese key*/
 static test_return_t user_supplied_bug17(memcached_st *memc)
 {
-    const char *key= "豆瓣";
-    const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
-    memcached_return_t rc= memcached_set(memc, key, strlen(key),
-                                         value, strlen(value),
-                                         (time_t)0, 0);
+  const char *key= "豆瓣";
+  const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
+  memcached_return_t rc= memcached_set(memc, key, strlen(key),
+                                       value, strlen(value),
+                                       (time_t)0, 0);
 
-    test_compare(MEMCACHED_SUCCESS, rc);
+  test_compare(MEMCACHED_SUCCESS, rc);
 
-    size_t length;
-    uint32_t flags;
-    char *value2= memcached_get(memc, key, strlen(key),
-                                &length, &flags, &rc);
+  size_t length;
+  uint32_t flags;
+  char *value2= memcached_get(memc, key, strlen(key),
+                              &length, &flags, &rc);
 
-    test_true(length==strlen(value));
-    test_compare(MEMCACHED_SUCCESS, rc);
-    test_memcmp(value, value2, length);
-    free(value2);
+  test_true(length==strlen(value));
+  test_compare(MEMCACHED_SUCCESS, rc);
+  test_memcmp(value, value2, length);
+  free(value2);
 
-    return TEST_SUCCESS;
+  return TEST_SUCCESS;
 }
 #endif
 
@@ -3037,13 +3031,7 @@ static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
 
 static test_return_t user_supplied_bug21(memcached_st *memc)
 {
-  test_return_t test_rc;
-  test_rc= pre_binary(memc);
-
-  if (test_rc != TEST_SUCCESS)
-  {
-    return test_rc;
-  }
+  test_skip(TEST_SUCCESS, pre_binary(memc));
 
   /* should work as of r580 */
   test_compare(TEST_SUCCESS,
@@ -3450,7 +3438,7 @@ static test_return_t add_host_test1(memcached_st *memc)
 
     snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
     servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
-                                     &rc);
+                                                      &rc);
     test_compare(MEMCACHED_SUCCESS, rc);
     test_compare(x, memcached_server_list_count(servers));
   }
@@ -3612,23 +3600,6 @@ static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
   return TEST_SUCCESS;
 }
 
-/**
-  @note This should be testing to see if the server really supports the binary protocol.
-*/
-static test_return_t pre_binary(memcached_st *memc)
-{
-  memcached_return_t rc= MEMCACHED_FAILURE;
-
-  if (libmemcached_util_version_check(memc, 1, 4, 4))
-  {
-    rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
-    test_compare(MEMCACHED_SUCCESS, rc);
-    test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
-  }
-
-  return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
-}
-
 static test_return_t pre_replication(memcached_st *memc)
 {
   test_skip(TEST_SUCCESS, pre_binary(memc));
@@ -3636,7 +3607,7 @@ static test_return_t pre_replication(memcached_st *memc)
   /*
    * Make sure that we store the item on all servers
    * (master + replicas == number of servers)
  */
+ */
   test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, memcached_server_count(memc) - 1));
   test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS), uint64_t(memcached_server_count(memc) - 1));
 
@@ -3733,7 +3704,7 @@ static test_return_t selection_of_namespace_tests(memcached_st *memc)
   /* Make sure be default none exists */
   value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
   test_null(value);
-  test_compare_got(MEMCACHED_FAILURE, rc, memcached_strerror(NULL, rc));
+  test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
 
   /* Test a clean set */
   test_compare(MEMCACHED_SUCCESS,
@@ -3749,8 +3720,8 @@ static test_return_t selection_of_namespace_tests(memcached_st *memc)
                memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
 
   value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
-  test_false(value);
-  test_compare_got(MEMCACHED_FAILURE, rc, memcached_strerror(NULL, rc));
+  test_null(value);
+  test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
 
   /* Now setup for main test */
   test_compare(MEMCACHED_SUCCESS,
@@ -3770,9 +3741,8 @@ static test_return_t selection_of_namespace_tests(memcached_st *memc)
                  memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
 
     value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
-    test_false(value);
-    test_true(rc == MEMCACHED_FAILURE);
-    test_true(value == NULL);
+    test_null(value);
+    test_compare(MEMCACHED_SUCCESS, rc);
 
     /* Test a long key for failure */
     /* TODO, extend test to determine based on setting, what result should be */
@@ -3802,10 +3772,10 @@ static test_return_t set_namespace(memcached_st *memc)
   const char *key= "mine";
   char *value;
 
-  /* Make sure be default none exists */
+  // Make sure we default to a null namespace
   value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
   test_null(value);
-  test_compare_got(MEMCACHED_FAILURE, rc, memcached_strerror(NULL, rc));
+  test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
 
   /* Test a clean set */
   test_compare(MEMCACHED_SUCCESS,
@@ -4064,10 +4034,10 @@ static test_return_t noreply_test(memcached_st *memc)
     }
 
     /*
-    ** NOTE: Don't ever do this in your code! this is not a supported use of the
-    ** API and is _ONLY_ done this way to verify that the library works the
-    ** way it is supposed to do!!!!
-    */
+     ** NOTE: Don't ever do this in your code! this is not a supported use of the
+     ** API and is _ONLY_ done this way to verify that the library works the
+     ** way it is supposed to do!!!!
+   */
     int no_msg=0;
     for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
     {
@@ -4081,7 +4051,7 @@ static test_return_t noreply_test(memcached_st *memc)
 
     /*
      ** Now validate that all items was set properly!
-     */
+   */
     for (size_t x= 0; x < 100; ++x)
     {
       char key[10];
@@ -4120,7 +4090,7 @@ static test_return_t noreply_test(memcached_st *memc)
 
   /* Try setting an illegal cas value (should not return an error to
    * the caller (because we don't expect a return message from the server)
  */
+ */
   const char* keys[]= {"0"};
   size_t lengths[]= {1};
   size_t length;
@@ -4144,7 +4114,7 @@ static test_return_t noreply_test(memcached_st *memc)
   /*
    * The item will have a new cas value, so try to set it again with the old
    * value. This should fail!
  */
+ */
   test_compare(MEMCACHED_SUCCESS, 
                memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
   test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
@@ -4277,7 +4247,7 @@ static test_return_t connection_pool2_test(memcached_st *memc)
   /* verify that I can set behaviors on the pool when I don't have all
    * of the connections in the pool. It should however be enabled
    * when I push the item into the pool
  */
+ */
   mmc[0]= memcached_pool_fetch(pool, NULL, NULL);
   test_true(mmc[0]);
 
@@ -4358,6 +4328,10 @@ static void* connection_release(void *arg)
 
 static test_return_t connection_pool3_test(memcached_st *memc)
 {
+#ifdef __APPLE__
+  return TEST_SKIPPED;
+#endif
+
   memcached_pool_st* pool= memcached_pool_create(memc, 1, 1);
   test_true(pool);
 
@@ -4385,17 +4359,24 @@ static test_return_t connection_pool3_test(memcached_st *memc)
 
   memcached_return_t rc;
   memcached_st *pop_memc;
+  // We do a hard loop, and try N times
   int counter= 5;
   do
   {
     struct timespec relative_time= { 0, 0 };
     pop_memc= memcached_pool_fetch(pool, &relative_time, &rc);
 
+    if (memcached_success(rc))
+    {
+      break;
+    }
+
     if (memcached_failed(rc))
     {
       test_null(pop_memc);
+      test_true(rc != MEMCACHED_TIMEOUT); // As long as relative_time is zero, MEMCACHED_TIMEOUT is invalid
     }
-  } while (rc == MEMCACHED_TIMEOUT and --counter);
+  } while (--counter);
 
   if (memcached_failed(rc)) // Cleanup thread since we will exit once we test.
   {
@@ -4417,10 +4398,10 @@ static test_return_t connection_pool3_test(memcached_st *memc)
 
 static test_return_t util_version_test(memcached_st *memc)
 {
-  bool if_successful= libmemcached_util_version_check(memc, 0, 0, 0);
-  test_true(if_successful);
+  test_compare_hint(MEMCACHED_SUCCESS, memcached_version(memc), memcached_last_error_message(memc));
+  test_true(libmemcached_util_version_check(memc, 0, 0, 0));
 
-  if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
+  bool if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
 
   // We expect failure
   if (if_successful)
@@ -4914,11 +4895,7 @@ static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
 
 static test_return_t regression_bug_434484(memcached_st *memc)
 {
-  test_return_t test_rc;
-  test_rc= pre_binary(memc);
-
-  if (test_rc != TEST_SUCCESS)
-    return test_rc;
+  test_skip(TEST_SUCCESS, pre_binary(memc));
 
   const char *key= "regression_bug_434484";
   size_t keylen= strlen(key);
@@ -4938,11 +4915,7 @@ static test_return_t regression_bug_434484(memcached_st *memc)
 
 static test_return_t regression_bug_434843(memcached_st *memc)
 {
-  test_return_t test_rc;
-  test_rc= pre_binary(memc);
-
-  if (test_rc != TEST_SUCCESS)
-    return test_rc;
+  test_skip(TEST_SUCCESS, pre_binary(memc));
 
   memcached_return_t rc;
   size_t counter= 0;
@@ -4953,7 +4926,7 @@ static test_return_t regression_bug_434843(memcached_st *memc)
    * sending in the pipleine to the server. Let's try to do a multiget of
    * 1024 (that should satisfy most users don't you think?). Future versions
    * will include a mget_execute function call if you need a higher number.
  */
+ */
   uint32_t number_of_hosts= memcached_server_count(memc);
   memc->number_of_hosts= 1;
   const size_t max_keys= 1024;
@@ -4962,17 +4935,17 @@ static test_return_t regression_bug_434843(memcached_st *memc)
 
   for (size_t x= 0; x < max_keys; ++x)
   {
-     char k[251];
+    char k[251];
 
-     key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
-     keys[x]= strdup(k);
-     test_true(keys[x]);
+    key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
+    keys[x]= strdup(k);
+    test_true(keys[x]);
   }
 
   /*
    * Run two times.. the first time we should have 100% cache miss,
    * and the second time we should have 100% cache hits
  */
+ */
   for (size_t y= 0; y < 2; y++)
   {
     test_compare(MEMCACHED_SUCCESS,
@@ -4998,7 +4971,7 @@ static test_return_t regression_bug_434843(memcached_st *memc)
     else
     {
       /* Verify that we received all of the key/value pairs */
-       test_compare(counter, max_keys);
+      test_compare(counter, max_keys);
     }
   }
 
@@ -5083,9 +5056,9 @@ static test_return_t regression_bug_442914(memcached_st *memc)
 
   for (uint32_t x= 0; x < 250; ++x)
   {
-     len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
-     memcached_return_t rc= memcached_delete(memc, k, len, 0);
-     test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+    len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
+    memcached_return_t rc= memcached_delete(memc, k, len, 0);
+    test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
   }
 
   (void)snprintf(k, sizeof(k), "%037u", 251U);
@@ -5129,23 +5102,23 @@ static test_return_t regression_bug_447342(memcached_st *memc)
   }
 
   /*
-  ** We are using the quiet commands to store the replicas, so we need
-  ** to ensure that all of them are processed before we can continue.
-  ** In the test we go directly from storing the object to trying to
-  ** receive the object from all of the different servers, so we
-  ** could end up in a race condition (the memcached server hasn't yet
-  ** processed the quiet command from the replication set when it process
-  ** the request from the other client (created by the clone)). As a
-  ** workaround for that we call memcached_quit to send the quit command
-  ** to the server and wait for the response ;-) If you use the test code
-  ** as an example for your own code, please note that you shouldn't need
-  ** to do this ;-)
 */
+   ** We are using the quiet commands to store the replicas, so we need
+   ** to ensure that all of them are processed before we can continue.
+   ** In the test we go directly from storing the object to trying to
+   ** receive the object from all of the different servers, so we
+   ** could end up in a race condition (the memcached server hasn't yet
+   ** processed the quiet command from the replication set when it process
+   ** the request from the other client (created by the clone)). As a
+   ** workaround for that we call memcached_quit to send the quit command
+   ** to the server and wait for the response ;-) If you use the test code
+   ** as an example for your own code, please note that you shouldn't need
+   ** to do this ;-)
+ */
   memcached_quit(memc);
 
   /* Verify that all messages are stored, and we didn't stuff too much
    * into the servers
  */
+ */
   test_compare(MEMCACHED_SUCCESS,
                memcached_mget(memc, (const char* const *)keys, key_length, max_keys));
 
@@ -5163,7 +5136,7 @@ static test_return_t regression_bug_447342(memcached_st *memc)
    * within the library, and this is not a supported interface.
    * This is to verify correct behavior in the library. Fake that two servers
    * are dead..
  */
+ */
   instance_one= memcached_server_instance_by_position(memc, 0);
   instance_two= memcached_server_instance_by_position(memc, 2);
   in_port_t port0= instance_one->port;
@@ -5255,7 +5228,7 @@ static test_return_t regression_bug_463297(memcached_st *memc)
 
     /* but there is a bug in some of the memcached servers (1.4) that treats
      * the counter as noreply so it doesn't send the proper error message
-     */
+   */
     test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
 
     /* And buffered mode should be disabled and we should get protocol error */
@@ -5433,7 +5406,7 @@ static test_return_t wrong_failure_counter_test(memcached_st *memc)
    * Please note that I'm abusing the internal structures in libmemcached
    * in a non-portable way and you shouldn't be doing this. I'm only
    * doing this in order to verify that the library works the way it should
  */
+ */
   uint32_t number_of_hosts= memcached_server_count(memc);
   memc->number_of_hosts= 1;
 
@@ -5448,7 +5421,7 @@ static test_return_t wrong_failure_counter_test(memcached_st *memc)
   /* The test is to see that the memcached_quit doesn't increase the
    * the server failure conter, so let's ensure that it is zero
    * before sending quit
  */
+ */
   ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
 
   memcached_quit(memc);
@@ -5456,7 +5429,7 @@ static test_return_t wrong_failure_counter_test(memcached_st *memc)
   /* Verify that it memcached_quit didn't increment the failure counter
    * Please note that this isn't bullet proof, because an error could
    * occur...
  */
+ */
   test_zero(instance->server_failure_counter);
 
   /* restore the instance */
@@ -5536,7 +5509,7 @@ static test_return_t regression_bug_490486(memcached_st *memc)
   /*
    * I only want to hit _one_ server so I know the number of requests I'm
    * sending in the pipeline.
  */
+ */
   uint32_t number_of_hosts= memc->number_of_hosts;
   memc->number_of_hosts= 1;
   size_t max_keys= 20480;
@@ -5780,16 +5753,16 @@ static test_return_t regression_bug_854604(memcached_st *)
   test_compare(MEMCACHED_INVALID_ARGUMENTS, libmemcached_check_configuration(0, 0, buffer, 0));
 
   test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 0));
-  
+
   test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 1));
   test_compare(buffer[0], 0);
-  
+
   test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 10));
   test_true(strlen(buffer));
 
   test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, sizeof(buffer)));
   test_true(strlen(buffer));
-  
+
   return TEST_SUCCESS;
 }
 
@@ -5954,7 +5927,7 @@ test_st tests[] ={
   {"bad_key", true, (test_callback_fn*)bad_key_test },
   {"memcached_server_cursor", true, (test_callback_fn*)memcached_server_cursor_test },
   {"read_through", true, (test_callback_fn*)read_through },
-  {"delete_through", true, (test_callback_fn*)delete_through },
+  {"delete_through", true, (test_callback_fn*)test_MEMCACHED_CALLBACK_DELETE_TRIGGER },
   {"noreply", true, (test_callback_fn*)noreply_test},
   {"analyzer", true, (test_callback_fn*)analyzer_test},
   {"memcached_pool_st", true, (test_callback_fn*)connection_pool_test },
@@ -5968,6 +5941,14 @@ test_st tests[] ={
   {"memcached_exist(MEMCACHED_SUCCESS)", true, (test_callback_fn*)memcached_exist_SUCCESS },
   {"memcached_exist_by_key(MEMCACHED_NOTFOUND)", true, (test_callback_fn*)memcached_exist_by_key_NOTFOUND },
   {"memcached_exist_by_key(MEMCACHED_SUCCESS)", true, (test_callback_fn*)memcached_exist_by_key_SUCCESS },
+  {"memcached_touch", 0, (test_callback_fn*)test_memcached_touch},
+  {"memcached_touch_with_prefix", 0, (test_callback_fn*)test_memcached_touch_by_key},
+  {0, 0, 0}
+};
+
+test_st touch_tests[] ={
+  {"memcached_touch", 0, (test_callback_fn*)test_memcached_touch},
+  {"memcached_touch_with_prefix", 0, (test_callback_fn*)test_memcached_touch_by_key},
   {0, 0, 0}
 };
 
@@ -5979,6 +5960,7 @@ test_st behavior_tests[] ={
   {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", false, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
   {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", false, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
   {"MEMCACHED_BEHAVIOR_POLL_TIMEOUT", false, (test_callback_fn*)MEMCACHED_BEHAVIOR_POLL_TIMEOUT_test},
+  {"MEMCACHED_CALLBACK_DELETE_TRIGGER_and_MEMCACHED_BEHAVIOR_NOREPLY", false, (test_callback_fn*)test_MEMCACHED_CALLBACK_DELETE_TRIGGER_and_MEMCACHED_BEHAVIOR_NOREPLY},
   {0, 0, 0}
 };
 
@@ -6055,12 +6037,12 @@ test_st user_tests[] ={
   {"user_supplied_bug16", true, (test_callback_fn*)user_supplied_bug16 },
 #if !defined(__sun) && !defined(__OpenBSD__)
   /*
-  ** It seems to be something weird with the character sets..
-  ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
-  ** guess I need to find out how this is supposed to work.. Perhaps I need
-  ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
-  ** so just disable the code for now...).
 */
+   ** It seems to be something weird with the character sets..
+   ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
+   ** guess I need to find out how this is supposed to work.. Perhaps I need
+   ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
+   ** so just disable the code for now...).
+ */
   {"user_supplied_bug17", true, (test_callback_fn*)user_supplied_bug17 },
 #endif
   {"user_supplied_bug18", true, (test_callback_fn*)user_supplied_bug18 },
@@ -6200,7 +6182,6 @@ test_st error_conditions[] ={
   {0, 0, (test_callback_fn*)0}
 };
 
-
 test_st parser_tests[] ={
   {"behavior", false, (test_callback_fn*)behavior_parser_test },
   {"boolean_options", false, (test_callback_fn*)parser_boolean_options_test },
@@ -6306,6 +6287,7 @@ collection_st collection[] ={
   {"parser", 0, 0, parser_tests},
   {"virtual buckets", 0, 0, virtual_bucket_tests},
   {"memcached_server_get_last_disconnect", 0, 0, memcached_server_get_last_disconnect_tests},
+  {"touch", 0, 0, touch_tests},
   {0, 0, 0, 0}
 };
 
diff --git a/tests/memtouch.cc b/tests/memtouch.cc
new file mode 100644 (file)
index 0000000..21378d7
--- /dev/null
@@ -0,0 +1,153 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Test memtouch
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+/*
+  Test that we are cycling the servers we are creating during testing.
+*/
+
+#include <config.h>
+
+#include <libtest/test.hpp>
+#include <libmemcached/memcached.h>
+
+using namespace libtest;
+
+#ifndef __INTEL_COMPILER
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif
+
+static std::string executable;
+
+static test_return_t quiet_test(void *)
+{
+  const char *args[]= { "--quiet", 0 };
+
+  test_true(exec_cmdline(executable, args));
+  return TEST_SUCCESS;
+}
+
+static test_return_t help_test(void *)
+{
+  const char *args[]= { "--quiet", "--help", 0 };
+
+  test_true(exec_cmdline(executable, args));
+  return TEST_SUCCESS;
+}
+
+static test_return_t touch_test(void *)
+{
+  char buffer[1024];
+  snprintf(buffer, sizeof(buffer), "--server=localhost:%d", int(default_port()));
+  const char *args[]= { "--quiet", "--expire=30", buffer, "foo", 0 };
+
+  memcached_st *memc= memcached(buffer, strlen(buffer));
+  test_true(memc);
+
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_set(memc, test_literal_param("foo"), 0, 0, 0, 0));
+
+  test_compare(MEMCACHED_SUCCESS, memcached_exist(memc, test_literal_param("foo")));
+
+  test_true(exec_cmdline(executable, args));
+
+  test_compare(MEMCACHED_SUCCESS, memcached_exist(memc, test_literal_param("foo")));
+
+  memcached_free(memc);
+
+  return TEST_SUCCESS;
+}
+
+static test_return_t NOT_FOUND_test(void *)
+{
+  char buffer[1024];
+  snprintf(buffer, sizeof(buffer), "--server=localhost:%d", int(default_port()));
+  const char *args[]= { "--quiet", "--expire=30", buffer, "foo", 0 };
+
+  memcached_st *memc= memcached(buffer, strlen(buffer));
+  test_true(memc);
+
+  test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
+
+  test_compare(MEMCACHED_NOTFOUND, memcached_exist(memc, test_literal_param("foo")));
+
+  test_true(exec_cmdline(executable, args));
+
+  test_compare(MEMCACHED_NOTFOUND, memcached_exist(memc, test_literal_param("foo")));
+
+  memcached_free(memc);
+
+  return TEST_SUCCESS;
+}
+
+test_st memtouch_tests[] ={
+  {"--quiet", true, quiet_test },
+  {"--help", true, help_test },
+  {"touch(FOUND)", true, touch_test },
+  {"touch(NOT_FOUND)", true, NOT_FOUND_test },
+  {0, 0, 0}
+};
+
+collection_st collection[] ={
+  {"memtouch", 0, 0, memtouch_tests },
+  {0, 0, 0, 0}
+};
+
+static void *world_create(server_startup_st& servers, test_return_t& error)
+{
+  if (HAVE_MEMCACHED_BINARY == 0)
+  {
+    error= TEST_FATAL;
+    return NULL;
+  }
+
+  const char *argv[1]= { "memtouch" };
+  if (not server_startup(servers, "memcached", MEMCACHED_DEFAULT_PORT +10, 1, argv))
+  {
+    error= TEST_FAILURE;
+  }
+
+  return &servers;
+}
+
+
+void get_world(Framework *world)
+{
+  executable= "./clients/memtouch";
+  world->collections= collection;
+  world->_create= world_create;
+}
+
index 898fdb54a73494e9b21403e94e2f365b393c98a8..bfcb08161c558815779f59fac64a480f46b54672 100644 (file)
@@ -99,11 +99,13 @@ static test_return_t __check_host(memcached_st *memc, const scanner_string_st &h
 }
 
 // Check and make sure the prefix_key is what we expect it to be
-static test_return_t __check_namespace(memcached_st *memc, const scanner_string_st &arg)
+static test_return_t __check_namespace(memcached_st *, const scanner_string_st &)
 {
+#if 0
   const char *_namespace = memcached_get_namespace(memc);
   test_true(_namespace);
   test_strcmp(_namespace, arg.c_str);
+#endif
 
   return TEST_SUCCESS;
 }
@@ -645,11 +647,7 @@ test_return_t regression_bug_71231153_poll(memcached_st *)
     char *value= memcached_get(memc, test_literal_param("test"), &value_len, NULL, &rc);
     test_false(value);
     test_zero(value_len);
-#ifdef __APPLE__
-    test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_last_error_message(memc));
-#else
     test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_last_error_message(memc));
-#endif
 
     memcached_free(memc);
   }
index 1b5631d144fc29e6b7a81c2d31fac9b236db86ce..d9d00ad1604713910cc329adeb6d047aefccd83f 100644 (file)
@@ -40,7 +40,7 @@
 /*
   C++ interface test
 */
-#include <libmemcached/memcached.hpp>
+#include <libmemcached-1.0/memcached.hpp>
 #include <libtest/test.hpp>
 
 #include <cstdio>
diff --git a/tests/touch.cc b/tests/touch.cc
new file mode 100644 (file)
index 0000000..50e6a35
--- /dev/null
@@ -0,0 +1,156 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached Client and Server 
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include <libtest/test.hpp>
+
+using namespace libtest;
+
+#include <libmemcached-1.0/memcached.h>
+#include <libmemcachedutil-1.0/util.h>
+
+#include "tests/touch.h"
+
+static test_return_t pre_touch(memcached_st *memc)
+{
+  test_compare(MEMCACHED_SUCCESS, memcached_version(memc));
+  test_skip(true, libmemcached_util_version_check(memc, 1, 4, 8));
+
+  return TEST_SUCCESS;
+}
+
+test_return_t test_memcached_touch(memcached_st *memc)
+{
+
+  test_skip(TEST_SUCCESS, pre_touch(memc));
+
+  size_t len;
+  uint32_t flags;
+  memcached_return rc;
+
+  test_null(memcached_get(memc, 
+                          test_literal_param("touchkey"),
+                          &len, &flags, &rc));
+  test_zero(len);
+  test_compare(MEMCACHED_NOTFOUND, rc);
+
+  test_compare(MEMCACHED_SUCCESS, 
+               memcached_set(memc,
+                             test_literal_param("touchkey"),
+                             test_literal_param("touchval"),
+                             2, 0));
+
+  {
+    char *value= memcached_get(memc, 
+                               test_literal_param("touchkey"),
+                               &len, &flags, &rc);
+    test_compare(8U, test_literal_param_size("touchval"));
+    test_true(value);
+    test_strcmp(value, "touchval");
+    test_compare(MEMCACHED_SUCCESS, rc);
+    free(value);
+  }
+
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_touch(memc, test_literal_param("touchkey"), 60 *60));
+
+  test_skip(false ,memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
+
+  rc= memcached_touch(memc, test_literal_param("touchkey"), 60 *60 *24 *60);
+  test_compare_hint(MEMCACHED_SUCCESS, rc, memcached_last_error_message(memc));
+
+  test_compare(MEMCACHED_NOTFOUND,
+               memcached_exist(memc, test_literal_param("touchkey")));
+
+  return TEST_SUCCESS;
+}
+
+test_return_t test_memcached_touch_by_key(memcached_st *memc)
+{
+
+  test_skip(TEST_SUCCESS, pre_touch(memc));
+
+  size_t len;
+  uint32_t flags;
+  memcached_return rc;
+
+  test_null(memcached_get_by_key(memc, 
+                                 test_literal_param("grouping_key"),
+                                 test_literal_param("touchkey"),
+                                 &len, &flags, &rc));
+  test_zero(len);
+  test_compare(MEMCACHED_NOTFOUND, rc);
+
+  test_compare(MEMCACHED_SUCCESS, 
+               memcached_set_by_key(memc,
+                                    test_literal_param("grouping_key"),
+                                    test_literal_param("touchkey"),
+                                    test_literal_param("touchval"),
+                                    2, 0));
+
+  {
+    char *value= memcached_get_by_key(memc, 
+                                      test_literal_param("grouping_key"),
+                                      test_literal_param("touchkey"),
+                                      &len, &flags, &rc);
+    test_compare(8U, test_literal_param_size("touchval"));
+    test_true(value);
+    test_strcmp(value, "touchval");
+    test_compare(MEMCACHED_SUCCESS, rc);
+    free(value);
+  }
+
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_touch_by_key(memc,
+                                      test_literal_param("grouping_key"),
+                                      test_literal_param("touchkey"),
+                                      60 *60));
+
+  test_skip(false ,memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_touch_by_key(memc,
+                                      test_literal_param("grouping_key"),
+                                      test_literal_param("touchkey"),
+                                      60 *60 *24 *60));
+  test_compare(MEMCACHED_NOTFOUND,
+               memcached_exist_by_key(memc, test_literal_param("grouping_key"),test_literal_param("touchkey")));
+
+  return TEST_SUCCESS;
+}
+
+
+
diff --git a/tests/touch.h b/tests/touch.h
new file mode 100644 (file)
index 0000000..1cf2813
--- /dev/null
@@ -0,0 +1,41 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+test_return_t test_memcached_touch(memcached_st *);
+test_return_t test_memcached_touch_by_key(memcached_st *);
index f81ae3e3ffbc058f149e07c5508472d9e1795565..43e8d9b180d83c5b19436d14e2e2f6c641d1aef3 100644 (file)
@@ -4,8 +4,8 @@
 noinst_HEADERS+= win32/wrappers.h
 
 if BUILD_WIN32_WRAPPERS
+libhashkit_libhashkit_la_LDFLAGS+=-no-undefined
 libmemcached_libmemcached_la_LDFLAGS+=-no-undefined
 libmemcached_libmemcachedprotocol_la_LDFLAGS+=-no-undefined
 libmemcached_libmemcachedutil_la_LDFLAGS+=-no-undefined
-libhashkit_libhashkit_la_LDFLAGS+=-no-undefined
 endif