State.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. namespace System.Net.ApiService.Compression.Brotli {
  2. internal sealed class State {
  3. internal int runningState = RunningState.Uninitialized;
  4. internal int nextRunningState;
  5. internal readonly BitReader br = new BitReader();
  6. internal byte[] ringBuffer;
  7. internal readonly int[] blockTypeTrees = new int[3 * System.Net.ApiService.Compression.Brotli.Huffman.HuffmanMaxTableSize];
  8. internal readonly int[] blockLenTrees = new int[3 * System.Net.ApiService.Compression.Brotli.Huffman.HuffmanMaxTableSize];
  9. internal int metaBlockLength;
  10. internal bool inputEnd;
  11. internal bool isUncompressed;
  12. internal bool isMetadata;
  13. internal readonly System.Net.ApiService.Compression.Brotli.HuffmanTreeGroup hGroup0 = new System.Net.ApiService.Compression.Brotli.HuffmanTreeGroup();
  14. internal readonly System.Net.ApiService.Compression.Brotli.HuffmanTreeGroup hGroup1 = new System.Net.ApiService.Compression.Brotli.HuffmanTreeGroup();
  15. internal readonly System.Net.ApiService.Compression.Brotli.HuffmanTreeGroup hGroup2 = new System.Net.ApiService.Compression.Brotli.HuffmanTreeGroup();
  16. internal readonly int[] blockLength = new int[3];
  17. internal readonly int[] numBlockTypes = new int[3];
  18. internal readonly int[] blockTypeRb = new int[6];
  19. internal readonly int[] distRb = new int[] { 16, 15, 11, 4 };
  20. internal int pos = 0;
  21. internal int maxDistance = 0;
  22. internal int distRbIdx = 0;
  23. internal bool trivialLiteralContext = false;
  24. internal int literalTreeIndex = 0;
  25. internal int literalTree;
  26. internal int j;
  27. internal int insertLength;
  28. internal byte[] contextModes;
  29. internal byte[] contextMap;
  30. internal int contextMapSlice;
  31. internal int distContextMapSlice;
  32. internal int contextLookupOffset1;
  33. internal int contextLookupOffset2;
  34. internal int treeCommandOffset;
  35. internal int distanceCode;
  36. internal byte[] distContextMap;
  37. internal int numDirectDistanceCodes;
  38. internal int distancePostfixMask;
  39. internal int distancePostfixBits;
  40. internal int distance;
  41. internal int copyLength;
  42. internal int copyDst;
  43. internal int maxBackwardDistance;
  44. internal int maxRingBufferSize;
  45. internal int ringBufferSize = 0;
  46. internal long expectedTotalSize = 0;
  47. internal byte[] customDictionary = new byte[0];
  48. internal int bytesToIgnore = 0;
  49. internal int outputOffset;
  50. internal int outputLength;
  51. internal int outputUsed;
  52. internal int bytesWritten;
  53. internal int bytesToWrite;
  54. internal byte[] output;
  55. // Current meta-block header information.
  56. // TODO: Update to current spec.
  57. private static int DecodeWindowBits(BitReader br) {
  58. if (BitReader.ReadBits(br, 1) == 0) {
  59. return 16;
  60. }
  61. int n = BitReader.ReadBits(br, 3);
  62. if (n != 0) {
  63. return 17 + n;
  64. }
  65. n = BitReader.ReadBits(br, 3);
  66. if (n != 0) {
  67. return 8 + n;
  68. }
  69. return 17;
  70. }
  71. /// <summary>Associate input with decoder state.</summary>
  72. /// <param name="state">uninitialized state without associated input</param>
  73. /// <param name="input">compressed data source</param>
  74. internal static void SetInput(System.Net.ApiService.Compression.Brotli.State state, System.IO.Stream input) {
  75. if (state.runningState != System.Net.ApiService.Compression.Brotli.RunningState.Uninitialized) {
  76. throw new System.InvalidOperationException("State MUST be uninitialized");
  77. }
  78. System.Net.ApiService.Compression.Brotli.BitReader.Init(state.br, input);
  79. int windowBits = DecodeWindowBits(state.br);
  80. if (windowBits == 9) {
  81. /* Reserved case for future expansion. */
  82. throw new System.Net.ApiService.Compression.Brotli.BrotliRuntimeException("Invalid 'windowBits' code");
  83. }
  84. state.maxRingBufferSize = 1 << windowBits;
  85. state.maxBackwardDistance = state.maxRingBufferSize - 16;
  86. state.runningState = System.Net.ApiService.Compression.Brotli.RunningState.BlockStart;
  87. }
  88. /// <exception cref="System.IO.IOException"/>
  89. internal static void Close(System.Net.ApiService.Compression.Brotli.State state) {
  90. if (state.runningState == System.Net.ApiService.Compression.Brotli.RunningState.Uninitialized) {
  91. throw new System.InvalidOperationException("State MUST be initialized");
  92. }
  93. if (state.runningState == System.Net.ApiService.Compression.Brotli.RunningState.Closed) {
  94. return;
  95. }
  96. state.runningState = System.Net.ApiService.Compression.Brotli.RunningState.Closed;
  97. System.Net.ApiService.Compression.Brotli.BitReader.Close(state.br);
  98. }
  99. }
  100. }