Remove exposed C++ namespace.
[awesomized/libmemcached] / libmemcached / response.cc
index 67b0999f7f2afff67e462ec9c2c5a4894577aea8..c01d508942ea8ddb199ff41f1f7c066d44066864 100644 (file)
@@ -38,7 +38,7 @@
 #include <libmemcached/common.h>
 #include <libmemcached/string.hpp>
 
-static memcached_return_t textual_value_fetch(org::libmemcached::Instance* instance,
+static memcached_return_t textual_value_fetch(memcached_instance_st* instance,
                                               char *buffer,
                                               memcached_result_st *result)
 {
@@ -90,9 +90,10 @@ static memcached_return_t textual_value_fetch(org::libmemcached::Instance* insta
   }
 
   for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++) {};
+  errno= 0;
   result->item_flags= (uint32_t) strtoul(next_ptr, &string_ptr, 10);
 
-  if (end_ptr == string_ptr)
+  if (errno != 0 or end_ptr == string_ptr)
   {
     goto read_error;
   }
@@ -105,9 +106,10 @@ static memcached_return_t textual_value_fetch(org::libmemcached::Instance* insta
   }
 
   for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++) {};
+  errno= 0;
   value_length= (size_t)strtoull(next_ptr, &string_ptr, 10);
 
-  if (end_ptr == string_ptr)
+  if (errno != 0 or end_ptr == string_ptr)
   {
     goto read_error;
   }
@@ -122,10 +124,11 @@ static memcached_return_t textual_value_fetch(org::libmemcached::Instance* insta
   {
     string_ptr++;
     for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++) {};
+    errno= 0;
     result->item_cas= strtoull(next_ptr, &string_ptr, 10);
   }
 
-  if (end_ptr < string_ptr)
+  if (errno != 0 or end_ptr < string_ptr)
   {
     goto read_error;
   }
@@ -207,7 +210,7 @@ read_error:
   return MEMCACHED_PARTIAL_READ;
 }
 
-static memcached_return_t textual_read_one_response(org::libmemcached::Instance* instance,
+static memcached_return_t textual_read_one_response(memcached_instance_st* instance,
                                                     char *buffer, const size_t buffer_length,
                                                     memcached_result_st *result)
 {
@@ -238,8 +241,9 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance*
         char *response_ptr= index(buffer, ' ');
 
         char *endptr;
+        errno= 0;
         long int version= strtol(response_ptr, &endptr, 10);
-        if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
+        if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX or version == 0)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
           return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version"));
@@ -247,8 +251,9 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance*
         instance->major_version= uint8_t(version);
 
         endptr++;
+        errno= 0;
         version= strtol(endptr, &endptr, 10);
-        if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
+        if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
           return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version"));
@@ -256,8 +261,9 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance*
         instance->minor_version= uint8_t(version);
 
         endptr++;
+        errno= 0;
         version= strtol(endptr, &endptr, 10);
-        if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
+        if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
           return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
@@ -416,7 +422,17 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance*
           and buffer[6] == '_'
           and buffer[7] == 'E' and buffer[8] == 'R' and buffer[9] == 'R' and buffer[10] == 'O' and buffer[11] == 'R')
       {
-        return MEMCACHED_CLIENT_ERROR;
+        // Move past the basic error message and whitespace
+        char *startptr= buffer + memcached_literal_param_size("CLIENT_ERROR");
+        if (startptr[0] == ' ')
+        {
+          startptr++;
+        }
+
+        char *endptr= startptr;
+        while (*endptr != '\r' && *endptr != '\n') endptr++;
+
+        return memcached_set_error(*instance, MEMCACHED_CLIENT_ERROR, MEMCACHED_AT, startptr, size_t(endptr - startptr));
       }
     }
     break;
@@ -432,6 +448,7 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance*
   case '8': /* INCR/DECR response */
   case '9': /* INCR/DECR response */
     {
+      errno= 0;
       unsigned long long int auto_return_value= strtoull(buffer, (char **)NULL, 10);
 
       if (auto_return_value == ULLONG_MAX and errno == ERANGE)
@@ -446,6 +463,12 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance*
         return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT,
                                    memcached_literal_param("Numeric response was out of range"));
       }
+      else if (errno != 0)
+      {
+        result->numeric_value= UINT64_MAX;
+        return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT,
+                                   memcached_literal_param("Numeric response was out of range"));
+      }
 
       result->numeric_value= uint64_t(auto_return_value);
 
@@ -470,7 +493,7 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance*
                              buffer, total_read);
 }
 
-static memcached_return_t binary_read_one_response(org::libmemcached::Instance* instance,
+static memcached_return_t binary_read_one_response(memcached_instance_st* instance,
                                                    char *buffer, const size_t buffer_length,
                                                    memcached_result_st *result)
 {
@@ -610,8 +633,9 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance*
         }
 
         char *endptr;
+        errno= 0;
         long int version= strtol(version_buffer, &endptr, 10);
-        if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
+        if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX or version == 0)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
           return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version"));
@@ -619,8 +643,9 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance*
         instance->major_version= uint8_t(version);
 
         endptr++;
+        errno= 0;
         version= strtol(endptr, &endptr, 10);
-        if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
+        if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
           return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version"));
@@ -628,8 +653,9 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance*
         instance->minor_version= uint8_t(version);
 
         endptr++;
+        errno= 0;
         version= strtol(endptr, &endptr, 10);
-        if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
+        if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
           return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
@@ -638,6 +664,25 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance*
       }
       break;
 
+    case PROTOCOL_BINARY_CMD_TOUCH:
+      {
+        rc= MEMCACHED_SUCCESS;
+        if (bodylen == 4) // The four byte read is a bug?
+        {
+          char touch_buffer[4]; // @todo document this number
+          rc= memcached_safe_read(instance, touch_buffer, sizeof(touch_buffer));
+#if 0
+          fprintf(stderr, "%s:%d %d %d %d %d %.*s(%d)\n", __FILE__, __LINE__,
+                  int(touch_buffer[0]),
+                  int(touch_buffer[1]),
+                  int(touch_buffer[2]),
+                  int(touch_buffer[3]),
+                  int(bodylen), touch_buffer, int(bodylen));
+#endif
+        }
+        return memcached_set_error(*instance, rc, MEMCACHED_AT);
+      }
+
     case PROTOCOL_BINARY_CMD_FLUSH:
     case PROTOCOL_BINARY_CMD_QUIT:
     case PROTOCOL_BINARY_CMD_SET:
@@ -646,7 +691,6 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance*
     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;
@@ -787,7 +831,7 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance*
   return rc;
 }
 
-static memcached_return_t _read_one_response(org::libmemcached::Instance* instance,
+static memcached_return_t _read_one_response(memcached_instance_st* instance,
                                              char *buffer, const size_t buffer_length,
                                              memcached_result_st *result)
 {
@@ -795,7 +839,7 @@ static memcached_return_t _read_one_response(org::libmemcached::Instance* instan
 
   if (result == NULL)
   {
-    memcached_st *root= (memcached_st *)instance->root;
+    Memcached *root= (Memcached *)instance->root;
     result = &root->result;
   }
 
@@ -817,7 +861,7 @@ static memcached_return_t _read_one_response(org::libmemcached::Instance* instan
   return rc;
 }
 
-memcached_return_t memcached_read_one_response(org::libmemcached::Instance* instance,
+memcached_return_t memcached_read_one_response(memcached_instance_st* instance,
                                                memcached_result_st *result)
 {
   char buffer[SMALL_STRING_LEN];
@@ -831,7 +875,7 @@ memcached_return_t memcached_read_one_response(org::libmemcached::Instance* inst
   return _read_one_response(instance, buffer, sizeof(buffer), result);
 }
 
-memcached_return_t memcached_response(org::libmemcached::Instance* instance,
+memcached_return_t memcached_response(memcached_instance_st* instance,
                                       memcached_result_st *result)
 {
   char buffer[1024];
@@ -839,7 +883,7 @@ memcached_return_t memcached_response(org::libmemcached::Instance* instance,
   return memcached_response(instance, buffer, sizeof(buffer), result);
 }
 
-memcached_return_t memcached_response(org::libmemcached::Instance* instance,
+memcached_return_t memcached_response(memcached_instance_st* instance,
                                       char *buffer, size_t buffer_length,
                                       memcached_result_st *result)
 {