~brianaker/libmemcached/1164440

« back to all changes in this revision

Viewing changes to libmemcached/memcached_fetch.c

  • Committer: patg@patg.net
  • Date: 2008-05-05 03:32:10 UTC
  • mfrom: (317.1.71)
  • Revision ID: patg@patg.net-20080505033210-yxv0us02t8lb44dy
Merge 477:75823cad36b7 with -r 476

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "common.h"
 
2
#include "memcached_io.h"
 
3
 
 
4
memcached_return value_fetch(memcached_server_st *ptr,
 
5
                             char *buffer,
 
6
                             memcached_result_st *result)
 
7
{
 
8
  memcached_return rc= MEMCACHED_SUCCESS;
 
9
  char *string_ptr;
 
10
  char *end_ptr;
 
11
  char *next_ptr;
 
12
  size_t value_length;
 
13
  size_t read_length;
 
14
  size_t to_read;
 
15
  char *value_ptr;
 
16
 
 
17
  end_ptr= buffer + MEMCACHED_DEFAULT_COMMAND_SIZE;
 
18
 
 
19
  memcached_result_reset(result);
 
20
 
 
21
  string_ptr= buffer;
 
22
  string_ptr+= 6; /* "VALUE " */
 
23
 
 
24
 
 
25
  /* We load the key */
 
26
  {
 
27
    char *key;
 
28
 
 
29
    key= result->key;
 
30
    result->key_length= 0;
 
31
 
 
32
    for (; isgraph(*string_ptr); string_ptr++)
 
33
    {
 
34
      *key= *string_ptr;
 
35
      key++;
 
36
      result->key_length++;
 
37
    }
 
38
    result->key[result->key_length]= 0;
 
39
  }
 
40
 
 
41
  if (end_ptr == string_ptr)
 
42
    goto read_error;
 
43
 
 
44
  /* Flags fetch move past space */
 
45
  string_ptr++;
 
46
  if (end_ptr == string_ptr)
 
47
    goto read_error;
 
48
  for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
 
49
  result->flags= (uint32_t)strtol(next_ptr, &string_ptr, 10);
 
50
 
 
51
  if (end_ptr == string_ptr)
 
52
    goto read_error;
 
53
 
 
54
  /* Length fetch move past space*/
 
55
  string_ptr++;
 
56
  if (end_ptr == string_ptr)
 
57
    goto read_error;
 
58
 
 
59
  for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
 
60
  value_length= (size_t)strtoll(next_ptr, &string_ptr, 10);
 
61
 
 
62
  if (end_ptr == string_ptr)
 
63
    goto read_error;
 
64
 
 
65
  /* Skip spaces */
 
66
  if (*string_ptr == '\r')
 
67
  {
 
68
    /* Skip past the \r\n */
 
69
    string_ptr+= 2;
 
70
  }
 
71
  else
 
72
  {
 
73
    string_ptr++;
 
74
    for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
 
75
    result->cas= (size_t)strtoll(next_ptr, &string_ptr, 10);
 
76
  }
 
77
 
 
78
  if (end_ptr < string_ptr)
 
79
    goto read_error;
 
80
 
 
81
  /* We add two bytes so that we can walk the \r\n */
 
82
  rc= memcached_string_check(&result->value, value_length+2);
 
83
  if (rc != MEMCACHED_SUCCESS)
 
84
  {
 
85
    value_length= 0;
 
86
    return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
 
87
  }
 
88
 
 
89
  value_ptr= memcached_string_value(&result->value);
 
90
  read_length= 0;
 
91
  /* 
 
92
    We read the \r\n into the string since not doing so is more 
 
93
    cycles then the waster of memory to do so.
 
94
 
 
95
    We are null terminating through, which will most likely make
 
96
    some people lazy about using the return length.
 
97
  */
 
98
  to_read= (value_length) + 2;
 
99
  read_length= memcached_io_read(ptr, value_ptr, to_read);
 
100
  if (read_length != (size_t)(value_length + 2))
 
101
  {
 
102
    goto read_error;
 
103
  }
 
104
 
 
105
/* This next bit blows the API, but this is internal....*/
 
106
  {
 
107
    char *char_ptr;
 
108
    char_ptr= memcached_string_value(&result->value);;
 
109
    char_ptr[value_length]= 0;
 
110
    char_ptr[value_length + 1]= 0;
 
111
    memcached_string_set_length(&result->value, value_length);
 
112
  }
 
113
 
 
114
  return MEMCACHED_SUCCESS;
 
115
 
 
116
read_error:
 
117
  memcached_io_reset(ptr);
 
118
 
 
119
  return MEMCACHED_PARTIAL_READ;
 
120
}
 
121
 
 
122
char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, 
 
123
                    size_t *value_length, 
 
124
                    uint32_t *flags,
 
125
                    memcached_return *error)
 
126
{
 
127
  memcached_result_st *result_buffer= &ptr->result;
 
128
 
 
129
  while (ptr->cursor_server < ptr->number_of_hosts)
 
130
  {
 
131
    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
 
132
 
 
133
    if (memcached_server_response_count(&ptr->hosts[ptr->cursor_server]) == 0)
 
134
    {
 
135
      ptr->cursor_server++;
 
136
      continue;
 
137
    }
 
138
 
 
139
  *error= memcached_response(&ptr->hosts[ptr->cursor_server], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result_buffer);
 
140
 
 
141
    if (*error == MEMCACHED_END) /* END means that we move on to the next */
 
142
    {
 
143
      memcached_server_response_reset(&ptr->hosts[ptr->cursor_server]);
 
144
      ptr->cursor_server++;
 
145
      continue;
 
146
    }
 
147
    else if (*error == MEMCACHED_SUCCESS)
 
148
    {
 
149
      *value_length= memcached_string_length(&result_buffer->value);
 
150
    
 
151
      if (key)
 
152
      {
 
153
        strncpy(key, result_buffer->key, result_buffer->key_length);
 
154
        *key_length= result_buffer->key_length;
 
155
      }
 
156
 
 
157
      if (result_buffer->flags)
 
158
        *flags= result_buffer->flags;
 
159
      else
 
160
        *flags= 0;
 
161
 
 
162
      return  memcached_string_c_copy(&result_buffer->value);
 
163
    }
 
164
    else
 
165
    {
 
166
      *value_length= 0;
 
167
      return NULL;
 
168
    }
 
169
  }
 
170
 
 
171
  ptr->cursor_server= 0;
 
172
  *value_length= 0;
 
173
  return NULL;
 
174
}
 
175
 
 
176
memcached_result_st *memcached_fetch_result(memcached_st *ptr, 
 
177
                                            memcached_result_st *result,
 
178
                                            memcached_return *error)
 
179
{
 
180
  if (result == NULL)
 
181
    result= memcached_result_create(ptr, NULL);
 
182
 
 
183
  WATCHPOINT_ASSERT(result->value.is_allocated != MEMCACHED_USED);
 
184
 
 
185
#ifdef UNUSED
 
186
  if (ptr->flags & MEM_NO_BLOCK)
 
187
    memcached_io_preread(ptr);
 
188
#endif
 
189
 
 
190
  while (ptr->cursor_server < ptr->number_of_hosts)
 
191
  {
 
192
    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
 
193
 
 
194
    if (memcached_server_response_count(&ptr->hosts[ptr->cursor_server]) == 0)
 
195
    {
 
196
      ptr->cursor_server++;
 
197
      continue;
 
198
    }
 
199
 
 
200
    *error= memcached_response(&ptr->hosts[ptr->cursor_server], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result);
 
201
    
 
202
    if (*error == MEMCACHED_END) /* END means that we move on to the next */
 
203
    {
 
204
      memcached_server_response_reset(&ptr->hosts[ptr->cursor_server]);
 
205
      ptr->cursor_server++;
 
206
      continue;
 
207
    }
 
208
    else if (*error == MEMCACHED_SUCCESS)
 
209
      return result;
 
210
    else
 
211
      return NULL;
 
212
  }
 
213
 
 
214
  /* We have completed reading data */
 
215
  if (result->is_allocated == MEMCACHED_ALLOCATED)
 
216
    memcached_result_free(result);
 
217
  else
 
218
    memcached_string_reset(&result->value);
 
219
 
 
220
  ptr->cursor_server= 0;
 
221
  return NULL;
 
222
}