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; } }
int64_t LineBasedFrameDecoder::findEndOfLine(IOBufQueue& buf) { Cursor c(buf.front()); for (uint32_t i = 0; i < maxLength_ && i < buf.chainLength(); i++) { auto b = c.read<char>(); if (b == '\n' && terminatorType_ != TerminatorType::CARRIAGENEWLINE) { return i; } else if (terminatorType_ != TerminatorType::NEWLINE && b == '\r' && !c.isAtEnd() && c.read<char>() == '\n') { return i; } } return -1; }
uint64_t LengthFieldBasedFrameDecoder::getUnadjustedFrameLength( IOBufQueue& buf, int offset, int length, bool networkByteOrder) { folly::io::Cursor c(buf.front()); uint64_t frameLength; c.skip(offset); switch(length) { case 1:{ if (networkByteOrder) { frameLength = c.readBE<uint8_t>(); } else { frameLength = c.readLE<uint8_t>(); } break; } case 2:{ if (networkByteOrder) { frameLength = c.readBE<uint16_t>(); } else { frameLength = c.readLE<uint16_t>(); } break; } case 4:{ if (networkByteOrder) { frameLength = c.readBE<uint32_t>(); } else { frameLength = c.readLE<uint32_t>(); } break; } case 8:{ if (networkByteOrder) { frameLength = c.readBE<uint64_t>(); } else { frameLength = c.readLE<uint64_t>(); } break; } } return frameLength; }