couchbase-memcached 1.2.8

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 (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
+