CFolder.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. using System;
  2. using System.Collections.Generic;
  3. using SharpCompress.Compressors.LZMA;
  4. namespace SharpCompress.Common.SevenZip
  5. {
  6. internal class CFolder
  7. {
  8. internal List<CCoderInfo> _coders = new List<CCoderInfo>();
  9. internal List<CBindPair> _bindPairs = new List<CBindPair>();
  10. internal List<int> _packStreams = new List<int>();
  11. internal int _firstPackStreamId;
  12. internal List<long> _unpackSizes = new List<long>();
  13. internal uint? _unpackCrc;
  14. internal bool UnpackCrcDefined => _unpackCrc != null;
  15. public long GetUnpackSize()
  16. {
  17. if (_unpackSizes.Count == 0)
  18. {
  19. return 0;
  20. }
  21. for (int i = _unpackSizes.Count - 1; i >= 0; i--)
  22. {
  23. if (FindBindPairForOutStream(i) < 0)
  24. {
  25. return _unpackSizes[i];
  26. }
  27. }
  28. throw new Exception();
  29. }
  30. public int GetNumOutStreams()
  31. {
  32. int count = 0;
  33. for (int i = 0; i < _coders.Count; i++)
  34. {
  35. count += _coders[i]._numOutStreams;
  36. }
  37. return count;
  38. }
  39. public int FindBindPairForInStream(int inStreamIndex)
  40. {
  41. for (int i = 0; i < _bindPairs.Count; i++)
  42. {
  43. if (_bindPairs[i]._inIndex == inStreamIndex)
  44. {
  45. return i;
  46. }
  47. }
  48. return -1;
  49. }
  50. public int FindBindPairForOutStream(int outStreamIndex)
  51. {
  52. for (int i = 0; i < _bindPairs.Count; i++)
  53. {
  54. if (_bindPairs[i]._outIndex == outStreamIndex)
  55. {
  56. return i;
  57. }
  58. }
  59. return -1;
  60. }
  61. public int FindPackStreamArrayIndex(int inStreamIndex)
  62. {
  63. for (int i = 0; i < _packStreams.Count; i++)
  64. {
  65. if (_packStreams[i] == inStreamIndex)
  66. {
  67. return i;
  68. }
  69. }
  70. return -1;
  71. }
  72. public bool IsEncrypted()
  73. {
  74. for (int i = _coders.Count - 1; i >= 0; i--)
  75. {
  76. if (_coders[i]._methodId == CMethodId.K_AES)
  77. {
  78. return true;
  79. }
  80. }
  81. return false;
  82. }
  83. public bool CheckStructure()
  84. {
  85. const int kNumCodersMax = 32; // don't change it
  86. const int kMaskSize = 32; // it must be >= kNumCodersMax
  87. const int kNumBindsMax = 32;
  88. if (_coders.Count > kNumCodersMax || _bindPairs.Count > kNumBindsMax)
  89. {
  90. return false;
  91. }
  92. {
  93. var v = new BitVector(_bindPairs.Count + _packStreams.Count);
  94. for (int i = 0; i < _bindPairs.Count; i++)
  95. {
  96. if (v.GetAndSet(_bindPairs[i]._inIndex))
  97. {
  98. return false;
  99. }
  100. }
  101. for (int i = 0; i < _packStreams.Count; i++)
  102. {
  103. if (v.GetAndSet(_packStreams[i]))
  104. {
  105. return false;
  106. }
  107. }
  108. }
  109. {
  110. var v = new BitVector(_unpackSizes.Count);
  111. for (int i = 0; i < _bindPairs.Count; i++)
  112. {
  113. if (v.GetAndSet(_bindPairs[i]._outIndex))
  114. {
  115. return false;
  116. }
  117. }
  118. }
  119. uint[] mask = new uint[kMaskSize];
  120. {
  121. List<int> inStreamToCoder = new List<int>();
  122. List<int> outStreamToCoder = new List<int>();
  123. for (int i = 0; i < _coders.Count; i++)
  124. {
  125. CCoderInfo coder = _coders[i];
  126. for (int j = 0; j < coder._numInStreams; j++)
  127. {
  128. inStreamToCoder.Add(i);
  129. }
  130. for (int j = 0; j < coder._numOutStreams; j++)
  131. {
  132. outStreamToCoder.Add(i);
  133. }
  134. }
  135. for (int i = 0; i < _bindPairs.Count; i++)
  136. {
  137. CBindPair bp = _bindPairs[i];
  138. mask[inStreamToCoder[bp._inIndex]] |= (1u << outStreamToCoder[bp._outIndex]);
  139. }
  140. }
  141. for (int i = 0; i < kMaskSize; i++)
  142. {
  143. for (int j = 0; j < kMaskSize; j++)
  144. {
  145. if (((1u << j) & mask[i]) != 0)
  146. {
  147. mask[i] |= mask[j];
  148. }
  149. }
  150. }
  151. for (int i = 0; i < kMaskSize; i++)
  152. {
  153. if (((1u << i) & mask[i]) != 0)
  154. {
  155. return false;
  156. }
  157. }
  158. return true;
  159. }
  160. }
  161. }