libcouchbase 0.3.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }