bool LineBasedFrameDecoder::decode(Context* ctx, IOBufQueue& buf, std::unique_ptr<IOBuf>& result, size_t&) { int64_t eol = findEndOfLine(buf); if (!discarding_) { if (eol >= 0) { Cursor c(buf.front()); c += eol; auto delimLength = c.read<char>() == '\r' ? 2 : 1; if (eol > maxLength_) { buf.split(eol + delimLength); fail(ctx, folly::to<std::string>(eol)); return false; } std::unique_ptr<folly::IOBuf> frame; if (stripDelimiter_) { frame = buf.split(eol); buf.trimStart(delimLength); } else { frame = buf.split(eol + delimLength); } result = std::move(frame); return true; } else { auto len = buf.chainLength(); if (len > maxLength_) { discardedBytes_ = len; buf.trimStart(len); discarding_ = true; fail(ctx, "over " + folly::to<std::string>(len)); } return false; } } else { if (eol >= 0) { Cursor c(buf.front()); c += eol; auto delimLength = c.read<char>() == '\r' ? 2 : 1; buf.trimStart(eol + delimLength); discardedBytes_ = 0; discarding_ = false; } else { discardedBytes_ = buf.chainLength(); buf.move(); } return false; } }
std::unique_ptr<IOBuf> LengthFieldBasedFrameDecoder::decode( Context* ctx, IOBufQueue& buf, size_t&) { // discarding too long frame if (buf.chainLength() <= lengthFieldEndOffset_) { return nullptr; } uint64_t frameLength = getUnadjustedFrameLength( buf, lengthFieldOffset_, lengthFieldLength_, networkByteOrder_); frameLength += lengthAdjustment_ + lengthFieldEndOffset_; if (frameLength < lengthFieldEndOffset_) { throw std::runtime_error("Frame too small"); } if (frameLength > maxFrameLength_) { throw std::runtime_error("Frame larger than " + folly::to<std::string>(maxFrameLength_)); } if (buf.chainLength() < frameLength) { return nullptr; } if (initialBytesToStrip_ > frameLength) { throw std::runtime_error("InitialBytesToSkip larger than frame"); } buf.trimStart(initialBytesToStrip_); int actualFrameLength = frameLength - initialBytesToStrip_; return buf.split(actualFrameLength); }