+typedef enum _eReadState {
+ eReadFail,
+ eReadSuccess,
+ eMustReadMore,
+ eBufferNotEmpty
+} eReadState;
+
+typedef struct _file_buffer {
+ StrBuf *Buf;
+ const char *ReadWritePointer;
+ int fd;
+ int LineCompleted;
+ int nBlobBytesWanted;
+} IOBuffer;
+
+
+typedef struct __fd_iobuffer {
+ IOBuffer *IOB;
+ int OtherFD;
+ int SplicePipe[2];
+ long TotalSendSize;
+ long TotalSentAlready;
+ long ChunkSize;
+ long ChunkSendRemain;
+ StrBuf *ChunkBuffer; /* just used if we don't have sendfile */
+} FDIOBuffer;
+
+
+void FDIOBufferInit(FDIOBuffer *FDB, IOBuffer *IO, int FD, long TotalSendSize);
+void FDIOBufferDelete(FDIOBuffer *FDB);
+int FileSendChunked(FDIOBuffer *FDB, const char **Err);
+int FileRecvChunked(FDIOBuffer *FDB, const char **Err);
+eReadState WriteIOBAlreadyRead(FDIOBuffer *FDB, const char **Error);
+
+long StrBuf_read_one_chunk_callback (int fd, short event, IOBuffer *FB);
+int StrBuf_write_one_chunk_callback(int fd, short event, IOBuffer *FB);
+
+eReadState StrBufChunkSipLine(StrBuf *LineBuf, IOBuffer *FB);
+eReadState StrBufCheckBuffer(IOBuffer *FB);
+long IOBufferStrLength(IOBuffer *FB);
+
+int StrBufSipLine(StrBuf *LineBuf, const StrBuf *Buf, const char **Ptr);
+int StrBufReplaceToken(StrBuf *Buf, long where, long HowLong, const char *Repl, long ReplLen);