libcouchbase 0.3.3 → 1.0.0

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/CMakeLists.txt +6 -8
  3. data/ext/libcouchbase/README.markdown +2 -2
  4. data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
  5. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  6. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
  7. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
  8. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  9. data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
  10. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  11. data/ext/libcouchbase/cmake/source_files.cmake +21 -5
  12. data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
  13. data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
  14. data/ext/libcouchbase/example/users/README +48 -0
  15. data/ext/libcouchbase/example/users/users.c +147 -0
  16. data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
  17. data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
  18. data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
  19. data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
  20. data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
  21. data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
  22. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
  23. data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
  24. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  25. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  26. data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
  27. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  28. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  29. data/ext/libcouchbase/src/README.md +0 -2
  30. data/ext/libcouchbase/src/auth-priv.h +23 -4
  31. data/ext/libcouchbase/src/auth.cc +51 -43
  32. data/ext/libcouchbase/src/bootstrap.cc +244 -0
  33. data/ext/libcouchbase/src/bootstrap.h +58 -38
  34. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
  35. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  36. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
  37. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  38. data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
  39. data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
  40. data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
  41. data/ext/libcouchbase/src/cbft.cc +22 -27
  42. data/ext/libcouchbase/src/cntl.cc +56 -22
  43. data/ext/libcouchbase/src/connspec.cc +47 -6
  44. data/ext/libcouchbase/src/connspec.h +27 -0
  45. data/ext/libcouchbase/src/dns-srv.cc +147 -0
  46. data/ext/libcouchbase/src/dump.cc +3 -3
  47. data/ext/libcouchbase/src/errmap.cc +173 -0
  48. data/ext/libcouchbase/src/errmap.h +198 -0
  49. data/ext/libcouchbase/src/getconfig.cc +7 -33
  50. data/ext/libcouchbase/src/handler.cc +118 -7
  51. data/ext/libcouchbase/src/hostlist.cc +0 -36
  52. data/ext/libcouchbase/src/hostlist.h +44 -62
  53. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  54. data/ext/libcouchbase/src/http/http.cc +27 -35
  55. data/ext/libcouchbase/src/http/http.h +1 -34
  56. data/ext/libcouchbase/src/http/http_io.cc +28 -36
  57. data/ext/libcouchbase/src/instance.cc +131 -34
  58. data/ext/libcouchbase/src/internal.h +58 -26
  59. data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
  60. data/ext/libcouchbase/src/jsparse/parser.h +84 -98
  61. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  62. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  63. data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
  64. data/ext/libcouchbase/src/lcbio/connect.h +16 -7
  65. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  66. data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
  67. data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
  68. data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
  69. data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
  70. data/ext/libcouchbase/src/lcbio/manager.h +133 -96
  71. data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
  72. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  73. data/ext/libcouchbase/src/mc/mcreq.c +11 -2
  74. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  75. data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
  76. data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
  77. data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
  78. data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
  79. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  80. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  81. data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
  82. data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
  83. data/ext/libcouchbase/src/newconfig.cc +6 -6
  84. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  85. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  86. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  87. data/ext/libcouchbase/src/operations/durability.cc +6 -26
  88. data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
  89. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  90. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
  91. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  92. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  93. data/ext/libcouchbase/src/operations/stats.cc +3 -8
  94. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  95. data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
  96. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  97. data/ext/libcouchbase/src/packetutils.h +30 -2
  98. data/ext/libcouchbase/src/probes.d +1 -1
  99. data/ext/libcouchbase/src/rdb/rope.c +1 -1
  100. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
  101. data/ext/libcouchbase/src/retryq.cc +52 -14
  102. data/ext/libcouchbase/src/retryq.h +3 -3
  103. data/ext/libcouchbase/src/settings.c +5 -0
  104. data/ext/libcouchbase/src/settings.h +11 -0
  105. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  106. data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
  107. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  108. data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
  109. data/ext/libcouchbase/src/trace.h +4 -4
  110. data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
  111. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  112. data/ext/libcouchbase/src/views/docreq.h +24 -30
  113. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  114. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  115. data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
  116. data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
  117. data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
  118. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
  119. data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
  120. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
  121. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  122. data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
  123. data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
  124. data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
  125. data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
  126. data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
  127. data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
  128. data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
  129. data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
  130. data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
  131. data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
  132. data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
  133. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
  134. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
  135. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  136. data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
  137. data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
  138. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  139. data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
  140. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  141. data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
  142. data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
  143. data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
  144. data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
  145. data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
  146. data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
  147. data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
  148. data/ext/libcouchbase/tools/cbc.cc +143 -10
  149. data/ext/libcouchbase/tools/docgen/loc.h +1 -1
  150. data/lib/libcouchbase/connection.rb +4 -3
  151. data/lib/libcouchbase/version.rb +1 -1
  152. metadata +37 -28
  153. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  154. data/ext/libcouchbase/src/bootstrap.c +0 -269
  155. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  156. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  157. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  158. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  159. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  160. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  161. data/ext/libcouchbase/src/lcbio/manager.c +0 -584
  162. data/ext/libcouchbase/src/packetutils.c +0 -37
  163. data/ext/libcouchbase/src/simplestring.c +0 -211
  164. data/ext/libcouchbase/src/simplestring.h +0 -228
  165. data/ext/libcouchbase/src/ssobuf.h +0 -82
  166. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  167. data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -41,6 +41,7 @@
41
41
  #include "mcserver/mcserver.h"
42
42
  #include "mc/mcreq.h"
43
43
  #include "settings.h"
44
+ #include "contrib/genhash/genhash.h"
44
45
 
45
46
  /* lcb_t-specific includes */
46
47
  #include "retryq.h"
@@ -57,12 +58,15 @@ namespace lcb {
57
58
  class Connspec;
58
59
  struct Spechost;
59
60
  class RetryQueue;
61
+ class Bootstrap;
62
+ namespace clconfig {
63
+ struct Confmon;
64
+ class ConfigInfo;
65
+ }
60
66
  }
61
67
  extern "C" {
62
68
  #endif
63
69
 
64
- struct lcb_string_st;
65
-
66
70
  struct lcb_callback_st {
67
71
  lcb_RESPCALLBACK v3callbacks[LCB_CALLBACK__MAX];
68
72
  lcb_get_callback get;
@@ -87,27 +91,31 @@ struct lcb_callback_st {
87
91
  lcb_pktflushed_callback pktflushed;
88
92
  };
89
93
 
90
- struct lcb_confmon_st;
91
- struct lcb_BOOTSTRAP;
92
94
  struct lcb_GUESSVB_st;
93
95
 
94
96
  #ifdef __cplusplus
95
97
  #include <string>
96
98
  typedef std::string* lcb_pSCRATCHBUF;
97
99
  typedef lcb::RetryQueue lcb_RETRYQ;
100
+ typedef lcb::clconfig::Confmon* lcb_pCONFMON;
101
+ typedef lcb::clconfig::ConfigInfo *lcb_pCONFIGINFO;
102
+ typedef lcb::Bootstrap lcb_BOOTSTRAP;
98
103
  #else
99
104
  typedef struct lcb_SCRATCHBUF* lcb_pSCRATCHBUF;
100
105
  typedef struct lcb_RETRYQ_st lcb_RETRYQ;
106
+ typedef struct lcb_CONFMON_st* lcb_pCONFMON;
107
+ typedef struct lcb_CONFIGINFO_st* lcb_pCONFIGINFO;
108
+ typedef struct lcb_BOOTSTRAP_st lcb_BOOTSTRAP;
101
109
  #endif
102
110
 
103
111
  struct lcb_st {
104
112
  mc_CMDQUEUE cmdq; /**< Base command queue object */
105
113
  const void *cookie; /**< User defined pointer */
106
- struct lcb_confmon_st *confmon; /**< Cluster config manager */
114
+ lcb_pCONFMON confmon; /**< Cluster config manager */
107
115
  hostlist_t mc_nodes; /**< List of current memcached endpoints */
108
116
  hostlist_t ht_nodes; /**< List of current management endpoints */
109
- struct clconfig_info_st *cur_configinfo; /**< Pointer to current config */
110
- struct lcb_BOOTSTRAP *bootstrap; /**< Bootstrapping state */
117
+ lcb_pCONFIGINFO cur_configinfo; /**< Pointer to current config */
118
+ lcb_BOOTSTRAP *bs_state; /**< Bootstrapping state */
111
119
  struct lcb_callback_st callbacks; /**< Callback table */
112
120
  lcb_HISTOGRAM *kv_timings; /**< Histogram object (for timing) */
113
121
  lcb_ASPEND pendops; /**< Pending asynchronous requests */
@@ -130,10 +138,49 @@ struct lcb_st {
130
138
  lcbio_pTABLE getIOT() { return iotable; }
131
139
  inline void add_bs_host(const char *host, int port, unsigned bstype);
132
140
  inline void add_bs_host(const lcb::Spechost& host, int defl_http, int defl_cccp);
141
+ inline lcb_error_t process_dns_srv(lcb::Connspec& spec);
133
142
  inline void populate_nodes(const lcb::Connspec&);
134
- mc_SERVER *get_server(size_t index) const {
135
- return static_cast<mc_SERVER*>(cmdq.pipelines[index]);
143
+ lcb::Server *get_server(size_t index) const {
144
+ return static_cast<lcb::Server*>(cmdq.pipelines[index]);
145
+ }
146
+ lcb::Server *find_server(const lcb_host_t& host) const;
147
+ lcb_error_t request_config(const void *cookie, lcb::Server* server);
148
+
149
+ /**
150
+ * @brief Request that the handle update its configuration.
151
+ *
152
+ * This function acts as a gateway to the more abstract confmon interface.
153
+ *
154
+ * @param instance The instance
155
+ * @param options A set of options specified as flags, indicating under what
156
+ * conditions a new configuration should be refetched.
157
+ *
158
+ * This should be a combination of one or more @ref lcb::BootstrapOptions
159
+ *
160
+ * Note, the definition for this function (and the flags)
161
+ * are found in bootstrap.cc
162
+ */
163
+ inline lcb_error_t bootstrap(unsigned options) {
164
+ if (!bs_state) {
165
+ bs_state = new lcb::Bootstrap(this);
166
+ }
167
+ return bs_state->bootstrap(options);
168
+ }
169
+
170
+ lcbvb_CONFIG *getConfig() const {
171
+ return cur_configinfo->vbc;
136
172
  }
173
+
174
+ int map_key(const std::string& key) {
175
+ int srvix, tmpvb;
176
+ lcbvb_map_key(getConfig(), key.c_str(), key.size(), &tmpvb, &srvix);
177
+ return srvix;
178
+ }
179
+
180
+ const char *get_bucketname() const {
181
+ return settings->bucket;
182
+ }
183
+
137
184
  #endif
138
185
  };
139
186
 
@@ -141,7 +188,7 @@ struct lcb_st {
141
188
  #define LCBT_NSERVERS(instance) (instance)->cmdq.npipelines
142
189
  #define LCBT_NDATASERVERS(instance) LCBVB_NDATASERVERS(LCBT_VBCONFIG(instance))
143
190
  #define LCBT_NREPLICAS(instance) LCBVB_NREPLICAS(LCBT_VBCONFIG(instance))
144
- #define LCBT_GET_SERVER(instance, ix) ((mc_SERVER *)(instance)->cmdq.pipelines[ix])
191
+ #define LCBT_GET_SERVER(instance, ix) (instance)->cmdq.pipelines[ix]
145
192
  #define LCBT_SETTING(instance, name) (instance)->settings->name
146
193
 
147
194
  void lcb_initialize_packet_handlers(lcb_t instance);
@@ -149,8 +196,7 @@ void lcb_initialize_packet_handlers(lcb_t instance);
149
196
  LCB_INTERNAL_API
150
197
  void lcb_maybe_breakout(lcb_t instance);
151
198
 
152
- struct clconfig_info_st;
153
- void lcb_update_vbconfig(lcb_t instance, struct clconfig_info_st *config);
199
+ void lcb_update_vbconfig(lcb_t instance, lcb_pCONFIGINFO config);
154
200
  /**
155
201
  * Hashtable wrappers
156
202
  */
@@ -186,20 +232,6 @@ lcb_error_t lcb_init_providers2(lcb_t obj,
186
232
  const struct lcb_create_st2 *e_options);
187
233
  lcb_error_t lcb_reinit3(lcb_t obj, const char *connstr);
188
234
 
189
-
190
- LCB_INTERNAL_API
191
- mc_SERVER *
192
- lcb_find_server_by_host(lcb_t instance, const lcb_host_t *host);
193
-
194
-
195
- LCB_INTERNAL_API
196
- mc_SERVER *
197
- lcb_find_server_by_index(lcb_t instance, int ix);
198
-
199
- LCB_INTERNAL_API
200
- lcb_error_t
201
- lcb_getconfig(lcb_t instance, const void *cookie, mc_SERVER *server);
202
-
203
235
  int
204
236
  lcb_should_retry(const lcb_settings *settings, const mc_PACKET *pkt, lcb_error_t err);
205
237
 
@@ -35,27 +35,30 @@ DECLARE_JSONSL_CALLBACK(initial_pop_callback);
35
35
  DECLARE_JSONSL_CALLBACK(meta_header_complete_callback);
36
36
  DECLARE_JSONSL_CALLBACK(trailer_pop_callback);
37
37
 
38
+ using namespace lcb::jsparse;
39
+
38
40
  /* conform to void */
39
41
  #define JOBJ_RESPONSE_ROOT (void*)1
40
42
  #define JOBJ_ROWSET (void*)2
41
43
 
42
- #define NORMALIZE_OFFSETS(buf, len) buf++; len--;
43
-
44
- #define buffer_append lcb_string_append
44
+ template <typename T>
45
+ void NORMALIZE_OFFSETS(const char *& buf, T& len) {
46
+ buf++;
47
+ len--;
48
+ }
45
49
 
46
50
  /**
47
51
  * Gets a buffer, given an (absolute) position offset.
48
52
  * It will try to get a buffer of size desired. The actual size is
49
53
  * returned in 'actual' (and may be less than desired, maybe even 0)
50
54
  */
51
- static const char *
52
- get_buffer_region(lcbjsp_PARSER *ctx, size_t pos, size_t desired, size_t *actual)
55
+ const char * Parser::get_buffer_region(size_t pos, size_t desired, size_t *actual)
53
56
  {
54
- const char *ret = ctx->current_buf.base + pos - ctx->min_pos;
55
- const char *end = ctx->current_buf.base + ctx->current_buf.nused;
57
+ const char *ret = current_buf.c_str() + pos - min_pos;
58
+ const char *end = current_buf.c_str() + current_buf.size();
56
59
  *actual = end - ret;
57
60
 
58
- if (ctx->min_pos > pos) {
61
+ if (min_pos > pos) {
59
62
  /* swallowed */
60
63
  *actual = 0;
61
64
  return NULL;
@@ -71,55 +74,46 @@ get_buffer_region(lcbjsp_PARSER *ctx, size_t pos, size_t desired, size_t *actual
71
74
  /**
72
75
  * Consolidate the meta data into a single parsable string..
73
76
  */
74
- static void
75
- combine_meta(lcbjsp_PARSER *ctx)
76
- {
77
+ void Parser::combine_meta() {
77
78
  const char *meta_trailer;
78
79
  size_t ntrailer;
79
80
 
80
- if (ctx->meta_complete) {
81
+ if (meta_complete) {
81
82
  return;
82
83
  }
83
84
 
84
- assert(ctx->header_len <= ctx->meta_buf.nused);
85
+ assert(header_len <= meta_buf.size());
85
86
 
86
87
  /* Adjust the length for the first portion */
87
- ctx->meta_buf.nused = ctx->header_len;
88
+ meta_buf.resize(header_len);
88
89
 
89
90
  /* Append any trailing data */
90
- meta_trailer = get_buffer_region(ctx, ctx->last_row_endpos, -1, &ntrailer);
91
-
92
- buffer_append(&ctx->meta_buf, meta_trailer, ntrailer);
93
- ctx->meta_complete = 1;
91
+ meta_trailer = get_buffer_region(last_row_endpos, -1, &ntrailer);
92
+ meta_buf.append(meta_trailer, ntrailer);
93
+ meta_complete = 1;
94
94
  }
95
95
 
96
- static lcbjsp_PARSER *
97
- get_ctx(jsonsl_t jsn)
98
- {
99
- return reinterpret_cast<lcbjsp_PARSER*>(jsn->data);
96
+ static Parser * get_ctx(jsonsl_t jsn) {
97
+ return reinterpret_cast<Parser*>(jsn->data);
100
98
  }
101
99
 
102
100
  static void
103
- meta_header_complete_callback(jsonsl_t jsn, jsonsl_action_t action,
104
- struct jsonsl_state_st *state, const jsonsl_char_t *at)
101
+ meta_header_complete_callback(jsonsl_t jsn, jsonsl_action_t,
102
+ struct jsonsl_state_st *state, const jsonsl_char_t *)
105
103
  {
106
-
107
- lcbjsp_PARSER *ctx = get_ctx(jsn);
108
- buffer_append(&ctx->meta_buf, ctx->current_buf.base, state->pos_begin);
104
+ Parser *ctx = get_ctx(jsn);
105
+ ctx->meta_buf.append(ctx->current_buf.c_str(), state->pos_begin);
109
106
 
110
107
  ctx->header_len = state->pos_begin;
111
108
  jsn->action_callback_PUSH = NULL;
112
-
113
- (void)action; (void)at;
114
109
  }
115
110
 
116
111
 
117
112
  static void
118
- row_pop_callback(jsonsl_t jsn, jsonsl_action_t action,
119
- struct jsonsl_state_st *state, const jsonsl_char_t *at)
113
+ row_pop_callback(jsonsl_t jsn, jsonsl_action_t,
114
+ struct jsonsl_state_st *state, const jsonsl_char_t *)
120
115
  {
121
- lcbjsp_ROW dt = { LCBJSP_TYPE_ROW };
122
- lcbjsp_PARSER *ctx = get_ctx(jsn);
116
+ Parser *ctx = get_ctx(jsn);
123
117
  const char *rowbuf;
124
118
  size_t szdummy;
125
119
 
@@ -139,71 +133,59 @@ row_pop_callback(jsonsl_t jsn, jsonsl_action_t action,
139
133
 
140
134
  /* While the entire meta is available to us, the _closing_ part
141
135
  * of the meta is handled in a different callback. */
142
- buffer_append(&ctx->meta_buf, ctx->current_buf.base, jsn->pos);
136
+ ctx->meta_buf.append(ctx->current_buf.c_str(), jsn->pos);
143
137
  ctx->header_len = jsn->pos;
144
138
  }
145
139
  return;
146
140
  }
147
141
 
148
142
  ctx->rowcount++;
149
-
150
- if (!ctx->callback) {
143
+ if (!ctx->actions) {
151
144
  return;
152
145
  }
153
146
 
154
- rowbuf = get_buffer_region(ctx, state->pos_begin, -1, &szdummy);
155
- dt.type = LCBJSP_TYPE_ROW;
147
+ rowbuf = ctx->get_buffer_region(state->pos_begin, -1, &szdummy);
148
+ Row dt = {{0}};
156
149
  dt.row.iov_base = (void *)rowbuf;
157
150
  dt.row.iov_len = jsn->pos - state->pos_begin + 1;
158
- ctx->callback(ctx, &dt);
159
-
160
- (void)action; (void)at;
151
+ ctx->actions->JSPARSE_on_row(dt);
161
152
  }
162
153
 
163
154
  static int
164
- parse_error_callback(jsonsl_t jsn, jsonsl_error_t error,
165
- struct jsonsl_state_st *state, jsonsl_char_t *at)
155
+ parse_error_callback(jsonsl_t jsn, jsonsl_error_t,
156
+ struct jsonsl_state_st *, jsonsl_char_t *)
166
157
  {
167
- lcbjsp_PARSER *ctx = get_ctx(jsn);
168
- lcbjsp_ROW dt;
169
-
158
+ Parser *ctx = get_ctx(jsn);
170
159
  ctx->have_error = 1;
171
160
 
172
161
  /* invoke the callback */
173
- dt.type = LCBJSP_TYPE_ERROR;
174
- dt.row.iov_base = ctx->current_buf.base;
175
- dt.row.iov_len = ctx->current_buf.nused;
176
- ctx->callback(ctx, &dt);
177
-
178
- (void)error; (void)state; (void)at;
179
-
162
+ if (ctx->actions) {
163
+ ctx->actions->JSPARSE_on_error(ctx->current_buf);
164
+ ctx->actions = NULL;
165
+ }
180
166
  return 0;
181
167
  }
182
168
 
183
169
  static void
184
- trailer_pop_callback(jsonsl_t jsn, jsonsl_action_t action,
185
- struct jsonsl_state_st *state, const jsonsl_char_t *at)
170
+ trailer_pop_callback(jsonsl_t jsn, jsonsl_action_t,
171
+ struct jsonsl_state_st *state, const jsonsl_char_t *)
186
172
  {
187
- lcbjsp_PARSER *ctx = get_ctx(jsn);
188
- lcbjsp_ROW dt;
173
+ Parser *ctx = get_ctx(jsn);
189
174
  if (state->data != JOBJ_RESPONSE_ROOT) {
190
175
  return;
191
176
  }
192
- combine_meta(ctx);
193
- dt.row.iov_base = ctx->meta_buf.base;
194
- dt.row.iov_len = ctx->meta_buf.nused;
195
- dt.type = LCBJSP_TYPE_COMPLETE;
196
- ctx->callback(ctx, &dt);
197
-
198
- (void)action; (void)at;
177
+ ctx->combine_meta();
178
+ if (ctx->actions) {
179
+ ctx->actions->JSPARSE_on_complete(ctx->meta_buf);
180
+ ctx->actions = NULL;
181
+ }
199
182
  }
200
183
 
201
184
  static void
202
- initial_pop_callback(jsonsl_t jsn, jsonsl_action_t action,
203
- struct jsonsl_state_st *state, const jsonsl_char_t *at)
185
+ initial_pop_callback(jsonsl_t jsn, jsonsl_action_t,
186
+ struct jsonsl_state_st *state, const jsonsl_char_t *)
204
187
  {
205
- lcbjsp_PARSER *ctx = get_ctx(jsn);
206
- char *key;
188
+ Parser *ctx = get_ctx(jsn);
207
189
  unsigned long len;
208
190
 
209
191
  if (ctx->have_error) {
@@ -216,14 +198,10 @@ initial_pop_callback(jsonsl_t jsn, jsonsl_action_t action,
216
198
  return;
217
199
  }
218
200
 
219
- key = ctx->current_buf.base + state->pos_begin;
201
+ const char *key = ctx->current_buf.c_str() + state->pos_begin;
220
202
  len = jsn->pos - state->pos_begin;
221
203
  NORMALIZE_OFFSETS(key, len);
222
-
223
- lcb_string_clear(&ctx->last_hk);
224
- buffer_append(&ctx->last_hk, key, len);
225
-
226
- (void)action; (void)at;
204
+ ctx->last_hk.assign(key, len);
227
205
  }
228
206
 
229
207
  /**
@@ -231,10 +209,10 @@ initial_pop_callback(jsonsl_t jsn, jsonsl_action_t action,
231
209
  * for the row set.
232
210
  */
233
211
  static void
234
- initial_push_callback(jsonsl_t jsn, jsonsl_action_t action,
235
- struct jsonsl_state_st *state, const jsonsl_char_t *at)
212
+ initial_push_callback(jsonsl_t jsn, jsonsl_action_t,
213
+ struct jsonsl_state_st *state, const jsonsl_char_t *)
236
214
  {
237
- lcbjsp_PARSER *ctx = (lcbjsp_PARSER*)jsn->data;
215
+ Parser *ctx = (Parser*)jsn->data;
238
216
  jsonsl_jpr_match_t match = JSONSL_MATCH_UNKNOWN;
239
217
 
240
218
  if (ctx->have_error) {
@@ -242,11 +220,10 @@ initial_push_callback(jsonsl_t jsn, jsonsl_action_t action,
242
220
  }
243
221
 
244
222
  if (JSONSL_STATE_IS_CONTAINER(state)) {
245
- jsonsl_jpr_match_state(jsn, state, ctx->last_hk.base, ctx->last_hk.nused,
223
+ jsonsl_jpr_match_state(jsn, state, ctx->last_hk.c_str(), ctx->last_hk.size(),
246
224
  &match);
247
225
  }
248
-
249
- lcb_string_clear(&ctx->last_hk);
226
+ ctx->last_hk.clear();
250
227
 
251
228
  if (ctx->initialized == 0) {
252
229
  if (state->type != JSONSL_T_OBJECT) {
@@ -270,149 +247,101 @@ initial_push_callback(jsonsl_t jsn, jsonsl_action_t action,
270
247
  jsn->action_callback_PUSH = meta_header_complete_callback;
271
248
  state->data = JOBJ_ROWSET;
272
249
  }
273
-
274
- (void)action; /* always PUSH */
275
- (void)at;
276
250
  }
277
251
 
278
- static void
279
- feed_data(lcbjsp_PARSER *ctx, const char *data, size_t ndata)
252
+ void Parser::feed(const char *data_, size_t ndata)
280
253
  {
281
- size_t old_len = ctx->current_buf.nused;
282
-
283
- buffer_append(&ctx->current_buf, data, ndata);
284
- jsonsl_feed(ctx->jsn, ctx->current_buf.base + old_len, ndata);
254
+ size_t old_len = current_buf.size();
255
+ current_buf.append(data_, ndata);
256
+ jsonsl_feed(jsn, current_buf.c_str() + old_len, ndata);
285
257
 
286
258
  /* Do we need to cut off some bytes? */
287
- if (ctx->keep_pos > ctx->min_pos) {
288
- size_t lentmp, diff = ctx->keep_pos - ctx->min_pos;
289
- const char *buf = get_buffer_region(ctx, ctx->keep_pos, -1, &lentmp);
290
- memmove(ctx->current_buf.base, buf, ctx->current_buf.nused - diff);
291
- ctx->current_buf.nused -= diff;
259
+ if (keep_pos > min_pos) {
260
+ current_buf.erase(0, keep_pos - min_pos);
292
261
  }
293
262
 
294
- ctx->min_pos = ctx->keep_pos;
263
+ min_pos = keep_pos;
295
264
  }
296
265
 
297
- /* Non-static wrapper */
298
- void
299
- lcbjsp_feed(lcbjsp_PARSER *ctx, const char *data, size_t ndata)
300
- {
301
- feed_data(ctx, data, ndata);
302
- }
303
-
304
- lcbjsp_PARSER*
305
- lcbjsp_create(int mode)
306
- {
307
- lcbjsp_PARSER *ctx;
308
- jsonsl_error_t err;
309
-
310
- ctx = reinterpret_cast<lcbjsp_PARSER*>(calloc(1, sizeof(*ctx)));
311
- ctx->jsn = jsonsl_new(512);
312
- ctx->mode = mode;
313
- ctx->cxx_data = new Json::Value();
314
-
315
- if (ctx->mode == LCBJSP_MODE_VIEWS) {
316
- ctx->jpr = jsonsl_jpr_new("/rows/^", &err);
317
- } else if (ctx->mode == LCBJSP_MODE_N1QL) {
318
- ctx->jpr = jsonsl_jpr_new("/results/^", &err);
319
- } else {
320
- ctx->jpr = jsonsl_jpr_new("/hits/^", &err);
266
+ const char* Parser::jprstr_for_mode(Mode mode) {
267
+ switch (mode) {
268
+ case MODE_VIEWS:
269
+ return "/rows/^";
270
+ case MODE_N1QL:
271
+ return "/results/^";
272
+ case MODE_FTS:
273
+ return "/hits/^";
274
+ default:
275
+ lcb_assert(0 && "Invalid mode passed!");
276
+ return "/";
321
277
  }
322
- ctx->jsn_rdetails = jsonsl_new(32);
323
-
324
- lcb_string_init(&ctx->meta_buf);
325
- lcb_string_init(&ctx->current_buf);
326
- lcb_string_init(&ctx->last_hk);
327
-
328
- if (!ctx->jpr) { abort(); }
329
- if (!ctx->jsn_rdetails) { abort(); }
330
-
331
- jsonsl_jpr_match_state_init(ctx->jsn, &ctx->jpr, 1);
332
- assert(ctx->jsn_rdetails);
333
-
334
- lcbjsp_reset(ctx);
335
- assert(ctx->jsn_rdetails);
336
- return ctx;
337
278
  }
338
279
 
339
- void
340
- lcbjsp_get_postmortem(const lcbjsp_PARSER *v, lcb_IOV *out)
341
- {
342
- if (v->meta_complete) {
343
- out->iov_base = v->meta_buf.base;
344
- out->iov_len = v->meta_buf.nused;
345
- } else {
346
- out->iov_base = v->current_buf.base;
347
- out->iov_len = v->current_buf.nused;
348
- }
349
- }
350
-
351
- void
352
- lcbjsp_reset(lcbjsp_PARSER* ctx)
353
- {
354
- /**
355
- * We create a copy, and set its relevant fields. All other
356
- * fields are zeroed implicitly. Then we copy the object back.
357
- */
358
- jsonsl_reset(ctx->jsn);
359
- jsonsl_reset(ctx->jsn_rdetails);
360
-
361
- lcb_string_clear(&ctx->current_buf);
362
- lcb_string_clear(&ctx->meta_buf);
363
- lcb_string_clear(&ctx->last_hk);
280
+ Parser::Parser(Mode mode_, Parser::Actions* actions_) :
281
+ jsn(jsonsl_new(512)),
282
+ jsn_rdetails(jsonsl_new(32)),
283
+ jpr(jsonsl_jpr_new(jprstr_for_mode(mode_), NULL)),
284
+ mode(mode_),
285
+ have_error(0),
286
+ initialized(0),
287
+ meta_complete(0),
288
+ rowcount(0),
289
+ min_pos(0),
290
+ keep_pos(0),
291
+ header_len(0),
292
+ last_row_endpos(0),
293
+ cxx_data(),
294
+ actions(actions_) {
295
+
296
+ jsonsl_jpr_match_state_init(jsn, &jpr, 1);
297
+ jsonsl_reset(jsn);
298
+ jsonsl_reset(jsn_rdetails);
299
+ current_buf.clear();
300
+ meta_buf.clear();
301
+ last_hk.clear();
364
302
 
365
303
  /* Initially all callbacks are enabled so that we can search for the
366
304
  * rows array. */
367
- ctx->jsn->action_callback_POP = initial_pop_callback;
368
- ctx->jsn->action_callback_PUSH = initial_push_callback;
369
- ctx->jsn->error_callback = parse_error_callback;
370
- ctx->jsn->max_callback_level = 4;
371
- ctx->jsn->data = ctx;
372
- jsonsl_enable_all_callbacks(ctx->jsn);
373
-
374
- ctx->have_error = 0;
375
- ctx->initialized = 0;
376
- ctx->meta_complete = 0;
377
- ctx->rowcount = 0;
378
- ctx->min_pos = 0;
379
- ctx->keep_pos = 0;
380
- ctx->header_len = 0;
381
- ctx->last_row_endpos = 0;
382
- reinterpret_cast<Json::Value*>(ctx->cxx_data)->clear();
305
+ jsn->action_callback_POP = initial_pop_callback;
306
+ jsn->action_callback_PUSH = initial_push_callback;
307
+ jsn->error_callback = parse_error_callback;
308
+ jsn->max_callback_level = 4;
309
+ jsn->data = this;
310
+ jsonsl_enable_all_callbacks(jsn);
383
311
  }
384
312
 
385
- void
386
- lcbjsp_free(lcbjsp_PARSER *ctx)
387
- {
388
- jsonsl_jpr_match_state_cleanup(ctx->jsn);
389
- jsonsl_destroy(ctx->jsn);
390
- jsonsl_destroy(ctx->jsn_rdetails);
391
- jsonsl_jpr_destroy(ctx->jpr);
392
-
393
- lcb_string_release(&ctx->current_buf);
394
- lcb_string_release(&ctx->meta_buf);
395
- lcb_string_release(&ctx->last_hk);
396
- delete reinterpret_cast<Json::Value*>(ctx->cxx_data);
313
+ void Parser::get_postmortem(lcb_IOV &out) const {
314
+ if (meta_complete) {
315
+ out.iov_base = const_cast<char*>(meta_buf.c_str());
316
+ out.iov_len = meta_buf.size();
317
+ } else {
318
+ out.iov_base = const_cast<char*>(current_buf.c_str());
319
+ out.iov_len = current_buf.size();
320
+ }
321
+ }
397
322
 
398
- free(ctx);
323
+ Parser::~Parser() {
324
+ jsonsl_jpr_match_state_cleanup(jsn);
325
+ jsonsl_destroy(jsn);
326
+ jsonsl_destroy(jsn_rdetails);
327
+ jsonsl_jpr_destroy(jpr);
399
328
  }
400
329
 
401
330
  typedef struct {
402
331
  const char *root;
403
332
  lcb_IOV *next_iov;
404
- lcbjsp_ROW *datum;
405
- lcbjsp_PARSER *parent;
333
+ Row *datum;
334
+ Parser *parent;
406
335
  } miniparse_ctx;
407
336
 
408
337
  static void
409
- parse_json_docid(lcb_IOV* iov, lcbjsp_PARSER *parent)
338
+ parse_json_docid(lcb_IOV* iov, Parser *parent)
410
339
  {
411
340
  Json::Reader r;
412
341
  const char *s = static_cast<char*>(iov->iov_base);
413
342
  const char *s_end = s + iov->iov_len;
414
- Json::Value *jvp = reinterpret_cast<Json::Value*>(parent->cxx_data);
415
- bool rv = r.parse(s, s_end, *jvp);
343
+ Json::Value& jvp = parent->cxx_data;
344
+ bool rv = r.parse(s, s_end, jvp);
416
345
  if (!rv) {
417
346
  // fprintf(stderr, "libcouchbase: Failed to parse document ID as JSON!\n");
418
347
  return;
@@ -421,10 +350,10 @@ parse_json_docid(lcb_IOV* iov, lcbjsp_PARSER *parent)
421
350
  s = NULL;
422
351
  s_end = NULL;
423
352
 
424
- assert(jvp->isString());
353
+ assert(jvp.isString());
425
354
 
426
355
  // Re-use s and s_end values for the string value itself
427
- if (!jvp->getString(&s, &s_end)) {
356
+ if (!jvp.getString(&s, &s_end)) {
428
357
  // fprintf(stderr, "libcouchbase: couldn't get string value!\n");
429
358
  iov->iov_base = NULL;
430
359
  iov->iov_len = 0;
@@ -434,7 +363,7 @@ parse_json_docid(lcb_IOV* iov, lcbjsp_PARSER *parent)
434
363
  }
435
364
 
436
365
  static void
437
- miniparse_callback(jsonsl_t jsn, jsonsl_action_t action,
366
+ miniparse_callback(jsonsl_t jsn, jsonsl_action_t,
438
367
  struct jsonsl_state_st *state, const jsonsl_char_t *at)
439
368
  {
440
369
  miniparse_ctx *ctx = reinterpret_cast<miniparse_ctx*>(jsn->data);
@@ -496,24 +425,21 @@ miniparse_callback(jsonsl_t jsn, jsonsl_action_t action,
496
425
  iov->iov_len++;
497
426
  }
498
427
  }
499
- (void)at; (void)action;
500
428
  }
501
429
 
502
- void
503
- lcbjsp_parse_viewrow(lcbjsp_PARSER *vp, lcbjsp_ROW *vr)
504
- {
430
+ void Parser::parse_viewrow(Row &vr) {
505
431
  miniparse_ctx ctx = { NULL };
506
- ctx.datum = vr;
507
- ctx.root = static_cast<const char*>(vr->row.iov_base);
508
- ctx.parent = vp;
432
+ ctx.datum = &vr;
433
+ ctx.root = static_cast<const char*>(vr.row.iov_base);
434
+ ctx.parent = this;
509
435
 
510
- jsonsl_reset(vp->jsn_rdetails);
436
+ jsonsl_reset(jsn_rdetails);
511
437
 
512
- jsonsl_enable_all_callbacks(vp->jsn_rdetails);
513
- vp->jsn_rdetails->max_callback_level = 3;
514
- vp->jsn_rdetails->action_callback_POP = miniparse_callback;
515
- vp->jsn_rdetails->data = &ctx;
438
+ jsonsl_enable_all_callbacks(jsn_rdetails);
439
+ jsn_rdetails->max_callback_level = 3;
440
+ jsn_rdetails->action_callback_POP = miniparse_callback;
441
+ jsn_rdetails->data = &ctx;
516
442
 
517
- jsonsl_feed(vp->jsn_rdetails,
518
- static_cast<const char*>(vr->row.iov_base), vr->row.iov_len);
443
+ jsonsl_feed(jsn_rdetails,
444
+ static_cast<const char*>(vr.row.iov_base), vr.row.iov_len);
519
445
  }