upon success and NULL will be returned on failure. MEMCACHD_END is returned
by the *error value when all objects that have been found are returned.
The final value upon MEMCACHED_END is null. Values returned by
-memcached_fetch() musted be free'ed by the caller.
+memcached_fetch() musted be free'ed by the caller. memcached_fetch() will
+be DEPRECATED in the near future, memcached_fetch_result() should be used
+instead.
memcached_fetch_result() is used to return a memcached_result_st(3) structure
from a memcached server. The result object is forward compatible with changes
memcached_get() and memcached_fetch() will return NULL on error. You must
look at the value of error to determine what the actual error was.
+MEMCACHED_KEY_TOO_BIG is set to error whenever memcached_fetch() was used
+and the key was set larger then MEMCACHED_MAX_KEY, which was the largest
+key allowed for the original memcached ascii server.
+
=head1 HOME
To find out more information please check:
MEMCACHED_UNKNOWN_STAT_KEY,
MEMCACHED_E2BIG,
MEMCACHED_INVALID_ARGUMENTS,
+ MEMCACHED_KEY_TOO_BIG,
MEMCACHED_MAXIMUM_RETURN /* Always add new error code before */
} memcached_return_t;
if (key)
{
- strncpy(key, result_buffer->key, result_buffer->key_length);
+ if (result_buffer->key_length > MEMCACHED_MAX_KEY)
+ {
+ *error= MEMCACHED_KEY_TOO_BIG;
+ *value_length= 0;
+
+ return NULL;
+ }
+ strncpy(key, result_buffer->item_key, result_buffer->key_length); // For the binary protocol we will cut off the key :(
*key_length= result_buffer->key_length;
}
- if (result_buffer->flags)
- *flags= result_buffer->flags;
+ if (result_buffer->item_flags)
+ *flags= result_buffer->item_flags;
else
*flags= 0;
char *key;
size_t prefix_length;
- key= result->key;
+ key= result->item_key;
result->key_length= 0;
for (prefix_length= ptr->root->prefix_key_length; !(iscntrl(*string_ptr) || isspace(*string_ptr)) ; string_ptr++)
else
prefix_length--;
}
- result->key[result->key_length]= 0;
+ result->item_key[result->key_length]= 0;
}
if (end_ptr == string_ptr)
if (end_ptr == string_ptr)
goto read_error;
for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
- result->flags= (uint32_t) strtoul(next_ptr, &string_ptr, 10);
+ result->item_flags= (uint32_t) strtoul(next_ptr, &string_ptr, 10);
if (end_ptr == string_ptr)
goto read_error;
{
string_ptr++;
for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
- result->cas= strtoull(next_ptr, &string_ptr, 10);
+ result->item_cas= strtoull(next_ptr, &string_ptr, 10);
}
if (end_ptr < string_ptr)
{
uint16_t keylen= header.response.keylen;
memcached_result_reset(result);
- result->cas= header.response.cas;
+ result->item_cas= header.response.cas;
- if (memcached_safe_read(ptr, &result->flags,
- sizeof (result->flags)) != MEMCACHED_SUCCESS)
+ if (memcached_safe_read(ptr, &result->item_flags,
+ sizeof (result->item_flags)) != MEMCACHED_SUCCESS)
return MEMCACHED_UNKNOWN_READ_FAILURE;
- result->flags= ntohl(result->flags);
+ result->item_flags= ntohl(result->item_flags);
bodylen -= header.response.extlen;
result->key_length= keylen;
- if (memcached_safe_read(ptr, result->key, keylen) != MEMCACHED_SUCCESS)
+ if (memcached_safe_read(ptr, result->item_key, keylen) != MEMCACHED_SUCCESS)
return MEMCACHED_UNKNOWN_READ_FAILURE;
bodylen -= keylen;
*/
#include "common.h"
-memcached_result_st *memcached_result_create(memcached_st *memc,
+static inline void _result_init(memcached_result_st *self,
+ const memcached_st *memc)
+{
+ self->item_flags= 0;
+ self->item_expiration= 0;
+ self->key_length= 0;
+ self->item_cas= 0;
+ self->root= memc;
+ self->item_key[0]= 0;
+}
+
+memcached_result_st *memcached_result_create(const memcached_st *memc,
memcached_result_st *ptr)
{
WATCHPOINT_ASSERT(memc);
/* Saving malloc calls :) */
if (ptr)
{
- memset(ptr, 0, sizeof(memcached_result_st));
+ ptr->options.is_allocated= false;
}
else
{
- ptr= libmemcached_calloc(memc, 1, sizeof(memcached_result_st));
+ ptr= libmemcached_malloc(memc, sizeof(memcached_result_st));
if (ptr == NULL)
return NULL;
+
ptr->options.is_allocated= true;
}
ptr->options.is_initialized= true;
+ _result_init(ptr, memc);
+
ptr->root= memc;
memcached_string_create(memc, &ptr->value, 0);
WATCHPOINT_ASSERT_INITIALIZED(&ptr->value);
{
ptr->key_length= 0;
memcached_string_reset(&ptr->value);
- ptr->flags= 0;
- ptr->cas= 0;
- ptr->expiration= 0;
+ ptr->item_flags= 0;
+ ptr->item_cas= 0;
+ ptr->item_expiration= 0;
}
void memcached_result_free(memcached_result_st *ptr)
#endif
struct memcached_result_st {
+ uint32_t item_flags;
+ time_t item_expiration;
+ size_t key_length;
+ uint64_t item_cas;
+ const memcached_st *root;
+ memcached_string_st value;
+ char item_key[MEMCACHED_MAX_KEY];
struct {
bool is_allocated:1;
bool is_initialized:1;
} options;
- uint32_t flags;
- time_t expiration;
- memcached_st *root;
- size_t key_length;
- uint64_t cas;
- memcached_string_st value;
- char key[MEMCACHED_MAX_KEY];
/* Add result callback function */
};
/* Result Struct */
LIBMEMCACHED_API
void memcached_result_free(memcached_result_st *result);
+
LIBMEMCACHED_API
void memcached_result_reset(memcached_result_st *ptr);
+
LIBMEMCACHED_API
-memcached_result_st *memcached_result_create(memcached_st *ptr,
+memcached_result_st *memcached_result_create(const memcached_st *ptr,
memcached_result_st *result);
static inline const char *memcached_result_key_value(const memcached_result_st *self)
{
- return self->key;
+ return self->key_length ? self->item_key : NULL;
}
static inline size_t memcached_result_key_length(const memcached_result_st *self)
static inline uint32_t memcached_result_flags(const memcached_result_st *self)
{
- return self->flags;
+ return self->item_flags;
}
static inline uint64_t memcached_result_cas(const memcached_result_st *self)
{
- return self->cas;
+ return self->item_cas;
}
static inline memcached_return_t memcached_result_set_value(memcached_result_st *ptr, const char *value, size_t length)
static inline void memcached_result_set_flags(memcached_result_st *self, uint32_t flags)
{
- self->flags= flags;
+ self->item_flags= flags;
}
static inline void memcached_result_set_expiration(memcached_result_st *self, time_t expiration)
{
- self->expiration= expiration;
+ self->item_expiration= expiration;
}
#ifdef __cplusplus
char **list;
size_t length= sizeof(memcached_stat_keys);
- list= libmemcached_malloc(memc_stat && memc_stat->root
- ? memc_stat->root
- : ptr,
- length);
+ (void)memc_stat;
- if (!list)
+ list= libmemcached_malloc(ptr, length);
+
+ if (! list)
{
*error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
return NULL;
return "ITEM TOO BIG";
case MEMCACHED_INVALID_ARGUMENTS:
return "INVALID ARGUMENTS";
+ case MEMCACHED_KEY_TOO_BIG:
+ return "KEY RETURNED FROM SERVER WAS TOO LARGE";
case MEMCACHED_MAXIMUM_RETURN:
return "Gibberish returned!";
default:
self->end= self->string= NULL;
}
-memcached_string_st *memcached_string_create(memcached_st *memc, memcached_string_st *self, size_t initial_size)
+memcached_string_st *memcached_string_create(const memcached_st *memc, memcached_string_st *self, size_t initial_size)
{
memcached_return_t rc;
#define memcached_string_value(A) (A)->string
LIBMEMCACHED_LOCAL
-memcached_string_st *memcached_string_create(memcached_st *ptr,
+memcached_string_st *memcached_string_create(const memcached_st *ptr,
memcached_string_st *string,
size_t initial_size);
LIBMEMCACHED_LOCAL
4269430871U, 610793021U, 527273862U, 1437122909U,
2300930706U, 2943759320U, 674306647U, 2400528935U,
54481931U, 4186304426U, 1741088401U, 2979625118U,
- 4159057246U, 3425930182U, 2593724503U};
+ 4159057246U, 3425930182U, 2593724503U, 1868899624U};
// You have updated the memcache_error messages but not updated docs/tests.
- test_true(MEMCACHED_MAXIMUM_RETURN == 39);
+ test_true(MEMCACHED_MAXIMUM_RETURN == 40);
for (rc= MEMCACHED_SUCCESS; rc < MEMCACHED_MAXIMUM_RETURN; rc++)
{
uint32_t hash_val;
const char *msg= memcached_strerror(memc, rc);
hash_val= memcached_generate_hash_value(msg, strlen(msg),
MEMCACHED_HASH_JENKINS);
+ if (values[rc] != hash_val)
+ {
+ fprintf(stderr, "\n\nYou have updated memcached_return_t without updating the error_test\n");
+ fprintf(stderr, "%u, %s, (%u)\n\n", (uint32_t)rc, memcached_strerror(memc, rc), hash_val);
+ }
test_true(values[rc] == hash_val);
}
results= memcached_fetch_result(memc, &results_obj, &rc);
test_true(results);
- test_true(results->cas);
+ test_true(results->item_cas);
test_true(rc == MEMCACHED_SUCCESS);
test_true(memcached_result_cas(results));