Fix for connect() to invalidate socket on failure.
[m6w6/libmemcached] / lib / memcached_response.c
1 /*
2 Memcached library
3
4 memcached_response() is used to determine the return result
5 from an issued command.
6 */
7
8 #include "common.h"
9 #include "memcached_io.h"
10
11 memcached_return memcached_response(memcached_st *ptr,
12 char *buffer, size_t buffer_length,
13 memcached_result_st *result,
14 unsigned int server_key)
15 {
16 unsigned int x;
17 size_t send_length;
18 char *buffer_ptr;
19 unsigned int max_messages;
20
21
22 send_length= 0;
23
24 /* We may have old commands in the buffer not set, first purge */
25 if (ptr->flags & MEM_NO_BLOCK)
26 (void)memcached_io_write(ptr, server_key, NULL, 0, 1);
27
28 max_messages= memcached_server_response_count(ptr, server_key);
29 for (x= 0; x < max_messages; x++)
30 {
31 size_t total_length= 0;
32 buffer_ptr= buffer;
33
34 while (1)
35 {
36 unsigned int read_length;
37
38 read_length= memcached_io_read(ptr, server_key,
39 buffer_ptr, 1);
40
41 if (read_length != 1)
42 return MEMCACHED_UNKNOWN_READ_FAILURE;
43
44 if (*buffer_ptr == '\n')
45 break;
46 else
47 buffer_ptr++;
48
49 total_length++;
50 WATCHPOINT_ASSERT(total_length <= buffer_length);
51
52 if (total_length >= buffer_length)
53 return MEMCACHED_PROTOCOL_ERROR;
54 }
55 buffer_ptr++;
56 *buffer_ptr= 0;
57
58 memcached_server_response_decrement(ptr, server_key);
59 }
60
61 switch(buffer[0])
62 {
63 case 'V': /* VALUE || VERSION */
64 if (buffer[1] == 'A') /* VALUE */
65 {
66 memcached_return rc;
67
68 /* We add back in one because we will need to search for END */
69 memcached_server_response_increment(ptr, server_key);
70 if (result)
71 rc= value_fetch(ptr, buffer, result, server_key);
72 else
73 rc= value_fetch(ptr, buffer, &ptr->result, server_key);
74
75 return rc;
76 }
77 else if (buffer[1] == 'E') /* VERSION */
78 {
79 return MEMCACHED_SUCCESS;
80 }
81 else
82 {
83 WATCHPOINT_STRING(buffer);
84 WATCHPOINT_ASSERT(0);
85 return MEMCACHED_UNKNOWN_READ_FAILURE;
86 }
87 case 'O': /* OK */
88 return MEMCACHED_SUCCESS;
89 case 'S': /* STORED STATS SERVER_ERROR */
90 {
91 if (buffer[2] == 'A') /* STORED STATS */
92 {
93 memcached_server_response_increment(ptr, server_key);
94 return MEMCACHED_STAT;
95 }
96 else if (buffer[1] == 'E')
97 return MEMCACHED_SERVER_ERROR;
98 else if (buffer[1] == 'T')
99 return MEMCACHED_STORED;
100 else
101 {
102 WATCHPOINT_STRING(buffer);
103 WATCHPOINT_ASSERT(0);
104 return MEMCACHED_UNKNOWN_READ_FAILURE;
105 }
106 }
107 case 'D': /* DELETED */
108 return MEMCACHED_DELETED;
109 case 'N': /* NOT_FOUND */
110 {
111 if (buffer[4] == 'F')
112 return MEMCACHED_NOTFOUND;
113 else if (buffer[4] == 'S')
114 return MEMCACHED_NOTSTORED;
115 else
116 return MEMCACHED_UNKNOWN_READ_FAILURE;
117 }
118 case 'E': /* PROTOCOL ERROR or END */
119 {
120 if (buffer[1] == 'N')
121 return MEMCACHED_END;
122 else if (buffer[1] == 'R')
123 return MEMCACHED_PROTOCOL_ERROR;
124 else
125 return MEMCACHED_UNKNOWN_READ_FAILURE;
126 }
127 case 'C': /* CLIENT ERROR */
128 return MEMCACHED_CLIENT_ERROR;
129 default:
130 return MEMCACHED_UNKNOWN_READ_FAILURE;
131
132 }
133
134 return MEMCACHED_SUCCESS;
135 }
136
137 char *memcached_result_value(memcached_result_st *ptr)
138 {
139 memcached_string_st *sptr= &ptr->value;
140 return memcached_string_value(sptr);
141 }
142
143 size_t memcached_result_length(memcached_result_st *ptr)
144 {
145 memcached_string_st *sptr= &ptr->value;
146 return memcached_string_length(sptr);
147 }