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