OutBuffer.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // OutByte.cpp
  2. #include "StdAfx.h"
  3. #include "OutBuffer.h"
  4. extern "C"
  5. {
  6. #include "../../../C/Alloc.h"
  7. }
  8. bool COutBuffer::Create(UInt32 bufferSize)
  9. {
  10. const UInt32 kMinBlockSize = 1;
  11. if (bufferSize < kMinBlockSize)
  12. bufferSize = kMinBlockSize;
  13. if (_buffer != 0 && _bufferSize == bufferSize)
  14. return true;
  15. Free();
  16. _bufferSize = bufferSize;
  17. _buffer = (Byte *)::MidAlloc(bufferSize);
  18. return (_buffer != 0);
  19. }
  20. void COutBuffer::Free()
  21. {
  22. ::MidFree(_buffer);
  23. _buffer = 0;
  24. }
  25. void COutBuffer::SetStream(ISequentialOutStream *stream)
  26. {
  27. _stream = stream;
  28. }
  29. void COutBuffer::Init()
  30. {
  31. _streamPos = 0;
  32. _limitPos = _bufferSize;
  33. _pos = 0;
  34. _processedSize = 0;
  35. _overDict = false;
  36. #ifdef _NO_EXCEPTIONS
  37. ErrorCode = S_OK;
  38. #endif
  39. }
  40. UInt64 COutBuffer::GetProcessedSize() const
  41. {
  42. UInt64 res = _processedSize + _pos - _streamPos;
  43. if (_streamPos > _pos)
  44. res += _bufferSize;
  45. return res;
  46. }
  47. HRESULT COutBuffer::FlushPart()
  48. {
  49. // _streamPos < _bufferSize
  50. UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
  51. HRESULT result = S_OK;
  52. #ifdef _NO_EXCEPTIONS
  53. result = ErrorCode;
  54. #endif
  55. if (_buffer2 != 0)
  56. {
  57. memmove(_buffer2, _buffer + _streamPos, size);
  58. _buffer2 += size;
  59. }
  60. if (_stream != 0
  61. #ifdef _NO_EXCEPTIONS
  62. && (ErrorCode == S_OK)
  63. #endif
  64. )
  65. {
  66. UInt32 processedSize = 0;
  67. result = _stream->Write(_buffer + _streamPos, size, &processedSize);
  68. size = processedSize;
  69. }
  70. _streamPos += size;
  71. if (_streamPos == _bufferSize)
  72. _streamPos = 0;
  73. if (_pos == _bufferSize)
  74. {
  75. _overDict = true;
  76. _pos = 0;
  77. }
  78. _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
  79. _processedSize += size;
  80. return result;
  81. }
  82. HRESULT COutBuffer::Flush()
  83. {
  84. #ifdef _NO_EXCEPTIONS
  85. if (ErrorCode != S_OK)
  86. return ErrorCode;
  87. #endif
  88. while(_streamPos != _pos)
  89. {
  90. HRESULT result = FlushPart();
  91. if (result != S_OK)
  92. return result;
  93. }
  94. return S_OK;
  95. }
  96. void COutBuffer::FlushWithCheck()
  97. {
  98. HRESULT result = Flush();
  99. #ifdef _NO_EXCEPTIONS
  100. ErrorCode = result;
  101. #else
  102. if (result != S_OK)
  103. throw COutBufferException(result);
  104. #endif
  105. }