bool McAsciiParserBase::readValue(folly::IOBuf& buffer, folly::IOBuf& to) { if (remainingIOBufLength_) { // Copy IOBuf for part of (or whole) value. size_t offset = p_ - reinterpret_cast<const char*>(buffer.data()) + 1; size_t toUse = std::min(buffer.length() - offset, remainingIOBufLength_); buffer.cloneOneInto(to); // Adjust buffer pointers. to.trimStart(offset); to.trimEnd(buffer.length() - offset - toUse); remainingIOBufLength_ -= toUse; // Move the state machine to the proper character. p_ += toUse; // Now if we don't have enough data, we need to preallocate second piece // for remaining buffer and signal partial read. if (remainingIOBufLength_) { auto secondPiece = folly::IOBuf::createCombined(remainingIOBufLength_); currentIOBuf_ = secondPiece.get(); to.appendChain(std::move(secondPiece)); return false; } } return true; }
void IPv6RAImpl::sendRouteAdvertisement() { VLOG(5) << "sending route advertisement:\n" << PktUtil::hexDump(Cursor(&buf_)); // Allocate a new packet, and copy our data into it. // // Note that we unfortunately do need to perform a buffer copy here. // The TxPacket is required to use DMA memory for its buffer, so we can't do // a simple clone. // // TODO: In the future it would be nice to support allocating buf_ in a DMA // buffer so that we really can just clone a reference to it here, rather // than doing a copy. uint32_t pktLen = buf_.length(); auto pkt = sw_->allocatePacket(pktLen); RWPrivateCursor cursor(pkt->buf()); cursor.push(buf_.data(), buf_.length()); sw_->sendPacketSwitched(std::move(pkt)); }
void McAsciiParserBase::handleError(folly::IOBuf& buffer) { state_ = State::ERROR; // We've encoutered error we need to do proper logging. auto start = reinterpret_cast<const char*>(buffer.data()); auto length = std::min(p_ - start + kProtocolTailContextLength, buffer.length()); currentErrorDescription_ = folly::sformat("Error parsing message '{}' at character {}!", folly::cEscape<std::string>( folly::StringPiece(start, start + length)), p_ - start); }
McAsciiParserBase::State McClientAsciiParser::consume(folly::IOBuf& buffer) { assert(state_ == State::PARTIAL && !hasReadBuffer()); p_ = reinterpret_cast<const char*>(buffer.data()); pe_ = p_ + buffer.length(); (this->*consumer_)(buffer); if (savedCs_ == errorCs_) { handleError(buffer); } buffer.trimStart(p_ - reinterpret_cast<const char*>(buffer.data())); return state_; }
bool hasSameMemoryRegion(const folly::IOBuf& buf, folly::StringPiece range) { return !buf.isChained() && (buf.length() == 0 || (range.begin() == reinterpret_cast<const char*>(buf.data()) && range.size() == buf.length())); }
folly::StringPiece getRange(const folly::IOBuf& buf) { assert(!buf.isChained()); return {reinterpret_cast<const char*>(buf.data()), buf.length()}; }
bool hasSameMemoryRegion(const folly::IOBuf& a, const folly::IOBuf& b) { return !a.isChained() && !b.isChained() && ((a.length() == 0 && b.length() == 0) || (a.data() == b.data() && a.length() == b.length())); }