Rewrite of memcached_behavior_set() to take a uint64_t instead of a pointer.
[awesomized/libmemcached] / lib / memcached_response.c
index 1d0937af7999f6005ba677b798eccf55e32c2808..6f9e7c3341caa1be24830b6ec622ecae6ce7c779 100644 (file)
   from an issued command.
 */
 
-#include <memcached.h>
+#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;
   char *buffer_ptr;
+  unsigned int max_messages;
 
-  memset(buffer, 0, buffer_length);
 
-  buffer_ptr= buffer;
-  while (1)
+  send_length= 0;
+  /* UDP at the moment is odd...*/
+  if (ptr->type == MEMCACHED_CONNECTION_UDP)
   {
-    unsigned int read_length;
-    read_length= read(ptr->hosts[server_key].fd, buffer_ptr, 1);
+    char buffer[8];
+    ssize_t read_length;
 
-    if (read_length != 1)
-      return  MEMCACHED_UNKNOWN_READ_FAILURE;
+    return MEMCACHED_SUCCESS;
 
-    if (*buffer_ptr == '\n')
-      break;
-    else
-      buffer_ptr++;
+    read_length= memcached_io_read(ptr, buffer, 8);
   }
 
-  if (send_length)
-    switch(buffer[0])
+  /* 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)
     {
-    case 'V': /* VALUE */
-      return MEMCACHED_SUCCESS;
-    case 'O': /* OK */
-      return MEMCACHED_SUCCESS;
-    case 'S': /* STORED STATS SERVER_ERROR */
+      ssize_t read_length;
+
+      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)
       {
-        if (buffer[1] == 'T') /* STORED STATS */
-          return MEMCACHED_SUCCESS;
-        else if (buffer[1] == 'E')
-          return MEMCACHED_SERVER_ERROR;
-        else
-          return MEMCACHED_UNKNOWN_READ_FAILURE;
+        memcached_io_reset(ptr);
+        return MEMCACHED_PROTOCOL_ERROR;
       }
-    case 'D': /* DELETED */
+    }
+    buffer_ptr++;
+    *buffer_ptr= 0;
+
+    memcached_server_response_decrement(ptr);
+  }
+
+  switch(buffer[0])
+  {
+  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;
-    case 'N': /* NOT_FOUND */
+    }
+    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 */
       {
-        if (buffer[4] == 'F')
-          return MEMCACHED_NOTFOUND;
-        else if (buffer[4] == 'S')
-          return MEMCACHED_NOTSTORED;
-        else
-          return MEMCACHED_UNKNOWN_READ_FAILURE;
+        memcached_server_response_increment(ptr);
+        return MEMCACHED_STAT;
       }
-    case 'E': /* PROTOCOL ERROR or END */
+      else if (buffer[1] == 'E')
+        return MEMCACHED_SERVER_ERROR;
+      else if (buffer[1] == 'T')
+        return MEMCACHED_STORED;
+      else
       {
-        if (buffer[1] == 'N')
-          return MEMCACHED_NOTFOUND;
-        else if (buffer[1] == 'R')
-          return MEMCACHED_PROTOCOL_ERROR;
-        else
-          return MEMCACHED_UNKNOWN_READ_FAILURE;
+        WATCHPOINT_STRING(buffer);
+        WATCHPOINT_ASSERT(0);
+        memcached_io_reset(ptr);
+        return MEMCACHED_UNKNOWN_READ_FAILURE;
       }
-    case 'C': /* CLIENT ERROR */
-      return MEMCACHED_CLIENT_ERROR;
-    default:
-      return MEMCACHED_UNKNOWN_READ_FAILURE;
     }
+  case 'D': /* DELETED */
+    return MEMCACHED_DELETED;
+  case 'N': /* NOT_FOUND */
+    {
+      if (buffer[4] == 'F')
+        return MEMCACHED_NOTFOUND;
+      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 if (buffer[1] == 'X')
+      {
+        memcached_io_reset(ptr);
+        return MEMCACHED_DATA_EXISTS;
+      }
+      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_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);
 }