memcached 1.2.6 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. data/CHANGELOG +2 -0
  2. data/Manifest +206 -12
  3. data/Rakefile +32 -1
  4. data/ext/extconf.rb +10 -35
  5. data/ext/libmemcached-0.32/AUTHORS +7 -0
  6. data/ext/libmemcached-0.32/COPYING +32 -0
  7. data/ext/libmemcached-0.32/ChangeLog +303 -0
  8. data/ext/libmemcached-0.32/INSTALL +302 -0
  9. data/ext/libmemcached-0.32/Makefile.am +36 -0
  10. data/ext/libmemcached-0.32/Makefile.in +828 -0
  11. data/ext/libmemcached-0.32/NEWS +1 -0
  12. data/ext/libmemcached-0.32/README +33 -0
  13. data/ext/libmemcached-0.32/THANKS +14 -0
  14. data/ext/libmemcached-0.32/TODO +11 -0
  15. data/ext/libmemcached-0.32/aclocal.m4 +1852 -0
  16. data/ext/libmemcached-0.32/clients/Makefile.am +73 -0
  17. data/ext/libmemcached-0.32/clients/Makefile.in +770 -0
  18. data/ext/libmemcached-0.32/clients/client_options.h +32 -0
  19. data/ext/libmemcached-0.32/clients/execute.c +64 -0
  20. data/ext/libmemcached-0.32/clients/execute.h +5 -0
  21. data/ext/libmemcached-0.32/clients/generator.c +74 -0
  22. data/ext/libmemcached-0.32/clients/generator.h +20 -0
  23. data/ext/libmemcached-0.32/clients/memcat.c +178 -0
  24. data/ext/libmemcached-0.32/clients/memcp.c +251 -0
  25. data/ext/libmemcached-0.32/clients/memdump.c +170 -0
  26. data/ext/libmemcached-0.32/clients/memerror.c +80 -0
  27. data/ext/libmemcached-0.32/clients/memflush.c +143 -0
  28. data/ext/libmemcached-0.32/clients/memrm.c +160 -0
  29. data/ext/libmemcached-0.32/clients/memslap.c +441 -0
  30. data/ext/libmemcached-0.32/clients/memstat.c +326 -0
  31. data/ext/libmemcached-0.32/clients/utilities.c +207 -0
  32. data/ext/libmemcached-0.32/clients/utilities.h +41 -0
  33. data/ext/libmemcached-0.32/config.h.in +252 -0
  34. data/ext/libmemcached-0.32/config/compile +143 -0
  35. data/ext/libmemcached-0.32/config/config.guess +1561 -0
  36. data/ext/libmemcached-0.32/config/config.rpath +666 -0
  37. data/ext/libmemcached-0.32/config/config.sub +1686 -0
  38. data/ext/libmemcached-0.32/config/depcomp +630 -0
  39. data/ext/libmemcached-0.32/config/install-sh +520 -0
  40. data/ext/libmemcached-0.32/config/ltmain.sh +8406 -0
  41. data/ext/libmemcached-0.32/config/missing +376 -0
  42. data/ext/libmemcached-0.32/configure +23048 -0
  43. data/ext/libmemcached-0.32/configure.ac +122 -0
  44. data/ext/libmemcached-0.32/docs/Makefile.am +415 -0
  45. data/ext/libmemcached-0.32/docs/Makefile.in +918 -0
  46. data/ext/libmemcached-0.32/docs/libmemcached.pod +123 -0
  47. data/ext/libmemcached-0.32/docs/libmemcached_examples.pod +115 -0
  48. data/ext/libmemcached-0.32/docs/libmemcachedutil.pod +40 -0
  49. data/ext/libmemcached-0.32/docs/memcached_analyze.pod +52 -0
  50. data/ext/libmemcached-0.32/docs/memcached_auto.pod +97 -0
  51. data/ext/libmemcached-0.32/docs/memcached_behavior.pod +224 -0
  52. data/ext/libmemcached-0.32/docs/memcached_callback.pod +123 -0
  53. data/ext/libmemcached-0.32/docs/memcached_create.pod +61 -0
  54. data/ext/libmemcached-0.32/docs/memcached_delete.pod +54 -0
  55. data/ext/libmemcached-0.32/docs/memcached_dump.pod +53 -0
  56. data/ext/libmemcached-0.32/docs/memcached_flush.pod +46 -0
  57. data/ext/libmemcached-0.32/docs/memcached_flush_buffers.pod +42 -0
  58. data/ext/libmemcached-0.32/docs/memcached_generate_hash_value.pod +57 -0
  59. data/ext/libmemcached-0.32/docs/memcached_get.pod +161 -0
  60. data/ext/libmemcached-0.32/docs/memcached_memory_allocators.pod +73 -0
  61. data/ext/libmemcached-0.32/docs/memcached_pool.pod +77 -0
  62. data/ext/libmemcached-0.32/docs/memcached_quit.pod +47 -0
  63. data/ext/libmemcached-0.32/docs/memcached_sasl.pod +63 -0
  64. data/ext/libmemcached-0.32/docs/memcached_server_st.pod +75 -0
  65. data/ext/libmemcached-0.32/docs/memcached_servers.pod +102 -0
  66. data/ext/libmemcached-0.32/docs/memcached_set.pod +187 -0
  67. data/ext/libmemcached-0.32/docs/memcached_stats.pod +82 -0
  68. data/ext/libmemcached-0.32/docs/memcached_strerror.pod +46 -0
  69. data/ext/libmemcached-0.32/docs/memcached_user_data.pod +49 -0
  70. data/ext/libmemcached-0.32/docs/memcached_verbosity.pod +41 -0
  71. data/ext/libmemcached-0.32/docs/memcached_version.pod +56 -0
  72. data/ext/libmemcached-0.32/docs/memcat.pod +37 -0
  73. data/ext/libmemcached-0.32/docs/memcp.pod +40 -0
  74. data/ext/libmemcached-0.32/docs/memdump.pod +31 -0
  75. data/ext/libmemcached-0.32/docs/memerror.pod +30 -0
  76. data/ext/libmemcached-0.32/docs/memflush.pod +35 -0
  77. data/ext/libmemcached-0.32/docs/memrm.pod +34 -0
  78. data/ext/libmemcached-0.32/docs/memslap.pod +33 -0
  79. data/ext/libmemcached-0.32/docs/memstat.pod +35 -0
  80. data/ext/libmemcached-0.32/libmemcached/Makefile.am +107 -0
  81. data/ext/libmemcached-0.32/libmemcached/Makefile.in +1050 -0
  82. data/ext/libmemcached-0.32/libmemcached/byteorder.c +31 -0
  83. data/ext/libmemcached-0.32/libmemcached/common.h +183 -0
  84. data/ext/libmemcached-0.32/libmemcached/crc.c +86 -0
  85. data/ext/libmemcached-0.32/libmemcached/hsieh_hash.c +68 -0
  86. data/ext/libmemcached-0.32/libmemcached/jenkins_hash.c +213 -0
  87. data/ext/libmemcached-0.32/libmemcached/libmemcached.ver +1 -0
  88. data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.d +28 -0
  89. data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.h +78 -0
  90. data/ext/libmemcached-0.32/libmemcached/md5.c +354 -0
  91. data/ext/libmemcached-0.32/libmemcached/memcached.c +152 -0
  92. data/ext/libmemcached-0.32/libmemcached/memcached.h +302 -0
  93. data/ext/libmemcached-0.32/libmemcached/memcached.hpp +799 -0
  94. data/ext/libmemcached-0.32/libmemcached/memcached/README.txt +7 -0
  95. data/ext/libmemcached-0.32/libmemcached/memcached/protocol_binary.h +366 -0
  96. data/ext/libmemcached-0.32/libmemcached/memcached_allocators.c +72 -0
  97. data/ext/libmemcached-0.32/libmemcached/memcached_analyze.c +100 -0
  98. data/ext/libmemcached-0.32/libmemcached/memcached_auto.c +207 -0
  99. data/ext/libmemcached-0.32/libmemcached/memcached_behavior.c +285 -0
  100. data/ext/libmemcached-0.32/libmemcached/memcached_callback.c +175 -0
  101. data/ext/libmemcached-0.32/libmemcached/memcached_configure.h.in +23 -0
  102. data/ext/libmemcached-0.32/libmemcached/memcached_connect.c +361 -0
  103. data/ext/libmemcached-0.32/libmemcached/memcached_constants.h +145 -0
  104. data/ext/libmemcached-0.32/libmemcached/memcached_delete.c +0 -0
  105. data/ext/libmemcached-0.32/libmemcached/memcached_do.c +34 -0
  106. data/ext/libmemcached-0.32/libmemcached/memcached_dump.c +79 -0
  107. data/ext/libmemcached-0.32/libmemcached/memcached_fetch.c +102 -0
  108. data/ext/libmemcached-0.32/libmemcached/memcached_flush.c +89 -0
  109. data/ext/libmemcached-0.32/libmemcached/memcached_flush_buffers.c +22 -0
  110. data/ext/libmemcached-0.32/libmemcached/memcached_get.c +495 -0
  111. data/ext/libmemcached-0.32/libmemcached/memcached_get.h +87 -0
  112. data/ext/libmemcached-0.32/libmemcached/memcached_hash.c +252 -0
  113. data/ext/libmemcached-0.32/libmemcached/memcached_hosts.c +510 -0
  114. data/ext/libmemcached-0.32/libmemcached/memcached_internal.h +31 -0
  115. data/ext/libmemcached-0.32/libmemcached/memcached_io.c +547 -0
  116. data/ext/libmemcached-0.32/libmemcached/memcached_io.h +59 -0
  117. data/ext/libmemcached-0.32/libmemcached/memcached_key.c +28 -0
  118. data/ext/libmemcached-0.32/libmemcached/memcached_parse.c +74 -0
  119. data/ext/libmemcached-0.32/libmemcached/memcached_pool.h +38 -0
  120. data/ext/libmemcached-0.32/libmemcached/memcached_purge.c +76 -0
  121. data/ext/libmemcached-0.32/libmemcached/memcached_quit.c +75 -0
  122. data/ext/libmemcached-0.32/libmemcached/memcached_response.c +528 -0
  123. data/ext/libmemcached-0.32/libmemcached/memcached_result.c +57 -0
  124. data/ext/libmemcached-0.32/libmemcached/memcached_result.h +59 -0
  125. data/ext/libmemcached-0.32/libmemcached/memcached_sasl.c +225 -0
  126. data/ext/libmemcached-0.32/libmemcached/memcached_sasl.h +44 -0
  127. data/ext/libmemcached-0.32/libmemcached/memcached_server.c +159 -0
  128. data/ext/libmemcached-0.32/libmemcached/memcached_server.h +93 -0
  129. data/ext/libmemcached-0.32/libmemcached/memcached_stats.c +454 -0
  130. data/ext/libmemcached-0.32/libmemcached/memcached_storage.c +514 -0
  131. data/ext/libmemcached-0.32/libmemcached/memcached_storage.h +107 -0
  132. data/ext/libmemcached-0.32/libmemcached/memcached_strerror.c +92 -0
  133. data/ext/libmemcached-0.32/libmemcached/memcached_string.c +138 -0
  134. data/ext/libmemcached-0.32/libmemcached/memcached_string.h +53 -0
  135. data/ext/libmemcached-0.32/libmemcached/memcached_types.h +44 -0
  136. data/ext/libmemcached-0.32/libmemcached/memcached_util.h +15 -0
  137. data/ext/libmemcached-0.32/libmemcached/memcached_verbosity.c +36 -0
  138. data/ext/libmemcached-0.32/libmemcached/memcached_version.c +112 -0
  139. data/ext/libmemcached-0.32/libmemcached/memcached_watchpoint.h +38 -0
  140. data/ext/libmemcached-0.32/libmemcached/murmur_hash.c +76 -0
  141. data/ext/libmemcached-0.32/libmemcached/visibility.h +51 -0
  142. data/ext/libmemcached-0.32/libmemcachedutil/Makefile.am +11 -0
  143. data/ext/libmemcached-0.32/libmemcachedutil/Makefile.in +602 -0
  144. data/ext/libmemcached-0.32/libmemcachedutil/libmemcachedutil.ver +1 -0
  145. data/ext/libmemcached-0.32/libmemcachedutil/memcached_pool.c +170 -0
  146. data/ext/libmemcached-0.32/m4/ac_cxx_compile_stdcxx_0x.m4 +103 -0
  147. data/ext/libmemcached-0.32/m4/ac_cxx_header_stdcxx_98.m4 +67 -0
  148. data/ext/libmemcached-0.32/m4/acx_pthread.m4 +276 -0
  149. data/ext/libmemcached-0.32/m4/byteorder.m4 +40 -0
  150. data/ext/libmemcached-0.32/m4/deprecated.m4 +17 -0
  151. data/ext/libmemcached-0.32/m4/enable_utillib.m4 +16 -0
  152. data/ext/libmemcached-0.32/m4/extensions.m4 +94 -0
  153. data/ext/libmemcached-0.32/m4/hsieh.m4 +18 -0
  154. data/ext/libmemcached-0.32/m4/lib-prefix.m4 +221 -0
  155. data/ext/libmemcached-0.32/m4/libtool.m4 +7360 -0
  156. data/ext/libmemcached-0.32/m4/ltoptions.m4 +368 -0
  157. data/ext/libmemcached-0.32/m4/ltsugar.m4 +123 -0
  158. data/ext/libmemcached-0.32/m4/ltversion.m4 +23 -0
  159. data/ext/libmemcached-0.32/m4/lt~obsolete.m4 +92 -0
  160. data/ext/libmemcached-0.32/m4/memcached.m4 +30 -0
  161. data/ext/libmemcached-0.32/m4/pandora_64bit.m4 +55 -0
  162. data/ext/libmemcached-0.32/m4/pandora_canonical.m4 +151 -0
  163. data/ext/libmemcached-0.32/m4/pandora_check_compiler_version.m4 +37 -0
  164. data/ext/libmemcached-0.32/m4/pandora_check_cxx_standard.m4 +16 -0
  165. data/ext/libmemcached-0.32/m4/pandora_enable_dtrace.m4 +41 -0
  166. data/ext/libmemcached-0.32/m4/pandora_ensure_gcc_version.m4 +36 -0
  167. data/ext/libmemcached-0.32/m4/pandora_have_better_malloc.m4 +54 -0
  168. data/ext/libmemcached-0.32/m4/pandora_have_sasl.m4 +133 -0
  169. data/ext/libmemcached-0.32/m4/pandora_header_assert.m4 +23 -0
  170. data/ext/libmemcached-0.32/m4/pandora_libtool.m4 +15 -0
  171. data/ext/libmemcached-0.32/m4/pandora_optimize.m4 +79 -0
  172. data/ext/libmemcached-0.32/m4/pandora_shared_ptr.m4 +56 -0
  173. data/ext/libmemcached-0.32/m4/pandora_vc_build.m4 +32 -0
  174. data/ext/libmemcached-0.32/m4/pandora_warnings.m4 +262 -0
  175. data/ext/libmemcached-0.32/m4/pod2man.m4 +7 -0
  176. data/ext/libmemcached-0.32/m4/protocol_binary.m4 +23 -0
  177. data/ext/libmemcached-0.32/m4/setsockopt.m4 +57 -0
  178. data/ext/libmemcached-0.32/m4/visibility.m4 +52 -0
  179. data/ext/libmemcached-0.32/support/Makefile.am +4 -0
  180. data/ext/libmemcached-0.32/support/Makefile.in +485 -0
  181. data/ext/libmemcached-0.32/support/libmemcached-fc.spec.in +105 -0
  182. data/ext/libmemcached-0.32/support/libmemcached.pc.in +10 -0
  183. data/ext/libmemcached-0.32/support/libmemcached.spec +105 -0
  184. data/ext/libmemcached-0.32/support/libmemcached.spec.in +105 -0
  185. data/ext/libmemcached-0.32/support/set_benchmark.sh +5 -0
  186. data/ext/libmemcached-0.32/tests/Makefile.am +105 -0
  187. data/ext/libmemcached-0.32/tests/Makefile.in +748 -0
  188. data/ext/libmemcached-0.32/tests/atomsmasher.c +245 -0
  189. data/ext/libmemcached-0.32/tests/function.c +4781 -0
  190. data/ext/libmemcached-0.32/tests/ketama_test_cases.h +108 -0
  191. data/ext/libmemcached-0.32/tests/output.cmp +7 -0
  192. data/ext/libmemcached-0.32/tests/output.res +7 -0
  193. data/ext/libmemcached-0.32/tests/output2.res +46 -0
  194. data/ext/libmemcached-0.32/tests/plus.cpp +293 -0
  195. data/ext/libmemcached-0.32/tests/r/memcat.res +19 -0
  196. data/ext/libmemcached-0.32/tests/r/memcp.res +27 -0
  197. data/ext/libmemcached-0.32/tests/r/memrm.res +19 -0
  198. data/ext/libmemcached-0.32/tests/r/memslap.res +33 -0
  199. data/ext/libmemcached-0.32/tests/r/memstat.res +33 -0
  200. data/ext/libmemcached-0.32/tests/server.c +118 -0
  201. data/ext/libmemcached-0.32/tests/server.h +25 -0
  202. data/ext/libmemcached-0.32/tests/start.c +16 -0
  203. data/ext/libmemcached-0.32/tests/t/memcat.test +4 -0
  204. data/ext/libmemcached-0.32/tests/t/memcp.test +3 -0
  205. data/ext/libmemcached-0.32/tests/t/memrm.test +3 -0
  206. data/ext/libmemcached-0.32/tests/t/memslap.test +5 -0
  207. data/ext/libmemcached-0.32/tests/t/memstat.test +3 -0
  208. data/ext/libmemcached-0.32/tests/test.c +137 -0
  209. data/ext/libmemcached-0.32/tests/test.h +46 -0
  210. data/ext/libmemcached-0.32/tests/udp.c +76 -0
  211. data/memcached.gemspec +4 -4
  212. data/test/unit/memcached_test.rb +30 -0
  213. metadata +213 -16
  214. data/ext/libmemcached-0.32.tar.gz +0 -0
  215. data/ext/libmemcached-1.patch +0 -270
  216. data/ext/libmemcached-10.patch +0 -12
  217. data/ext/libmemcached-2.patch +0 -116
  218. data/ext/libmemcached-3.patch +0 -8
  219. data/ext/libmemcached-4.patch +0 -40
  220. data/ext/libmemcached-5.patch +0 -832
  221. data/ext/libmemcached-6.patch +0 -20
  222. data/ext/libmemcached-7.patch +0 -2989
  223. data/ext/libmemcached-8.patch +0 -137
  224. data/ext/libmemcached-9.patch +0 -13
  225. data/ext/sasl.patch +0 -29283
@@ -0,0 +1,59 @@
1
+ /*
2
+ * Summary: Server IO, Not public!
3
+ *
4
+ * Copy: See Copyright for the status of this software.
5
+ *
6
+ * Author: Brian Aker
7
+ */
8
+
9
+ #ifndef LIBMEMCACHED_MEMCACHED_IO_H
10
+ #define LIBMEMCACHED_MEMCACHED_IO_H
11
+
12
+ #if defined(BUILDING_LIBMEMCACHED)
13
+
14
+ #include "libmemcached/memcached.h"
15
+
16
+ #define MAX_UDP_DATAGRAM_LENGTH 1400
17
+ #define UDP_DATAGRAM_HEADER_LENGTH 8
18
+ #define UDP_REQUEST_ID_MSG_SIG_DIGITS 10
19
+ #define UDP_REQUEST_ID_THREAD_MASK 0xFFFF << UDP_REQUEST_ID_MSG_SIG_DIGITS
20
+ #define get_udp_datagram_request_id(A) ntohs((A)->request_id)
21
+ #define get_udp_datagram_seq_num(A) ntohs((A)->sequence_number)
22
+ #define get_udp_datagram_num_datagrams(A) ntohs((A)->num_datagrams)
23
+ #define get_msg_num_from_request_id(A) ( (A) & (~(UDP_REQUEST_ID_THREAD_MASK)) )
24
+ #define get_thread_id_from_request_id(A) ( (A) & (UDP_REQUEST_ID_THREAD_MASK) ) >> UDP_REQUEST_ID_MSG_SIG_DIGITS
25
+ #define generate_udp_request_thread_id(A) (A) << UDP_REQUEST_ID_MSG_SIG_DIGITS
26
+ #define UDP_REQUEST_ID_MAX_THREAD_ID get_thread_id_from_request_id(0xFFFF)
27
+
28
+ struct udp_datagram_header_st {
29
+ uint16_t request_id;
30
+ uint16_t sequence_number;
31
+ uint16_t num_datagrams;
32
+ uint16_t reserved;
33
+ };
34
+
35
+ ssize_t memcached_io_write(memcached_server_st *ptr,
36
+ const void *buffer, size_t length, char with_flush);
37
+ void memcached_io_reset(memcached_server_st *ptr);
38
+ memcached_return memcached_io_read(memcached_server_st *ptr,
39
+ void *buffer, size_t length, ssize_t *nread);
40
+ /* Read a line (terminated by '\n') into the buffer */
41
+ memcached_return memcached_io_readline(memcached_server_st *ptr,
42
+ char *buffer_ptr,
43
+ size_t size);
44
+ memcached_return memcached_io_close(memcached_server_st *ptr);
45
+ /* Read n bytes of data from the server and store them in dta */
46
+ memcached_return memcached_safe_read(memcached_server_st *ptr,
47
+ void *dta,
48
+ size_t size);
49
+ /* Read a single response from the server */
50
+ memcached_return memcached_read_one_response(memcached_server_st *ptr,
51
+ char *buffer, size_t buffer_length,
52
+ memcached_result_st *result);
53
+ memcached_return memcached_io_init_udp_header(memcached_server_st *ptr,
54
+ uint16_t thread_id);
55
+
56
+ memcached_server_st *memcached_io_get_readable_server(memcached_st *memc);
57
+
58
+ #endif /* BUILDING_LIBMEMCACHED */
59
+ #endif /* LIBMEMCACHED_MEMCACHED_IO_H */
@@ -0,0 +1,28 @@
1
+ #include "common.h"
2
+
3
+ memcached_return memcached_key_test(const char **keys, size_t *key_length,
4
+ size_t number_of_keys)
5
+ {
6
+ uint32_t x;
7
+ memcached_return rc;
8
+
9
+ for (x= 0; x < number_of_keys; x++)
10
+ {
11
+ size_t y;
12
+
13
+ rc= memcached_validate_key_length(*(key_length + x), false);
14
+ if (rc != MEMCACHED_SUCCESS)
15
+ return rc;
16
+
17
+
18
+
19
+ for (y= 0; y < *(key_length + x); y++)
20
+ {
21
+ if ((isgraph(keys[x][y])) == 0)
22
+ return MEMCACHED_BAD_KEY_PROVIDED;
23
+ }
24
+ }
25
+
26
+ return MEMCACHED_SUCCESS;
27
+ }
28
+
@@ -0,0 +1,74 @@
1
+ /*
2
+ I debated about putting this in the client library since it does an
3
+ action I don't really believe belongs in the library.
4
+
5
+ Frankly its too damn useful not to be here though.
6
+ */
7
+
8
+ #include "common.h"
9
+
10
+ memcached_server_st *memcached_servers_parse(const char *server_strings)
11
+ {
12
+ char *string;
13
+ uint32_t port;
14
+ uint32_t weight;
15
+ const char *begin_ptr;
16
+ const char *end_ptr;
17
+ memcached_server_st *servers= NULL;
18
+ memcached_return rc;
19
+
20
+ WATCHPOINT_ASSERT(server_strings);
21
+
22
+ end_ptr= server_strings + strlen(server_strings);
23
+
24
+ for (begin_ptr= server_strings, string= index(server_strings, ',');
25
+ begin_ptr != end_ptr;
26
+ string= index(begin_ptr, ','))
27
+ {
28
+ char buffer[HUGE_STRING_LEN];
29
+ char *ptr, *ptr2;
30
+ port= 0;
31
+ weight= 0;
32
+
33
+ if (string)
34
+ {
35
+ memcpy(buffer, begin_ptr, (size_t) (string - begin_ptr));
36
+ buffer[(unsigned int)(string - begin_ptr)]= 0;
37
+ begin_ptr= string+1;
38
+ }
39
+ else
40
+ {
41
+ size_t length= strlen(begin_ptr);
42
+ memcpy(buffer, begin_ptr, length);
43
+ buffer[length]= 0;
44
+ begin_ptr= end_ptr;
45
+ }
46
+
47
+ ptr= index(buffer, ':');
48
+
49
+ if (ptr)
50
+ {
51
+ ptr[0]= 0;
52
+
53
+ ptr++;
54
+
55
+ port= (uint32_t) strtoul(ptr, (char **)NULL, 10);
56
+
57
+ ptr2= index(ptr, ' ');
58
+ if (! ptr2)
59
+ ptr2= index(ptr, ':');
60
+ if (ptr2)
61
+ {
62
+ ptr2++;
63
+ weight = (uint32_t) strtoul(ptr2, (char **)NULL, 10);
64
+ }
65
+ }
66
+
67
+ servers= memcached_server_list_append_with_weight(servers, buffer, port, weight, &rc);
68
+
69
+ if (isspace(*begin_ptr))
70
+ begin_ptr++;
71
+ }
72
+
73
+ return servers;
74
+ }
@@ -0,0 +1,38 @@
1
+ /*
2
+ * Summary: Connection pool implementation for libmemcached.
3
+ *
4
+ * Copy: See Copyright for the status of this software.
5
+ *
6
+ * Author: Trond Norbye
7
+ */
8
+
9
+ #ifndef MEMCACHED_POOL_H
10
+ #define MEMCACHED_POOL_H
11
+
12
+ #include <libmemcached/memcached.h>
13
+
14
+ #ifdef __cplusplus
15
+ extern "C" {
16
+ #endif
17
+
18
+ struct memcached_pool_st;
19
+ typedef struct memcached_pool_st memcached_pool_st;
20
+
21
+ LIBMEMCACHED_API
22
+ memcached_pool_st *memcached_pool_create(memcached_st* mmc, uint32_t initial,
23
+ uint32_t max);
24
+ LIBMEMCACHED_API
25
+ memcached_st* memcached_pool_destroy(memcached_pool_st* pool);
26
+ LIBMEMCACHED_API
27
+ memcached_st* memcached_pool_pop(memcached_pool_st* pool,
28
+ bool block,
29
+ memcached_return* rc);
30
+ LIBMEMCACHED_API
31
+ memcached_return memcached_pool_push(memcached_pool_st* pool,
32
+ memcached_st* mmc);
33
+
34
+ #ifdef __cplusplus
35
+ }
36
+ #endif
37
+
38
+ #endif /* MEMCACHED_POOL_H */
@@ -0,0 +1,76 @@
1
+ #include "common.h"
2
+ #include "memcached_io.h"
3
+ #include "memcached_constants.h"
4
+
5
+ memcached_return memcached_purge(memcached_server_st *ptr)
6
+ {
7
+ uint32_t x;
8
+ memcached_return ret= MEMCACHED_SUCCESS;
9
+
10
+ if (ptr->root->purging || /* already purging */
11
+ (memcached_server_response_count(ptr) < ptr->root->io_msg_watermark &&
12
+ ptr->io_bytes_sent < ptr->root->io_bytes_watermark) ||
13
+ (ptr->io_bytes_sent > ptr->root->io_bytes_watermark &&
14
+ memcached_server_response_count(ptr) < 2))
15
+ {
16
+ return MEMCACHED_SUCCESS;
17
+ }
18
+
19
+ /* memcached_io_write and memcached_response may call memcached_purge
20
+ so we need to be able stop any recursion.. */
21
+ ptr->root->purging= 1;
22
+
23
+ WATCHPOINT_ASSERT(ptr->fd != -1);
24
+ /* Force a flush of the buffer to ensure that we don't have the n-1 pending
25
+ requests buffered up.. */
26
+ if (memcached_io_write(ptr, NULL, 0, 1) == -1)
27
+ {
28
+ ptr->root->purging= 0;
29
+ return MEMCACHED_WRITE_FAILURE;
30
+ }
31
+ WATCHPOINT_ASSERT(ptr->fd != -1);
32
+
33
+ uint32_t no_msg= memcached_server_response_count(ptr) - 1;
34
+ if (no_msg > 0)
35
+ {
36
+ memcached_result_st result;
37
+ memcached_result_st *result_ptr;
38
+ char buffer[SMALL_STRING_LEN];
39
+
40
+ /*
41
+ * We need to increase the timeout, because we might be waiting for
42
+ * data to be sent from the server (the commands was in the output buffer
43
+ * and just flushed
44
+ */
45
+ int32_t timeo= ptr->root->poll_timeout;
46
+ ptr->root->poll_timeout= 2000;
47
+
48
+ result_ptr= memcached_result_create(ptr->root, &result);
49
+ WATCHPOINT_ASSERT(result_ptr);
50
+
51
+ for (x= 0; x < no_msg; x++)
52
+ {
53
+ memcached_result_reset(result_ptr);
54
+ memcached_return rc= memcached_read_one_response(ptr, buffer,
55
+ sizeof (buffer),
56
+ result_ptr);
57
+ /*
58
+ * Purge doesn't care for what kind of command results that is received.
59
+ * The only kind of errors I care about if is I'm out of sync with the
60
+ * protocol or have problems reading data from the network..
61
+ */
62
+ if (rc== MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_UNKNOWN_READ_FAILURE)
63
+ {
64
+ WATCHPOINT_ERROR(rc);
65
+ ret = rc;
66
+ memcached_io_reset(ptr);
67
+ }
68
+ }
69
+
70
+ memcached_result_free(result_ptr);
71
+ ptr->root->poll_timeout= timeo;
72
+ }
73
+ ptr->root->purging= 0;
74
+
75
+ return ret;
76
+ }
@@ -0,0 +1,75 @@
1
+ #include "common.h"
2
+
3
+ /*
4
+ This closes all connections (forces flush of input as well).
5
+
6
+ Maybe add a host specific, or key specific version?
7
+
8
+ The reason we send "quit" is that in case we have buffered IO, this
9
+ will force data to be completed.
10
+ */
11
+
12
+ void memcached_quit_server(memcached_server_st *ptr, uint8_t io_death)
13
+ {
14
+ if (ptr->fd != -1)
15
+ {
16
+ if (io_death == 0 && ptr->type != MEMCACHED_CONNECTION_UDP)
17
+ {
18
+ memcached_return rc;
19
+ char buffer[MEMCACHED_MAX_BUFFER];
20
+
21
+ if (ptr->root->flags & MEM_BINARY_PROTOCOL)
22
+ {
23
+ protocol_binary_request_quit request = {.bytes= {0}};
24
+ request.message.header.request.magic = PROTOCOL_BINARY_REQ;
25
+ request.message.header.request.opcode = PROTOCOL_BINARY_CMD_QUIT;
26
+ request.message.header.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
27
+ rc= memcached_do(ptr, request.bytes, sizeof(request.bytes), 1);
28
+ }
29
+ else
30
+ rc= memcached_do(ptr, "quit\r\n", 6, 1);
31
+
32
+ WATCHPOINT_ASSERT(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_FETCH_NOTFINISHED);
33
+
34
+ /* read until socket is closed, or there is an error
35
+ * closing the socket before all data is read
36
+ * results in server throwing away all data which is
37
+ * not read
38
+ */
39
+ ssize_t nread;
40
+ while (memcached_io_read(ptr, buffer, sizeof(buffer)/sizeof(*buffer),
41
+ &nread) == MEMCACHED_SUCCESS);
42
+ }
43
+ memcached_io_close(ptr);
44
+
45
+ ptr->fd= -1;
46
+ ptr->write_buffer_offset= (size_t) ((ptr->type == MEMCACHED_CONNECTION_UDP) ? UDP_DATAGRAM_HEADER_LENGTH : 0);
47
+ ptr->read_buffer_length= 0;
48
+ ptr->read_ptr= ptr->read_buffer;
49
+ memcached_server_response_reset(ptr);
50
+ }
51
+
52
+ if (io_death)
53
+ {
54
+ ptr->server_failure_counter++;
55
+ }
56
+ else
57
+ {
58
+ ptr->server_failure_counter = 0;
59
+ }
60
+ }
61
+
62
+ void memcached_quit(memcached_st *ptr)
63
+ {
64
+ unsigned int x;
65
+
66
+ if (ptr->hosts == NULL ||
67
+ ptr->number_of_hosts == 0)
68
+ return;
69
+
70
+ if (ptr->hosts && ptr->number_of_hosts)
71
+ {
72
+ for (x= 0; x < ptr->number_of_hosts; x++)
73
+ memcached_quit_server(&ptr->hosts[x], 0);
74
+ }
75
+ }
@@ -0,0 +1,528 @@
1
+ /*
2
+ Memcached library
3
+
4
+ memcached_response() is used to determine the return result
5
+ from an issued command.
6
+ */
7
+
8
+ #include "common.h"
9
+ #include "memcached_io.h"
10
+
11
+ static memcached_return textual_read_one_response(memcached_server_st *ptr,
12
+ char *buffer, size_t buffer_length,
13
+ memcached_result_st *result);
14
+ static memcached_return binary_read_one_response(memcached_server_st *ptr,
15
+ char *buffer, size_t buffer_length,
16
+ memcached_result_st *result);
17
+
18
+ memcached_return memcached_read_one_response(memcached_server_st *ptr,
19
+ char *buffer, size_t buffer_length,
20
+ memcached_result_st *result)
21
+ {
22
+ memcached_server_response_decrement(ptr);
23
+
24
+ if (result == NULL)
25
+ result = &ptr->root->result;
26
+
27
+ memcached_return rc;
28
+ if (ptr->root->flags & MEM_BINARY_PROTOCOL)
29
+ rc= binary_read_one_response(ptr, buffer, buffer_length, result);
30
+ else
31
+ rc= textual_read_one_response(ptr, buffer, buffer_length, result);
32
+
33
+ unlikely(rc == MEMCACHED_UNKNOWN_READ_FAILURE ||
34
+ rc == MEMCACHED_PROTOCOL_ERROR ||
35
+ rc == MEMCACHED_CLIENT_ERROR ||
36
+ rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE)
37
+ memcached_io_reset(ptr);
38
+
39
+ return rc;
40
+ }
41
+
42
+ memcached_return memcached_response(memcached_server_st *ptr,
43
+ char *buffer, size_t buffer_length,
44
+ memcached_result_st *result)
45
+ {
46
+ /* We may have old commands in the buffer not set, first purge */
47
+ if (ptr->root->flags & MEM_NO_BLOCK)
48
+ (void)memcached_io_write(ptr, NULL, 0, 1);
49
+
50
+ /*
51
+ * The previous implementation purged all pending requests and just
52
+ * returned the last one. Purge all pending messages to ensure backwards
53
+ * compatibility.
54
+ */
55
+ if ((ptr->root->flags & MEM_BINARY_PROTOCOL) == 0)
56
+ while (memcached_server_response_count(ptr) > 1)
57
+ {
58
+ memcached_return rc= memcached_read_one_response(ptr, buffer, buffer_length, result);
59
+
60
+ unlikely (rc != MEMCACHED_END &&
61
+ rc != MEMCACHED_STORED &&
62
+ rc != MEMCACHED_SUCCESS &&
63
+ rc != MEMCACHED_STAT &&
64
+ rc != MEMCACHED_DELETED &&
65
+ rc != MEMCACHED_NOTFOUND &&
66
+ rc != MEMCACHED_NOTSTORED &&
67
+ rc != MEMCACHED_DATA_EXISTS)
68
+ return rc;
69
+ }
70
+
71
+ return memcached_read_one_response(ptr, buffer, buffer_length, result);
72
+ }
73
+
74
+ static memcached_return textual_value_fetch(memcached_server_st *ptr,
75
+ char *buffer,
76
+ memcached_result_st *result)
77
+ {
78
+ memcached_return rc= MEMCACHED_SUCCESS;
79
+ char *string_ptr;
80
+ char *end_ptr;
81
+ char *next_ptr;
82
+ size_t value_length;
83
+ size_t to_read;
84
+ char *value_ptr;
85
+
86
+ if (ptr->root->flags & MEM_USE_UDP)
87
+ return MEMCACHED_NOT_SUPPORTED;
88
+
89
+ WATCHPOINT_ASSERT(ptr->root);
90
+ end_ptr= buffer + MEMCACHED_DEFAULT_COMMAND_SIZE;
91
+
92
+ memcached_result_reset(result);
93
+
94
+ string_ptr= buffer;
95
+ string_ptr+= 6; /* "VALUE " */
96
+
97
+
98
+ /* We load the key */
99
+ {
100
+ char *key;
101
+ size_t prefix_length;
102
+
103
+ key= result->key;
104
+ result->key_length= 0;
105
+
106
+ for (prefix_length= ptr->root->prefix_key_length; !(iscntrl(*string_ptr) || isspace(*string_ptr)) ; string_ptr++)
107
+ {
108
+ if (prefix_length == 0)
109
+ {
110
+ *key= *string_ptr;
111
+ key++;
112
+ result->key_length++;
113
+ }
114
+ else
115
+ prefix_length--;
116
+ }
117
+ result->key[result->key_length]= 0;
118
+ }
119
+
120
+ if (end_ptr == string_ptr)
121
+ goto read_error;
122
+
123
+ /* Flags fetch move past space */
124
+ string_ptr++;
125
+ if (end_ptr == string_ptr)
126
+ goto read_error;
127
+ for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
128
+ result->flags= (uint32_t) strtoul(next_ptr, &string_ptr, 10);
129
+
130
+ if (end_ptr == string_ptr)
131
+ goto read_error;
132
+
133
+ /* Length fetch move past space*/
134
+ string_ptr++;
135
+ if (end_ptr == string_ptr)
136
+ goto read_error;
137
+
138
+ for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
139
+ value_length= (size_t)strtoull(next_ptr, &string_ptr, 10);
140
+
141
+ if (end_ptr == string_ptr)
142
+ goto read_error;
143
+
144
+ /* Skip spaces */
145
+ if (*string_ptr == '\r')
146
+ {
147
+ /* Skip past the \r\n */
148
+ string_ptr+= 2;
149
+ }
150
+ else
151
+ {
152
+ string_ptr++;
153
+ for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
154
+ result->cas= strtoull(next_ptr, &string_ptr, 10);
155
+ }
156
+
157
+ if (end_ptr < string_ptr)
158
+ goto read_error;
159
+
160
+ /* We add two bytes so that we can walk the \r\n */
161
+ rc= memcached_string_check(&result->value, value_length+2);
162
+ if (rc != MEMCACHED_SUCCESS)
163
+ {
164
+ value_length= 0;
165
+ return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
166
+ }
167
+
168
+ value_ptr= memcached_string_value(&result->value);
169
+ /*
170
+ We read the \r\n into the string since not doing so is more
171
+ cycles then the waster of memory to do so.
172
+
173
+ We are null terminating through, which will most likely make
174
+ some people lazy about using the return length.
175
+ */
176
+ to_read= (value_length) + 2;
177
+ ssize_t read_length= 0;
178
+ memcached_return rrc= memcached_io_read(ptr, value_ptr, to_read, &read_length);
179
+ if (rrc != MEMCACHED_SUCCESS)
180
+ return rrc;
181
+
182
+ if (read_length != (ssize_t)(value_length + 2))
183
+ {
184
+ goto read_error;
185
+ }
186
+
187
+ /* This next bit blows the API, but this is internal....*/
188
+ {
189
+ char *char_ptr;
190
+ char_ptr= memcached_string_value(&result->value);;
191
+ char_ptr[value_length]= 0;
192
+ char_ptr[value_length + 1]= 0;
193
+ memcached_string_set_length(&result->value, value_length);
194
+ }
195
+
196
+ return MEMCACHED_SUCCESS;
197
+
198
+ read_error:
199
+ memcached_io_reset(ptr);
200
+
201
+ return MEMCACHED_PARTIAL_READ;
202
+ }
203
+
204
+ static memcached_return textual_read_one_response(memcached_server_st *ptr,
205
+ char *buffer, size_t buffer_length,
206
+ memcached_result_st *result)
207
+ {
208
+ memcached_return rc= memcached_io_readline(ptr, buffer, buffer_length);
209
+ if (rc != MEMCACHED_SUCCESS)
210
+ return rc;
211
+
212
+ switch(buffer[0])
213
+ {
214
+ case 'V': /* VALUE || VERSION */
215
+ if (buffer[1] == 'A') /* VALUE */
216
+ {
217
+ /* We add back in one because we will need to search for END */
218
+ memcached_server_response_increment(ptr);
219
+ return textual_value_fetch(ptr, buffer, result);
220
+ }
221
+ else if (buffer[1] == 'E') /* VERSION */
222
+ {
223
+ return MEMCACHED_SUCCESS;
224
+ }
225
+ else
226
+ {
227
+ WATCHPOINT_STRING(buffer);
228
+ WATCHPOINT_ASSERT(0);
229
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
230
+ }
231
+ case 'O': /* OK */
232
+ return MEMCACHED_SUCCESS;
233
+ case 'S': /* STORED STATS SERVER_ERROR */
234
+ {
235
+ if (buffer[2] == 'A') /* STORED STATS */
236
+ {
237
+ memcached_server_response_increment(ptr);
238
+ return MEMCACHED_STAT;
239
+ }
240
+ else if (buffer[1] == 'E') /* SERVER_ERROR */
241
+ {
242
+ memcached_server_error_reset(ptr);
243
+
244
+ char *startptr= buffer + 13, *endptr= startptr;
245
+ while (*endptr != '\r' && *endptr != '\n')
246
+ endptr++;
247
+ size_t err_len = (endptr - startptr + 1);
248
+
249
+ ptr->cached_server_error = malloc(err_len);
250
+ if (ptr->cached_server_error == NULL)
251
+ return MEMCACHED_SERVER_ERROR;
252
+
253
+ strncpy(ptr->cached_server_error, startptr, err_len);
254
+ ptr->cached_server_error[err_len - 1]= 0;
255
+ return MEMCACHED_SERVER_ERROR;
256
+ }
257
+ else if (buffer[1] == 'T')
258
+ return MEMCACHED_STORED;
259
+ else
260
+ {
261
+ WATCHPOINT_STRING(buffer);
262
+ WATCHPOINT_ASSERT(0);
263
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
264
+ }
265
+ }
266
+ case 'D': /* DELETED */
267
+ return MEMCACHED_DELETED;
268
+ case 'N': /* NOT_FOUND */
269
+ {
270
+ if (buffer[4] == 'F')
271
+ return MEMCACHED_NOTFOUND;
272
+ else if (buffer[4] == 'S')
273
+ return MEMCACHED_NOTSTORED;
274
+ else
275
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
276
+ }
277
+ case 'E': /* PROTOCOL ERROR or END */
278
+ {
279
+ if (buffer[1] == 'N')
280
+ return MEMCACHED_END;
281
+ else if (buffer[1] == 'R')
282
+ return MEMCACHED_PROTOCOL_ERROR;
283
+ else if (buffer[1] == 'X')
284
+ return MEMCACHED_DATA_EXISTS;
285
+ else
286
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
287
+ }
288
+ case 'I': /* CLIENT ERROR */
289
+ /* We add back in one because we will need to search for END */
290
+ memcached_server_response_increment(ptr);
291
+ return MEMCACHED_ITEM;
292
+ case 'C': /* CLIENT ERROR */
293
+ return MEMCACHED_CLIENT_ERROR;
294
+ default:
295
+ {
296
+ unsigned long long auto_return_value;
297
+
298
+ if (sscanf(buffer, "%llu", &auto_return_value) == 1)
299
+ return MEMCACHED_SUCCESS;
300
+
301
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
302
+ }
303
+ }
304
+
305
+ /* NOTREACHED */
306
+ }
307
+
308
+ char *memcached_result_value(memcached_result_st *ptr)
309
+ {
310
+ memcached_string_st *sptr= &ptr->value;
311
+ return memcached_string_value(sptr);
312
+ }
313
+
314
+ size_t memcached_result_length(memcached_result_st *ptr)
315
+ {
316
+ memcached_string_st *sptr= &ptr->value;
317
+ return memcached_string_length(sptr);
318
+ }
319
+
320
+ static memcached_return binary_read_one_response(memcached_server_st *ptr,
321
+ char *buffer, size_t buffer_length,
322
+ memcached_result_st *result)
323
+ {
324
+ protocol_binary_response_header header;
325
+
326
+ unlikely (memcached_safe_read(ptr, &header.bytes,
327
+ sizeof(header.bytes)) != MEMCACHED_SUCCESS)
328
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
329
+
330
+ unlikely (header.response.magic != PROTOCOL_BINARY_RES)
331
+ return MEMCACHED_PROTOCOL_ERROR;
332
+
333
+ /*
334
+ ** Convert the header to host local endian!
335
+ */
336
+ header.response.keylen= ntohs(header.response.keylen);
337
+ header.response.status= ntohs(header.response.status);
338
+ header.response.bodylen= ntohl(header.response.bodylen);
339
+ header.response.cas= ntohll(header.response.cas);
340
+ uint32_t bodylen= header.response.bodylen;
341
+
342
+ if (header.response.status == PROTOCOL_BINARY_RESPONSE_SUCCESS ||
343
+ header.response.status == PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE)
344
+ {
345
+ switch (header.response.opcode)
346
+ {
347
+ case PROTOCOL_BINARY_CMD_GETK:
348
+ case PROTOCOL_BINARY_CMD_GETKQ:
349
+ {
350
+ uint16_t keylen= header.response.keylen;
351
+ memcached_result_reset(result);
352
+ result->cas= header.response.cas;
353
+
354
+ if (memcached_safe_read(ptr, &result->flags,
355
+ sizeof (result->flags)) != MEMCACHED_SUCCESS)
356
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
357
+
358
+ result->flags= ntohl(result->flags);
359
+ bodylen -= header.response.extlen;
360
+
361
+ result->key_length= keylen;
362
+ if (memcached_safe_read(ptr, result->key, keylen) != MEMCACHED_SUCCESS)
363
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
364
+
365
+ bodylen -= keylen;
366
+ if (memcached_string_check(&result->value,
367
+ bodylen) != MEMCACHED_SUCCESS)
368
+ return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
369
+
370
+ char *vptr= memcached_string_value(&result->value);
371
+ if (memcached_safe_read(ptr, vptr, bodylen) != MEMCACHED_SUCCESS)
372
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
373
+
374
+ size_t prefix_length = ptr->root->prefix_key_length;
375
+ memmove(result->key, (result->key + prefix_length), keylen - prefix_length + 1);
376
+ result->key_length = keylen - prefix_length;
377
+
378
+ memcached_string_set_length(&result->value, bodylen);
379
+ }
380
+ break;
381
+ case PROTOCOL_BINARY_CMD_INCREMENT:
382
+ case PROTOCOL_BINARY_CMD_DECREMENT:
383
+ {
384
+ if (bodylen != sizeof(uint64_t) || buffer_length != sizeof(uint64_t))
385
+ return MEMCACHED_PROTOCOL_ERROR;
386
+
387
+ WATCHPOINT_ASSERT(bodylen == buffer_length);
388
+ uint64_t val;
389
+ if (memcached_safe_read(ptr, &val, sizeof(val)) != MEMCACHED_SUCCESS)
390
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
391
+
392
+ val= ntohll(val);
393
+ memcpy(buffer, &val, sizeof(val));
394
+ }
395
+ break;
396
+ case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS:
397
+ case PROTOCOL_BINARY_CMD_VERSION:
398
+ {
399
+ memset(buffer, 0, buffer_length);
400
+ if (bodylen >= buffer_length)
401
+ /* not enough space in buffer.. should not happen... */
402
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
403
+ else if (memcached_safe_read(ptr, buffer, bodylen) != MEMCACHED_SUCCESS)
404
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
405
+ }
406
+ break;
407
+ case PROTOCOL_BINARY_CMD_FLUSH:
408
+ case PROTOCOL_BINARY_CMD_QUIT:
409
+ case PROTOCOL_BINARY_CMD_SET:
410
+ case PROTOCOL_BINARY_CMD_ADD:
411
+ case PROTOCOL_BINARY_CMD_REPLACE:
412
+ case PROTOCOL_BINARY_CMD_APPEND:
413
+ case PROTOCOL_BINARY_CMD_PREPEND:
414
+ case PROTOCOL_BINARY_CMD_DELETE:
415
+ {
416
+ WATCHPOINT_ASSERT(bodylen == 0);
417
+ return MEMCACHED_SUCCESS;
418
+ }
419
+ case PROTOCOL_BINARY_CMD_NOOP:
420
+ {
421
+ WATCHPOINT_ASSERT(bodylen == 0);
422
+ return MEMCACHED_END;
423
+ }
424
+ case PROTOCOL_BINARY_CMD_STAT:
425
+ {
426
+ if (bodylen == 0)
427
+ return MEMCACHED_END;
428
+ else if (bodylen + 1 > buffer_length)
429
+ /* not enough space in buffer.. should not happen... */
430
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
431
+ else
432
+ {
433
+ size_t keylen= header.response.keylen;
434
+ memset(buffer, 0, buffer_length);
435
+ if (memcached_safe_read(ptr, buffer, keylen) != MEMCACHED_SUCCESS ||
436
+ memcached_safe_read(ptr, buffer + keylen + 1,
437
+ bodylen - keylen) != MEMCACHED_SUCCESS)
438
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
439
+ }
440
+ }
441
+ break;
442
+
443
+ case PROTOCOL_BINARY_CMD_SASL_AUTH:
444
+ case PROTOCOL_BINARY_CMD_SASL_STEP:
445
+ {
446
+ memcached_result_reset(result);
447
+ result->cas= header.response.cas;
448
+
449
+ if (memcached_string_check(&result->value,
450
+ bodylen) != MEMCACHED_SUCCESS)
451
+ return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
452
+
453
+ char *vptr= memcached_string_value(&result->value);
454
+ if (memcached_safe_read(ptr, vptr, bodylen) != MEMCACHED_SUCCESS)
455
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
456
+
457
+ memcached_string_set_length(&result->value, bodylen);
458
+ }
459
+ break;
460
+
461
+ default:
462
+ {
463
+ /* Command not implemented yet! */
464
+ WATCHPOINT_ASSERT(0);
465
+ return MEMCACHED_PROTOCOL_ERROR;
466
+ }
467
+ }
468
+ }
469
+ else if (header.response.bodylen)
470
+ {
471
+ /* What should I do with the error message??? just discard it for now */
472
+ char hole[SMALL_STRING_LEN];
473
+ while (bodylen > 0)
474
+ {
475
+ size_t nr= (bodylen > SMALL_STRING_LEN) ? SMALL_STRING_LEN : bodylen;
476
+ if (memcached_safe_read(ptr, hole, nr) != MEMCACHED_SUCCESS)
477
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
478
+ bodylen-= (uint32_t) nr;
479
+ }
480
+
481
+ /* This might be an error from one of the quiet commands.. if
482
+ * so, just throw it away and get the next one. What about creating
483
+ * a callback to the user with the error information?
484
+ */
485
+ switch (header.response.opcode)
486
+ {
487
+ case PROTOCOL_BINARY_CMD_SETQ:
488
+ case PROTOCOL_BINARY_CMD_ADDQ:
489
+ case PROTOCOL_BINARY_CMD_REPLACEQ:
490
+ case PROTOCOL_BINARY_CMD_APPENDQ:
491
+ case PROTOCOL_BINARY_CMD_PREPENDQ:
492
+ return binary_read_one_response(ptr, buffer, buffer_length, result);
493
+ default:
494
+ break;
495
+ }
496
+ }
497
+
498
+ memcached_return rc= MEMCACHED_SUCCESS;
499
+ unlikely(header.response.status != 0)
500
+ switch (header.response.status)
501
+ {
502
+ case PROTOCOL_BINARY_RESPONSE_KEY_ENOENT:
503
+ rc= MEMCACHED_NOTFOUND;
504
+ break;
505
+ case PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS:
506
+ rc= MEMCACHED_DATA_EXISTS;
507
+ break;
508
+ case PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE:
509
+ rc= MEMCACHED_AUTH_CONTINUE;
510
+ break;
511
+ case PROTOCOL_BINARY_RESPONSE_AUTH_ERROR:
512
+ rc= MEMCACHED_AUTH_FAILURE;
513
+ break;
514
+ case PROTOCOL_BINARY_RESPONSE_E2BIG:
515
+ case PROTOCOL_BINARY_RESPONSE_EINVAL:
516
+ case PROTOCOL_BINARY_RESPONSE_NOT_STORED:
517
+ rc= MEMCACHED_NOTSTORED;
518
+ break;
519
+ case PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND:
520
+ case PROTOCOL_BINARY_RESPONSE_ENOMEM:
521
+ default:
522
+ /* @todo fix the error mappings */
523
+ rc= MEMCACHED_PROTOCOL_ERROR;
524
+ break;
525
+ }
526
+
527
+ return rc;
528
+ }