2 #include "memcached_io.h"
4 memcached_return
value_fetch(memcached_server_st
*ptr
,
6 memcached_result_st
*result
)
8 memcached_return rc
= MEMCACHED_SUCCESS
;
17 if (ptr
->root
->flags
& MEM_USE_UDP
)
18 return MEMCACHED_NOT_SUPPORTED
;
20 WATCHPOINT_ASSERT(ptr
->root
);
21 end_ptr
= buffer
+ MEMCACHED_DEFAULT_COMMAND_SIZE
;
23 memcached_result_reset(result
);
26 string_ptr
+= 6; /* "VALUE " */
35 result
->key_length
= 0;
37 for (prefix_length
= ptr
->root
->prefix_key_length
; !(iscntrl(*string_ptr
) || isspace(*string_ptr
)) ; string_ptr
++)
39 if (prefix_length
== 0)
48 result
->key
[result
->key_length
]= 0;
51 if (end_ptr
== string_ptr
)
54 /* Flags fetch move past space */
56 if (end_ptr
== string_ptr
)
58 for (next_ptr
= string_ptr
; isdigit(*string_ptr
); string_ptr
++);
59 result
->flags
= strtoul(next_ptr
, &string_ptr
, 10);
61 if (end_ptr
== string_ptr
)
64 /* Length fetch move past space*/
66 if (end_ptr
== string_ptr
)
69 for (next_ptr
= string_ptr
; isdigit(*string_ptr
); string_ptr
++);
70 value_length
= (size_t)strtoull(next_ptr
, &string_ptr
, 10);
72 if (end_ptr
== string_ptr
)
76 if (*string_ptr
== '\r')
78 /* Skip past the \r\n */
84 for (next_ptr
= string_ptr
; isdigit(*string_ptr
); string_ptr
++);
85 result
->cas
= strtoull(next_ptr
, &string_ptr
, 10);
88 if (end_ptr
< string_ptr
)
91 /* We add two bytes so that we can walk the \r\n */
92 rc
= memcached_string_check(&result
->value
, value_length
+2);
93 if (rc
!= MEMCACHED_SUCCESS
)
96 return MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
99 value_ptr
= memcached_string_value(&result
->value
);
102 We read the \r\n into the string since not doing so is more
103 cycles then the waster of memory to do so.
105 We are null terminating through, which will most likely make
106 some people lazy about using the return length.
108 to_read
= (value_length
) + 2;
109 read_length
= memcached_io_read(ptr
, value_ptr
, to_read
);
110 if (read_length
!= (size_t)(value_length
+ 2))
115 /* This next bit blows the API, but this is internal....*/
118 char_ptr
= memcached_string_value(&result
->value
);;
119 char_ptr
[value_length
]= 0;
120 char_ptr
[value_length
+ 1]= 0;
121 memcached_string_set_length(&result
->value
, value_length
);
124 return MEMCACHED_SUCCESS
;
127 memcached_io_reset(ptr
);
129 return MEMCACHED_PARTIAL_READ
;
132 char *memcached_fetch(memcached_st
*ptr
, char *key
, size_t *key_length
,
133 size_t *value_length
,
135 memcached_return
*error
)
137 memcached_result_st
*result_buffer
= &ptr
->result
;
139 if (ptr
->flags
& MEM_USE_UDP
)
141 *error
= MEMCACHED_NOT_SUPPORTED
;
145 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
147 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
149 if (memcached_server_response_count(&ptr
->hosts
[ptr
->cursor_server
]) == 0)
151 ptr
->cursor_server
++;
155 *error
= memcached_response(&ptr
->hosts
[ptr
->cursor_server
], buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, result_buffer
);
157 if (*error
== MEMCACHED_END
) /* END means that we move on to the next */
159 memcached_server_response_reset(&ptr
->hosts
[ptr
->cursor_server
]);
160 ptr
->cursor_server
++;
163 else if (*error
== MEMCACHED_SUCCESS
)
165 *value_length
= memcached_string_length(&result_buffer
->value
);
169 strncpy(key
, result_buffer
->key
, result_buffer
->key_length
);
170 *key_length
= result_buffer
->key_length
;
173 if (result_buffer
->flags
)
174 *flags
= result_buffer
->flags
;
178 return memcached_string_c_copy(&result_buffer
->value
);
187 ptr
->cursor_server
= 0;
192 memcached_result_st
*memcached_fetch_result(memcached_st
*ptr
,
193 memcached_result_st
*result
,
194 memcached_return
*error
)
197 if (ptr
->flags
& MEM_USE_UDP
)
199 *error
= MEMCACHED_NOT_SUPPORTED
;
204 result
= memcached_result_create(ptr
, NULL
);
207 if (ptr
->flags
& MEM_NO_BLOCK
)
208 memcached_io_preread(ptr
);
211 while (ptr
->cursor_server
< ptr
->number_of_hosts
)
213 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
215 if (memcached_server_response_count(&ptr
->hosts
[ptr
->cursor_server
]) == 0)
217 ptr
->cursor_server
++;
221 *error
= memcached_response(&ptr
->hosts
[ptr
->cursor_server
], buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, result
);
223 if (*error
== MEMCACHED_END
) /* END means that we move on to the next */
225 memcached_server_response_reset(&ptr
->hosts
[ptr
->cursor_server
]);
226 ptr
->cursor_server
++;
229 else if (*error
== MEMCACHED_SUCCESS
)
235 /* We have completed reading data */
236 if (result
->is_allocated
)
237 memcached_result_free(result
);
239 memcached_string_reset(&result
->value
);
241 ptr
->cursor_server
= 0;