/** * Copyright 2013 Couchbase, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. **/ #ifndef LCB_VIEWROW_H_ #define LCB_VIEWROW_H_ #include #include #include "contrib/jsonsl/jsonsl.h" #include "contrib/lcb-jsoncpp/lcb-jsoncpp.h" #include namespace lcb { namespace jsparse { struct Parser; struct Row { lcb_IOV docid; lcb_IOV key; lcb_IOV value; lcb_IOV row; lcb_IOV geo; }; struct Parser { enum Mode { MODE_VIEWS, MODE_N1QL, MODE_FTS }; struct Actions { /** * Called when a row is received. * This is a row of view data. You can parse this as JSON from your * favorite decoder/converter */ virtual void JSPARSE_on_row(const Row&) = 0; /** * A JSON parse error occured. The payload will contain string data. This * may be JSON (but this is not likely). * The callback will be delivered twice. First when the error is noticed, * and second at the end (instead of a COMPLETE callback) */ virtual void JSPARSE_on_error(const std::string& buf) = 0; /** * All the rows have been returned. In this case, the data is the 'meta'. * This is a valid JSON payload which was returned from the server. * The "rows" : [] array will be empty. */ virtual void JSPARSE_on_complete(const std::string& meta) = 0; virtual ~Actions(){} }; /** * Creates a new vrow context object. * You must set callbacks on this object if you wish it to be useful. * You must feed it data (calling vrow_feed) as well. The data may be fed * in chunks and callbacks will be invoked as each row is read. */ Parser(Mode mode, Actions* actions_); ~Parser(); /** * Feeds data into the vrow. The callback may be invoked multiple times * in this function. In the context of normal lcb usage, this will typically * be invoked from within an http_data_callback. */ void feed(const char *s, size_t n); void feed(const std::string& s) { feed(s.c_str(), s.size()); } /** * Parse the row buffer into its constituent parts. This should be called * if you want to split the row into its basic 'docid', 'key' and 'value' * fields * @param vp The parser to use * @param vr The row to parse. This assumes the row's "row" field is properly * set. */ void parse_viewrow(Row& vr); /** * Get the raw contents of the current buffer. This can be used to debug errors. * * Note that the buffer may be partial or malformed or otherwise unsuitable * for structured inspection, but may help human observers debug problems. * * @param out The iov structure to contain the buffer/offset */ void get_postmortem(lcb_IOV& out) const; inline const char *get_buffer_region(size_t pos, size_t desired, size_t* actual); inline void combine_meta(); inline static const char *jprstr_for_mode(Mode); jsonsl_t jsn; /**< Parser for the row itself */ jsonsl_t jsn_rdetails; /**< Parser for the row details */ jsonsl_jpr_t jpr; /**< jsonpointer match object */ std::string meta_buf; /**< String containing the skeleton (outer layer) */ std::string current_buf; /**< Scratch/read buffer */ std::string last_hk; /**< Last hashkey */ lcb_U8 mode; /* flags. This should be an int with a bunch of constant flags */ lcb_U8 have_error; lcb_U8 initialized; lcb_U8 meta_complete; unsigned rowcount; /* absolute position offset corresponding to the first byte in current_buf */ size_t min_pos; /* minimum (absolute) position to keep */ size_t keep_pos; /** * size of the metadata header chunk (i.e. everything until the opening * bracket of "rows" [ */ size_t header_len; /** * Position of last row returned. If there are no subsequent rows, this * signals the beginning of the metadata trailer */ size_t last_row_endpos; /** * std::string to contain parsed document ID. */ Json::Value cxx_data; /* callback to invoke */ Actions *actions; }; } } #endif /* LCB_VIEWROW_H_ */