2 #include "memcached_io.h"
4 static memcached_return
memcached_value_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
5 memcached_string_st
*value
,
8 unsigned int server_key
)
11 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
15 end_ptr
= buffer
+ MEMCACHED_DEFAULT_COMMAND_SIZE
;
20 memcached_string_reset(value
);
22 rc
= memcached_response(ptr
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, server_key
);
25 if (rc
== MEMCACHED_SUCCESS
)
31 string_ptr
+= 6; /* "VALUE " */
38 for (; isgraph(*string_ptr
); string_ptr
++)
45 else /* Skip characters */
46 for (; isgraph(*string_ptr
); string_ptr
++);
48 if (end_ptr
== string_ptr
)
51 /* Flags fetch move past space */
53 if (end_ptr
== string_ptr
)
55 for (next_ptr
= string_ptr
; isdigit(*string_ptr
); string_ptr
++);
57 *flags
= (uint32_t)strtol(next_ptr
, &string_ptr
, 10);
59 if (end_ptr
== string_ptr
)
62 /* Length fetch move past space*/
64 if (end_ptr
== string_ptr
)
67 for (next_ptr
= string_ptr
; isdigit(*string_ptr
); string_ptr
++);
68 value_length
= (size_t)strtoll(next_ptr
, &string_ptr
, 10);
70 if (end_ptr
== string_ptr
)
74 if (*string_ptr
== '\r')
76 /* Skip past the \r\n */
82 for (next_ptr
= string_ptr
; isdigit(*string_ptr
); string_ptr
++);
84 *cas
= (size_t)strtoll(next_ptr
, &string_ptr
, 10);
87 if (end_ptr
< string_ptr
)
96 /* We add two bytes so that we can walk the \r\n */
97 rc
= memcached_string_check(value
, value_length
+2);
98 if (rc
!= MEMCACHED_SUCCESS
)
101 return MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
104 value_ptr
= memcached_string_value(value
);
107 We read the \r\n into the string since not doing so is more
108 cycles then the waster of memory to do so.
110 We are null terminating through, which will most likely make
111 some people lazy about using the return length.
113 to_read
= (value_length
) + 2;
115 read_length
= memcached_io_read(ptr
, server_key
,
118 if (read_length
!= (size_t)(value_length
+ 2))
123 /* This next bit blows the API, but this is internal....*/
126 char_ptr
= memcached_string_value(value
);;
127 char_ptr
[value_length
]= 0;
128 char_ptr
[value_length
+ 1]= 0;
129 memcached_string_set_length(value
, value_length
);
132 return MEMCACHED_SUCCESS
;
139 return MEMCACHED_PARTIAL_READ
;
142 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
143 size_t *value_length
,
145 memcached_return
*error
)
147 memcached_string_st
*result_buffer
;
148 result_buffer
= &ptr
->result_buffer
;
150 if (ptr
->flags
& MEM_NO_BLOCK
)
151 memcached_io_preread(ptr
);
153 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
155 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
157 ptr
->cursor_server
++;
161 *error
= memcached_value_fetch(ptr
, key
, key_length
, result_buffer
,
162 flags
, NULL
, ptr
->cursor_server
);
163 *value_length
= memcached_string_length(result_buffer
);
165 if (*error
== MEMCACHED_END
) /* END means that we move on to the next */
167 ptr
->hosts
[ptr
->cursor_server
].cursor_active
= 0;
168 ptr
->cursor_server
++;
171 else if (*error
== MEMCACHED_SUCCESS
)
172 return memcached_string_c_copy(result_buffer
);
177 ptr
->cursor_server
= 0;
182 memcached_result_st
*memcached_fetch_result(memcached_st
*ptr
,
183 memcached_result_st
*result
,
184 memcached_return
*error
)
187 result
= memcached_result_create(ptr
, NULL
);
189 WATCHPOINT_ASSERT(result
->value
.is_allocated
!= MEMCACHED_USED
);
191 if (ptr
->flags
& MEM_NO_BLOCK
)
192 memcached_io_preread(ptr
);
194 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
196 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
198 ptr
->cursor_server
++;
202 result
->cas
= 0; /* We do this so we do not send in any junk */
203 *error
= memcached_value_fetch(ptr
, result
->key
, &result
->key_length
,
209 if (*error
== MEMCACHED_END
) /* END means that we move on to the next */
211 ptr
->hosts
[ptr
->cursor_server
].cursor_active
= 0;
212 ptr
->cursor_server
++;
215 else if (*error
== MEMCACHED_SUCCESS
)
221 /* We have completed reading data */
222 if (result
->is_allocated
== MEMCACHED_ALLOCATED
)
223 memcached_result_free(result
);
225 memcached_string_reset(&result
->value
);
227 ptr
->cursor_server
= 0;
231 memcached_return
memcached_finish_server(memcached_st
*ptr
, unsigned int server_key
)
234 memcached_string_st
*result_buffer
;
236 result_buffer
= &ptr
->result_buffer
;
238 rc
= MEMCACHED_SUCCESS
;
239 while (rc
== MEMCACHED_SUCCESS
)
241 rc
= memcached_value_fetch(ptr
, NULL
, NULL
, result_buffer
,
242 NULL
, NULL
, server_key
);
244 ptr
->hosts
[server_key
].cursor_active
= 0;
249 void memcached_finish(memcached_st
*ptr
)
253 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
255 if (ptr
->hosts
[x
].cursor_active
)
256 (void)memcached_finish_server(ptr
, x
);
259 ptr
->cursor_server
= 0;