Increment and decrement now works.
[awesomized/libmemcached] / lib / memcached_get.c
1 #include <memcached.h>
2
3 char *memcached_get(memcached_st *ptr, char *key, size_t key_length,
4 size_t *value_length,
5 uint16_t *flags,
6 memcached_return *error)
7 {
8 size_t send_length;
9 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
10 char *string_ptr;
11 unsigned int server_key;
12
13 *error= memcached_connect(ptr);
14
15 if (*error != MEMCACHED_SUCCESS)
16 return NULL;
17
18 server_key= memcached_generate_hash(key, key_length) % ptr->number_of_hosts;
19
20 send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "get %.*s\r\n",
21 key_length, key);
22 if (*error != MEMCACHED_SUCCESS)
23 return NULL;
24
25 if ((send(ptr->hosts[server_key].fd, buffer, send_length, 0) == -1))
26 {
27 fprintf(stderr, "failed fetch on %.*s TCP\n", key_length+1, key);
28 *error= MEMCACHED_WRITE_FAILURE;
29 return NULL;
30 }
31
32 memset(buffer, 0, MEMCACHED_DEFAULT_COMMAND_SIZE);
33 *error= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
34
35 if (*error == MEMCACHED_SUCCESS)
36 {
37 char *end_ptr;
38
39 string_ptr= buffer;
40 string_ptr+= 6; /* "VALUE " */
41
42 /* We do nothing with the key, since we only asked for one key */
43 for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
44
45 /* Flags fetch */
46 string_ptr= end_ptr + 1;
47 for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
48 *flags= (uint16_t)strtol(string_ptr, &end_ptr, 10);
49
50 /* Length fetch */
51 string_ptr= end_ptr + 1;
52 for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
53 *value_length= strtoll(string_ptr, &end_ptr, 10);
54
55 /* Skip past the \r\n */
56 string_ptr= end_ptr +2;
57
58 if (*value_length)
59 {
60 size_t need_to_copy;
61 char *pos_ptr;
62 char *value;
63
64 value= (char *)malloc(*value_length * sizeof(char));
65
66 if (!value)
67 {
68 *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
69 return NULL;
70 }
71
72 need_to_copy= (*value_length < (size_t)(buffer-string_ptr))
73 ? *value_length
74 : (size_t)(buffer-string_ptr) ;
75
76 pos_ptr= memcpy(value, string_ptr, need_to_copy);
77
78 if ( need_to_copy > *value_length)
79 {
80 size_t read_length;
81 size_t need_to_read;
82
83 need_to_read= *value_length - need_to_copy;
84
85 read_length= read(ptr->hosts[server_key].fd, pos_ptr, need_to_read);
86 if (read_length != need_to_read)
87 {
88 free(value);
89 *error= MEMCACHED_PARTIAL_READ;
90
91 return NULL;
92 }
93 }
94
95 return value;
96 }
97 }
98
99 return NULL;
100 }