Added behavior method around testing of keys.
[m6w6/libmemcached] / lib / memcached_response.c
index 10547504743c476956ade3a7a5ebfe664f44aa4c..33dc0b1e5bfd41d9c28bb41d061028ab313fa619 100644 (file)
@@ -8,9 +8,9 @@
 #include "common.h"
 #include "memcached_io.h"
 
-memcached_return memcached_response(memcached_st *ptr, 
+memcached_return memcached_response(memcached_server_st *ptr, 
                                     char *buffer, size_t buffer_length,
-                                    unsigned int server_key)
+                                    memcached_result_st *result)
 {
   unsigned int x;
   size_t send_length;
@@ -18,50 +18,109 @@ memcached_return memcached_response(memcached_st *ptr,
   unsigned int max_messages;
 
 
-  memset(buffer, 0, buffer_length);
   send_length= 0;
+  /* UDP at the moment is odd...*/
+  if (ptr->type == MEMCACHED_CONNECTION_UDP)
+  {
+    char buffer[8];
+    ssize_t read_length;
+
+    return MEMCACHED_SUCCESS;
 
-  max_messages= memcached_server_response_count(ptr, server_key);
-  for (x= 0; x <=  max_messages; x++)
+    read_length= memcached_io_read(ptr, buffer, 8);
+  }
+
+  /* We may have old commands in the buffer not set, first purge */
+  if (ptr->root->flags & MEM_NO_BLOCK)
+    (void)memcached_io_write(ptr, NULL, 0, 1);
+
+  max_messages= memcached_server_response_count(ptr);
+  for (x= 0; x <  max_messages; x++)
   {
+    size_t total_length= 0;
     buffer_ptr= buffer;
 
+
     while (1)
     {
-      unsigned int read_length;
+      ssize_t read_length;
 
-      read_length= memcached_io_read(ptr, server_key,
-                                     buffer_ptr, 1);
+      read_length= memcached_io_read(ptr, buffer_ptr, 1);
+      WATCHPOINT_ASSERT(isgraph(*buffer_ptr) || isspace(*buffer_ptr));
 
       if (read_length != 1)
+      {
+        memcached_io_reset(ptr);
         return  MEMCACHED_UNKNOWN_READ_FAILURE;
+      }
 
       if (*buffer_ptr == '\n')
         break;
       else
         buffer_ptr++;
+
+      total_length++;
+      WATCHPOINT_ASSERT(total_length <= buffer_length);
+
+      if (total_length >= buffer_length)
+      {
+        memcached_io_reset(ptr);
+        return MEMCACHED_PROTOCOL_ERROR;
+      }
     }
+    buffer_ptr++;
+    *buffer_ptr= 0;
 
-    if (memcached_server_response_count(ptr, server_key))
-      memcached_server_response_decrement(ptr, server_key);
+    memcached_server_response_decrement(ptr);
   }
 
   switch(buffer[0])
   {
-  case 'V': /* VALUE */
-    return MEMCACHED_SUCCESS;
+  case 'V': /* VALUE || VERSION */
+    if (buffer[1] == 'A') /* VALUE */
+    {
+      memcached_return rc;
+
+      /* We add back in one because we will need to search for END */
+      memcached_server_response_increment(ptr);
+      if (result)
+        rc= value_fetch(ptr, buffer, result);
+      else
+        rc= value_fetch(ptr, buffer, &ptr->root->result);
+
+      return rc;
+    }
+    else if (buffer[1] == 'E') /* VERSION */
+    {
+      return MEMCACHED_SUCCESS;
+    }
+    else
+    {
+      WATCHPOINT_STRING(buffer);
+      WATCHPOINT_ASSERT(0);
+      memcached_io_reset(ptr);
+      return MEMCACHED_UNKNOWN_READ_FAILURE;
+    }
   case 'O': /* OK */
     return MEMCACHED_SUCCESS;
   case 'S': /* STORED STATS SERVER_ERROR */
     {
       if (buffer[2] == 'A') /* STORED STATS */
+      {
+        memcached_server_response_increment(ptr);
         return MEMCACHED_STAT;
+      }
       else if (buffer[1] == 'E')
         return MEMCACHED_SERVER_ERROR;
       else if (buffer[1] == 'T')
         return MEMCACHED_STORED;
       else
+      {
+        WATCHPOINT_STRING(buffer);
+        WATCHPOINT_ASSERT(0);
+        memcached_io_reset(ptr);
         return MEMCACHED_UNKNOWN_READ_FAILURE;
+      }
     }
   case 'D': /* DELETED */
     return MEMCACHED_DELETED;
@@ -72,23 +131,46 @@ memcached_return memcached_response(memcached_st *ptr,
       else if (buffer[4] == 'S')
         return MEMCACHED_NOTSTORED;
       else
+      {
+        memcached_io_reset(ptr);
         return MEMCACHED_UNKNOWN_READ_FAILURE;
+      }
     }
   case 'E': /* PROTOCOL ERROR or END */
     {
       if (buffer[1] == 'N')
         return MEMCACHED_END;
       else if (buffer[1] == 'R')
+      {
+        memcached_io_reset(ptr);
         return MEMCACHED_PROTOCOL_ERROR;
+      }
       else
+      {
+        memcached_io_reset(ptr);
         return MEMCACHED_UNKNOWN_READ_FAILURE;
+      }
     }
   case 'C': /* CLIENT ERROR */
+    memcached_io_reset(ptr);
     return MEMCACHED_CLIENT_ERROR;
   default:
+    memcached_io_reset(ptr);
     return MEMCACHED_UNKNOWN_READ_FAILURE;
 
   }
 
   return MEMCACHED_SUCCESS;
 }
+
+char *memcached_result_value(memcached_result_st *ptr)
+{
+  memcached_string_st *sptr= &ptr->value;
+  return memcached_string_value(sptr);
+}
+
+size_t memcached_result_length(memcached_result_st *ptr)
+{
+  memcached_string_st *sptr= &ptr->value;
+  return memcached_string_length(sptr);
+}