// PHZ // 2018-5-15 #ifndef XOP_BUFFER_READER_H #define XOP_BUFFER_READER_H #include #include #include #include #include #include "Socket.h" namespace xop { uint32_t ReadUint32BE(char* data); uint32_t ReadUint32LE(char* data); uint32_t ReadUint24BE(char* data); uint32_t ReadUint24LE(char* data); uint16_t ReadUint16BE(char* data); uint16_t ReadUint16LE(char* data); class BufferReader { public: BufferReader(uint32_t initial_size = 2048); virtual ~BufferReader(); uint32_t ReadableBytes() const { return (uint32_t)(writer_index_ - reader_index_); } uint32_t WritableBytes() const { return (uint32_t)(buffer_.size() - writer_index_); } char* Peek() { return Begin() + reader_index_; } const char* Peek() const { return Begin() + reader_index_; } const char* FindFirstCrlf() const { const char* crlf = std::search(Peek(), BeginWrite(), kCRLF, kCRLF+2); return crlf == BeginWrite() ? nullptr : crlf; } const char* FindLastCrlf() const { const char* crlf = std::find_end(Peek(), BeginWrite(), kCRLF, kCRLF+2); return crlf == BeginWrite() ? nullptr : crlf; } const char* FindLastCrlfCrlf() const { char crlfCrlf[] = "\r\n\r\n"; const char* crlf = std::find_end(Peek(), BeginWrite(), crlfCrlf, crlfCrlf + 4); return crlf == BeginWrite() ? nullptr : crlf; } void RetrieveAll() { writer_index_ = 0; reader_index_ = 0; } void Retrieve(size_t len) { if (len <= ReadableBytes()) { reader_index_ += len; if(reader_index_ == writer_index_) { reader_index_ = 0; writer_index_ = 0; } } else { RetrieveAll(); } } void RetrieveUntil(const char* end) { Retrieve(end - Peek()); } int Read(SOCKET sockfd); uint32_t ReadAll(std::string& data); uint32_t ReadUntilCrlf(std::string& data); uint32_t Size() const { return (uint32_t)buffer_.size(); } private: char* Begin() { return &*buffer_.begin(); } const char* Begin() const { return &*buffer_.begin(); } char* beginWrite() { return Begin() + writer_index_; } const char* BeginWrite() const { return Begin() + writer_index_; } std::vector buffer_; size_t reader_index_ = 0; size_t writer_index_ = 0; static const char kCRLF[]; static const uint32_t MAX_BYTES_PER_READ = 4096; static const uint32_t MAX_BUFFER_SIZE = 1024 * 100000; }; } #endif