/usr/include/binpac_buffer.h is in binpac 0.48-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | #ifndef binpac_buffer_h
#define binpac_buffer_h
#include <sys/types.h>
#include "binpac.h"
namespace binpac {
class FlowBuffer {
public:
enum LineBreakStyle {
CR_OR_LF, // CR or LF or CRLF
STRICT_CRLF, // CR followed by LF
CR_LF_NUL, // CR or LF or CR-LF or CR-NUL
};
FlowBuffer(LineBreakStyle linebreak_style = CR_OR_LF);
virtual ~FlowBuffer();
void NewData(const_byteptr begin, const_byteptr end);
void NewGap(int length);
// Interface for delayed parsing. Sometimes BinPAC doesn't get the
// buffering right and then one can use these to feed parts
// individually and assemble them internally. After calling
// FinishBuffer(), one can send the uppper-layer flow an FlowEOF() to
// trigger parsing.
void BufferData(const_byteptr data, const_byteptr end);
void FinishBuffer();
// Discard unprocessed data
void DiscardData();
// Whether there is enough data for the frame
bool ready() const{ return message_complete_ || mode_ == UNKNOWN_MODE; }
inline const_byteptr begin() const
{
BINPAC_ASSERT(ready());
return ( buffer_n_ == 0 ) ?
orig_data_begin_ : buffer_;
}
inline const_byteptr end() const
{
BINPAC_ASSERT(ready());
if ( buffer_n_ == 0 )
{
BINPAC_ASSERT(frame_length_ >= 0);
const_byteptr end = orig_data_begin_ + frame_length_;
BINPAC_ASSERT(end <= orig_data_end_);
return end;
}
else
return buffer_ + buffer_n_;
}
inline int data_length() const
{
if ( buffer_n_ > 0 )
return buffer_n_;
if ( frame_length_ < 0 ||
orig_data_begin_ + frame_length_ > orig_data_end_ )
return orig_data_end_ - orig_data_begin_;
else
return frame_length_;
}
inline bool data_available() const
{
return buffer_n_ > 0 || orig_data_end_ > orig_data_begin_;
}
void NewLine();
// A negative frame_length represents a frame till EOF
void NewFrame(int frame_length, bool chunked_);
void GrowFrame(int new_frame_length);
int data_seq() const
{
int data_seq_at_orig_data_begin =
data_seq_at_orig_data_end_ -
(orig_data_end_ - orig_data_begin_);
if ( buffer_n_ > 0 )
return data_seq_at_orig_data_begin;
else
return data_seq_at_orig_data_begin + data_length();
}
bool eof() const { return eof_; }
void set_eof();
bool have_pending_request() const { return have_pending_request_; }
protected:
// Reset the buffer for a new message
void NewMessage();
void ClearPreviousData();
// Expand the buffer to at least <length> bytes. If there
// are contents in the existing buffer, copy them to the new
// buffer.
void ExpandBuffer(int length);
// Reset line state when transit from frame mode to line mode.
void ResetLineState();
void AppendToBuffer(const_byteptr data, int len);
// MarkOrCopy{Line,Frame} sets message_complete_ and
// marks begin/end pointers if a line/frame is complete,
// otherwise it clears message_complete_ and copies all
// the original data to the buffer.
//
void MarkOrCopy();
void MarkOrCopyLine();
void MarkOrCopyFrame();
void MarkOrCopyLine_CR_OR_LF();
void MarkOrCopyLine_STRICT_CRLF();
int buffer_n_; // number of bytes in the buffer
int buffer_length_; // size of the buffer
u_char *buffer_;
bool message_complete_;
int frame_length_;
bool chunked_;
const_byteptr orig_data_begin_, orig_data_end_;
LineBreakStyle linebreak_style_;
enum {
UNKNOWN_MODE,
LINE_MODE,
FRAME_MODE,
} mode_;
enum {
CR_OR_LF_0,
CR_OR_LF_1,
STRICT_CRLF_0,
STRICT_CRLF_1,
FRAME_0,
} state_;
int data_seq_at_orig_data_end_;
bool eof_;
bool have_pending_request_;
};
typedef FlowBuffer *flow_buffer_t;
} // namespace binpac
#endif // binpac_buffer_h
|