libcouchbase 0.2.0 → 0.3.1

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