Esempio n. 1
0
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)));
}
Esempio n. 2
0
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;
    }
}
Esempio n. 3
0
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;
    }
}