Exemple #1
0
LegacyReply::LegacyReply(const Message* message) : _message(std::move(message)) {
    invariant(message->operation() == opReply);

    QueryResult::View qr = _message->singleData().view2ptr();

    // should be checked by caller.
    invariant(qr.msgdata().getNetworkOp() == opReply);

    uassert(ErrorCodes::BadValue,
            str::stream() << "Got legacy command reply with a bad cursorId field,"
                          << " expected a value of 0 but got " << qr.getCursorId(),
            qr.getCursorId() == 0);

    uassert(ErrorCodes::BadValue,
            str::stream() << "Got legacy command reply with a bad nReturned field,"
                          << " expected a value of 1 but got " << qr.getNReturned(),
            qr.getNReturned() == 1);

    uassert(ErrorCodes::BadValue,
            str::stream() << "Got legacy command reply with a bad startingFrom field,"
                          << " expected a value of 0 but got " << qr.getStartingFrom(),
            qr.getStartingFrom() == 0);

    std::tie(_commandReply, _metadata) =
        uassertStatusOK(rpc::upconvertReplyMetadata(BSONObj(qr.data())));

    // Copy the bson array of documents from the message into
    // a contiguous area of memory owned by _docBuffer so
    // DocumentRange can be used to iterate over documents
    auto cursorElem = _commandReply[LegacyReplyBuilder::kCursorTag];
    if (cursorElem.eoo())
        return;

    BSONObj cursorObj = cursorElem.Obj();
    auto firstBatchElem = cursorObj[LegacyReplyBuilder::kFirstBatchTag];
    if (firstBatchElem.eoo())
        return;

    for (BSONObjIterator it(firstBatchElem.Obj()); it.more(); it.next()) {
        invariant((*it).isABSONObj());
        BSONObj doc = (*it).Obj();
        doc.appendSelfToBufBuilder(_docBuffer);
    }
    const char* dataBegin = _docBuffer.buf();
    const char* dataEnd = dataBegin + _docBuffer.len();
    _outputDocs = DocumentRange(dataBegin, dataEnd);

    return;
}
CommandReply::CommandReply(const Message* message) : _message(message) {
    const char* begin = _message->singleData().data();
    std::size_t length = _message->singleData().dataLen();

    // This check failing would normally be operation fatal, but we expect it to have been
    // done earlier in the network layer, so we make it an invariant.
    invariant(length <= MaxMessageSizeBytes);

    const char* messageEnd = begin + length;
    ConstDataRangeCursor cur(begin, messageEnd);

    _commandReply = uassertStatusOK(cur.readAndAdvance<Validated<BSONObj>>()).val;
    _metadata = uassertStatusOK(cur.readAndAdvance<Validated<BSONObj>>()).val;
    _outputDocs = DocumentRange(cur.data(), messageEnd);
}
Exemple #3
0
Reply::Reply(const Message* message)
    : _message(message) {

    char* begin = _message->singleData().data();
    std::size_t length = _message->singleData().dataLen();

    invariant(length <= MaxMessageSizeBytes); // checked by message_port.cpp

    char* messageEnd = begin + length;
    ConstDataRangeCursor cur(begin, messageEnd);

    // TODO(amidvidy): we don't currently handle BSON validation.
    // we will eventually have to thread serverGlobalParams.objcheck through here
    // similarly to DbMessage::nextJsObj
    uassertStatusOK(cur.readAndAdvance<BSONObj>(&_metadata));
    uassertStatusOK(cur.readAndAdvance<BSONObj>(&_commandReply));
    _outputDocs = DocumentRange(cur.data(), messageEnd);
}