Byte ProtocolParser::pick() const { while(true) { if (buffers_.empty()) { yield_to_client(); } auto& top = buffers_.front(); throw_if_poisoned(top); if (top.pos < top.size) { auto buf = top.buffer.get(); return buf[top.pos]; } buffers_.pop(); yield_to_client(); } auto ctx = get_error_context("unexpected end of stream"); BOOST_THROW_EXCEPTION(ProtocolParserError(std::get<0>(ctx), std::get<1>(ctx))); }
void ProtocolParser::worker(Caller& caller) { // Remember caller for use in ByteStreamReader's methods set_caller(caller); // Buffer to read strings from const int buffer_len = RESPStream::STRING_LENGTH_MAX; Byte buffer[buffer_len] = {}; int bytes_read = 0; // Data to read std::string sid; aku_Sample sample; // try { RESPStream stream(this); while(true) { // read id auto next = stream.next_type(); switch(next) { case RESPStream::AK_INTEGER: sample.paramid = stream.read_int(); break; case RESPStream::AK_STRING: bytes_read = stream.read_string(buffer, buffer_len); consumer_->series_to_param_id(buffer, bytes_read, &sample); break; case RESPStream::AK_BULK_STR: // Compressed chunk of data bytes_read = stream.read_bulkstr(buffer, buffer_len); consumer_->add_bulk_string(buffer, bytes_read); continue; default: // Bad frame { std::string msg; size_t pos; std::tie(msg, pos) = get_error_context("unexpected parameter id format"); BOOST_THROW_EXCEPTION(ProtocolParserError(msg, pos)); } }; // read ts next = stream.next_type(); switch(next) { case RESPStream::AK_INTEGER: sample.timestamp = stream.read_int(); break; case RESPStream::AK_STRING: bytes_read = stream.read_string(buffer, buffer_len); buffer[bytes_read] = '\0'; if (aku_parse_timestamp(buffer, &sample) == AKU_SUCCESS) { break; } default: { std::string msg; size_t pos; std::tie(msg, pos) = get_error_context("Unexpected parameter timestamp format"); BOOST_THROW_EXCEPTION(ProtocolParserError(msg, pos)); } }; // read value next = stream.next_type(); switch(next) { case RESPStream::AK_INTEGER: sample.payload.type = AKU_PAYLOAD_FLOAT; sample.payload.float64 = stream.read_int(); sample.payload.size = sizeof(aku_Sample); break; case RESPStream::AK_STRING: bytes_read = stream.read_string(buffer, buffer_len); buffer[bytes_read] = '\0'; sample.payload.type = AKU_PAYLOAD_FLOAT; sample.payload.float64 = strtod(buffer, nullptr); sample.payload.size = sizeof(aku_Sample); memset(buffer, 0, bytes_read); break; default: // Bad frame { std::string msg; size_t pos; std::tie(msg, pos) = get_error_context("Unexpected parameter value format"); BOOST_THROW_EXCEPTION(ProtocolParserError(msg, pos)); } }; consumer_->write(sample); } } catch(EStopIteration const&) { logger_.info() << "EStopIteration"; done_ = true; } }
void ProtocolParser::worker(Caller& caller) { // Remember caller for use in ByteStreamReader's methods set_caller(caller); // Buffer to read strings from const int buffer_len = RESPStream::STRING_LENGTH_MAX; Byte buffer[buffer_len] = {}; int bytes_read = 0; // Data to read aku_ParamId id = 0; std::string sid; bool integer_id = false; aku_Timestamp ts = 0; double value =.0; // try { RESPStream stream(this); while(true) { // read id auto next = stream.next_type(); switch(next) { case RESPStream::INTEGER: id = stream.read_int(); integer_id = true; break; case RESPStream::STRING: bytes_read = stream.read_string(buffer, buffer_len); sid = std::string(buffer, buffer + bytes_read); integer_id = false; break; case RESPStream::BULK_STR: // Compressed chunk of data bytes_read = stream.read_bulkstr(buffer, buffer_len); consumer_->add_bulk_string(buffer, bytes_read); continue; default: // Bad frame { std::string msg; size_t pos; std::tie(msg, pos) = get_error_context("unexpected parameter id format"); BOOST_THROW_EXCEPTION(ProtocolParserError(msg, pos)); } }; // read ts next = stream.next_type(); switch(next) { case RESPStream::INTEGER: ts = stream.read_int(); break; case RESPStream::STRING: bytes_read = stream.read_string(buffer, buffer_len); // TODO: parse date-time { std::string msg; size_t pos; std::tie(msg, pos) = get_error_context("not implemented"); BOOST_THROW_EXCEPTION(ProtocolParserError(msg, pos)); } default: // Bad frame { std::string msg; size_t pos; std::tie(msg, pos) = get_error_context("Unexpected parameter timestamp format"); BOOST_THROW_EXCEPTION(ProtocolParserError(msg, pos)); } }; // read value next = stream.next_type(); switch(next) { case RESPStream::INTEGER: value = stream.read_int(); break; case RESPStream::STRING: bytes_read = stream.read_string(buffer, buffer_len); value = strtod(buffer, nullptr); memset(buffer, 0, bytes_read); break; default: // Bad frame { std::string msg; size_t pos; std::tie(msg, pos) = get_error_context("Unexpected parameter value format"); BOOST_THROW_EXCEPTION(ProtocolParserError(msg, pos)); } }; if (integer_id) { consumer_->write_double(id, ts, value); } else { // TODO: write blob BOOST_THROW_EXCEPTION(std::runtime_error("not implemented")); } } } catch(EStopIteration const&) { logger_.info() << "EStopIteration"; done_ = true; } }