113 lines
2.3 KiB
C++
113 lines
2.3 KiB
C++
// PHZ
|
|
// 2018-5-15
|
|
|
|
#ifndef XOP_BUFFER_READER_H
|
|
#define XOP_BUFFER_READER_H
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <algorithm>
|
|
#include <memory>
|
|
#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<char> 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
|
|
|
|
|