libcouchbase 0.0.7 → 0.0.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 (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