couchbase-memcached 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (539) hide show
  1. data.tar.gz.sig +2 -0
  2. data/BENCHMARKS +134 -0
  3. data/CHANGELOG +127 -0
  4. data/LICENSE +184 -0
  5. data/Manifest +535 -0
  6. data/README +118 -0
  7. data/Rakefile +83 -0
  8. data/TODO +4 -0
  9. data/couchbase-memcached.gemspec +33 -0
  10. data/ext/extconf-make.rb +25 -0
  11. data/ext/extconf.rb +91 -0
  12. data/ext/libmemcached-0.50/AUTHORS +11 -0
  13. data/ext/libmemcached-0.50/COPYING +33 -0
  14. data/ext/libmemcached-0.50/ChangeLog +392 -0
  15. data/ext/libmemcached-0.50/Makefile.am +114 -0
  16. data/ext/libmemcached-0.50/Makefile.in +4232 -0
  17. data/ext/libmemcached-0.50/NEWS +1 -0
  18. data/ext/libmemcached-0.50/README +43 -0
  19. data/ext/libmemcached-0.50/README.FIRST +31 -0
  20. data/ext/libmemcached-0.50/README.win32 +25 -0
  21. data/ext/libmemcached-0.50/THANKS +14 -0
  22. data/ext/libmemcached-0.50/TODO +11 -0
  23. data/ext/libmemcached-0.50/aclocal.m4 +1077 -0
  24. data/ext/libmemcached-0.50/clients/client_options.h +45 -0
  25. data/ext/libmemcached-0.50/clients/execute.cc +131 -0
  26. data/ext/libmemcached-0.50/clients/execute.h +30 -0
  27. data/ext/libmemcached-0.50/clients/generator.cc +96 -0
  28. data/ext/libmemcached-0.50/clients/generator.h +36 -0
  29. data/ext/libmemcached-0.50/clients/include.am +116 -0
  30. data/ext/libmemcached-0.50/clients/memaslap.c +908 -0
  31. data/ext/libmemcached-0.50/clients/memcapable.cc +2094 -0
  32. data/ext/libmemcached-0.50/clients/memcat.cc +242 -0
  33. data/ext/libmemcached-0.50/clients/memcp.cc +317 -0
  34. data/ext/libmemcached-0.50/clients/memdump.cc +183 -0
  35. data/ext/libmemcached-0.50/clients/memerror.cc +102 -0
  36. data/ext/libmemcached-0.50/clients/memflush.cc +154 -0
  37. data/ext/libmemcached-0.50/clients/memparse.cc +68 -0
  38. data/ext/libmemcached-0.50/clients/memrm.cc +177 -0
  39. data/ext/libmemcached-0.50/clients/memslap.cc +495 -0
  40. data/ext/libmemcached-0.50/clients/memstat.cc +349 -0
  41. data/ext/libmemcached-0.50/clients/ms_atomic.h +69 -0
  42. data/ext/libmemcached-0.50/clients/ms_conn.c +3413 -0
  43. data/ext/libmemcached-0.50/clients/ms_conn.h +241 -0
  44. data/ext/libmemcached-0.50/clients/ms_memslap.h +132 -0
  45. data/ext/libmemcached-0.50/clients/ms_setting.c +1068 -0
  46. data/ext/libmemcached-0.50/clients/ms_setting.h +181 -0
  47. data/ext/libmemcached-0.50/clients/ms_sigsegv.c +126 -0
  48. data/ext/libmemcached-0.50/clients/ms_sigsegv.h +34 -0
  49. data/ext/libmemcached-0.50/clients/ms_stats.c +307 -0
  50. data/ext/libmemcached-0.50/clients/ms_stats.h +69 -0
  51. data/ext/libmemcached-0.50/clients/ms_task.c +1114 -0
  52. data/ext/libmemcached-0.50/clients/ms_task.h +94 -0
  53. data/ext/libmemcached-0.50/clients/ms_thread.c +351 -0
  54. data/ext/libmemcached-0.50/clients/ms_thread.h +78 -0
  55. data/ext/libmemcached-0.50/clients/utilities.cc +231 -0
  56. data/ext/libmemcached-0.50/clients/utilities.h +64 -0
  57. data/ext/libmemcached-0.50/config.h.in +647 -0
  58. data/ext/libmemcached-0.50/config/autorun.sh +126 -0
  59. data/ext/libmemcached-0.50/config/compile +143 -0
  60. data/ext/libmemcached-0.50/config/config.guess +1517 -0
  61. data/ext/libmemcached-0.50/config/config.rpath +666 -0
  62. data/ext/libmemcached-0.50/config/config.sub +1760 -0
  63. data/ext/libmemcached-0.50/config/depcomp +630 -0
  64. data/ext/libmemcached-0.50/config/install-sh +520 -0
  65. data/ext/libmemcached-0.50/config/ltmain.sh +9642 -0
  66. data/ext/libmemcached-0.50/config/missing +376 -0
  67. data/ext/libmemcached-0.50/config/pandora-plugin +752 -0
  68. data/ext/libmemcached-0.50/config/uncrustify.cfg +1112 -0
  69. data/ext/libmemcached-0.50/configure +27103 -0
  70. data/ext/libmemcached-0.50/configure.ac +186 -0
  71. data/ext/libmemcached-0.50/docs/conf.py.in +354 -0
  72. data/ext/libmemcached-0.50/docs/include.am +240 -0
  73. data/ext/libmemcached-0.50/docs/man/hashkit_clone.3 +88 -0
  74. data/ext/libmemcached-0.50/docs/man/hashkit_crc32.3 +105 -0
  75. data/ext/libmemcached-0.50/docs/man/hashkit_create.3 +88 -0
  76. data/ext/libmemcached-0.50/docs/man/hashkit_fnv1_32.3 +105 -0
  77. data/ext/libmemcached-0.50/docs/man/hashkit_fnv1_64.3 +105 -0
  78. data/ext/libmemcached-0.50/docs/man/hashkit_fnv1a_32.3 +105 -0
  79. data/ext/libmemcached-0.50/docs/man/hashkit_fnv1a_64.3 +105 -0
  80. data/ext/libmemcached-0.50/docs/man/hashkit_free.3 +88 -0
  81. data/ext/libmemcached-0.50/docs/man/hashkit_functions.3 +105 -0
  82. data/ext/libmemcached-0.50/docs/man/hashkit_hsieh.3 +105 -0
  83. data/ext/libmemcached-0.50/docs/man/hashkit_is_allocated.3 +88 -0
  84. data/ext/libmemcached-0.50/docs/man/hashkit_jenkins.3 +105 -0
  85. data/ext/libmemcached-0.50/docs/man/hashkit_md5.3 +105 -0
  86. data/ext/libmemcached-0.50/docs/man/hashkit_murmur.3 +105 -0
  87. data/ext/libmemcached-0.50/docs/man/hashkit_value.3 +66 -0
  88. data/ext/libmemcached-0.50/docs/man/libhashkit.3 +57 -0
  89. data/ext/libmemcached-0.50/docs/man/libmemcached.3 +208 -0
  90. data/ext/libmemcached-0.50/docs/man/libmemcached_check_configuration.3 +293 -0
  91. data/ext/libmemcached-0.50/docs/man/libmemcached_configuration.3 +293 -0
  92. data/ext/libmemcached-0.50/docs/man/libmemcached_examples.3 +144 -0
  93. data/ext/libmemcached-0.50/docs/man/libmemcachedutil.3 +68 -0
  94. data/ext/libmemcached-0.50/docs/man/memaslap.1 +1222 -0
  95. data/ext/libmemcached-0.50/docs/man/memcached.3 +293 -0
  96. data/ext/libmemcached-0.50/docs/man/memcached_add.3 +132 -0
  97. data/ext/libmemcached-0.50/docs/man/memcached_add_by_key.3 +132 -0
  98. data/ext/libmemcached-0.50/docs/man/memcached_analyze.3 +77 -0
  99. data/ext/libmemcached-0.50/docs/man/memcached_append.3 +111 -0
  100. data/ext/libmemcached-0.50/docs/man/memcached_append_by_key.3 +111 -0
  101. data/ext/libmemcached-0.50/docs/man/memcached_behavior_get.3 +333 -0
  102. data/ext/libmemcached-0.50/docs/man/memcached_behavior_set.3 +333 -0
  103. data/ext/libmemcached-0.50/docs/man/memcached_callback_get.3 +159 -0
  104. data/ext/libmemcached-0.50/docs/man/memcached_callback_set.3 +159 -0
  105. data/ext/libmemcached-0.50/docs/man/memcached_cas.3 +91 -0
  106. data/ext/libmemcached-0.50/docs/man/memcached_cas_by_key.3 +91 -0
  107. data/ext/libmemcached-0.50/docs/man/memcached_clone.3 +99 -0
  108. data/ext/libmemcached-0.50/docs/man/memcached_create.3 +99 -0
  109. data/ext/libmemcached-0.50/docs/man/memcached_decrement.3 +124 -0
  110. data/ext/libmemcached-0.50/docs/man/memcached_decrement_with_initial.3 +124 -0
  111. data/ext/libmemcached-0.50/docs/man/memcached_delete.3 +83 -0
  112. data/ext/libmemcached-0.50/docs/man/memcached_delete_by_key.3 +83 -0
  113. data/ext/libmemcached-0.50/docs/man/memcached_destroy_sasl_auth_data.3 +95 -0
  114. data/ext/libmemcached-0.50/docs/man/memcached_dump.3 +77 -0
  115. data/ext/libmemcached-0.50/docs/man/memcached_fetch.3 +174 -0
  116. data/ext/libmemcached-0.50/docs/man/memcached_fetch_execute.3 +174 -0
  117. data/ext/libmemcached-0.50/docs/man/memcached_fetch_result.3 +174 -0
  118. data/ext/libmemcached-0.50/docs/man/memcached_flush_buffers.3 +72 -0
  119. data/ext/libmemcached-0.50/docs/man/memcached_free.3 +99 -0
  120. data/ext/libmemcached-0.50/docs/man/memcached_generate_hash.3 +85 -0
  121. data/ext/libmemcached-0.50/docs/man/memcached_generate_hash_value.3 +85 -0
  122. data/ext/libmemcached-0.50/docs/man/memcached_get.3 +174 -0
  123. data/ext/libmemcached-0.50/docs/man/memcached_get_by_key.3 +174 -0
  124. data/ext/libmemcached-0.50/docs/man/memcached_get_memory_allocators.3 +111 -0
  125. data/ext/libmemcached-0.50/docs/man/memcached_get_sasl_callbacks.3 +95 -0
  126. data/ext/libmemcached-0.50/docs/man/memcached_get_user_data.3 +79 -0
  127. data/ext/libmemcached-0.50/docs/man/memcached_increment.3 +124 -0
  128. data/ext/libmemcached-0.50/docs/man/memcached_increment_with_initial.3 +124 -0
  129. data/ext/libmemcached-0.50/docs/man/memcached_lib_version.3 +76 -0
  130. data/ext/libmemcached-0.50/docs/man/memcached_mget.3 +174 -0
  131. data/ext/libmemcached-0.50/docs/man/memcached_mget_by_key.3 +174 -0
  132. data/ext/libmemcached-0.50/docs/man/memcached_mget_execute.3 +174 -0
  133. data/ext/libmemcached-0.50/docs/man/memcached_mget_execute_by_key.3 +174 -0
  134. data/ext/libmemcached-0.50/docs/man/memcached_pool_behavior_get.3 +139 -0
  135. data/ext/libmemcached-0.50/docs/man/memcached_pool_behavior_set.3 +139 -0
  136. data/ext/libmemcached-0.50/docs/man/memcached_pool_create.3 +139 -0
  137. data/ext/libmemcached-0.50/docs/man/memcached_pool_destroy.3 +139 -0
  138. data/ext/libmemcached-0.50/docs/man/memcached_pool_pop.3 +139 -0
  139. data/ext/libmemcached-0.50/docs/man/memcached_pool_push.3 +139 -0
  140. data/ext/libmemcached-0.50/docs/man/memcached_pool_st.3 +139 -0
  141. data/ext/libmemcached-0.50/docs/man/memcached_prepend.3 +111 -0
  142. data/ext/libmemcached-0.50/docs/man/memcached_prepend_by_key.3 +111 -0
  143. data/ext/libmemcached-0.50/docs/man/memcached_quit.3 +74 -0
  144. data/ext/libmemcached-0.50/docs/man/memcached_replace.3 +132 -0
  145. data/ext/libmemcached-0.50/docs/man/memcached_replace_by_key.3 +132 -0
  146. data/ext/libmemcached-0.50/docs/man/memcached_sasl_set_auth_data.3 +95 -0
  147. data/ext/libmemcached-0.50/docs/man/memcached_server_add.3 +141 -0
  148. data/ext/libmemcached-0.50/docs/man/memcached_server_count.3 +141 -0
  149. data/ext/libmemcached-0.50/docs/man/memcached_server_cursor.3 +141 -0
  150. data/ext/libmemcached-0.50/docs/man/memcached_server_list.3 +141 -0
  151. data/ext/libmemcached-0.50/docs/man/memcached_server_list_append.3 +111 -0
  152. data/ext/libmemcached-0.50/docs/man/memcached_server_list_count.3 +111 -0
  153. data/ext/libmemcached-0.50/docs/man/memcached_server_list_free.3 +111 -0
  154. data/ext/libmemcached-0.50/docs/man/memcached_server_push.3 +141 -0
  155. data/ext/libmemcached-0.50/docs/man/memcached_servers_parse.3 +111 -0
  156. data/ext/libmemcached-0.50/docs/man/memcached_set.3 +132 -0
  157. data/ext/libmemcached-0.50/docs/man/memcached_set_by_key.3 +132 -0
  158. data/ext/libmemcached-0.50/docs/man/memcached_set_memory_allocators.3 +111 -0
  159. data/ext/libmemcached-0.50/docs/man/memcached_set_sasl_callbacks.3 +95 -0
  160. data/ext/libmemcached-0.50/docs/man/memcached_set_user_data.3 +79 -0
  161. data/ext/libmemcached-0.50/docs/man/memcached_stat.3 +116 -0
  162. data/ext/libmemcached-0.50/docs/man/memcached_stat_execute.3 +116 -0
  163. data/ext/libmemcached-0.50/docs/man/memcached_stat_get_keys.3 +116 -0
  164. data/ext/libmemcached-0.50/docs/man/memcached_stat_get_value.3 +116 -0
  165. data/ext/libmemcached-0.50/docs/man/memcached_stat_servername.3 +116 -0
  166. data/ext/libmemcached-0.50/docs/man/memcached_strerror.3 +69 -0
  167. data/ext/libmemcached-0.50/docs/man/memcached_verbosity.3 +66 -0
  168. data/ext/libmemcached-0.50/docs/man/memcached_version.3 +76 -0
  169. data/ext/libmemcached-0.50/docs/man/memcapable.1 +92 -0
  170. data/ext/libmemcached-0.50/docs/man/memcat.1 +71 -0
  171. data/ext/libmemcached-0.50/docs/man/memcp.1 +77 -0
  172. data/ext/libmemcached-0.50/docs/man/memdump.1 +66 -0
  173. data/ext/libmemcached-0.50/docs/man/memerror.1 +65 -0
  174. data/ext/libmemcached-0.50/docs/man/memflush.1 +73 -0
  175. data/ext/libmemcached-0.50/docs/man/memrm.1 +72 -0
  176. data/ext/libmemcached-0.50/docs/man/memslap.1 +59 -0
  177. data/ext/libmemcached-0.50/docs/man/memstat.1 +70 -0
  178. data/ext/libmemcached-0.50/example/include.am +24 -0
  179. data/ext/libmemcached-0.50/example/interface_v0.c +594 -0
  180. data/ext/libmemcached-0.50/example/interface_v1.c +411 -0
  181. data/ext/libmemcached-0.50/example/memcached_light.c +474 -0
  182. data/ext/libmemcached-0.50/example/memcached_light.h +7 -0
  183. data/ext/libmemcached-0.50/example/storage.c +172 -0
  184. data/ext/libmemcached-0.50/example/storage.h +27 -0
  185. data/ext/libmemcached-0.50/example/storage_innodb.c +535 -0
  186. data/ext/libmemcached-0.50/libhashkit/algorithm.cc +69 -0
  187. data/ext/libmemcached-0.50/libhashkit/algorithm.h +96 -0
  188. data/ext/libmemcached-0.50/libhashkit/behavior.cc +9 -0
  189. data/ext/libmemcached-0.50/libhashkit/behavior.h +26 -0
  190. data/ext/libmemcached-0.50/libhashkit/common.h +33 -0
  191. data/ext/libmemcached-0.50/libhashkit/configure.h.in +19 -0
  192. data/ext/libmemcached-0.50/libhashkit/crc32.cc +86 -0
  193. data/ext/libmemcached-0.50/libhashkit/digest.cc +62 -0
  194. data/ext/libmemcached-0.50/libhashkit/digest.h +30 -0
  195. data/ext/libmemcached-0.50/libhashkit/fnv.cc +75 -0
  196. data/ext/libmemcached-0.50/libhashkit/function.cc +156 -0
  197. data/ext/libmemcached-0.50/libhashkit/function.h +44 -0
  198. data/ext/libmemcached-0.50/libhashkit/hashkit.cc +100 -0
  199. data/ext/libmemcached-0.50/libhashkit/hashkit.h +95 -0
  200. data/ext/libmemcached-0.50/libhashkit/hashkit.hpp +97 -0
  201. data/ext/libmemcached-0.50/libhashkit/hsieh.cc +70 -0
  202. data/ext/libmemcached-0.50/libhashkit/include.am +69 -0
  203. data/ext/libmemcached-0.50/libhashkit/jenkins.cc +214 -0
  204. data/ext/libmemcached-0.50/libhashkit/ketama.cc +164 -0
  205. data/ext/libmemcached-0.50/libhashkit/md5.cc +367 -0
  206. data/ext/libmemcached-0.50/libhashkit/murmur.cc +77 -0
  207. data/ext/libmemcached-0.50/libhashkit/one_at_a_time.cc +34 -0
  208. data/ext/libmemcached-0.50/libhashkit/str_algorithm.cc +58 -0
  209. data/ext/libmemcached-0.50/libhashkit/str_algorithm.h +48 -0
  210. data/ext/libmemcached-0.50/libhashkit/strerror.cc +25 -0
  211. data/ext/libmemcached-0.50/libhashkit/strerror.h +23 -0
  212. data/ext/libmemcached-0.50/libhashkit/types.h +90 -0
  213. data/ext/libmemcached-0.50/libhashkit/visibility.h +48 -0
  214. data/ext/libmemcached-0.50/libmemcached/allocators.cc +119 -0
  215. data/ext/libmemcached-0.50/libmemcached/allocators.h +87 -0
  216. data/ext/libmemcached-0.50/libmemcached/analyze.cc +110 -0
  217. data/ext/libmemcached-0.50/libmemcached/analyze.h +66 -0
  218. data/ext/libmemcached-0.50/libmemcached/array.c +128 -0
  219. data/ext/libmemcached-0.50/libmemcached/array.h +75 -0
  220. data/ext/libmemcached-0.50/libmemcached/auto.cc +383 -0
  221. data/ext/libmemcached-0.50/libmemcached/auto.h +111 -0
  222. data/ext/libmemcached-0.50/libmemcached/basic_string.h +55 -0
  223. data/ext/libmemcached-0.50/libmemcached/behavior.cc +590 -0
  224. data/ext/libmemcached-0.50/libmemcached/behavior.h +86 -0
  225. data/ext/libmemcached-0.50/libmemcached/byteorder.cc +90 -0
  226. data/ext/libmemcached-0.50/libmemcached/byteorder.h +52 -0
  227. data/ext/libmemcached-0.50/libmemcached/callback.cc +160 -0
  228. data/ext/libmemcached-0.50/libmemcached/callback.h +61 -0
  229. data/ext/libmemcached-0.50/libmemcached/common.h +182 -0
  230. data/ext/libmemcached-0.50/libmemcached/configure.h.in +52 -0
  231. data/ext/libmemcached-0.50/libmemcached/connect.cc +626 -0
  232. data/ext/libmemcached-0.50/libmemcached/constants.h +167 -0
  233. data/ext/libmemcached-0.50/libmemcached/delete.cc +266 -0
  234. data/ext/libmemcached-0.50/libmemcached/delete.h +57 -0
  235. data/ext/libmemcached-0.50/libmemcached/do.cc +100 -0
  236. data/ext/libmemcached-0.50/libmemcached/do.hpp +49 -0
  237. data/ext/libmemcached-0.50/libmemcached/dump.cc +107 -0
  238. data/ext/libmemcached-0.50/libmemcached/dump.h +51 -0
  239. data/ext/libmemcached-0.50/libmemcached/error.cc +419 -0
  240. data/ext/libmemcached-0.50/libmemcached/error.h +61 -0
  241. data/ext/libmemcached-0.50/libmemcached/error.hpp +87 -0
  242. data/ext/libmemcached-0.50/libmemcached/exception.hpp +63 -0
  243. data/ext/libmemcached-0.50/libmemcached/fetch.cc +267 -0
  244. data/ext/libmemcached-0.50/libmemcached/fetch.h +53 -0
  245. data/ext/libmemcached-0.50/libmemcached/flush.cc +149 -0
  246. data/ext/libmemcached-0.50/libmemcached/flush.h +49 -0
  247. data/ext/libmemcached-0.50/libmemcached/flush_buffers.cc +66 -0
  248. data/ext/libmemcached-0.50/libmemcached/flush_buffers.h +49 -0
  249. data/ext/libmemcached-0.50/libmemcached/get.cc +842 -0
  250. data/ext/libmemcached-0.50/libmemcached/get.h +135 -0
  251. data/ext/libmemcached-0.50/libmemcached/hash.cc +178 -0
  252. data/ext/libmemcached-0.50/libmemcached/hash.h +68 -0
  253. data/ext/libmemcached-0.50/libmemcached/hosts.cc +516 -0
  254. data/ext/libmemcached-0.50/libmemcached/include.am +183 -0
  255. data/ext/libmemcached-0.50/libmemcached/initialize_query.cc +70 -0
  256. data/ext/libmemcached-0.50/libmemcached/initialize_query.h +51 -0
  257. data/ext/libmemcached-0.50/libmemcached/internal.h +46 -0
  258. data/ext/libmemcached-0.50/libmemcached/io.cc +920 -0
  259. data/ext/libmemcached-0.50/libmemcached/io.h +119 -0
  260. data/ext/libmemcached-0.50/libmemcached/is.h +48 -0
  261. data/ext/libmemcached-0.50/libmemcached/key.cc +23 -0
  262. data/ext/libmemcached-0.50/libmemcached/libmemcached_probes.d +30 -0
  263. data/ext/libmemcached-0.50/libmemcached/libmemcached_probes.h +118 -0
  264. data/ext/libmemcached-0.50/libmemcached/memcached.cc +437 -0
  265. data/ext/libmemcached-0.50/libmemcached/memcached.h +214 -0
  266. data/ext/libmemcached-0.50/libmemcached/memcached.hpp +799 -0
  267. data/ext/libmemcached-0.50/libmemcached/memcached/README.txt +7 -0
  268. data/ext/libmemcached-0.50/libmemcached/memcached/protocol_binary.h +726 -0
  269. data/ext/libmemcached-0.50/libmemcached/memcached/vbucket.h +26 -0
  270. data/ext/libmemcached-0.50/libmemcached/memcached_util.h +44 -0
  271. data/ext/libmemcached-0.50/libmemcached/memory.h +79 -0
  272. data/ext/libmemcached-0.50/libmemcached/options.cc +178 -0
  273. data/ext/libmemcached-0.50/libmemcached/options.h +49 -0
  274. data/ext/libmemcached-0.50/libmemcached/options.hpp +56 -0
  275. data/ext/libmemcached-0.50/libmemcached/options/context.h +151 -0
  276. data/ext/libmemcached-0.50/libmemcached/options/include.am +19 -0
  277. data/ext/libmemcached-0.50/libmemcached/options/parser.am +0 -0
  278. data/ext/libmemcached-0.50/libmemcached/options/parser.cc +2324 -0
  279. data/ext/libmemcached-0.50/libmemcached/options/parser.h +122 -0
  280. data/ext/libmemcached-0.50/libmemcached/options/scanner.cc +3203 -0
  281. data/ext/libmemcached-0.50/libmemcached/options/scanner.h +479 -0
  282. data/ext/libmemcached-0.50/libmemcached/options/server.h +60 -0
  283. data/ext/libmemcached-0.50/libmemcached/options/symbol.h +57 -0
  284. data/ext/libmemcached-0.50/libmemcached/parse.cc +110 -0
  285. data/ext/libmemcached-0.50/libmemcached/parse.h +23 -0
  286. data/ext/libmemcached-0.50/libmemcached/platform.h +56 -0
  287. data/ext/libmemcached-0.50/libmemcached/prefix_key.cc +65 -0
  288. data/ext/libmemcached-0.50/libmemcached/prefix_key.h +49 -0
  289. data/ext/libmemcached-0.50/libmemcached/protocol/ascii_handler.c +963 -0
  290. data/ext/libmemcached-0.50/libmemcached/protocol/ascii_handler.h +40 -0
  291. data/ext/libmemcached-0.50/libmemcached/protocol/binary_handler.c +1121 -0
  292. data/ext/libmemcached-0.50/libmemcached/protocol/binary_handler.h +47 -0
  293. data/ext/libmemcached-0.50/libmemcached/protocol/cache.c +149 -0
  294. data/ext/libmemcached-0.50/libmemcached/protocol/cache.h +116 -0
  295. data/ext/libmemcached-0.50/libmemcached/protocol/callback.h +418 -0
  296. data/ext/libmemcached-0.50/libmemcached/protocol/common.h +163 -0
  297. data/ext/libmemcached-0.50/libmemcached/protocol/include.am +26 -0
  298. data/ext/libmemcached-0.50/libmemcached/protocol/pedantic.c +202 -0
  299. data/ext/libmemcached-0.50/libmemcached/protocol/protocol_handler.c +365 -0
  300. data/ext/libmemcached-0.50/libmemcached/protocol_handler.h +215 -0
  301. data/ext/libmemcached-0.50/libmemcached/purge.cc +90 -0
  302. data/ext/libmemcached-0.50/libmemcached/quit.cc +139 -0
  303. data/ext/libmemcached-0.50/libmemcached/quit.h +55 -0
  304. data/ext/libmemcached-0.50/libmemcached/response.cc +619 -0
  305. data/ext/libmemcached-0.50/libmemcached/response.h +57 -0
  306. data/ext/libmemcached-0.50/libmemcached/result.cc +173 -0
  307. data/ext/libmemcached-0.50/libmemcached/result.h +100 -0
  308. data/ext/libmemcached-0.50/libmemcached/return.h +98 -0
  309. data/ext/libmemcached-0.50/libmemcached/sasl.c +408 -0
  310. data/ext/libmemcached-0.50/libmemcached/sasl.h +86 -0
  311. data/ext/libmemcached-0.50/libmemcached/server.cc +351 -0
  312. data/ext/libmemcached-0.50/libmemcached/server.h +169 -0
  313. data/ext/libmemcached-0.50/libmemcached/server_list.cc +88 -0
  314. data/ext/libmemcached-0.50/libmemcached/server_list.h +77 -0
  315. data/ext/libmemcached-0.50/libmemcached/stats.cc +623 -0
  316. data/ext/libmemcached-0.50/libmemcached/stats.h +96 -0
  317. data/ext/libmemcached-0.50/libmemcached/storage.cc +567 -0
  318. data/ext/libmemcached-0.50/libmemcached/storage.h +133 -0
  319. data/ext/libmemcached-0.50/libmemcached/strerror.cc +189 -0
  320. data/ext/libmemcached-0.50/libmemcached/strerror.h +50 -0
  321. data/ext/libmemcached-0.50/libmemcached/string.cc +253 -0
  322. data/ext/libmemcached-0.50/libmemcached/string.h +121 -0
  323. data/ext/libmemcached-0.50/libmemcached/touch.cc +106 -0
  324. data/ext/libmemcached-0.50/libmemcached/touch.h +59 -0
  325. data/ext/libmemcached-0.50/libmemcached/types.h +117 -0
  326. data/ext/libmemcached-0.50/libmemcached/util.h +40 -0
  327. data/ext/libmemcached-0.50/libmemcached/util/flush.cc +61 -0
  328. data/ext/libmemcached-0.50/libmemcached/util/flush.h +50 -0
  329. data/ext/libmemcached-0.50/libmemcached/util/include.am +34 -0
  330. data/ext/libmemcached-0.50/libmemcached/util/ping.cc +62 -0
  331. data/ext/libmemcached-0.50/libmemcached/util/ping.h +49 -0
  332. data/ext/libmemcached-0.50/libmemcached/util/pool.cc +392 -0
  333. data/ext/libmemcached-0.50/libmemcached/util/pool.h +78 -0
  334. data/ext/libmemcached-0.50/libmemcached/util/version.cc +87 -0
  335. data/ext/libmemcached-0.50/libmemcached/util/version.h +53 -0
  336. data/ext/libmemcached-0.50/libmemcached/verbosity.cc +97 -0
  337. data/ext/libmemcached-0.50/libmemcached/verbosity.h +50 -0
  338. data/ext/libmemcached-0.50/libmemcached/version.cc +214 -0
  339. data/ext/libmemcached-0.50/libmemcached/version.h +52 -0
  340. data/ext/libmemcached-0.50/libmemcached/virtual_bucket.c +118 -0
  341. data/ext/libmemcached-0.50/libmemcached/virtual_bucket.h +59 -0
  342. data/ext/libmemcached-0.50/libmemcached/visibility.h +51 -0
  343. data/ext/libmemcached-0.50/libmemcached/watchpoint.h +110 -0
  344. data/ext/libmemcached-0.50/libtest/callbacks.h +21 -0
  345. data/ext/libmemcached-0.50/libtest/collection.h +19 -0
  346. data/ext/libmemcached-0.50/libtest/common.h +50 -0
  347. data/ext/libmemcached-0.50/libtest/core.h +11 -0
  348. data/ext/libmemcached-0.50/libtest/error.h +18 -0
  349. data/ext/libmemcached-0.50/libtest/failed.h +52 -0
  350. data/ext/libmemcached-0.50/libtest/framework.cc +57 -0
  351. data/ext/libmemcached-0.50/libtest/framework.h +137 -0
  352. data/ext/libmemcached-0.50/libtest/get.h +22 -0
  353. data/ext/libmemcached-0.50/libtest/include.am +52 -0
  354. data/ext/libmemcached-0.50/libtest/runner.h +19 -0
  355. data/ext/libmemcached-0.50/libtest/server.c +355 -0
  356. data/ext/libmemcached-0.50/libtest/server.h +43 -0
  357. data/ext/libmemcached-0.50/libtest/stats.h +30 -0
  358. data/ext/libmemcached-0.50/libtest/strerror.h +14 -0
  359. data/ext/libmemcached-0.50/libtest/test.cc +319 -0
  360. data/ext/libmemcached-0.50/libtest/test.h +162 -0
  361. data/ext/libmemcached-0.50/libtest/test.hpp +46 -0
  362. data/ext/libmemcached-0.50/libtest/visibility.h +69 -0
  363. data/ext/libmemcached-0.50/m4/ac_cxx_header_stdcxx_98.m4 +83 -0
  364. data/ext/libmemcached-0.50/m4/acx_pthread.m4 +271 -0
  365. data/ext/libmemcached-0.50/m4/byteorder.m4 +19 -0
  366. data/ext/libmemcached-0.50/m4/deprecated.m4 +17 -0
  367. data/ext/libmemcached-0.50/m4/eagain.m4 +28 -0
  368. data/ext/libmemcached-0.50/m4/enable_utillib.m4 +16 -0
  369. data/ext/libmemcached-0.50/m4/gettext.m4 +379 -0
  370. data/ext/libmemcached-0.50/m4/hsieh.m4 +18 -0
  371. data/ext/libmemcached-0.50/m4/iconv.m4 +214 -0
  372. data/ext/libmemcached-0.50/m4/lib-ld.m4 +110 -0
  373. data/ext/libmemcached-0.50/m4/lib-link.m4 +767 -0
  374. data/ext/libmemcached-0.50/m4/lib-prefix.m4 +221 -0
  375. data/ext/libmemcached-0.50/m4/libtool.m4 +7851 -0
  376. data/ext/libmemcached-0.50/m4/ltoptions.m4 +369 -0
  377. data/ext/libmemcached-0.50/m4/ltsugar.m4 +123 -0
  378. data/ext/libmemcached-0.50/m4/ltversion.m4 +23 -0
  379. data/ext/libmemcached-0.50/m4/lt~obsolete.m4 +98 -0
  380. data/ext/libmemcached-0.50/m4/memaslap.m4 +9 -0
  381. data/ext/libmemcached-0.50/m4/memcached.m4 +31 -0
  382. data/ext/libmemcached-0.50/m4/murmur.m4 +18 -0
  383. data/ext/libmemcached-0.50/m4/pandora_64bit.m4 +60 -0
  384. data/ext/libmemcached-0.50/m4/pandora_bison.m4 +33 -0
  385. data/ext/libmemcached-0.50/m4/pandora_canonical.m4 +418 -0
  386. data/ext/libmemcached-0.50/m4/pandora_check_compiler_version.m4 +37 -0
  387. data/ext/libmemcached-0.50/m4/pandora_check_cxx_standard.m4 +23 -0
  388. data/ext/libmemcached-0.50/m4/pandora_cinttypes.m4 +39 -0
  389. data/ext/libmemcached-0.50/m4/pandora_clock_gettime.m4 +15 -0
  390. data/ext/libmemcached-0.50/m4/pandora_compile_stdcxx_0x.m4 +103 -0
  391. data/ext/libmemcached-0.50/m4/pandora_cstdint.m4 +38 -0
  392. data/ext/libmemcached-0.50/m4/pandora_cxx_demangle.m4 +27 -0
  393. data/ext/libmemcached-0.50/m4/pandora_enable_dtrace.m4 +60 -0
  394. data/ext/libmemcached-0.50/m4/pandora_ensure_gcc_version.m4 +62 -0
  395. data/ext/libmemcached-0.50/m4/pandora_extensions.m4 +16 -0
  396. data/ext/libmemcached-0.50/m4/pandora_fdatasync.m4 +25 -0
  397. data/ext/libmemcached-0.50/m4/pandora_flex.m4 +33 -0
  398. data/ext/libmemcached-0.50/m4/pandora_have_better_malloc.m4 +66 -0
  399. data/ext/libmemcached-0.50/m4/pandora_have_boost.m4 +93 -0
  400. data/ext/libmemcached-0.50/m4/pandora_have_gcc_atomics.m4 +37 -0
  401. data/ext/libmemcached-0.50/m4/pandora_have_innodb.m4 +41 -0
  402. data/ext/libmemcached-0.50/m4/pandora_have_libaio.m4 +56 -0
  403. data/ext/libmemcached-0.50/m4/pandora_have_libavahi.m4 +41 -0
  404. data/ext/libmemcached-0.50/m4/pandora_have_libbdb.m4 +40 -0
  405. data/ext/libmemcached-0.50/m4/pandora_have_libboost_date_time.m4 +46 -0
  406. data/ext/libmemcached-0.50/m4/pandora_have_libboost_filesystem.m4 +47 -0
  407. data/ext/libmemcached-0.50/m4/pandora_have_libboost_iostreams.m4 +49 -0
  408. data/ext/libmemcached-0.50/m4/pandora_have_libboost_options.m4 +47 -0
  409. data/ext/libmemcached-0.50/m4/pandora_have_libboost_regex.m4 +54 -0
  410. data/ext/libmemcached-0.50/m4/pandora_have_libboost_test.m4 +45 -0
  411. data/ext/libmemcached-0.50/m4/pandora_have_libboost_thread.m4 +54 -0
  412. data/ext/libmemcached-0.50/m4/pandora_have_libcassandra.m4 +44 -0
  413. data/ext/libmemcached-0.50/m4/pandora_have_libcurl.m4 +62 -0
  414. data/ext/libmemcached-0.50/m4/pandora_have_libdl.m4 +51 -0
  415. data/ext/libmemcached-0.50/m4/pandora_have_libdrizzle.m4 +61 -0
  416. data/ext/libmemcached-0.50/m4/pandora_have_libevent.m4 +66 -0
  417. data/ext/libmemcached-0.50/m4/pandora_have_libgearman.m4 +41 -0
  418. data/ext/libmemcached-0.50/m4/pandora_have_libgtest.m4 +47 -0
  419. data/ext/libmemcached-0.50/m4/pandora_have_libhaildb.m4 +43 -0
  420. data/ext/libmemcached-0.50/m4/pandora_have_libhashkit.m4 +42 -0
  421. data/ext/libmemcached-0.50/m4/pandora_have_libinnodb.m4 +64 -0
  422. data/ext/libmemcached-0.50/m4/pandora_have_libldap.m4 +73 -0
  423. data/ext/libmemcached-0.50/m4/pandora_have_libmemcached.m4 +106 -0
  424. data/ext/libmemcached-0.50/m4/pandora_have_libmysqlclient.m4 +146 -0
  425. data/ext/libmemcached-0.50/m4/pandora_have_libndbclient.m4 +80 -0
  426. data/ext/libmemcached-0.50/m4/pandora_have_libpcre.m4 +73 -0
  427. data/ext/libmemcached-0.50/m4/pandora_have_libpq.m4 +46 -0
  428. data/ext/libmemcached-0.50/m4/pandora_have_libpqxx.m4 +44 -0
  429. data/ext/libmemcached-0.50/m4/pandora_have_libsqlite3.m4 +42 -0
  430. data/ext/libmemcached-0.50/m4/pandora_have_libtokyocabinet.m4 +54 -0
  431. data/ext/libmemcached-0.50/m4/pandora_have_libuuid.m4 +55 -0
  432. data/ext/libmemcached-0.50/m4/pandora_have_libvbucket.m4 +40 -0
  433. data/ext/libmemcached-0.50/m4/pandora_have_libxml2.m4 +52 -0
  434. data/ext/libmemcached-0.50/m4/pandora_have_libz.m4 +51 -0
  435. data/ext/libmemcached-0.50/m4/pandora_have_protobuf.m4 +82 -0
  436. data/ext/libmemcached-0.50/m4/pandora_have_sasl.m4 +133 -0
  437. data/ext/libmemcached-0.50/m4/pandora_have_thrift.m4 +45 -0
  438. data/ext/libmemcached-0.50/m4/pandora_header_assert.m4 +23 -0
  439. data/ext/libmemcached-0.50/m4/pandora_header_stdcxx_98.m4 +83 -0
  440. data/ext/libmemcached-0.50/m4/pandora_intltool.m4 +225 -0
  441. data/ext/libmemcached-0.50/m4/pandora_libtool.m4 +25 -0
  442. data/ext/libmemcached-0.50/m4/pandora_optimize.m4 +75 -0
  443. data/ext/libmemcached-0.50/m4/pandora_platform.m4 +117 -0
  444. data/ext/libmemcached-0.50/m4/pandora_plugins.m4 +62 -0
  445. data/ext/libmemcached-0.50/m4/pandora_print_callstack.m4 +61 -0
  446. data/ext/libmemcached-0.50/m4/pandora_pthread.m4 +258 -0
  447. data/ext/libmemcached-0.50/m4/pandora_python3_devel.m4 +236 -0
  448. data/ext/libmemcached-0.50/m4/pandora_run_cpplint.m4 +8 -0
  449. data/ext/libmemcached-0.50/m4/pandora_sasl.m4 +133 -0
  450. data/ext/libmemcached-0.50/m4/pandora_shared_ptr.m4 +59 -0
  451. data/ext/libmemcached-0.50/m4/pandora_stack_direction.m4 +39 -0
  452. data/ext/libmemcached-0.50/m4/pandora_stl_hash.m4 +94 -0
  453. data/ext/libmemcached-0.50/m4/pandora_swig.m4 +39 -0
  454. data/ext/libmemcached-0.50/m4/pandora_use_pipe.m4 +36 -0
  455. data/ext/libmemcached-0.50/m4/pandora_vc_build.m4 +168 -0
  456. data/ext/libmemcached-0.50/m4/pandora_version.m4 +11 -0
  457. data/ext/libmemcached-0.50/m4/pandora_visibility.m4 +75 -0
  458. data/ext/libmemcached-0.50/m4/pandora_warnings.m4 +447 -0
  459. data/ext/libmemcached-0.50/m4/pandora_with_gettext.m4 +44 -0
  460. data/ext/libmemcached-0.50/m4/pandora_with_lua.m4 +55 -0
  461. data/ext/libmemcached-0.50/m4/pandora_with_memcached.m4 +41 -0
  462. data/ext/libmemcached-0.50/m4/pandora_with_perl.m4 +81 -0
  463. data/ext/libmemcached-0.50/m4/pandora_with_php.m4 +56 -0
  464. data/ext/libmemcached-0.50/m4/pandora_with_python.m4 +37 -0
  465. data/ext/libmemcached-0.50/m4/pandora_with_python3.m4 +44 -0
  466. data/ext/libmemcached-0.50/m4/pandora_with_r.m4 +33 -0
  467. data/ext/libmemcached-0.50/m4/pandora_with_ruby.m4 +79 -0
  468. data/ext/libmemcached-0.50/m4/pandora_with_valgrind.m4 +17 -0
  469. data/ext/libmemcached-0.50/m4/pkg.m4 +157 -0
  470. data/ext/libmemcached-0.50/m4/po.m4 +449 -0
  471. data/ext/libmemcached-0.50/m4/progtest.m4 +92 -0
  472. data/ext/libmemcached-0.50/m4/protocol_binary.m4 +36 -0
  473. data/ext/libmemcached-0.50/m4/setsockopt.m4 +73 -0
  474. data/ext/libmemcached-0.50/m4/socket_send_flags.m4 +66 -0
  475. data/ext/libmemcached-0.50/poll/include.am +8 -0
  476. data/ext/libmemcached-0.50/poll/poll.c +77 -0
  477. data/ext/libmemcached-0.50/poll/poll.h +45 -0
  478. data/ext/libmemcached-0.50/support/include.am +11 -0
  479. data/ext/libmemcached-0.50/support/libmemcached-fc.spec.in +105 -0
  480. data/ext/libmemcached-0.50/support/libmemcached.pc.in +10 -0
  481. data/ext/libmemcached-0.50/support/libmemcached.spec.in +281 -0
  482. data/ext/libmemcached-0.50/support/set_benchmark.sh +5 -0
  483. data/ext/libmemcached-0.50/tests/atomsmasher.cc +295 -0
  484. data/ext/libmemcached-0.50/tests/basic.cc +134 -0
  485. data/ext/libmemcached-0.50/tests/basic.h +66 -0
  486. data/ext/libmemcached-0.50/tests/cpp_example.cc +195 -0
  487. data/ext/libmemcached-0.50/tests/deprecated.cc +72 -0
  488. data/ext/libmemcached-0.50/tests/deprecated.h +49 -0
  489. data/ext/libmemcached-0.50/tests/error_conditions.cc +63 -0
  490. data/ext/libmemcached-0.50/tests/error_conditions.h +48 -0
  491. data/ext/libmemcached-0.50/tests/hash_plus.cc +225 -0
  492. data/ext/libmemcached-0.50/tests/hash_results.h +127 -0
  493. data/ext/libmemcached-0.50/tests/hashkit_functions.cc +619 -0
  494. data/ext/libmemcached-0.50/tests/include.am +342 -0
  495. data/ext/libmemcached-0.50/tests/ketama_test_cases.h +121 -0
  496. data/ext/libmemcached-0.50/tests/ketama_test_cases_spy.h +118 -0
  497. data/ext/libmemcached-0.50/tests/libmemcached_world.h +205 -0
  498. data/ext/libmemcached-0.50/tests/mem_functions.cc +6648 -0
  499. data/ext/libmemcached-0.50/tests/mem_udp.cc +510 -0
  500. data/ext/libmemcached-0.50/tests/output_plus.res +5 -0
  501. data/ext/libmemcached-0.50/tests/parser.cc +599 -0
  502. data/ext/libmemcached-0.50/tests/parser.h +109 -0
  503. data/ext/libmemcached-0.50/tests/plus.cpp +240 -0
  504. data/ext/libmemcached-0.50/tests/pool.cc +78 -0
  505. data/ext/libmemcached-0.50/tests/pool.h +49 -0
  506. data/ext/libmemcached-0.50/tests/print.cc +58 -0
  507. data/ext/libmemcached-0.50/tests/print.h +51 -0
  508. data/ext/libmemcached-0.50/tests/replication.cc +333 -0
  509. data/ext/libmemcached-0.50/tests/replication.h +64 -0
  510. data/ext/libmemcached-0.50/tests/start.cc +29 -0
  511. data/ext/libmemcached-0.50/tests/string.cc +174 -0
  512. data/ext/libmemcached-0.50/tests/string.h +67 -0
  513. data/ext/libmemcached-0.50/tests/virtual_buckets.cc +143 -0
  514. data/ext/libmemcached-0.50/tests/virtual_buckets.h +51 -0
  515. data/ext/libmemcached-0.50/win32/include.am +11 -0
  516. data/ext/libmemcached-0.50/win32/wrappers.h +55 -0
  517. data/ext/rlibmemcached.i +263 -0
  518. data/ext/rlibmemcached_wrap.c +16732 -0
  519. data/lib/memcached.rb +32 -0
  520. data/lib/memcached/auth.rb +16 -0
  521. data/lib/memcached/behaviors.rb +77 -0
  522. data/lib/memcached/exceptions.rb +84 -0
  523. data/lib/memcached/experimental.rb +48 -0
  524. data/lib/memcached/memcached.rb +660 -0
  525. data/lib/memcached/rails.rb +133 -0
  526. data/test/profile/benchmark.rb +245 -0
  527. data/test/profile/c_profiler.rb +14 -0
  528. data/test/profile/exercise.rb +185 -0
  529. data/test/profile/rb_profiler.rb +21 -0
  530. data/test/profile/valgrind.rb +10 -0
  531. data/test/setup.rb +30 -0
  532. data/test/teardown.rb +0 -0
  533. data/test/test_helper.rb +19 -0
  534. data/test/unit/binding_test.rb +8 -0
  535. data/test/unit/memcached_experimental_test.rb +274 -0
  536. data/test/unit/memcached_test.rb +1293 -0
  537. data/test/unit/rails_test.rb +122 -0
  538. metadata +650 -0
  539. metadata.gz.sig +0 -0
@@ -0,0 +1,40 @@
1
+ /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2
+ *
3
+ * Libmemcached library
4
+ *
5
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are
9
+ * met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ *
14
+ * * Redistributions in binary form must reproduce the above
15
+ * copyright notice, this list of conditions and the following disclaimer
16
+ * in the documentation and/or other materials provided with the
17
+ * distribution.
18
+ *
19
+ * * The names of its contributors may not be used to endorse or
20
+ * promote products derived from this software without specific prior
21
+ * written permission.
22
+ *
23
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ *
35
+ */
36
+
37
+ #pragma once
38
+
39
+ LIBMEMCACHED_LOCAL
40
+ memcached_protocol_event_t memcached_ascii_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr);
@@ -0,0 +1,1121 @@
1
+ /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2
+ *
3
+ * Libmemcached library
4
+ *
5
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are
9
+ * met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ *
14
+ * * Redistributions in binary form must reproduce the above
15
+ * copyright notice, this list of conditions and the following disclaimer
16
+ * in the documentation and/or other materials provided with the
17
+ * distribution.
18
+ *
19
+ * * The names of its contributors may not be used to endorse or
20
+ * promote products derived from this software without specific prior
21
+ * written permission.
22
+ *
23
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ *
35
+ */
36
+
37
+ #include <libmemcached/protocol/common.h>
38
+ #include <libmemcached/byteorder.h>
39
+
40
+ #include <stdlib.h>
41
+ #include <sys/types.h>
42
+ #include <errno.h>
43
+ #include <stdbool.h>
44
+ #include <string.h>
45
+ #include <stdio.h>
46
+
47
+ /*
48
+ ** **********************************************************************
49
+ ** INTERNAL INTERFACE
50
+ ** **********************************************************************
51
+ */
52
+
53
+ /**
54
+ * Send a preformatted packet back to the client. If the connection is in
55
+ * pedantic mode, it will validate the packet and refuse to send it if it
56
+ * breaks the specification.
57
+ *
58
+ * @param cookie client identification
59
+ * @param request the original request packet
60
+ * @param response the packet to send
61
+ * @return The status of the operation
62
+ */
63
+ static protocol_binary_response_status
64
+ raw_response_handler(const void *cookie,
65
+ protocol_binary_request_header *request,
66
+ protocol_binary_response_header *response)
67
+ {
68
+ memcached_protocol_client_st *client= (void*)cookie;
69
+
70
+ if (client->root->pedantic &&
71
+ !memcached_binary_protocol_pedantic_check_response(request, response))
72
+ {
73
+ return PROTOCOL_BINARY_RESPONSE_EINVAL;
74
+ }
75
+
76
+ if (!client->root->drain(client))
77
+ {
78
+ return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
79
+ }
80
+
81
+ size_t len= sizeof(*response) + htonl(response->response.bodylen);
82
+ size_t offset= 0;
83
+ char *ptr= (void*)response;
84
+
85
+ if (client->output == NULL)
86
+ {
87
+ /* I can write directly to the socket.... */
88
+ do
89
+ {
90
+ size_t num_bytes= len - offset;
91
+ ssize_t nw= client->root->send(client,
92
+ client->sock,
93
+ ptr + offset,
94
+ num_bytes);
95
+ if (nw == -1)
96
+ {
97
+ if (get_socket_errno() == EWOULDBLOCK)
98
+ {
99
+ break;
100
+ }
101
+ else if (get_socket_errno() != EINTR)
102
+ {
103
+ client->error= errno;
104
+ return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
105
+ }
106
+ }
107
+ else
108
+ {
109
+ offset += (size_t)nw;
110
+ }
111
+ } while (offset < len);
112
+ }
113
+
114
+ return client->root->spool(client, ptr, len - offset);
115
+ }
116
+
117
+ /*
118
+ * Version 0 of the interface is really low level and protocol specific,
119
+ * while the version 1 of the interface is more API focused. We need a
120
+ * way to translate between the command codes on the wire and the
121
+ * application level interface in V1, so let's just use the V0 of the
122
+ * interface as a map instead of creating a huuuge switch :-)
123
+ */
124
+
125
+ /**
126
+ * Callback for the GET/GETQ/GETK and GETKQ responses
127
+ * @param cookie client identifier
128
+ * @param key the key for the item
129
+ * @param keylen the length of the key
130
+ * @param body the length of the body
131
+ * @param bodylen the length of the body
132
+ * @param flags the flags for the item
133
+ * @param cas the CAS id for the item
134
+ */
135
+ static protocol_binary_response_status
136
+ get_response_handler(const void *cookie,
137
+ const void *key,
138
+ uint16_t keylen,
139
+ const void *body,
140
+ uint32_t bodylen,
141
+ uint32_t flags,
142
+ uint64_t cas) {
143
+
144
+ memcached_protocol_client_st *client= (void*)cookie;
145
+ uint8_t opcode= client->current_command->request.opcode;
146
+
147
+ if (opcode == PROTOCOL_BINARY_CMD_GET || opcode == PROTOCOL_BINARY_CMD_GETQ)
148
+ {
149
+ keylen= 0;
150
+ }
151
+
152
+ protocol_binary_response_get response= {
153
+ .message.header.response= {
154
+ .magic= PROTOCOL_BINARY_RES,
155
+ .opcode= opcode,
156
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
157
+ .opaque= client->current_command->request.opaque,
158
+ .cas= memcached_htonll(cas),
159
+ .keylen= htons(keylen),
160
+ .extlen= 4,
161
+ .bodylen= htonl(bodylen + keylen + 4),
162
+ },
163
+ };
164
+
165
+ response.message.body.flags= htonl(flags);
166
+
167
+ protocol_binary_response_status rval;
168
+ const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS;
169
+ if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success ||
170
+ (rval= client->root->spool(client, key, keylen)) != success ||
171
+ (rval= client->root->spool(client, body, bodylen)) != success)
172
+ {
173
+ return rval;
174
+ }
175
+
176
+ return PROTOCOL_BINARY_RESPONSE_SUCCESS;
177
+ }
178
+
179
+ /**
180
+ * Callback for the STAT responses
181
+ * @param cookie client identifier
182
+ * @param key the key for the item
183
+ * @param keylen the length of the key
184
+ * @param body the length of the body
185
+ * @param bodylen the length of the body
186
+ */
187
+ static protocol_binary_response_status stat_response_handler(const void *cookie,
188
+ const void *key,
189
+ uint16_t keylen,
190
+ const void *body,
191
+ uint32_t bodylen)
192
+ {
193
+
194
+ memcached_protocol_client_st *client= (void*)cookie;
195
+
196
+ protocol_binary_response_no_extras response= {
197
+ .message.header.response= {
198
+ .magic= PROTOCOL_BINARY_RES,
199
+ .opcode= client->current_command->request.opcode,
200
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
201
+ .opaque= client->current_command->request.opaque,
202
+ .keylen= htons(keylen),
203
+ .bodylen= htonl(bodylen + keylen),
204
+ .cas= 0
205
+ },
206
+ };
207
+
208
+ protocol_binary_response_status rval;
209
+ const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS;
210
+ if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success ||
211
+ (rval= client->root->spool(client, key, keylen)) != success ||
212
+ (rval= client->root->spool(client, body, bodylen)) != success)
213
+ {
214
+ return rval;
215
+ }
216
+
217
+ return PROTOCOL_BINARY_RESPONSE_SUCCESS;
218
+ }
219
+
220
+ /**
221
+ * Callback for the VERSION responses
222
+ * @param cookie client identifier
223
+ * @param text the length of the body
224
+ * @param textlen the length of the body
225
+ */
226
+ static protocol_binary_response_status
227
+ version_response_handler(const void *cookie,
228
+ const void *text,
229
+ uint32_t textlen) {
230
+
231
+ memcached_protocol_client_st *client= (void*)cookie;
232
+
233
+ protocol_binary_response_no_extras response= {
234
+ .message.header.response= {
235
+ .magic= PROTOCOL_BINARY_RES,
236
+ .opcode= client->current_command->request.opcode,
237
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
238
+ .opaque= client->current_command->request.opaque,
239
+ .bodylen= htonl(textlen),
240
+ .cas= 0
241
+ },
242
+ };
243
+
244
+ protocol_binary_response_status rval;
245
+ const protocol_binary_response_status success= PROTOCOL_BINARY_RESPONSE_SUCCESS;
246
+ if ((rval= client->root->spool(client, response.bytes, sizeof(response.bytes))) != success ||
247
+ (rval= client->root->spool(client, text, textlen)) != success)
248
+ {
249
+ return rval;
250
+ }
251
+
252
+ return PROTOCOL_BINARY_RESPONSE_SUCCESS;
253
+ }
254
+
255
+ /**
256
+ * Callback for ADD and ADDQ
257
+ * @param cookie the calling client
258
+ * @param header the add/addq command
259
+ * @param response_handler not used
260
+ * @return the result of the operation
261
+ */
262
+ static protocol_binary_response_status
263
+ add_command_handler(const void *cookie,
264
+ protocol_binary_request_header *header,
265
+ memcached_binary_protocol_raw_response_handler response_handler)
266
+ {
267
+ protocol_binary_response_status rval;
268
+
269
+ memcached_protocol_client_st *client= (void*)cookie;
270
+ if (client->root->callback->interface.v1.add != NULL)
271
+ {
272
+ uint16_t keylen= ntohs(header->request.keylen);
273
+ uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
274
+ protocol_binary_request_add *request= (void*)header;
275
+ uint32_t flags= ntohl(request->message.body.flags);
276
+ uint32_t timeout= ntohl(request->message.body.expiration);
277
+ char *key= ((char*)header) + sizeof(*header) + 8;
278
+ char *data= key + keylen;
279
+ uint64_t cas;
280
+
281
+ rval= client->root->callback->interface.v1.add(cookie, key, keylen,
282
+ data, datalen, flags,
283
+ timeout, &cas);
284
+
285
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
286
+ header->request.opcode == PROTOCOL_BINARY_CMD_ADD)
287
+ {
288
+ /* Send a positive request */
289
+ protocol_binary_response_no_extras response= {
290
+ .message= {
291
+ .header.response= {
292
+ .magic= PROTOCOL_BINARY_RES,
293
+ .opcode= PROTOCOL_BINARY_CMD_ADD,
294
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
295
+ .opaque= header->request.opaque,
296
+ .cas= memcached_ntohll(cas)
297
+ }
298
+ }
299
+ };
300
+ rval= response_handler(cookie, header, (void*)&response);
301
+ }
302
+ }
303
+ else
304
+ {
305
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
306
+ }
307
+
308
+ return rval;
309
+ }
310
+
311
+ /**
312
+ * Callback for DECREMENT and DECREMENTQ
313
+ * @param cookie the calling client
314
+ * @param header the command
315
+ * @param response_handler not used
316
+ * @return the result of the operation
317
+ */
318
+ static protocol_binary_response_status
319
+ decrement_command_handler(const void *cookie,
320
+ protocol_binary_request_header *header,
321
+ memcached_binary_protocol_raw_response_handler response_handler)
322
+ {
323
+ (void)response_handler;
324
+ protocol_binary_response_status rval;
325
+
326
+ memcached_protocol_client_st *client= (void*)cookie;
327
+ if (client->root->callback->interface.v1.decrement != NULL)
328
+ {
329
+ uint16_t keylen= ntohs(header->request.keylen);
330
+ protocol_binary_request_decr *request= (void*)header;
331
+ uint64_t init= memcached_ntohll(request->message.body.initial);
332
+ uint64_t delta= memcached_ntohll(request->message.body.delta);
333
+ uint32_t timeout= ntohl(request->message.body.expiration);
334
+ void *key= request->bytes + sizeof(request->bytes);
335
+ uint64_t result;
336
+ uint64_t cas;
337
+
338
+ rval= client->root->callback->interface.v1.decrement(cookie, key, keylen,
339
+ delta, init, timeout,
340
+ &result, &cas);
341
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
342
+ header->request.opcode == PROTOCOL_BINARY_CMD_DECREMENT)
343
+ {
344
+ /* Send a positive request */
345
+ protocol_binary_response_decr response= {
346
+ .message= {
347
+ .header.response= {
348
+ .magic= PROTOCOL_BINARY_RES,
349
+ .opcode= PROTOCOL_BINARY_CMD_DECREMENT,
350
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
351
+ .opaque= header->request.opaque,
352
+ .cas= memcached_ntohll(cas),
353
+ .bodylen= htonl(8)
354
+ },
355
+ .body.value= memcached_htonll(result)
356
+ }
357
+ };
358
+ rval= response_handler(cookie, header, (void*)&response);
359
+ }
360
+ }
361
+ else
362
+ {
363
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
364
+ }
365
+
366
+ return rval;
367
+ }
368
+
369
+ /**
370
+ * Callback for DELETE and DELETEQ
371
+ * @param cookie the calling client
372
+ * @param header the command
373
+ * @param response_handler not used
374
+ * @return the result of the operation
375
+ */
376
+ static protocol_binary_response_status
377
+ delete_command_handler(const void *cookie,
378
+ protocol_binary_request_header *header,
379
+ memcached_binary_protocol_raw_response_handler response_handler)
380
+ {
381
+ (void)response_handler;
382
+ protocol_binary_response_status rval;
383
+
384
+ memcached_protocol_client_st *client= (void*)cookie;
385
+ if (client->root->callback->interface.v1.delete != NULL)
386
+ {
387
+ uint16_t keylen= ntohs(header->request.keylen);
388
+ void *key= (header +1);
389
+ uint64_t cas= memcached_ntohll(header->request.cas);
390
+ rval= client->root->callback->interface.v1.delete(cookie, key, keylen, cas);
391
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
392
+ header->request.opcode == PROTOCOL_BINARY_CMD_DELETE)
393
+ {
394
+ /* Send a positive request */
395
+ protocol_binary_response_no_extras response= {
396
+ .message= {
397
+ .header.response= {
398
+ .magic= PROTOCOL_BINARY_RES,
399
+ .opcode= PROTOCOL_BINARY_CMD_DELETE,
400
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
401
+ .opaque= header->request.opaque,
402
+ }
403
+ }
404
+ };
405
+ rval= response_handler(cookie, header, (void*)&response);
406
+ }
407
+ }
408
+ else
409
+ {
410
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
411
+ }
412
+
413
+ return rval;
414
+ }
415
+
416
+ /**
417
+ * Callback for FLUSH and FLUSHQ
418
+ * @param cookie the calling client
419
+ * @param header the command
420
+ * @param response_handler not used
421
+ * @return the result of the operation
422
+ */
423
+ static protocol_binary_response_status
424
+ flush_command_handler(const void *cookie,
425
+ protocol_binary_request_header *header,
426
+ memcached_binary_protocol_raw_response_handler response_handler)
427
+ {
428
+ (void)response_handler;
429
+ protocol_binary_response_status rval;
430
+
431
+ memcached_protocol_client_st *client= (void*)cookie;
432
+ if (client->root->callback->interface.v1.flush != NULL)
433
+ {
434
+ protocol_binary_request_flush *flush= (void*)header;
435
+ uint32_t timeout= 0;
436
+ if (htonl(header->request.bodylen) == 4)
437
+ {
438
+ timeout= ntohl(flush->message.body.expiration);
439
+ }
440
+
441
+ rval= client->root->callback->interface.v1.flush(cookie, timeout);
442
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
443
+ header->request.opcode == PROTOCOL_BINARY_CMD_FLUSH)
444
+ {
445
+ /* Send a positive request */
446
+ protocol_binary_response_no_extras response= {
447
+ .message= {
448
+ .header.response= {
449
+ .magic= PROTOCOL_BINARY_RES,
450
+ .opcode= PROTOCOL_BINARY_CMD_FLUSH,
451
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
452
+ .opaque= header->request.opaque,
453
+ }
454
+ }
455
+ };
456
+ rval= response_handler(cookie, header, (void*)&response);
457
+ }
458
+ }
459
+ else
460
+ {
461
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
462
+ }
463
+
464
+ return rval;
465
+ }
466
+
467
+ /**
468
+ * Callback for GET, GETK, GETQ, GETKQ
469
+ * @param cookie the calling client
470
+ * @param header the command
471
+ * @param response_handler not used
472
+ * @return the result of the operation
473
+ */
474
+ static protocol_binary_response_status
475
+ get_command_handler(const void *cookie,
476
+ protocol_binary_request_header *header,
477
+ memcached_binary_protocol_raw_response_handler response_handler)
478
+ {
479
+ (void)response_handler;
480
+ protocol_binary_response_status rval;
481
+
482
+ memcached_protocol_client_st *client= (void*)cookie;
483
+ if (client->root->callback->interface.v1.get != NULL)
484
+ {
485
+ uint16_t keylen= ntohs(header->request.keylen);
486
+ void *key= (header + 1);
487
+ rval= client->root->callback->interface.v1.get(cookie, key, keylen,
488
+ get_response_handler);
489
+
490
+ if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT &&
491
+ (header->request.opcode == PROTOCOL_BINARY_CMD_GETQ ||
492
+ header->request.opcode == PROTOCOL_BINARY_CMD_GETKQ))
493
+ {
494
+ /* Quiet commands shouldn't respond on cache misses */
495
+ rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
496
+ }
497
+ }
498
+ else
499
+ {
500
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
501
+ }
502
+
503
+ return rval;
504
+ }
505
+
506
+ /**
507
+ * Callback for INCREMENT and INCREMENTQ
508
+ * @param cookie the calling client
509
+ * @param header the command
510
+ * @param response_handler not used
511
+ * @return the result of the operation
512
+ */
513
+ static protocol_binary_response_status
514
+ increment_command_handler(const void *cookie,
515
+ protocol_binary_request_header *header,
516
+ memcached_binary_protocol_raw_response_handler response_handler)
517
+ {
518
+ (void)response_handler;
519
+ protocol_binary_response_status rval;
520
+
521
+ memcached_protocol_client_st *client= (void*)cookie;
522
+ if (client->root->callback->interface.v1.increment != NULL)
523
+ {
524
+ uint16_t keylen= ntohs(header->request.keylen);
525
+ protocol_binary_request_incr *request= (void*)header;
526
+ uint64_t init= memcached_ntohll(request->message.body.initial);
527
+ uint64_t delta= memcached_ntohll(request->message.body.delta);
528
+ uint32_t timeout= ntohl(request->message.body.expiration);
529
+ void *key= request->bytes + sizeof(request->bytes);
530
+ uint64_t cas;
531
+ uint64_t result;
532
+
533
+ rval= client->root->callback->interface.v1.increment(cookie, key, keylen,
534
+ delta, init, timeout,
535
+ &result, &cas);
536
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
537
+ header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENT)
538
+ {
539
+ /* Send a positive request */
540
+ protocol_binary_response_incr response= {
541
+ .message= {
542
+ .header.response= {
543
+ .magic= PROTOCOL_BINARY_RES,
544
+ .opcode= PROTOCOL_BINARY_CMD_INCREMENT,
545
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
546
+ .opaque= header->request.opaque,
547
+ .cas= memcached_ntohll(cas),
548
+ .bodylen= htonl(8)
549
+ },
550
+ .body.value= memcached_htonll(result)
551
+ }
552
+ };
553
+
554
+ rval= response_handler(cookie, header, (void*)&response);
555
+ }
556
+ }
557
+ else
558
+ {
559
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
560
+ }
561
+
562
+ return rval;
563
+ }
564
+
565
+ /**
566
+ * Callback for noop. Inform the v1 interface about the noop packet, and
567
+ * create and send a packet back to the client
568
+ *
569
+ * @param cookie the calling client
570
+ * @param header the command
571
+ * @param response_handler the response handler
572
+ * @return the result of the operation
573
+ */
574
+ static protocol_binary_response_status
575
+ noop_command_handler(const void *cookie,
576
+ protocol_binary_request_header *header,
577
+ memcached_binary_protocol_raw_response_handler response_handler)
578
+ {
579
+ memcached_protocol_client_st *client= (void*)cookie;
580
+ if (client->root->callback->interface.v1.noop != NULL)
581
+ {
582
+ client->root->callback->interface.v1.noop(cookie);
583
+ }
584
+
585
+ protocol_binary_response_no_extras response= {
586
+ .message= {
587
+ .header.response= {
588
+ .magic= PROTOCOL_BINARY_RES,
589
+ .opcode= PROTOCOL_BINARY_CMD_NOOP,
590
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
591
+ .opaque= header->request.opaque,
592
+ }
593
+ }
594
+ };
595
+
596
+ return response_handler(cookie, header, (void*)&response);
597
+ }
598
+
599
+ /**
600
+ * Callback for APPEND and APPENDQ
601
+ * @param cookie the calling client
602
+ * @param header the command
603
+ * @param response_handler not used
604
+ * @return the result of the operation
605
+ */
606
+ static protocol_binary_response_status
607
+ append_command_handler(const void *cookie,
608
+ protocol_binary_request_header *header,
609
+ memcached_binary_protocol_raw_response_handler response_handler)
610
+ {
611
+ (void)response_handler;
612
+ protocol_binary_response_status rval;
613
+
614
+ memcached_protocol_client_st *client= (void*)cookie;
615
+ if (client->root->callback->interface.v1.append != NULL)
616
+ {
617
+ uint16_t keylen= ntohs(header->request.keylen);
618
+ uint32_t datalen= ntohl(header->request.bodylen) - keylen;
619
+ char *key= (void*)(header +1);
620
+ char *data= key +keylen;
621
+ uint64_t cas= memcached_ntohll(header->request.cas);
622
+ uint64_t result_cas;
623
+
624
+ rval= client->root->callback->interface.v1.append(cookie, key, keylen,
625
+ data, datalen, cas,
626
+ &result_cas);
627
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
628
+ header->request.opcode == PROTOCOL_BINARY_CMD_APPEND)
629
+ {
630
+ /* Send a positive request */
631
+ protocol_binary_response_no_extras response= {
632
+ .message= {
633
+ .header.response= {
634
+ .magic= PROTOCOL_BINARY_RES,
635
+ .opcode= PROTOCOL_BINARY_CMD_APPEND,
636
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
637
+ .opaque= header->request.opaque,
638
+ .cas= memcached_ntohll(result_cas),
639
+ },
640
+ }
641
+ };
642
+ rval= response_handler(cookie, header, (void*)&response);
643
+ }
644
+ }
645
+ else
646
+ {
647
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
648
+ }
649
+
650
+ return rval;
651
+ }
652
+
653
+ /**
654
+ * Callback for PREPEND and PREPENDQ
655
+ * @param cookie the calling client
656
+ * @param header the command
657
+ * @param response_handler not used
658
+ * @return the result of the operation
659
+ */
660
+ static protocol_binary_response_status
661
+ prepend_command_handler(const void *cookie,
662
+ protocol_binary_request_header *header,
663
+ memcached_binary_protocol_raw_response_handler response_handler)
664
+ {
665
+ (void)response_handler;
666
+ protocol_binary_response_status rval;
667
+
668
+ memcached_protocol_client_st *client= (void*)cookie;
669
+ if (client->root->callback->interface.v1.prepend != NULL)
670
+ {
671
+ uint16_t keylen= ntohs(header->request.keylen);
672
+ uint32_t datalen= ntohl(header->request.bodylen) - keylen;
673
+ char *key= (char*)(header + 1);
674
+ char *data= key + keylen;
675
+ uint64_t cas= memcached_ntohll(header->request.cas);
676
+ uint64_t result_cas;
677
+ rval= client->root->callback->interface.v1.prepend(cookie, key, keylen,
678
+ data, datalen, cas,
679
+ &result_cas);
680
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
681
+ header->request.opcode == PROTOCOL_BINARY_CMD_PREPEND)
682
+ {
683
+ /* Send a positive request */
684
+ protocol_binary_response_no_extras response= {
685
+ .message= {
686
+ .header.response= {
687
+ .magic= PROTOCOL_BINARY_RES,
688
+ .opcode= PROTOCOL_BINARY_CMD_PREPEND,
689
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
690
+ .opaque= header->request.opaque,
691
+ .cas= memcached_ntohll(result_cas),
692
+ },
693
+ }
694
+ };
695
+ rval= response_handler(cookie, header, (void*)&response);
696
+ }
697
+ }
698
+ else
699
+ {
700
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
701
+ }
702
+
703
+ return rval;
704
+ }
705
+
706
+ /**
707
+ * Callback for QUIT and QUITQ. Notify the client and shut down the connection
708
+ * @param cookie the calling client
709
+ * @param header the command
710
+ * @param response_handler not used
711
+ * @return the result of the operation
712
+ */
713
+ static protocol_binary_response_status
714
+ quit_command_handler(const void *cookie,
715
+ protocol_binary_request_header *header,
716
+ memcached_binary_protocol_raw_response_handler response_handler)
717
+ {
718
+ memcached_protocol_client_st *client= (void*)cookie;
719
+ if (client->root->callback->interface.v1.quit != NULL)
720
+ {
721
+ client->root->callback->interface.v1.quit(cookie);
722
+ }
723
+
724
+ protocol_binary_response_no_extras response= {
725
+ .message= {
726
+ .header.response= {
727
+ .magic= PROTOCOL_BINARY_RES,
728
+ .opcode= PROTOCOL_BINARY_CMD_QUIT,
729
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
730
+ .opaque= header->request.opaque
731
+ }
732
+ }
733
+ };
734
+
735
+ if (header->request.opcode == PROTOCOL_BINARY_CMD_QUIT)
736
+ {
737
+ response_handler(cookie, header, (void*)&response);
738
+ }
739
+
740
+ /* I need a better way to signal to close the connection */
741
+ return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
742
+ }
743
+
744
+ /**
745
+ * Callback for REPLACE and REPLACEQ
746
+ * @param cookie the calling client
747
+ * @param header the command
748
+ * @param response_handler not used
749
+ * @return the result of the operation
750
+ */
751
+ static protocol_binary_response_status
752
+ replace_command_handler(const void *cookie,
753
+ protocol_binary_request_header *header,
754
+ memcached_binary_protocol_raw_response_handler response_handler)
755
+ {
756
+ (void)response_handler;
757
+ protocol_binary_response_status rval;
758
+
759
+ memcached_protocol_client_st *client= (void*)cookie;
760
+ if (client->root->callback->interface.v1.replace != NULL)
761
+ {
762
+ uint16_t keylen= ntohs(header->request.keylen);
763
+ uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
764
+ protocol_binary_request_replace *request= (void*)header;
765
+ uint32_t flags= ntohl(request->message.body.flags);
766
+ uint32_t timeout= ntohl(request->message.body.expiration);
767
+ char *key= ((char*)header) + sizeof(*header) + 8;
768
+ char *data= key + keylen;
769
+ uint64_t cas= memcached_ntohll(header->request.cas);
770
+ uint64_t result_cas;
771
+
772
+ rval= client->root->callback->interface.v1.replace(cookie, key, keylen,
773
+ data, datalen, flags,
774
+ timeout, cas,
775
+ &result_cas);
776
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
777
+ header->request.opcode == PROTOCOL_BINARY_CMD_REPLACE)
778
+ {
779
+ /* Send a positive request */
780
+ protocol_binary_response_no_extras response= {
781
+ .message= {
782
+ .header.response= {
783
+ .magic= PROTOCOL_BINARY_RES,
784
+ .opcode= PROTOCOL_BINARY_CMD_REPLACE,
785
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
786
+ .opaque= header->request.opaque,
787
+ .cas= memcached_ntohll(result_cas),
788
+ },
789
+ }
790
+ };
791
+ rval= response_handler(cookie, header, (void*)&response);
792
+ }
793
+ }
794
+ else
795
+ {
796
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
797
+ }
798
+
799
+ return rval;
800
+ }
801
+
802
+ /**
803
+ * Callback for SET and SETQ
804
+ * @param cookie the calling client
805
+ * @param header the command
806
+ * @param response_handler not used
807
+ * @return the result of the operation
808
+ */
809
+ static protocol_binary_response_status
810
+ set_command_handler(const void *cookie,
811
+ protocol_binary_request_header *header,
812
+ memcached_binary_protocol_raw_response_handler response_handler)
813
+ {
814
+ (void)response_handler;
815
+ protocol_binary_response_status rval;
816
+
817
+ memcached_protocol_client_st *client= (void*)cookie;
818
+ if (client->root->callback->interface.v1.set != NULL)
819
+ {
820
+ uint16_t keylen= ntohs(header->request.keylen);
821
+ uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
822
+ protocol_binary_request_replace *request= (void*)header;
823
+ uint32_t flags= ntohl(request->message.body.flags);
824
+ uint32_t timeout= ntohl(request->message.body.expiration);
825
+ char *key= ((char*)header) + sizeof(*header) + 8;
826
+ char *data= key + keylen;
827
+ uint64_t cas= memcached_ntohll(header->request.cas);
828
+ uint64_t result_cas;
829
+
830
+
831
+ rval= client->root->callback->interface.v1.set(cookie, key, keylen,
832
+ data, datalen, flags,
833
+ timeout, cas, &result_cas);
834
+ if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
835
+ header->request.opcode == PROTOCOL_BINARY_CMD_SET)
836
+ {
837
+ /* Send a positive request */
838
+ protocol_binary_response_no_extras response= {
839
+ .message= {
840
+ .header.response= {
841
+ .magic= PROTOCOL_BINARY_RES,
842
+ .opcode= PROTOCOL_BINARY_CMD_SET,
843
+ .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
844
+ .opaque= header->request.opaque,
845
+ .cas= memcached_ntohll(result_cas),
846
+ },
847
+ }
848
+ };
849
+ rval= response_handler(cookie, header, (void*)&response);
850
+ }
851
+ }
852
+ else
853
+ {
854
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
855
+ }
856
+
857
+ return rval;
858
+ }
859
+
860
+ /**
861
+ * Callback for STAT
862
+ * @param cookie the calling client
863
+ * @param header the command
864
+ * @param response_handler not used
865
+ * @return the result of the operation
866
+ */
867
+ static protocol_binary_response_status
868
+ stat_command_handler(const void *cookie,
869
+ protocol_binary_request_header *header,
870
+ memcached_binary_protocol_raw_response_handler response_handler)
871
+ {
872
+ (void)response_handler;
873
+ protocol_binary_response_status rval;
874
+
875
+ memcached_protocol_client_st *client= (void*)cookie;
876
+ if (client->root->callback->interface.v1.stat != NULL)
877
+ {
878
+ uint16_t keylen= ntohs(header->request.keylen);
879
+
880
+ rval= client->root->callback->interface.v1.stat(cookie,
881
+ (void*)(header + 1),
882
+ keylen,
883
+ stat_response_handler);
884
+ }
885
+ else
886
+ {
887
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
888
+ }
889
+
890
+ return rval;
891
+ }
892
+
893
+ /**
894
+ * Callback for VERSION
895
+ * @param cookie the calling client
896
+ * @param header the command
897
+ * @param response_handler not used
898
+ * @return the result of the operation
899
+ */
900
+ static protocol_binary_response_status
901
+ version_command_handler(const void *cookie,
902
+ protocol_binary_request_header *header,
903
+ memcached_binary_protocol_raw_response_handler response_handler)
904
+ {
905
+ (void)response_handler;
906
+ (void)header;
907
+ protocol_binary_response_status rval;
908
+
909
+ memcached_protocol_client_st *client= (void*)cookie;
910
+ if (client->root->callback->interface.v1.version != NULL)
911
+ {
912
+ rval= client->root->callback->interface.v1.version(cookie,
913
+ version_response_handler);
914
+ }
915
+ else
916
+ {
917
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
918
+ }
919
+
920
+ return rval;
921
+ }
922
+
923
+ /**
924
+ * The map to remap between the com codes and the v1 logical setting
925
+ */
926
+ static memcached_binary_protocol_command_handler comcode_v0_v1_remap[256]= {
927
+ [PROTOCOL_BINARY_CMD_ADDQ]= add_command_handler,
928
+ [PROTOCOL_BINARY_CMD_ADD]= add_command_handler,
929
+ [PROTOCOL_BINARY_CMD_APPENDQ]= append_command_handler,
930
+ [PROTOCOL_BINARY_CMD_APPEND]= append_command_handler,
931
+ [PROTOCOL_BINARY_CMD_DECREMENTQ]= decrement_command_handler,
932
+ [PROTOCOL_BINARY_CMD_DECREMENT]= decrement_command_handler,
933
+ [PROTOCOL_BINARY_CMD_DELETEQ]= delete_command_handler,
934
+ [PROTOCOL_BINARY_CMD_DELETE]= delete_command_handler,
935
+ [PROTOCOL_BINARY_CMD_FLUSHQ]= flush_command_handler,
936
+ [PROTOCOL_BINARY_CMD_FLUSH]= flush_command_handler,
937
+ [PROTOCOL_BINARY_CMD_GETKQ]= get_command_handler,
938
+ [PROTOCOL_BINARY_CMD_GETK]= get_command_handler,
939
+ [PROTOCOL_BINARY_CMD_GETQ]= get_command_handler,
940
+ [PROTOCOL_BINARY_CMD_GET]= get_command_handler,
941
+ [PROTOCOL_BINARY_CMD_INCREMENTQ]= increment_command_handler,
942
+ [PROTOCOL_BINARY_CMD_INCREMENT]= increment_command_handler,
943
+ [PROTOCOL_BINARY_CMD_NOOP]= noop_command_handler,
944
+ [PROTOCOL_BINARY_CMD_PREPENDQ]= prepend_command_handler,
945
+ [PROTOCOL_BINARY_CMD_PREPEND]= prepend_command_handler,
946
+ [PROTOCOL_BINARY_CMD_QUITQ]= quit_command_handler,
947
+ [PROTOCOL_BINARY_CMD_QUIT]= quit_command_handler,
948
+ [PROTOCOL_BINARY_CMD_REPLACEQ]= replace_command_handler,
949
+ [PROTOCOL_BINARY_CMD_REPLACE]= replace_command_handler,
950
+ [PROTOCOL_BINARY_CMD_SETQ]= set_command_handler,
951
+ [PROTOCOL_BINARY_CMD_SET]= set_command_handler,
952
+ [PROTOCOL_BINARY_CMD_STAT]= stat_command_handler,
953
+ [PROTOCOL_BINARY_CMD_VERSION]= version_command_handler,
954
+ };
955
+
956
+ /**
957
+ * Try to execute a command. Fire the pre/post functions and the specialized
958
+ * handler function if it's set. If not, the unknown probe should be fired
959
+ * if it's present.
960
+ * @param client the client connection to operate on
961
+ * @param header the command to execute
962
+ * @return true if success or false if a fatal error occured so that the
963
+ * connection should be shut down.
964
+ */
965
+ static protocol_binary_response_status execute_command(memcached_protocol_client_st *client, protocol_binary_request_header *header)
966
+ {
967
+ if (client->root->pedantic &&
968
+ memcached_binary_protocol_pedantic_check_request(header))
969
+ {
970
+ /* @todo return invalid command packet */
971
+ }
972
+
973
+ /* we got all data available, execute the callback! */
974
+ if (client->root->callback->pre_execute != NULL)
975
+ {
976
+ client->root->callback->pre_execute(client, header);
977
+ }
978
+
979
+ protocol_binary_response_status rval;
980
+ rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
981
+ uint8_t cc= header->request.opcode;
982
+
983
+ switch (client->root->callback->interface_version)
984
+ {
985
+ case 0:
986
+ if (client->root->callback->interface.v0.comcode[cc] != NULL) {
987
+ rval= client->root->callback->interface.v0.comcode[cc](client, header, raw_response_handler);
988
+ }
989
+ break;
990
+ case 1:
991
+ if (comcode_v0_v1_remap[cc] != NULL) {
992
+ rval= comcode_v0_v1_remap[cc](client, header, raw_response_handler);
993
+ }
994
+ break;
995
+ default:
996
+ /* Unknown interface.
997
+ * It should be impossible to get here so I'll just call abort
998
+ * to avoid getting a compiler warning :-)
999
+ */
1000
+ abort();
1001
+ }
1002
+
1003
+
1004
+ if (rval == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND &&
1005
+ client->root->callback->unknown != NULL)
1006
+ {
1007
+ rval= client->root->callback->unknown(client, header, raw_response_handler);
1008
+ }
1009
+
1010
+ if (rval != PROTOCOL_BINARY_RESPONSE_SUCCESS &&
1011
+ rval != PROTOCOL_BINARY_RESPONSE_EINTERNAL &&
1012
+ rval != PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED)
1013
+ {
1014
+ protocol_binary_response_no_extras response= {
1015
+ .message= {
1016
+ .header.response= {
1017
+ .magic= PROTOCOL_BINARY_RES,
1018
+ .opcode= cc,
1019
+ .status= htons(rval),
1020
+ .opaque= header->request.opaque,
1021
+ },
1022
+ }
1023
+ };
1024
+ rval= raw_response_handler(client, header, (void*)&response);
1025
+ }
1026
+
1027
+ if (client->root->callback->post_execute != NULL)
1028
+ {
1029
+ client->root->callback->post_execute(client, header);
1030
+ }
1031
+
1032
+ return rval;
1033
+ }
1034
+
1035
+ /*
1036
+ ** **********************************************************************
1037
+ ** "PROTOECTED" INTERFACE
1038
+ ** **********************************************************************
1039
+ */
1040
+ memcached_protocol_event_t memcached_binary_protocol_process_data(memcached_protocol_client_st *client, ssize_t *length, void **endptr)
1041
+ {
1042
+ /* try to parse all of the received packets */
1043
+ protocol_binary_request_header *header;
1044
+ header= (void*)client->root->input_buffer;
1045
+ if (header->request.magic != (uint8_t)PROTOCOL_BINARY_REQ)
1046
+ {
1047
+ client->error= EINVAL;
1048
+ return MEMCACHED_PROTOCOL_ERROR_EVENT;
1049
+ }
1050
+ ssize_t len= *length;
1051
+
1052
+ while (len >= (ssize_t)sizeof(*header) &&
1053
+ (len >= (ssize_t)(sizeof(*header) + ntohl(header->request.bodylen))))
1054
+ {
1055
+ /* I have the complete package */
1056
+ client->current_command= header;
1057
+ protocol_binary_response_status rv= execute_command(client, header);
1058
+
1059
+ if (rv == PROTOCOL_BINARY_RESPONSE_EINTERNAL)
1060
+ {
1061
+ *length= len;
1062
+ *endptr= (void*)header;
1063
+ return MEMCACHED_PROTOCOL_ERROR_EVENT;
1064
+ } else if (rv == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED)
1065
+ return MEMCACHED_PROTOCOL_PAUSE_EVENT;
1066
+
1067
+ ssize_t total= (ssize_t)(sizeof(*header) + ntohl(header->request.bodylen));
1068
+ len -= total;
1069
+ if (len > 0)
1070
+ {
1071
+ intptr_t ptr= (intptr_t)header;
1072
+ ptr += total;
1073
+ if ((ptr % 8) == 0)
1074
+ {
1075
+ header= (void*)ptr;
1076
+ }
1077
+ else
1078
+ {
1079
+ /* Fix alignment */
1080
+ memmove(client->root->input_buffer, (void*)ptr, (size_t)len);
1081
+ header= (void*)client->root->input_buffer;
1082
+ }
1083
+ }
1084
+ *length= len;
1085
+ *endptr= (void*)header;
1086
+ }
1087
+
1088
+ return MEMCACHED_PROTOCOL_READ_EVENT;
1089
+ }
1090
+
1091
+ /*
1092
+ ** **********************************************************************
1093
+ ** PUBLIC INTERFACE
1094
+ ** **********************************************************************
1095
+ */
1096
+ memcached_binary_protocol_callback_st *memcached_binary_protocol_get_callbacks(memcached_protocol_st *instance)
1097
+ {
1098
+ return instance->callback;
1099
+ }
1100
+
1101
+ void memcached_binary_protocol_set_callbacks(memcached_protocol_st *instance, memcached_binary_protocol_callback_st *callback)
1102
+ {
1103
+ instance->callback= callback;
1104
+ }
1105
+
1106
+ memcached_binary_protocol_raw_response_handler memcached_binary_protocol_get_raw_response_handler(const void *cookie)
1107
+ {
1108
+ (void)cookie;
1109
+ return raw_response_handler;
1110
+ }
1111
+
1112
+ void memcached_binary_protocol_set_pedantic(memcached_protocol_st *instance, bool enable)
1113
+ {
1114
+ instance->pedantic= enable;
1115
+ }
1116
+
1117
+ bool memcached_binary_protocol_get_pedantic(memcached_protocol_st *instance)
1118
+ {
1119
+ return instance->pedantic;
1120
+ }
1121
+