From efbfe4c006cfb6e0bf3ee4ed57d0657c0cd85c19 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Mon, 6 Sep 2010 14:29:36 +0000 Subject: 2010-09-06 Tatsuhiro Tsujikawa Data from remote server in HTTP/FTP download are now written to the disk(or memory) through StreamFilter. Decoding chunked and gziped streams are done cascading StreamFilter. Removed inefficient 1byte read code. * src/ChunkedDecodingStreamFilter.cc * src/ChunkedDecodingStreamFilter.h * src/DownloadCommand.cc * src/DownloadCommand.h * src/GZipDecodingStreamFilter.cc * src/GZipDecodingStreamFilter.h * src/HttpConnection.cc * src/HttpDownloadCommand.cc * src/HttpResponse.cc * src/HttpResponse.h * src/HttpResponseCommand.cc * src/HttpResponseCommand.h * src/HttpSkipResponseCommand.cc * src/HttpSkipResponseCommand.h * src/Makefile.am * src/NullSinkStreamFilter.cc * src/NullSinkStreamFilter.h * src/RequestGroup.cc * src/SinkStreamFilter.cc * src/SinkStreamFilter.h * src/StreamFilter.cc * src/StreamFilter.h * test/ChunkedDecodingStreamFilterTest.cc * test/GZipDecodingStreamFilterTest.cc * test/HttpResponseTest.cc * test/Makefile.am * test/MockSegment.h --- src/ChunkedDecodingStreamFilter.h | 194 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 src/ChunkedDecodingStreamFilter.h (limited to 'src/ChunkedDecodingStreamFilter.h') diff --git a/src/ChunkedDecodingStreamFilter.h b/src/ChunkedDecodingStreamFilter.h new file mode 100644 index 00000000..6909e33e --- /dev/null +++ b/src/ChunkedDecodingStreamFilter.h @@ -0,0 +1,194 @@ +/* */ +#ifndef D_CHUNKED_DECODING_STREAM_FILTER_H +#define D_CHUNKED_DECODING_STREAM_FILTER_H + +#include "StreamFilter.h" + +namespace aria2 { + +class ChunkedDecodingStreamFilter : public StreamFilter { +private: + class StateHandler { + public: + virtual ~StateHandler() {} + + virtual bool execute + (ChunkedDecodingStreamFilter* filter, + ssize_t& outlen, + size_t& inbufOffset, + const unsigned char* inbuf, + size_t inlen, + const SharedHandle& out, + const SharedHandle& segment) const = 0; + }; + + StateHandler* state_; + + std::string buf_; + + uint64_t chunkSize_; + + size_t bytesProcessed_; + + static size_t MAX_BUF_SIZE; + + bool readChunkSize + (size_t& inbufOffset, const unsigned char* inbuf, size_t inlen); + + bool readTrailer + (size_t& inbufOffset, const unsigned char* inbuf, size_t inlen); + + bool readData + (ssize_t& outlen, + size_t& inbufOffset, + const unsigned char* inbuf, + size_t inlen, + const SharedHandle& out, + const SharedHandle& segment); + + bool readDataEnd + (size_t& inbufOffset, const unsigned char* inbuf, size_t inlen); + + class ReadChunkSizeStateHandler:public StateHandler { + public: + virtual bool execute + (ChunkedDecodingStreamFilter* filter, + ssize_t& outlen, + size_t& inbufOffset, + const unsigned char* inbuf, + size_t inlen, + const SharedHandle& out, + const SharedHandle& segment) const + { + return filter->readChunkSize(inbufOffset, inbuf, inlen); + } + }; + + class ReadTrailerStateHandler:public StateHandler { + public: + virtual bool execute + (ChunkedDecodingStreamFilter* filter, + ssize_t& outlen, + size_t& inbufOffset, + const unsigned char* inbuf, + size_t inlen, + const SharedHandle& out, + const SharedHandle& segment) const + { + return filter->readTrailer(inbufOffset, inbuf, inlen); + } + }; + + class ReadDataStateHandler:public StateHandler { + public: + virtual bool execute + (ChunkedDecodingStreamFilter* filter, + ssize_t& outlen, + size_t& inbufOffset, + const unsigned char* inbuf, + size_t inlen, + const SharedHandle& out, + const SharedHandle& segment) const + { + return filter->readData(outlen, inbufOffset, inbuf, inlen, out, segment); + } + }; + + class ReadDataEndStateHandler:public StateHandler { + public: + virtual bool execute + (ChunkedDecodingStreamFilter* filter, + ssize_t& outlen, + size_t& inbufOffset, + const unsigned char* inbuf, + size_t inlen, + const SharedHandle& out, + const SharedHandle& segment) const + { + return filter->readDataEnd(inbufOffset, inbuf, inlen); + } + }; + + class StreamEndStatehandler:public StateHandler { + public: + virtual bool execute + (ChunkedDecodingStreamFilter* filter, + ssize_t& outlen, + size_t& inbufOffset, + const unsigned char* inbuf, + size_t inlen, + const SharedHandle& out, + const SharedHandle& segment) const + { + return false; + } + }; + + static ReadChunkSizeStateHandler* readChunkSizeStateHandler_; + static ReadTrailerStateHandler* readTrailerStateHandler_; + static ReadDataStateHandler* readDataStateHandler_; + static ReadDataEndStateHandler* readDataEndStateHandler_; + static StreamEndStatehandler* streamEndStateHandler_; +public: + ChunkedDecodingStreamFilter + (const SharedHandle& delegate = SharedHandle()); + + virtual ~ChunkedDecodingStreamFilter(); + + virtual void init(); + + virtual ssize_t transform + (const SharedHandle& out, + const SharedHandle& segment, + const unsigned char* inbuf, size_t inlen); + + virtual bool finished(); + + virtual void release(); + + virtual const std::string& getName() const; + + virtual size_t getBytesProcessed() const + { + return bytesProcessed_; + } + + static const std::string NAME; +}; + +} // namespace aria2 + +#endif // D_CHUNKED_DECODING_STREAM_FILTER_H -- cgit