libcouchbase 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/.gitignore +2 -0
  3. data/ext/libcouchbase/CMakeLists.txt +5 -7
  4. data/ext/libcouchbase/README.markdown +2 -2
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +49 -0
  6. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  7. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
  8. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +2 -1
  9. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  10. data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
  11. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  12. data/ext/libcouchbase/cmake/source_files.cmake +34 -14
  13. data/ext/libcouchbase/configure.pl +1 -1
  14. data/ext/libcouchbase/contrib/genhash/genhash.h +6 -0
  15. data/ext/libcouchbase/include/libcouchbase/auth.h +10 -0
  16. data/ext/libcouchbase/include/libcouchbase/couchbase.h +10 -0
  17. data/ext/libcouchbase/include/libcouchbase/error.h +7 -0
  18. data/ext/libcouchbase/include/libcouchbase/n1ql.h +13 -1
  19. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
  20. data/ext/libcouchbase/include/libcouchbase/subdoc.h +9 -0
  21. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  22. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  23. data/ext/libcouchbase/include/memcached/protocol_binary.h +21 -1132
  24. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  25. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  26. data/ext/libcouchbase/src/README.md +0 -2
  27. data/ext/libcouchbase/src/auth-priv.h +1 -0
  28. data/ext/libcouchbase/src/auth.cc +10 -0
  29. data/ext/libcouchbase/src/bootstrap.cc +216 -0
  30. data/ext/libcouchbase/src/bootstrap.h +50 -39
  31. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +455 -0
  32. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  33. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +528 -0
  34. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  35. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +115 -0
  36. data/ext/libcouchbase/src/bucketconfig/clconfig.h +407 -386
  37. data/ext/libcouchbase/src/bucketconfig/confmon.cc +378 -0
  38. data/ext/libcouchbase/src/cbft.cc +22 -27
  39. data/ext/libcouchbase/src/cntl.cc +24 -24
  40. data/ext/libcouchbase/src/connspec.cc +30 -1
  41. data/ext/libcouchbase/src/connspec.h +17 -0
  42. data/ext/libcouchbase/src/dns-srv.cc +143 -0
  43. data/ext/libcouchbase/src/{dump.c → dump.cc} +8 -11
  44. data/ext/libcouchbase/src/getconfig.cc +73 -0
  45. data/ext/libcouchbase/src/handler.cc +84 -85
  46. data/ext/libcouchbase/src/hostlist.cc +0 -1
  47. data/ext/libcouchbase/src/hostlist.h +6 -1
  48. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  49. data/ext/libcouchbase/src/http/http.cc +9 -29
  50. data/ext/libcouchbase/src/http/http.h +1 -34
  51. data/ext/libcouchbase/src/http/http_io.cc +22 -26
  52. data/ext/libcouchbase/src/instance.cc +102 -28
  53. data/ext/libcouchbase/src/internal.h +47 -29
  54. data/ext/libcouchbase/src/jsparse/parser.cc +146 -202
  55. data/ext/libcouchbase/src/jsparse/parser.h +91 -98
  56. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  57. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  58. data/ext/libcouchbase/src/lcbio/connect.cc +562 -0
  59. data/ext/libcouchbase/src/lcbio/connect.h +9 -2
  60. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  61. data/ext/libcouchbase/src/lcbio/iotable.h +61 -16
  62. data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
  63. data/ext/libcouchbase/src/lcbio/manager.c +2 -2
  64. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  65. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  66. data/ext/libcouchbase/src/mcserver/mcserver.cc +723 -0
  67. data/ext/libcouchbase/src/mcserver/mcserver.h +160 -70
  68. data/ext/libcouchbase/src/mcserver/negotiate.cc +118 -152
  69. data/ext/libcouchbase/src/mcserver/negotiate.h +85 -74
  70. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  71. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  72. data/ext/libcouchbase/src/n1ql/n1ql.cc +56 -32
  73. data/ext/libcouchbase/src/{newconfig.c → newconfig.cc} +42 -70
  74. data/ext/libcouchbase/src/nodeinfo.cc +4 -8
  75. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  76. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  77. data/ext/libcouchbase/src/operations/{durability-cas.c → durability-cas.cc} +92 -76
  78. data/ext/libcouchbase/src/operations/{durability-seqno.c → durability-seqno.cc} +55 -49
  79. data/ext/libcouchbase/src/operations/durability.cc +643 -0
  80. data/ext/libcouchbase/src/operations/durability_internal.h +212 -124
  81. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  82. data/ext/libcouchbase/src/operations/{observe-seqno.c → observe-seqno.cc} +5 -8
  83. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +69 -94
  84. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  85. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  86. data/ext/libcouchbase/src/operations/{stats.c → stats.cc} +66 -78
  87. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  88. data/ext/libcouchbase/src/operations/subdoc.cc +38 -18
  89. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  90. data/ext/libcouchbase/src/packetutils.h +200 -137
  91. data/ext/libcouchbase/src/probes.d +1 -1
  92. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +3 -4
  93. data/ext/libcouchbase/src/retryq.cc +394 -0
  94. data/ext/libcouchbase/src/retryq.h +116 -104
  95. data/ext/libcouchbase/src/settings.h +2 -1
  96. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  97. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  98. data/ext/libcouchbase/src/trace.h +8 -8
  99. data/ext/libcouchbase/src/vbucket/vbucket.c +0 -1
  100. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  101. data/ext/libcouchbase/src/views/docreq.h +24 -30
  102. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  103. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  104. data/ext/libcouchbase/src/{wait.c → wait.cc} +12 -17
  105. data/ext/libcouchbase/tests/basic/t_connstr.cc +89 -50
  106. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -78
  107. data/ext/libcouchbase/tests/basic/t_packet.cc +35 -42
  108. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  109. data/ext/libcouchbase/tests/iotests/t_confmon.cc +94 -111
  110. data/ext/libcouchbase/tests/iotests/t_sched.cc +1 -2
  111. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  112. data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
  113. data/lib/libcouchbase/version.rb +1 -1
  114. metadata +36 -39
  115. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  116. data/ext/libcouchbase/src/bootstrap.c +0 -269
  117. data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +0 -495
  118. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  119. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  120. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  121. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  122. data/ext/libcouchbase/src/getconfig.c +0 -100
  123. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  124. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  125. data/ext/libcouchbase/src/mcserver/mcserver.c +0 -784
  126. data/ext/libcouchbase/src/operations/durability.c +0 -668
  127. data/ext/libcouchbase/src/packetutils.c +0 -60
  128. data/ext/libcouchbase/src/retryq.c +0 -424
  129. data/ext/libcouchbase/src/simplestring.c +0 -211
  130. data/ext/libcouchbase/src/simplestring.h +0 -228
  131. data/ext/libcouchbase/src/ssobuf.h +0 -82
  132. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  133. data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -19,23 +19,30 @@
19
19
  #include "trace.h"
20
20
  #include "durability_internal.h"
21
21
 
22
- typedef struct {
23
- mc_REQDATAEX base;
22
+ struct DurStoreCtx : mc_REQDATAEX {
24
23
  lcb_t instance;
25
24
  lcb_U16 persist_to;
26
25
  lcb_U16 replicate_to;
27
- } DURSTORECTX;
26
+
27
+ static mc_REQDATAPROCS proctable;
28
+
29
+ DurStoreCtx(lcb_t instance_, lcb_U16 persist_, lcb_U16 replicate_,
30
+ const void *cookie_)
31
+ : mc_REQDATAEX(cookie_, proctable, gethrtime()),
32
+ instance(instance_), persist_to(persist_), replicate_to(replicate_) {
33
+ }
34
+ };
28
35
 
29
36
  /** Observe stuff */
30
37
  static void
31
- handle_dur_storecb(mc_PIPELINE *pl, mc_PACKET *pkt,
38
+ handle_dur_storecb(mc_PIPELINE *, mc_PACKET *pkt,
32
39
  lcb_error_t err, const void *arg)
33
40
  {
34
41
  lcb_RESPCALLBACK cb;
35
42
  lcb_RESPSTOREDUR resp = { 0 };
36
43
  lcb_CMDENDURE dcmd = { 0 };
37
44
  const lcb_MUTATION_TOKEN *mt;
38
- DURSTORECTX *dctx = (DURSTORECTX *)pkt->u_rdata.exdata;
45
+ DurStoreCtx *dctx = static_cast<DurStoreCtx*>(pkt->u_rdata.exdata);
39
46
  lcb_MULTICMD_CTX *mctx;
40
47
  lcb_durability_opts_t opts = { 0 };
41
48
  const lcb_RESPSTORE *sresp = (const lcb_RESPSTORE *)arg;
@@ -78,7 +85,7 @@ handle_dur_storecb(mc_PIPELINE *pl, mc_PACKET *pkt,
78
85
 
79
86
  if (err == LCB_SUCCESS) {
80
87
  /* Everything OK? */
81
- free(dctx);
88
+ delete dctx;
82
89
  return;
83
90
  }
84
91
 
@@ -92,20 +99,15 @@ handle_dur_storecb(mc_PIPELINE *pl, mc_PACKET *pkt,
92
99
  resp.dur_resp = &dresp;
93
100
  cb = lcb_find_callback(dctx->instance, LCB_CALLBACK_STOREDUR);
94
101
  cb(dctx->instance, LCB_CALLBACK_STOREDUR, (const lcb_RESPBASE*)&resp);
95
- free(dctx);
102
+ delete dctx;
96
103
  }
97
-
98
- (void)pl;
99
104
  }
100
105
 
101
- static void
102
- handle_dur_schedfail(mc_PACKET *pkt)
103
- {
104
- DURSTORECTX *dctx = (void *)pkt->u_rdata.exdata;
105
- free(dctx);
106
+ static void handle_dur_schedfail(mc_PACKET *pkt) {
107
+ delete static_cast<DurStoreCtx*>(pkt->u_rdata.exdata);
106
108
  }
107
109
 
108
- mc_REQDATAPROCS storedur_procs = {
110
+ mc_REQDATAPROCS DurStoreCtx::proctable = {
109
111
  handle_dur_storecb,
110
112
  handle_dur_schedfail
111
113
  };
@@ -150,7 +152,7 @@ static int
150
152
  can_compress(lcb_t instance, const mc_PIPELINE *pipeline,
151
153
  const lcb_VALBUF *vbuf, lcb_datatype_t datatype)
152
154
  {
153
- mc_SERVER *server = (mc_SERVER *)pipeline;
155
+ const lcb::Server *server = static_cast<const lcb::Server*>(pipeline);
154
156
  int compressopts = LCBT_SETTING(instance, compressopts);
155
157
 
156
158
  if (mcreq_compression_supported() == 0) {
@@ -163,7 +165,8 @@ can_compress(lcb_t instance, const mc_PIPELINE *pipeline,
163
165
  if ((compressopts & LCB_COMPRESS_OUT) == 0) {
164
166
  return 0;
165
167
  }
166
- if (server->compsupport == 0 && (compressopts & LCB_COMPRESS_FORCE) == 0) {
168
+ if (server->supports_compression() == false &&
169
+ (compressopts & LCB_COMPRESS_FORCE) == 0) {
167
170
  return 0;
168
171
  }
169
172
  if (datatype & LCB_VALUE_F_SNAPPYCOMP) {
@@ -178,7 +181,6 @@ do_store3(lcb_t instance, const void *cookie,
178
181
  {
179
182
  mc_PIPELINE *pipeline;
180
183
  mc_PACKET *packet;
181
- mc_REQDATA *rdata;
182
184
  mc_CMDQUEUE *cq = &instance->cmdq;
183
185
  int hsize;
184
186
  int should_compress = 0;
@@ -256,8 +258,6 @@ do_store3(lcb_t instance, const void *cookie,
256
258
  int duropts = 0;
257
259
  lcb_U16 persist_u , replicate_u;
258
260
  const lcb_CMDSTOREDUR *dcmd = (const lcb_CMDSTOREDUR *)cmd;
259
- DURSTORECTX *dctx = calloc(1, sizeof(*dctx));
260
-
261
261
  persist_u = dcmd->persist_to;
262
262
  replicate_u = dcmd->replicate_to;
263
263
  if (dcmd->replicate_to == -1 || dcmd->persist_to == -1) {
@@ -268,24 +268,19 @@ do_store3(lcb_t instance, const void *cookie,
268
268
  if (err != LCB_SUCCESS) {
269
269
  mcreq_wipe_packet(pipeline, packet);
270
270
  mcreq_release_packet(pipeline, packet);
271
- free(dctx);
272
271
  return err;
273
272
  }
274
273
 
275
- dctx->instance = instance;
276
- dctx->persist_to = persist_u;
277
- dctx->replicate_to = replicate_u;
278
- packet->u_rdata.exdata = &dctx->base;
274
+ DurStoreCtx *dctx = new DurStoreCtx(instance, persist_u, replicate_u,
275
+ cookie);
276
+ packet->u_rdata.exdata = dctx;
279
277
  packet->flags |= MCREQ_F_REQEXT;
280
-
281
- dctx->base.cookie = cookie;
282
- dctx->base.procs = &storedur_procs;
278
+ } else {
279
+ mc_REQDATA *rdata = MCREQ_PKT_RDATA(packet);
280
+ rdata->cookie = cookie;
281
+ rdata->start = gethrtime();
283
282
  }
284
283
 
285
- rdata = MCREQ_PKT_RDATA(packet);
286
- rdata->cookie = cookie;
287
- rdata->start = gethrtime();
288
-
289
284
  scmd.message.body.expiration = htonl(cmd->exptime);
290
285
  scmd.message.body.flags = htonl(flags);
291
286
  hdr->request.magic = PROTOCOL_BINARY_REQ;
@@ -58,6 +58,17 @@ struct Traits {
58
58
  return is_lookup ? LCB_SDMULTI_MODE_LOOKUP : LCB_SDMULTI_MODE_MUTATE;
59
59
  }
60
60
 
61
+ inline bool chk_allow_empty_path(uint32_t options) const {
62
+ if (allow_empty_path) {
63
+ return true;
64
+ }
65
+ if (!is_lookup) {
66
+ return false;
67
+ }
68
+
69
+ return (options & LCB_SDSPEC_F_XATTRPATH) != 0;
70
+ }
71
+
61
72
  inline Traits(uint8_t op, unsigned options) :
62
73
  allow_empty_path(options & EMPTY_PATH),
63
74
  allow_expiry(options & ALLOW_EXPIRY),
@@ -163,6 +174,28 @@ get_valbuf_size(const lcb_VALBUF& vb)
163
174
  }
164
175
  }
165
176
 
177
+ static uint8_t
178
+ make_subdoc_flags(const uint32_t user)
179
+ {
180
+ uint8_t subdoc_flags = 0;
181
+ if (user & LCB_SDSPEC_F_MKINTERMEDIATES) {
182
+ subdoc_flags |= SUBDOC_FLAG_MKDIR_P;
183
+ }
184
+ if (user & LCB_SDSPEC_F_MKDOCUMENT) {
185
+ subdoc_flags |= SUBDOC_FLAG_MKDOC;
186
+ }
187
+ if (user & LCB_SDSPEC_F_XATTRPATH) {
188
+ subdoc_flags |= SUBDOC_FLAG_XATTR_PATH;
189
+ }
190
+ if (user & LCB_SDSPEC_F_XATTR_MACROVALUES) {
191
+ subdoc_flags |= (SUBDOC_FLAG_EXPAND_MACROS | SUBDOC_FLAG_XATTR_PATH);
192
+ }
193
+ if (user & LCB_SDSPEC_F_XATTR_DELETED_OK) {
194
+ subdoc_flags |= (SUBDOC_FLAG_XATTR_PATH|SUBDOC_FLAG_ACCESS_DELETED);
195
+ }
196
+ return subdoc_flags;
197
+ }
198
+
166
199
  struct MultiBuilder {
167
200
  MultiBuilder(const lcb_CMDSUBDOC *cmd_)
168
201
  : cmd(cmd_), payload_size(0), mode(0) {
@@ -266,17 +299,10 @@ MultiBuilder::add_spec(const lcb_SDSPEC *spec)
266
299
  // opcode
267
300
  add_field(trait.opcode, 1);
268
301
  // flags
269
- uint8_t sdflags = 0;
270
- if (spec->options & LCB_SDSPEC_F_MKINTERMEDIATES) {
271
- sdflags = SUBDOC_FLAG_MKDIR_P;
272
- }
273
- if (spec->options & LCB_SDSPEC_F_MKDOCUMENT) {
274
- sdflags |= SUBDOC_FLAG_MKDOC;
275
- }
276
- add_field(sdflags, 1);
302
+ add_field(make_subdoc_flags(spec->options), 1);
277
303
 
278
304
  uint16_t npath = static_cast<uint16_t>(spec->path.contig.nbytes);
279
- if (!npath && !trait.allow_empty_path) {
305
+ if (!npath && !trait.chk_allow_empty_path(spec->options)) {
280
306
  return LCB_EMPTY_PATH;
281
307
  }
282
308
 
@@ -329,7 +355,8 @@ sd3_single(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
329
355
  if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) {
330
356
  return LCB_EMPTY_KEY;
331
357
  }
332
- if (LCB_KEYBUF_IS_EMPTY(&spec->path) && !traits.allow_empty_path) {
358
+ if (LCB_KEYBUF_IS_EMPTY(&spec->path) &&
359
+ !traits.chk_allow_empty_path(spec->options)) {
333
360
  return LCB_EMPTY_PATH;
334
361
  }
335
362
 
@@ -399,14 +426,7 @@ sd3_single(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
399
426
  ntohs(hdr->request.keylen) + get_value_size(packet));
400
427
 
401
428
  request.message.extras.pathlen = htons(spec->path.contig.nbytes);
402
- request.message.extras.subdoc_flags = 0;
403
-
404
- if (spec->options & LCB_SDSPEC_F_MKINTERMEDIATES) {
405
- request.message.extras.subdoc_flags |= SUBDOC_FLAG_MKDIR_P;
406
- }
407
- if (spec->options & LCB_SDSPEC_F_MKDOCUMENT) {
408
- request.message.extras.subdoc_flags |= SUBDOC_FLAG_MKDOC;
409
- }
429
+ request.message.extras.subdoc_flags = make_subdoc_flags(spec->options);
410
430
 
411
431
  hdr->request.opcode = traits.opcode;
412
432
  memcpy(SPAN_BUFFER(&packet->kh_span), request.bytes, sizeof request.bytes);
@@ -24,128 +24,209 @@
24
24
  #include <memcached/protocol_binary.h>
25
25
  #include "rdb/rope.h"
26
26
 
27
- #ifdef __cplusplus
28
- extern "C" {
29
- #endif
27
+ #ifndef __cplusplus
28
+ typedef struct packet_info_st packet_info;
29
+ #else
30
+ namespace lcb {
31
+ class Server;
32
+
30
33
  /**
31
34
  * Response packet informational structure.
32
35
  *
33
36
  * This contains information regarding the response packet which is used by
34
37
  * the response processors.
35
38
  */
36
- typedef struct packet_info_st {
37
- /** The response header */
38
- protocol_binary_response_header res;
39
- /** The payload of the response. This should only be used if there is a body */
40
- void *payload;
41
- /** Segment for payload */
42
- void *bufh;
43
- } packet_info;
39
+ class MemcachedResponse {
40
+ public:
41
+ MemcachedResponse() : payload(NULL), bufh(NULL) {
42
+ // Bodyless. Members are initialized via load!
43
+ }
44
44
 
45
- /**
46
- * Gets the size of the _total_ non-header part of the packet. This data is
47
- * also featured inside the payload field itself.
48
- */
49
- #define PACKET_NBODY(pkt) (ntohl((pkt)->res.response.bodylen))
45
+ MemcachedResponse(protocol_binary_command cmd, uint32_t opaque_,
46
+ protocol_binary_response_status code)
47
+ : res(), payload(NULL), bufh(NULL) {
48
+ res.response.opcode = cmd;
49
+ res.response.opaque = opaque_;
50
+ res.response.status = htons(code);
51
+ }
52
+ /**
53
+ * Read from an 'IOR' structure to parse the packet information. This will
54
+ * always load a full packet.
55
+ *
56
+ * @param ior the rope structure to read from
57
+ * @param[out] required how much total bytes must remain in the buffer for the
58
+ * parse to complete.
59
+ *
60
+ * @return false if more data is needed, true otherwise
61
+ */
62
+ bool load(rdb_IOROPE *ior, unsigned *required) {
63
+ unsigned total = rdb_get_nused(ior);
64
+ unsigned wanted = sizeof(res.bytes);
65
+
66
+ if (total < wanted) {
67
+ *required = wanted;
68
+ return false;
69
+ }
70
+
71
+ rdb_copyread(ior, res.bytes, sizeof(res.bytes));
72
+ if (!bodylen()) {
73
+ rdb_consumed(ior, sizeof(res.bytes));
74
+ return true;
75
+ }
76
+
77
+ wanted += bodylen();
78
+ if (total < wanted) {
79
+ *required = wanted;
80
+ return false;
81
+ }
82
+
83
+ rdb_consumed(ior, sizeof(res.bytes));
84
+ payload = rdb_get_consolidated(ior, bodylen());
85
+ return true;
86
+ }
50
87
 
51
- #define PACKET_BODY(pkt) (pkt)->payload
88
+ template <typename T>
89
+ bool load(T ctx, unsigned *required) {
90
+ return load(&ctx->ior, required);
91
+ }
52
92
 
53
- /**
54
- * Gets the key size, if included in the packet.
55
- */
56
- #define PACKET_NKEY(pkt) (ntohs((pkt)->res.response.keylen))
93
+ void release(rdb_IOROPE *ior) {
94
+ if (!bodylen()) {
95
+ return;
96
+ }
97
+ rdb_consumed(ior, bodylen());
98
+ }
57
99
 
58
- /**
59
- * Gets the status of the packet
60
- */
61
- #define PACKET_STATUS(pkt) (ntohs((pkt)->res.response.status))
100
+ template <typename T>
101
+ void release(T ctx) {
102
+ release(&ctx->ior);
103
+ }
62
104
 
63
- /**
64
- * Gets the length of the 'extras' in the body
65
- */
66
- #define PACKET_EXTLEN(pkt) ((pkt)->res.response.extlen)
105
+ /**
106
+ * Gets the command for the packet
107
+ */
108
+ uint8_t opcode() const {
109
+ return res.response.opcode;
110
+ }
67
111
 
68
- /**
69
- * Gets the raw unconverted 'opaque' 32 bit field
70
- */
71
- #define PACKET_OPAQUE(pkt) ((pkt)->res.response.opaque)
112
+ /**
113
+ * Gets the CAS for the packet
114
+ */
115
+ uint64_t cas() const {
116
+ return lcb_ntohll(res.response.cas);
117
+ }
72
118
 
73
- /**
74
- * Gets the command for the packet
75
- */
76
- #define PACKET_OPCODE(pkt) ((pkt)->res.response.opcode)
119
+ /**
120
+ * Gets the 'datatype' field for the packet.
121
+ */
122
+ uint8_t datatype() const {
123
+ return res.response.datatype;
124
+ }
77
125
 
78
- /**
79
- * Gets the CAS for the packet
80
- */
81
- #define PACKET_CAS(pkt) lcb_ntohll((pkt)->res.response.cas)
126
+ /**
127
+ * Gets a pointer starting at the packet's key field. Only use if NKEY is 0
128
+ */
129
+ const char *key() const {
130
+ return body<const char*>() + extlen();
131
+ }
82
132
 
83
- /**
84
- * Gets the 'datatype' field for the packet.
85
- */
86
- #define PACKET_DATATYPE(pkt) ((pkt)->res.response.datatype)
133
+ /**
134
+ * Gets a pointer starting at the packet's value field. Only use if NVALUE is 0
135
+ */
136
+ const char *value() const {
137
+ return body<const char*>() + keylen() + extlen();
138
+ }
87
139
 
88
- /**
89
- * Gets a pointer starting at the packet's key field. Only use if NKEY is 0
90
- */
91
- #define PACKET_KEY(pkt) \
92
- ( ((const char *)(pkt)->payload) + PACKET_EXTLEN(pkt))
140
+ /**
141
+ * Gets the size of the packet value. The value is the part of the payload
142
+ * which is after the key (if applicable) and extras (if applicable).
143
+ */
144
+ uint32_t vallen() const {
145
+ return bodylen() - (keylen() + extlen());
146
+ }
93
147
 
94
- #define PACKET_REQUEST(pkt) \
95
- ( (protocol_binary_request_header *) &(pkt)->res)
96
148
 
97
- #define PACKET_REQ_VBID(pkt) \
98
- (ntohs(PACKET_REQUEST(pkt)->request.vbucket))
149
+ /**
150
+ * Gets the status of the packet
151
+ */
152
+ uint16_t status() const {
153
+ return ntohs(res.response.status);
154
+ }
99
155
 
100
- /**
101
- * Gets a pointer starting at the packet's value field. Only use if NVALUE is 0
102
- */
103
- #define PACKET_VALUE(pkt) \
104
- ( ((const char *) (pkt)->payload) + PACKET_NKEY(pkt) + PACKET_EXTLEN(pkt))
156
+ /**
157
+ * Gets the payload
158
+ */
159
+ template <typename T>
160
+ const T body() const {
161
+ return reinterpret_cast<const T>(payload);
162
+ }
105
163
 
106
- /**
107
- * Gets the size of the packet value. The value is the part of the payload
108
- * which is after the key (if applicable) and extras (if applicable).
109
- */
110
- #define PACKET_NVALUE(pkt) \
111
- (PACKET_NBODY(pkt) - (PACKET_NKEY(pkt) + PACKET_EXTLEN(pkt)))
164
+ /**
165
+ * Map a command 'subclass' so that its body field starts at the payload. Note
166
+ * that the return value is actually an ephemeral pointer starting 24 bytes
167
+ * _before_ the actual memory block, so only use the non-header part.
168
+ */
169
+ const char *ephemeral_start() const {
170
+ return body<const char*>() - 24;
171
+ }
172
+
173
+ /**
174
+ * Gets the size of the _total_ non-header part of the packet. This data is
175
+ * also featured inside the payload field itself.
176
+ */
177
+ uint32_t bodylen() const {
178
+ return ntohl(res.response.bodylen);
179
+ }
112
180
 
181
+ /**
182
+ * Gets the key size, if included in the packet.
183
+ */
184
+ uint16_t keylen() const {
185
+ return ntohs(res.response.keylen);
186
+ }
113
187
 
114
- /**
115
- * Map a command 'subclass' so that its body field starts at the payload. Note
116
- * that the return value is actually an ephemeral pointer starting 24 bytes
117
- * _before_ the actual memory block, so only use the non-header part.
118
- */
119
- #define PACKET_EPHEMERAL_START(pkt) \
120
- (const void *)(( ((const char *)(pkt)->payload) - 24 ))
188
+ /**
189
+ * Gets the length of the 'extras' in the body
190
+ */
191
+ uint8_t extlen() const {
192
+ return (res.response.extlen);
193
+ }
121
194
 
122
- /**
123
- * Read from an 'IOR' structure to parse the packet information. This will
124
- * always load a full packet.
125
- *
126
- * @param info the info structure to populate
127
- * @param ior the rope structure to read from
128
- * @param[out] required how much total bytes must remain in the buffer for the
129
- * parse to complete.
130
- *
131
- * @return zero if more data is needed, a true value otherwise
132
- */
133
- int
134
- lcb_pktinfo_ior_get(packet_info *info, rdb_IOROPE *ior, unsigned *required);
195
+ /**
196
+ * Gets the raw unconverted 'opaque' 32 bit field
197
+ */
198
+ uint32_t opaque() const {
199
+ return (res.response.opaque);
200
+ }
135
201
 
136
- void
137
- lcb_pktinfo_ior_done(packet_info *info, rdb_IOROPE *ior);
202
+ size_t hdrsize() const {
203
+ return sizeof (res.bytes);
204
+ }
138
205
 
139
- #define lcb_pktinfo_ectx_get(info, ctx, n) lcb_pktinfo_ior_get(info, &(ctx)->ior, n)
140
- #define lcb_pktinfo_ectx_done(info, ctx) lcb_pktinfo_ior_done(info, &(ctx)->ior)
206
+ uint8_t *hdrbytes() {
207
+ return res.bytes;
208
+ }
141
209
 
210
+ void *bufseg() const {
211
+ return bufh;
212
+ }
142
213
 
214
+ protected:
215
+ /** The response header */
216
+ protocol_binary_response_header res;
217
+ /** The payload of the response. This should only be used if there is a body */
218
+ void *payload;
219
+ /** Segment for payload */
220
+ void *bufh;
143
221
 
144
- #ifdef __cplusplus
145
- }
222
+ friend class lcb::Server;
223
+ };
146
224
 
225
+ #define PACKET_REQUEST(pkt) \
226
+ ( (protocol_binary_request_header *) &(pkt)->res)
147
227
 
148
- namespace lcb {
228
+ #define PACKET_REQ_VBID(pkt) \
229
+ (ntohs(PACKET_REQUEST(pkt)->request.vbucket))
149
230
 
150
231
  class MemcachedRequest {
151
232
  public:
@@ -169,65 +250,47 @@ public:
169
250
  hdr.request.opaque = opaque_;
170
251
  }
171
252
 
172
- MemcachedRequest(uint8_t opcode) {
173
- hdr.request.opcode = opcode;
174
- hdr.request.magic = PROTOCOL_BINARY_REQ;
175
- hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
176
- hdr.request.cas = 0;
177
- hdr.request.vbucket = 0;
178
- hdr.request.opaque = 0;
179
- hdr.request.bodylen = 0;
180
- hdr.request.extlen = 0;
181
- hdr.request.keylen = 0;
182
- hdr.request.opaque = 0;
183
- }
184
-
185
- const void *data() const { return hdr.bytes; }
186
- size_t size() const { return sizeof hdr.bytes; }
187
-
188
- private:
189
- protocol_binary_request_header hdr;
190
- };
191
-
192
- class MemcachedResponse : private packet_info {
193
- public:
194
- bool load(rdb_IOROPE *ior, unsigned *required) {
195
- return lcb_pktinfo_ior_get(this, ior, required) != 0;
253
+ uint32_t opaque() const {
254
+ return hdr.request.opaque;
196
255
  }
197
256
 
198
- template <typename T>
199
- bool load(T ctx, unsigned *required) {
200
- return lcb_pktinfo_ectx_get(this, ctx, required);
257
+ uint8_t opcode() const {
258
+ return hdr.request.opcode;
201
259
  }
202
260
 
203
- void release(rdb_IOROPE *ior) {
204
- lcb_pktinfo_ior_done(this, ior);
261
+ MemcachedRequest(uint8_t opcode_) {
262
+ assign(opcode_);
205
263
  }
206
264
 
207
- template <typename T>
208
- void release(T ctx) {
209
- lcb_pktinfo_ectx_done(this, ctx);
265
+ MemcachedRequest(uint8_t opcode_, uint32_t opaque_) {
266
+ assign(opcode_);
267
+ hdr.request.opaque = opaque_;
210
268
  }
211
269
 
212
- uint8_t opcode() const {
213
- return PACKET_OPCODE(this);
270
+ MemcachedRequest(const void *buf) {
271
+ memcpy(hdr.bytes, buf, sizeof hdr.bytes);
214
272
  }
215
273
 
216
- uint16_t status() const {
217
- return PACKET_STATUS(this);
218
- }
274
+ const void *data() const { return hdr.bytes; }
275
+ size_t size() const { return sizeof hdr.bytes; }
219
276
 
220
- template <typename T>
221
- const T body() const {
222
- return reinterpret_cast<const T>(packet_info::payload);
223
- }
277
+ private:
278
+ protocol_binary_request_header hdr;
224
279
 
225
- size_t bodylen() const {
226
- return PACKET_NBODY(this);
280
+ void assign(uint8_t opcode_) {
281
+ hdr.request.opcode = opcode_;
282
+ hdr.request.magic = PROTOCOL_BINARY_REQ;
283
+ hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
284
+ hdr.request.cas = 0;
285
+ hdr.request.vbucket = 0;
286
+ hdr.request.opaque = 0;
287
+ hdr.request.bodylen = 0;
288
+ hdr.request.extlen = 0;
289
+ hdr.request.keylen = 0;
290
+ hdr.request.opaque = 0;
227
291
  }
228
292
  };
229
-
230
293
  }
294
+ typedef lcb::MemcachedResponse packet_info;
231
295
  #endif
232
-
233
296
  #endif