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
);
24 if (rc
== MEMCACHED_SUCCESS
)
30 string_ptr
+= 6; /* "VALUE " */
37 for (; isgraph(*string_ptr
); string_ptr
++)
44 else /* Skip characters */
45 for (; isgraph(*string_ptr
); string_ptr
++);
47 if (end_ptr
== string_ptr
)
50 /* Flags fetch move past space */
52 if (end_ptr
== string_ptr
)
54 for (next_ptr
= string_ptr
; isdigit(*string_ptr
); string_ptr
++);
56 *flags
= (uint32_t)strtol(next_ptr
, &string_ptr
, 10);
58 if (end_ptr
== string_ptr
)
61 /* Length fetch move past space*/
63 if (end_ptr
== string_ptr
)
66 for (next_ptr
= string_ptr
; isdigit(*string_ptr
); string_ptr
++);
67 value_length
= (size_t)strtoll(next_ptr
, &string_ptr
, 10);
69 if (end_ptr
== string_ptr
)
73 if (*string_ptr
== '\r')
75 /* Skip past the \r\n */
81 for (next_ptr
= string_ptr
; isdigit(*string_ptr
); string_ptr
++);
83 *cas
= (size_t)strtoll(next_ptr
, &string_ptr
, 10);
86 if (end_ptr
< string_ptr
)
95 /* We add two bytes so that we can walk the \r\n */
96 rc
= memcached_string_check(value
, value_length
+2);
97 if (rc
!= MEMCACHED_SUCCESS
)
100 return MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
103 value_ptr
= memcached_string_value(value
);
106 We read the \r\n into the string since not doing so is more
107 cycles then the waster of memory to do so.
109 We are null terminating through, which will most likely make
110 some people lazy about using the return length.
112 to_read
= (value_length
) + 2;
114 read_length
= memcached_io_read(ptr
, server_key
,
117 if (read_length
!= (size_t)(value_length
+ 2))
122 /* This next bit blows the API, but this is internal....*/
125 char_ptr
= memcached_string_value(value
);;
126 char_ptr
[value_length
]= 0;
127 char_ptr
[value_length
+ 1]= 0;
128 memcached_string_set_length(value
, value_length
);
131 return MEMCACHED_SUCCESS
;
138 return MEMCACHED_PARTIAL_READ
;
141 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
142 size_t *value_length
,
144 memcached_return
*error
)
146 memcached_string_st
*result_buffer
;
147 result_buffer
= &ptr
->result_buffer
;
149 if (ptr
->flags
& MEM_NO_BLOCK
)
150 memcached_io_preread(ptr
);
152 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
154 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
156 ptr
->cursor_server
++;
160 *error
= memcached_value_fetch(ptr
, key
, key_length
, result_buffer
,
161 flags
, NULL
, ptr
->cursor_server
);
162 *value_length
= memcached_string_length(result_buffer
);
164 if (*error
== MEMCACHED_END
) /* END means that we move on to the next */
166 ptr
->hosts
[ptr
->cursor_server
].cursor_active
= 0;
167 ptr
->cursor_server
++;
170 else if (*error
== MEMCACHED_SUCCESS
)
171 return memcached_string_c_copy(result_buffer
);
176 ptr
->cursor_server
= 0;
181 memcached_result_st
*memcached_fetch_result(memcached_st
*ptr
,
182 memcached_result_st
*result
,
183 memcached_return
*error
)
186 result
= memcached_result_create(ptr
, NULL
);
188 WATCHPOINT_ASSERT(result
->value
.is_allocated
!= MEMCACHED_USED
);
190 if (ptr
->flags
& MEM_NO_BLOCK
)
191 memcached_io_preread(ptr
);
193 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
195 if (!ptr
->hosts
[ptr
->cursor_server
].cursor_active
)
197 ptr
->cursor_server
++;
201 result
->cas
= 0; /* We do this so we do not send in any junk */
202 *error
= memcached_value_fetch(ptr
, result
->key
, &result
->key_length
,
208 if (*error
== MEMCACHED_END
) /* END means that we move on to the next */
210 ptr
->hosts
[ptr
->cursor_server
].cursor_active
= 0;
211 ptr
->cursor_server
++;
214 else if (*error
== MEMCACHED_SUCCESS
)
220 /* We have completed reading data */
221 if (result
->is_allocated
== MEMCACHED_ALLOCATED
)
222 memcached_result_free(result
);
224 memcached_string_reset(&result
->value
);
226 ptr
->cursor_server
= 0;
230 memcached_return
memcached_finish_server(memcached_st
*ptr
, unsigned int server_key
)
233 memcached_string_st
*result_buffer
;
235 result_buffer
= &ptr
->result_buffer
;
237 rc
= MEMCACHED_SUCCESS
;
238 while (rc
== MEMCACHED_SUCCESS
)
240 rc
= memcached_value_fetch(ptr
, NULL
, NULL
, result_buffer
,
241 NULL
, NULL
, server_key
);
243 ptr
->hosts
[server_key
].cursor_active
= 0;
248 void memcached_finish(memcached_st
*ptr
)
252 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
254 if (ptr
->hosts
[x
].cursor_active
)
255 (void)memcached_finish_server(ptr
, x
);
258 ptr
->cursor_server
= 0;