// OutBuffer.h #ifndef ZIP7_INC_OUT_BUFFER_H #define ZIP7_INC_OUT_BUFFER_H #include "../IStream.h" #include "../../Common/MyCom.h" #include "../../Common/MyException.h" #ifndef Z7_NO_EXCEPTIONS struct COutBufferException: public CSystemException { COutBufferException(HRESULT errorCode): CSystemException(errorCode) {} }; #endif class COutBuffer { protected: Byte *_buf; UInt32 _pos; UInt32 _limitPos; UInt32 _streamPos; UInt32 _bufSize; ISequentialOutStream *_stream; UInt64 _processedSize; Byte *_buf2; bool _overDict; HRESULT FlushPart() throw(); public: #ifdef Z7_NO_EXCEPTIONS HRESULT ErrorCode; #endif COutBuffer(): _buf(NULL), _pos(0), _stream(NULL), _buf2(NULL) {} ~COutBuffer() { Free(); } bool Create(UInt32 bufSize) throw(); void Free() throw(); void SetMemStream(Byte *buf) { _buf2 = buf; } void SetStream(ISequentialOutStream *stream) { _stream = stream; } void Init() throw(); HRESULT Flush() throw(); void FlushWithCheck(); Z7_FORCE_INLINE void WriteByte(Byte b) { UInt32 pos = _pos; _buf[pos] = b; pos++; _pos = pos; if (pos == _limitPos) FlushWithCheck(); } void WriteBytes(const void *data, size_t size) { while (size) { UInt32 pos = _pos; size_t cur = (size_t)(_limitPos - pos); if (cur >= size) cur = size; size -= cur; Byte *dest = _buf + pos; pos += (UInt32)cur; _pos = pos; #if 0 memcpy(dest, data, cur); data = (const void *)((const Byte *)data + cur); #else const Byte * const lim = (const Byte *)data + cur; do { *dest++ = *(const Byte *)data; data = (const void *)((const Byte *)data + 1); } while (data != lim); #endif if (pos == _limitPos) FlushWithCheck(); } } Byte *GetOutBuffer(size_t &avail) { const UInt32 pos = _pos; avail = (size_t)(_limitPos - pos); return _buf + pos; } void SkipWrittenBytes(size_t num) { const UInt32 pos = _pos; const UInt32 rem = _limitPos - pos; if (rem > num) { _pos = pos + (UInt32)num; return; } // (rem <= num) // the caller must not call it with (rem < num) // so (rem == num) _pos = _limitPos; FlushWithCheck(); } /* void WriteBytesBig(const void *data, size_t size) { while (size) { UInt32 pos = _pos; UInt32 rem = _limitPos - pos; if (rem > size) { _pos = pos + size; memcpy(_buf + pos, data, size); return; } memcpy(_buf + pos, data, rem); _pos = pos + rem; FlushWithCheck(); } } */ UInt64 GetProcessedSize() const throw(); }; #endif