PpmdStream.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using System;
  2. using System.IO;
  3. using SharpCompress.Compressors.LZMA.RangeCoder;
  4. using SharpCompress.Compressors.PPMd.H;
  5. using SharpCompress.Compressors.PPMd.I1;
  6. namespace SharpCompress.Compressors.PPMd
  7. {
  8. public class PpmdStream : Stream
  9. {
  10. private readonly PpmdProperties _properties;
  11. private readonly Stream _stream;
  12. private readonly bool _compress;
  13. private readonly Model _model;
  14. private readonly ModelPpm _modelH;
  15. private readonly Decoder _decoder;
  16. private long _position;
  17. private bool _isDisposed;
  18. public PpmdStream(PpmdProperties properties, Stream stream, bool compress)
  19. {
  20. _properties = properties;
  21. _stream = stream;
  22. _compress = compress;
  23. if (properties.Version == PpmdVersion.I1)
  24. {
  25. _model = new Model();
  26. if (compress)
  27. {
  28. _model.EncodeStart(properties);
  29. }
  30. else
  31. {
  32. _model.DecodeStart(stream, properties);
  33. }
  34. }
  35. if (properties.Version == PpmdVersion.H)
  36. {
  37. _modelH = new ModelPpm();
  38. if (compress)
  39. {
  40. throw new NotImplementedException();
  41. }
  42. _modelH.DecodeInit(stream, properties.ModelOrder, properties.AllocatorSize);
  43. }
  44. if (properties.Version == PpmdVersion.H7Z)
  45. {
  46. _modelH = new ModelPpm();
  47. if (compress)
  48. {
  49. throw new NotImplementedException();
  50. }
  51. _modelH.DecodeInit(null, properties.ModelOrder, properties.AllocatorSize);
  52. _decoder = new Decoder();
  53. _decoder.Init(stream);
  54. }
  55. }
  56. public override bool CanRead => !_compress;
  57. public override bool CanSeek => false;
  58. public override bool CanWrite => _compress;
  59. public override void Flush()
  60. {
  61. }
  62. protected override void Dispose(bool isDisposing)
  63. {
  64. if (_isDisposed)
  65. {
  66. return;
  67. }
  68. _isDisposed = true;
  69. if (isDisposing)
  70. {
  71. if (_compress)
  72. {
  73. _model.EncodeBlock(_stream, new MemoryStream(), true);
  74. }
  75. }
  76. base.Dispose(isDisposing);
  77. }
  78. public override long Length => throw new NotSupportedException();
  79. public override long Position { get => _position; set => throw new NotSupportedException(); }
  80. public override int Read(byte[] buffer, int offset, int count)
  81. {
  82. if (_compress)
  83. {
  84. return 0;
  85. }
  86. int size = 0;
  87. if (_properties.Version == PpmdVersion.I1)
  88. {
  89. size = _model.DecodeBlock(_stream, buffer, offset, count);
  90. }
  91. if (_properties.Version == PpmdVersion.H)
  92. {
  93. int c;
  94. while (size < count && (c = _modelH.DecodeChar()) >= 0)
  95. {
  96. buffer[offset++] = (byte)c;
  97. size++;
  98. }
  99. }
  100. if (_properties.Version == PpmdVersion.H7Z)
  101. {
  102. int c;
  103. while (size < count && (c = _modelH.DecodeChar(_decoder)) >= 0)
  104. {
  105. buffer[offset++] = (byte)c;
  106. size++;
  107. }
  108. }
  109. _position += size;
  110. return size;
  111. }
  112. public override long Seek(long offset, SeekOrigin origin)
  113. {
  114. throw new NotSupportedException();
  115. }
  116. public override void SetLength(long value)
  117. {
  118. throw new NotSupportedException();
  119. }
  120. public override void Write(byte[] buffer, int offset, int count)
  121. {
  122. if (_compress)
  123. {
  124. _model.EncodeBlock(_stream, new MemoryStream(buffer, offset, count), false);
  125. }
  126. }
  127. }
  128. }