package brotli

/* Copyright 2013 Google Inc. All Rights Reserved.

   Distributed under MIT license.
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/

const (
	decoderResultError           = 0
	decoderResultSuccess         = 1
	decoderResultNeedsMoreInput  = 2
	decoderResultNeedsMoreOutput = 3
)

/**
 * Error code for detailed logging / production debugging.
 *
 * See ::BrotliDecoderGetErrorCode and ::BROTLI_LAST_ERROR_CODE.
 */
const (
	decoderNoError                          = 0
	decoderSuccess                          = 1
	decoderNeedsMoreInput                   = 2
	decoderNeedsMoreOutput                  = 3
	decoderErrorFormatExuberantNibble       = -1
	decoderErrorFormatReserved              = -2
	decoderErrorFormatExuberantMetaNibble   = -3
	decoderErrorFormatSimpleHuffmanAlphabet = -4
	decoderErrorFormatSimpleHuffmanSame     = -5
	decoderErrorFormatClSpace               = -6
	decoderErrorFormatHuffmanSpace          = -7
	decoderErrorFormatContextMapRepeat      = -8
	decoderErrorFormatBlockLength1          = -9
	decoderErrorFormatBlockLength2          = -10
	decoderErrorFormatTransform             = -11
	decoderErrorFormatDictionary            = -12
	decoderErrorFormatWindowBits            = -13
	decoderErrorFormatPadding1              = -14
	decoderErrorFormatPadding2              = -15
	decoderErrorFormatDistance              = -16
	decoderErrorDictionaryNotSet            = -19
	decoderErrorInvalidArguments            = -20
	decoderErrorAllocContextModes           = -21
	decoderErrorAllocTreeGroups             = -22
	decoderErrorAllocContextMap             = -25
	decoderErrorAllocRingBuffer1            = -26
	decoderErrorAllocRingBuffer2            = -27
	decoderErrorAllocBlockTypeTrees         = -30
	decoderErrorUnreachable                 = -31
)

const huffmanTableBits = 8

const huffmanTableMask = 0xFF

/* We need the slack region for the following reasons:
   - doing up to two 16-byte copies for fast backward copying
   - inserting transformed dictionary word (5 prefix + 24 base + 8 suffix) */
const kRingBufferWriteAheadSlack uint32 = 42

var kCodeLengthCodeOrder = [codeLengthCodes]byte{1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15}

/* Static prefix code for the complex code length code lengths. */
var kCodeLengthPrefixLength = [16]byte{2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4}

var kCodeLengthPrefixValue = [16]byte{0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5}

/* Saves error code and converts it to BrotliDecoderResult. */
func saveErrorCode( *Reader,  int) int {
	.error_code = int()
	switch  {
	case decoderSuccess:
		return decoderResultSuccess

	case decoderNeedsMoreInput:
		return decoderResultNeedsMoreInput

	case decoderNeedsMoreOutput:
		return decoderResultNeedsMoreOutput

	default:
		return decoderResultError
	}
}

/* Decodes WBITS by reading 1 - 7 bits, or 0x11 for "Large Window Brotli".
   Precondition: bit-reader accumulator has at least 8 bits. */
func decodeWindowBits( *Reader,  *bitReader) int {
	var  uint32
	var  bool = .large_window
	.large_window = false
	takeBits(, 1, &)
	if  == 0 {
		.window_bits = 16
		return decoderSuccess
	}

	takeBits(, 3, &)
	if  != 0 {
		.window_bits = 17 + 
		return decoderSuccess
	}

	takeBits(, 3, &)
	if  == 1 {
		if  {
			takeBits(, 1, &)
			if  == 1 {
				return decoderErrorFormatWindowBits
			}

			.large_window = true
			return decoderSuccess
		} else {
			return decoderErrorFormatWindowBits
		}
	}

	if  != 0 {
		.window_bits = 8 + 
		return decoderSuccess
	}

	.window_bits = 17
	return decoderSuccess
}

/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
func decodeVarLenUint8( *Reader,  *bitReader,  *uint32) int {
	var  uint32
	switch .substate_decode_uint8 {
	case stateDecodeUint8None:
		if !safeReadBits(, 1, &) {
			return decoderNeedsMoreInput
		}

		if  == 0 {
			* = 0
			return decoderSuccess
		}
		fallthrough

		/* Fall through. */
	case stateDecodeUint8Short:
		if !safeReadBits(, 3, &) {
			.substate_decode_uint8 = stateDecodeUint8Short
			return decoderNeedsMoreInput
		}

		if  == 0 {
			* = 1
			.substate_decode_uint8 = stateDecodeUint8None
			return decoderSuccess
		}

		/* Use output value as a temporary storage. It MUST be persisted. */
		* = 
		fallthrough

		/* Fall through. */
	case stateDecodeUint8Long:
		if !safeReadBits(, *, &) {
			.substate_decode_uint8 = stateDecodeUint8Long
			return decoderNeedsMoreInput
		}

		* = (1 << *) + 
		.substate_decode_uint8 = stateDecodeUint8None
		return decoderSuccess

	default:
		return decoderErrorUnreachable
	}
}

/* Decodes a metablock length and flags by reading 2 - 31 bits. */
func decodeMetaBlockLength( *Reader,  *bitReader) int {
	var  uint32
	var  int
	for {
		switch .substate_metablock_header {
		case stateMetablockHeaderNone:
			if !safeReadBits(, 1, &) {
				return decoderNeedsMoreInput
			}

			if  != 0 {
				.is_last_metablock = 1
			} else {
				.is_last_metablock = 0
			}
			.meta_block_remaining_len = 0
			.is_uncompressed = 0
			.is_metadata = 0
			if .is_last_metablock == 0 {
				.substate_metablock_header = stateMetablockHeaderNibbles
				break
			}

			.substate_metablock_header = stateMetablockHeaderEmpty
			fallthrough

			/* Fall through. */
		case stateMetablockHeaderEmpty:
			if !safeReadBits(, 1, &) {
				return decoderNeedsMoreInput
			}

			if  != 0 {
				.substate_metablock_header = stateMetablockHeaderNone
				return decoderSuccess
			}

			.substate_metablock_header = stateMetablockHeaderNibbles
			fallthrough

			/* Fall through. */
		case stateMetablockHeaderNibbles:
			if !safeReadBits(, 2, &) {
				return decoderNeedsMoreInput
			}

			.size_nibbles = uint(byte( + 4))
			.loop_counter = 0
			if  == 3 {
				.is_metadata = 1
				.substate_metablock_header = stateMetablockHeaderReserved
				break
			}

			.substate_metablock_header = stateMetablockHeaderSize
			fallthrough

			/* Fall through. */
		case stateMetablockHeaderSize:
			 = .loop_counter

			for ;  < int(.size_nibbles); ++ {
				if !safeReadBits(, 4, &) {
					.loop_counter = 
					return decoderNeedsMoreInput
				}

				if uint(+1) == .size_nibbles && .size_nibbles > 4 &&  == 0 {
					return decoderErrorFormatExuberantNibble
				}

				.meta_block_remaining_len |= int( << uint(*4))
			}

			.substate_metablock_header = stateMetablockHeaderUncompressed
			fallthrough

			/* Fall through. */
		case stateMetablockHeaderUncompressed:
			if .is_last_metablock == 0 {
				if !safeReadBits(, 1, &) {
					return decoderNeedsMoreInput
				}

				if  != 0 {
					.is_uncompressed = 1
				} else {
					.is_uncompressed = 0
				}
			}

			.meta_block_remaining_len++
			.substate_metablock_header = stateMetablockHeaderNone
			return decoderSuccess

		case stateMetablockHeaderReserved:
			if !safeReadBits(, 1, &) {
				return decoderNeedsMoreInput
			}

			if  != 0 {
				return decoderErrorFormatReserved
			}

			.substate_metablock_header = stateMetablockHeaderBytes
			fallthrough

			/* Fall through. */
		case stateMetablockHeaderBytes:
			if !safeReadBits(, 2, &) {
				return decoderNeedsMoreInput
			}

			if  == 0 {
				.substate_metablock_header = stateMetablockHeaderNone
				return decoderSuccess
			}

			.size_nibbles = uint(byte())
			.substate_metablock_header = stateMetablockHeaderMetadata
			fallthrough

			/* Fall through. */
		case stateMetablockHeaderMetadata:
			 = .loop_counter

			for ;  < int(.size_nibbles); ++ {
				if !safeReadBits(, 8, &) {
					.loop_counter = 
					return decoderNeedsMoreInput
				}

				if uint(+1) == .size_nibbles && .size_nibbles > 1 &&  == 0 {
					return decoderErrorFormatExuberantMetaNibble
				}

				.meta_block_remaining_len |= int( << uint(*8))
			}

			.meta_block_remaining_len++
			.substate_metablock_header = stateMetablockHeaderNone
			return decoderSuccess

		default:
			return decoderErrorUnreachable
		}
	}
}

/* Decodes the Huffman code.
   This method doesn't read data from the bit reader, BUT drops the amount of
   bits that correspond to the decoded symbol.
   bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */
func decodeSymbol( uint32,  []huffmanCode,  *bitReader) uint32 {
	 = [&huffmanTableMask:]
	if [0].bits > huffmanTableBits {
		var  uint32 = uint32([0].bits) - huffmanTableBits
		dropBits(, huffmanTableBits)
		 = [uint32([0].value)+((>>huffmanTableBits)&bitMask()):]
	}

	dropBits(, uint32([0].bits))
	return uint32([0].value)
}

/* Reads and decodes the next Huffman code from bit-stream.
   This method peeks 16 bits of input and drops 0 - 15 of them. */
func readSymbol( []huffmanCode,  *bitReader) uint32 {
	return decodeSymbol(get16BitsUnmasked(), , )
}

/* Same as DecodeSymbol, but it is known that there is less than 15 bits of
   input are currently available. */
func safeDecodeSymbol( []huffmanCode,  *bitReader,  *uint32) bool {
	var  uint32
	var  uint32 = getAvailableBits()
	if  == 0 {
		if [0].bits == 0 {
			* = uint32([0].value)
			return true
		}

		return false /* No valid bits at all. */
	}

	 = uint32(getBitsUnmasked())
	 = [&huffmanTableMask:]
	if [0].bits <= huffmanTableBits {
		if uint32([0].bits) <=  {
			dropBits(, uint32([0].bits))
			* = uint32([0].value)
			return true
		} else {
			return false /* Not enough bits for the first level. */
		}
	}

	if  <= huffmanTableBits {
		return false /* Not enough bits to move to the second level. */
	}

	/* Speculatively drop HUFFMAN_TABLE_BITS. */
	 = ( & bitMask(uint32([0].bits))) >> huffmanTableBits

	 -= huffmanTableBits
	 = [uint32([0].value)+:]
	if  < uint32([0].bits) {
		return false /* Not enough bits for the second level. */
	}

	dropBits(, huffmanTableBits+uint32([0].bits))
	* = uint32([0].value)
	return true
}

func safeReadSymbol( []huffmanCode,  *bitReader,  *uint32) bool {
	var  uint32
	if safeGetBits(, 15, &) {
		* = decodeSymbol(, , )
		return true
	}

	return safeDecodeSymbol(, , )
}

/* Makes a look-up in first level Huffman table. Peeks 8 bits. */
func preloadSymbol( int,  []huffmanCode,  *bitReader,  *uint32,  *uint32) {
	if  != 0 {
		return
	}

	 = [getBits(, huffmanTableBits):]
	* = uint32([0].bits)
	* = uint32([0].value)
}

/* Decodes the next Huffman code using data prepared by PreloadSymbol.
   Reads 0 - 15 bits. Also peeks 8 following bits. */
func readPreloadedSymbol( []huffmanCode,  *bitReader,  *uint32,  *uint32) uint32 {
	var  uint32 = *
	var  []huffmanCode
	if * > huffmanTableBits {
		var  uint32 = get16BitsUnmasked()
		 = [&huffmanTableMask:][*:]
		var  uint32 = bitMask((* - huffmanTableBits))
		dropBits(, huffmanTableBits)
		 = [(>>huffmanTableBits)&:]
		dropBits(, uint32([0].bits))
		 = uint32([0].value)
	} else {
		dropBits(, *)
	}

	preloadSymbol(0, , , , )
	return 
}

func log2Floor( uint32) uint32 {
	var  uint32 = 0
	for  != 0 {
		 >>= 1
		++
	}

	return 
}

/* Reads (s->symbol + 1) symbols.
   Totally 1..4 symbols are read, 1..11 bits each.
   The list of symbols MUST NOT contain duplicates. */
func readSimpleHuffmanSymbols( uint32,  uint32,  *Reader) int {
	var  *bitReader = &.br
	var  uint32 = log2Floor( - 1)
	var  uint32 = .sub_loop_counter
	/* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */

	var  uint32 = .symbol
	for  <=  {
		var  uint32
		if !safeReadBits(, , &) {
			.sub_loop_counter = 
			.substate_huffman = stateHuffmanSimpleRead
			return decoderNeedsMoreInput
		}

		if  >=  {
			return decoderErrorFormatSimpleHuffmanAlphabet
		}

		.symbols_lists_array[] = uint16()
		++
	}

	for  = 0;  < ; ++ {
		var  uint32 =  + 1
		for ;  <= ; ++ {
			if .symbols_lists_array[] == .symbols_lists_array[] {
				return decoderErrorFormatSimpleHuffmanSame
			}
		}
	}

	return decoderSuccess
}

/* Process single decoded symbol code length:
   A) reset the repeat variable
   B) remember code length (if it is not 0)
   C) extend corresponding index-chain
   D) reduce the Huffman space
   E) update the histogram */
func processSingleCodeLength( uint32,  *uint32,  *uint32,  *uint32,  *uint32,  symbolList,  []uint16,  []int) {
	* = 0
	if  != 0 { /* code_len == 1..15 */
		symbolListPut(, [], uint16(*))
		[] = int(*)
		* = 
		* -= 32768 >> 
		[]++
	}

	(*)++
}

/* Process repeated symbol code length.
    A) Check if it is the extension of previous repeat sequence; if the decoded
       value is not BROTLI_REPEAT_PREVIOUS_CODE_LENGTH, then it is a new
       symbol-skip
    B) Update repeat variable
    C) Check if operation is feasible (fits alphabet)
    D) For each symbol do the same operations as in ProcessSingleCodeLength

   PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or
                 code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH */
func processRepeatedCodeLength( uint32,  uint32,  uint32,  *uint32,  *uint32,  *uint32,  *uint32,  *uint32,  symbolList,  []uint16,  []int) {
	var  uint32 /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */ /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
	var  uint32 = 3
	var  uint32 = 0
	if  == repeatPreviousCodeLength {
		 = *
		 = 2
	}

	if * !=  {
		* = 0
		* = 
	}

	 = *
	if * > 0 {
		* -= 2
		* <<= 
	}

	* +=  + 3
	 = * - 
	if *+ >  {
		* = 
		* = 0xFFFFF
		return
	}

	if * != 0 {
		var  uint = uint(* + )
		var  int = [*]
		for {
			symbolListPut(, , uint16(*))
			 = int(*)
			(*)++
			if (*) == uint32() {
				break
			}
		}

		[*] = 
		* -=  << (15 - *)
		[*] = uint16(uint32([*]) + )
	} else {
		* += 
	}
}

/* Reads and decodes symbol codelengths. */
func readSymbolCodeLengths( uint32,  *Reader) int {
	var  *bitReader = &.br
	var  uint32 = .symbol
	var  uint32 = .repeat
	var  uint32 = .space
	var  uint32 = .prev_code_len
	var  uint32 = .repeat_code_len
	var  symbolList = .symbol_lists
	var  []uint16 = .code_length_histo[:]
	var  []int = .next_symbol[:]
	if !warmupBitReader() {
		return decoderNeedsMoreInput
	}
	var  []huffmanCode
	for  <  &&  > 0 {
		 = .table[:]
		var  uint32
		if !checkInputAmount(, shortFillBitWindowRead) {
			.symbol = 
			.repeat = 
			.prev_code_len = 
			.repeat_code_len = 
			.space = 
			return decoderNeedsMoreInput
		}

		fillBitWindow16()
		 = [getBitsUnmasked()&uint64(bitMask(huffmanMaxCodeLengthCodeLength)):]
		dropBits(, uint32([0].bits)) /* Use 1..5 bits. */
		 = uint32([0].value)   /* code_len == 0..17 */
		if  < repeatPreviousCodeLength {
			processSingleCodeLength(, &, &, &, &, , , ) /* code_len == 16..17, extra_bits == 2..3 */
		} else {
			var  uint32
			if  == repeatPreviousCodeLength {
				 = 2
			} else {
				 = 3
			}
			var  uint32 = uint32(getBitsUnmasked()) & bitMask()
			dropBits(, )
			processRepeatedCodeLength(, , , &, &, &, &, &, , , )
		}
	}

	.space = 
	return decoderSuccess
}

func safeReadSymbolCodeLengths( uint32,  *Reader) int {
	var  *bitReader = &.br
	var  bool = false
	var  []huffmanCode
	for .symbol <  && .space > 0 {
		 = .table[:]
		var  uint32
		var  uint32
		var  uint32 = 0
		if  && !pullByte() {
			return decoderNeedsMoreInput
		}
		 = false
		 = getAvailableBits()
		if  != 0 {
			 = uint32(getBitsUnmasked())
		}

		 = [&bitMask(huffmanMaxCodeLengthCodeLength):]
		if uint32([0].bits) >  {
			 = true
			continue
		}

		 = uint32([0].value) /* code_len == 0..17 */
		if  < repeatPreviousCodeLength {
			dropBits(, uint32([0].bits))
			processSingleCodeLength(, &.symbol, &.repeat, &.space, &.prev_code_len, .symbol_lists, .code_length_histo[:], .next_symbol[:]) /* code_len == 16..17, extra_bits == 2..3 */
		} else {
			var  uint32 =  - 14
			var  uint32 = ( >> [0].bits) & bitMask()
			if  < uint32([0].bits)+ {
				 = true
				continue
			}

			dropBits(, uint32([0].bits)+)
			processRepeatedCodeLength(, , , &.symbol, &.repeat, &.space, &.prev_code_len, &.repeat_code_len, .symbol_lists, .code_length_histo[:], .next_symbol[:])
		}
	}

	return decoderSuccess
}

/* Reads and decodes 15..18 codes using static prefix code.
   Each code is 2..4 bits long. In total 30..72 bits are used. */
func readCodeLengthCodeLengths( *Reader) int {
	var  *bitReader = &.br
	var  uint32 = .repeat
	var  uint32 = .space
	var  uint32 = .sub_loop_counter
	for ;  < codeLengthCodes; ++ {
		var  byte = kCodeLengthCodeOrder[]
		var  uint32
		var  uint32
		if !safeGetBits(, 4, &) {
			var  uint32 = getAvailableBits()
			if  != 0 {
				 = uint32(getBitsUnmasked() & 0xF)
			} else {
				 = 0
			}

			if uint32(kCodeLengthPrefixLength[]) >  {
				.sub_loop_counter = 
				.repeat = 
				.space = 
				.substate_huffman = stateHuffmanComplex
				return decoderNeedsMoreInput
			}
		}

		 = uint32(kCodeLengthPrefixValue[])
		dropBits(, uint32(kCodeLengthPrefixLength[]))
		.code_length_code_lengths[] = byte()
		if  != 0 {
			 =  - (32 >> )
			++
			.code_length_histo[]++
			if -1 >= 32 {
				/* space is 0 or wrapped around. */
				break
			}
		}
	}

	if  != 1 &&  != 0 {
		return decoderErrorFormatClSpace
	}

	return decoderSuccess
}

/* Decodes the Huffman tables.
   There are 2 scenarios:
    A) Huffman code contains only few symbols (1..4). Those symbols are read
       directly; their code lengths are defined by the number of symbols.
       For this scenario 4 - 49 bits will be read.

    B) 2-phase decoding:
    B.1) Small Huffman table is decoded; it is specified with code lengths
         encoded with predefined entropy code. 32 - 74 bits are used.
    B.2) Decoded table is used to decode code lengths of symbols in resulting
         Huffman table. In worst case 3520 bits are read. */
func readHuffmanCode( uint32,  uint32,  []huffmanCode,  *uint32,  *Reader) int {
	var  *bitReader = &.br

	/* Unnecessary masking, but might be good for safety. */
	 &= 0x7FF

	/* State machine. */
	for {
		switch .substate_huffman {
		case stateHuffmanNone:
			if !safeReadBits(, 2, &.sub_loop_counter) {
				return decoderNeedsMoreInput
			}

			/* The value is used as follows:
			   1 for simple code;
			   0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
			if .sub_loop_counter != 1 {
				.space = 32
				.repeat = 0 /* num_codes */
				var  int
				for  = 0;  <= huffmanMaxCodeLengthCodeLength; ++ {
					.code_length_histo[] = 0
				}

				for  = 0;  < codeLengthCodes; ++ {
					.code_length_code_lengths[] = 0
				}

				.substate_huffman = stateHuffmanComplex
				continue
			}
			fallthrough

			/* Read symbols, codes & code lengths directly. */
		case stateHuffmanSimpleSize:
			if !safeReadBits(, 2, &.symbol) { /* num_symbols */
				.substate_huffman = stateHuffmanSimpleSize
				return decoderNeedsMoreInput
			}

			.sub_loop_counter = 0
			fallthrough

		case stateHuffmanSimpleRead:
			{
				var  int = readSimpleHuffmanSymbols(, , )
				if  != decoderSuccess {
					return 
				}
			}
			fallthrough

		case stateHuffmanSimpleBuild:
			var  uint32
			if .symbol == 3 {
				var  uint32
				if !safeReadBits(, 1, &) {
					.substate_huffman = stateHuffmanSimpleBuild
					return decoderNeedsMoreInput
				}

				.symbol += 
			}

			 = buildSimpleHuffmanTable(, huffmanTableBits, .symbols_lists_array[:], .symbol)
			if  != nil {
				* = 
			}

			.substate_huffman = stateHuffmanNone
			return decoderSuccess

			/* Decode Huffman-coded code lengths. */
		case stateHuffmanComplex:
			{
				var  uint32
				var  int = readCodeLengthCodeLengths()
				if  != decoderSuccess {
					return 
				}

				buildCodeLengthsHuffmanTable(.table[:], .code_length_code_lengths[:], .code_length_histo[:])
				for  = 0;  < 16; ++ {
					.code_length_histo[] = 0
				}

				for  = 0;  <= huffmanMaxCodeLength; ++ {
					.next_symbol[] = int() - (huffmanMaxCodeLength + 1)
					symbolListPut(.symbol_lists, .next_symbol[], 0xFFFF)
				}

				.symbol = 0
				.prev_code_len = initialRepeatedCodeLength
				.repeat = 0
				.repeat_code_len = 0
				.space = 32768
				.substate_huffman = stateHuffmanLengthSymbols
			}
			fallthrough

		case stateHuffmanLengthSymbols:
			var  uint32
			var  int = readSymbolCodeLengths(, )
			if  == decoderNeedsMoreInput {
				 = safeReadSymbolCodeLengths(, )
			}

			if  != decoderSuccess {
				return 
			}

			if .space != 0 {
				return decoderErrorFormatHuffmanSpace
			}

			 = buildHuffmanTable(, huffmanTableBits, .symbol_lists, .code_length_histo[:])
			if  != nil {
				* = 
			}

			.substate_huffman = stateHuffmanNone
			return decoderSuccess

		default:
			return decoderErrorUnreachable
		}
	}
}

/* Decodes a block length by reading 3..39 bits. */
func readBlockLength( []huffmanCode,  *bitReader) uint32 {
	var  uint32
	var  uint32
	 = readSymbol(, )
	 = kBlockLengthPrefixCode[].nbits /* nbits == 2..24 */
	return kBlockLengthPrefixCode[].offset + readBits(, )
}

/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then
   reading can't be continued with ReadBlockLength. */
func safeReadBlockLength( *Reader,  *uint32,  []huffmanCode,  *bitReader) bool {
	var  uint32
	if .substate_read_block_length == stateReadBlockLengthNone {
		if !safeReadSymbol(, , &) {
			return false
		}
	} else {
		 = .block_length_index
	}
	{
		var  uint32 /* nbits == 2..24 */
		var  uint32 = kBlockLengthPrefixCode[].nbits
		if !safeReadBits(, , &) {
			.block_length_index = 
			.substate_read_block_length = stateReadBlockLengthSuffix
			return false
		}

		* = kBlockLengthPrefixCode[].offset + 
		.substate_read_block_length = stateReadBlockLengthNone
		return true
	}
}

/* Transform:
    1) initialize list L with values 0, 1,... 255
    2) For each input element X:
    2.1) let Y = L[X]
    2.2) remove X-th element from L
    2.3) prepend Y to L
    2.4) append Y to output

   In most cases max(Y) <= 7, so most of L remains intact.
   To reduce the cost of initialization, we reuse L, remember the upper bound
   of Y values, and reinitialize only first elements in L.

   Most of input values are 0 and 1. To reduce number of branches, we replace
   inner for loop with do-while. */
func inverseMoveToFrontTransform( []byte,  uint32,  *Reader) {
	var  [256]byte
	var  int
	for  = 1;  < 256; ++ {
		[] = byte()
	}
	var  byte

	/* Transform the input. */
	for  = 0; uint32() < ; ++ {
		var  int = int([])
		var  byte = []
		[] = 
		 = 
		for  >= 1 {
			--
			[+1] = []
		}

		[0] = 
	}
}

/* Decodes a series of Huffman table using ReadHuffmanCode function. */
func huffmanTreeGroupDecode( *huffmanTreeGroup,  *Reader) int {
	if .substate_tree_group != stateTreeGroupLoop {
		.next = .codes
		.htree_index = 0
		.substate_tree_group = stateTreeGroupLoop
	}

	for .htree_index < int(.num_htrees) {
		var  uint32
		var  int = readHuffmanCode(uint32(.alphabet_size), uint32(.max_symbol), .next, &, )
		if  != decoderSuccess {
			return 
		}
		.htrees[.htree_index] = .next
		.next = .next[:]
		.htree_index++
	}

	.substate_tree_group = stateTreeGroupNone
	return decoderSuccess
}

/* Decodes a context map.
   Decoding is done in 4 phases:
    1) Read auxiliary information (6..16 bits) and allocate memory.
       In case of trivial context map, decoding is finished at this phase.
    2) Decode Huffman table using ReadHuffmanCode function.
       This table will be used for reading context map items.
    3) Read context map items; "0" values could be run-length encoded.
    4) Optionally, apply InverseMoveToFront transform to the resulting map. */
func decodeContextMap( uint32,  *uint32,  *[]byte,  *Reader) int {
	var  *bitReader = &.br
	var  int = decoderSuccess

	switch int(.substate_context_map) {
	case stateContextMapNone:
		 = decodeVarLenUint8(, , )
		if  != decoderSuccess {
			return 
		}

		(*)++
		.context_index = 0
		* = make([]byte, uint())
		if * == nil {
			return decoderErrorAllocContextMap
		}

		if * <= 1 {
			for  := 0;  < int(); ++ {
				(*)[] = 0
			}
			return decoderSuccess
		}

		.substate_context_map = stateContextMapReadPrefix
		fallthrough
	/* Fall through. */
	case stateContextMapReadPrefix:
		{
			var  uint32

			/* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe
			   to peek 4 bits ahead. */
			if !safeGetBits(, 5, &) {
				return decoderNeedsMoreInput
			}

			if &1 != 0 { /* Use RLE for zeros. */
				.max_run_length_prefix = ( >> 1) + 1
				dropBits(, 5)
			} else {
				.max_run_length_prefix = 0
				dropBits(, 1)
			}

			.substate_context_map = stateContextMapHuffman
		}
		fallthrough

		/* Fall through. */
	case stateContextMapHuffman:
		{
			var  uint32 = * + .max_run_length_prefix
			 = readHuffmanCode(, , .context_map_table[:], nil, )
			if  != decoderSuccess {
				return 
			}
			.code = 0xFFFF
			.substate_context_map = stateContextMapDecode
		}
		fallthrough

		/* Fall through. */
	case stateContextMapDecode:
		{
			var  uint32 = .context_index
			var  uint32 = .max_run_length_prefix
			var  []byte = *
			var  uint32 = .code
			var  bool = ( != 0xFFFF)
			for  <  ||  {
				if ! {
					if !safeReadSymbol(.context_map_table[:], , &) {
						.code = 0xFFFF
						.context_index = 
						return decoderNeedsMoreInput
					}

					if  == 0 {
						[] = 0
						++
						continue
					}

					if  >  {
						[] = byte( - )
						++
						continue
					}
				} else {
					 = false
				}

				/* RLE sub-stage. */
				{
					var  uint32
					if !safeReadBits(, , &) {
						.code = 
						.context_index = 
						return decoderNeedsMoreInput
					}

					 += 1 << 
					if + >  {
						return decoderErrorFormatContextMapRepeat
					}

					for {
						[] = 0
						++
						--
						if  == 0 {
							break
						}
					}
				}
			}
		}
		fallthrough

	case stateContextMapTransform:
		var  uint32
		if !safeReadBits(, 1, &) {
			.substate_context_map = stateContextMapTransform
			return decoderNeedsMoreInput
		}

		if  != 0 {
			inverseMoveToFrontTransform(*, , )
		}

		.substate_context_map = stateContextMapNone
		return decoderSuccess

	default:
		return decoderErrorUnreachable
	}
}

/* Decodes a command or literal and updates block type ring-buffer.
   Reads 3..54 bits. */
func decodeBlockTypeAndLength( int,  *Reader,  int) bool {
	var  uint32 = .num_block_types[]
	 := .block_type_trees[*huffmanMaxSize258:]
	 := .block_len_trees[*huffmanMaxSize26:]
	var  *bitReader = &.br
	var  []uint32 = .block_type_rb[*2:]
	var  uint32
	if  <= 1 {
		return false
	}

	/* Read 0..15 + 3..39 bits. */
	if  == 0 {
		 = readSymbol(, )
		.block_length[] = readBlockLength(, )
	} else {
		var  bitReaderState
		bitReaderSaveState(, &)
		if !safeReadSymbol(, , &) {
			return false
		}
		if !safeReadBlockLength(, &.block_length[], , ) {
			.substate_read_block_length = stateReadBlockLengthNone
			bitReaderRestoreState(, &)
			return false
		}
	}

	if  == 1 {
		 = [1] + 1
	} else if  == 0 {
		 = [0]
	} else {
		 -= 2
	}

	if  >=  {
		 -= 
	}

	[0] = [1]
	[1] = 
	return true
}

func detectTrivialLiteralBlockTypes( *Reader) {
	var  uint
	for  = 0;  < 8; ++ {
		.trivial_literal_contexts[] = 0
	}
	for  = 0; uint32() < .num_block_types[0]; ++ {
		var  uint =  << literalContextBits
		var  uint = 0
		var  uint = uint(.context_map[])
		var  uint
		for  = 0;  < 1<<literalContextBits; {
			var  int
			for  = 0;  < 4; ++ {
				 |= uint(.context_map[+]) ^ 
				++
			}
		}

		if  == 0 {
			.trivial_literal_contexts[>>5] |= 1 << ( & 31)
		}
	}
}

func prepareLiteralDecoding( *Reader) {
	var  byte
	var  uint
	var  uint32 = .block_type_rb[1]
	var  uint32 =  << literalContextBits
	.context_map_slice = .context_map[:]
	 = uint(.trivial_literal_contexts[>>5])
	.trivial_literal_context = int(( >> ( & 31)) & 1)
	.literal_htree = []huffmanCode(.literal_hgroup.htrees[.context_map_slice[0]])
	 = .context_modes[] & 3
	.context_lookup = getContextLUT(int())
}

/* Decodes the block type and updates the state for literal context.
   Reads 3..54 bits. */
func decodeLiteralBlockSwitchInternal( int,  *Reader) bool {
	if !decodeBlockTypeAndLength(, , 0) {
		return false
	}

	prepareLiteralDecoding()
	return true
}

func decodeLiteralBlockSwitch( *Reader) {
	decodeLiteralBlockSwitchInternal(0, )
}

func safeDecodeLiteralBlockSwitch( *Reader) bool {
	return decodeLiteralBlockSwitchInternal(1, )
}

/* Block switch for insert/copy length.
   Reads 3..54 bits. */
func decodeCommandBlockSwitchInternal( int,  *Reader) bool {
	if !decodeBlockTypeAndLength(, , 1) {
		return false
	}

	.htree_command = []huffmanCode(.insert_copy_hgroup.htrees[.block_type_rb[3]])
	return true
}

func decodeCommandBlockSwitch( *Reader) {
	decodeCommandBlockSwitchInternal(0, )
}

func safeDecodeCommandBlockSwitch( *Reader) bool {
	return decodeCommandBlockSwitchInternal(1, )
}

/* Block switch for distance codes.
   Reads 3..54 bits. */
func decodeDistanceBlockSwitchInternal( int,  *Reader) bool {
	if !decodeBlockTypeAndLength(, , 2) {
		return false
	}

	.dist_context_map_slice = .dist_context_map[.block_type_rb[5]<<distanceContextBits:]
	.dist_htree_index = .dist_context_map_slice[.distance_context]
	return true
}

func decodeDistanceBlockSwitch( *Reader) {
	decodeDistanceBlockSwitchInternal(0, )
}

func safeDecodeDistanceBlockSwitch( *Reader) bool {
	return decodeDistanceBlockSwitchInternal(1, )
}

func unwrittenBytes( *Reader,  bool) uint {
	var  uint
	if  && .pos > .ringbuffer_size {
		 = uint(.ringbuffer_size)
	} else {
		 = uint(.pos)
	}
	var  uint = (.rb_roundtrips * uint(.ringbuffer_size)) + 
	return  - .partial_pos_out
}

/* Dumps output.
   Returns BROTLI_DECODER_NEEDS_MORE_OUTPUT only if there is more output to push
   and either ring-buffer is as big as window size, or |force| is true. */
func writeRingBuffer( *Reader,  *uint,  *[]byte,  *uint,  bool) int {
	 := .ringbuffer[.partial_pos_out&uint(.ringbuffer_mask):]
	var  uint = unwrittenBytes(, true)
	var  uint = *
	if  >  {
		 = 
	}

	if .meta_block_remaining_len < 0 {
		return decoderErrorFormatBlockLength1
	}

	if  != nil && * == nil {
		* = 
	} else {
		if  != nil {
			copy(*, [:])
			* = (*)[:]
		}
	}

	* -= 
	.partial_pos_out += 
	if  != nil {
		* = .partial_pos_out
	}

	if  <  {
		if .ringbuffer_size == 1<<.window_bits ||  {
			return decoderNeedsMoreOutput
		} else {
			return decoderSuccess
		}
	}

	/* Wrap ring buffer only if it has reached its maximal size. */
	if .ringbuffer_size == 1<<.window_bits && .pos >= .ringbuffer_size {
		.pos -= .ringbuffer_size
		.rb_roundtrips++
		if uint(.pos) != 0 {
			.should_wrap_ringbuffer = 1
		} else {
			.should_wrap_ringbuffer = 0
		}
	}

	return decoderSuccess
}

func wrapRingBuffer( *Reader) {
	if .should_wrap_ringbuffer != 0 {
		copy(.ringbuffer, .ringbuffer_end[:uint(.pos)])
		.should_wrap_ringbuffer = 0
	}
}

/* Allocates ring-buffer.

   s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before
   this function is called.

   Last two bytes of ring-buffer are initialized to 0, so context calculation
   could be done uniformly for the first two and all other positions. */
func ensureRingBuffer( *Reader) bool {
	var  []byte
	if .ringbuffer_size == .new_ringbuffer_size {
		return true
	}
	 := int(.new_ringbuffer_size) + int(kRingBufferWriteAheadSlack)
	if len(.ringbuffer) <  {
		 = .ringbuffer
		.ringbuffer = make([]byte, )
	}

	.ringbuffer[.new_ringbuffer_size-2] = 0
	.ringbuffer[.new_ringbuffer_size-1] = 0

	if  != nil {
		copy(.ringbuffer, [:uint(.pos)])
	}

	.ringbuffer_size = .new_ringbuffer_size
	.ringbuffer_mask = .new_ringbuffer_size - 1
	.ringbuffer_end = .ringbuffer[.ringbuffer_size:]

	return true
}

func copyUncompressedBlockToOutput( *uint,  *[]byte,  *uint,  *Reader) int {
	/* TODO: avoid allocation for single uncompressed block. */
	if !ensureRingBuffer() {
		return decoderErrorAllocRingBuffer1
	}

	/* State machine */
	for {
		switch .substate_uncompressed {
		case stateUncompressedNone:
			{
				var  int = int(getRemainingBytes(&.br))
				if  > .meta_block_remaining_len {
					 = .meta_block_remaining_len
				}

				if .pos+ > .ringbuffer_size {
					 = .ringbuffer_size - .pos
				}

				/* Copy remaining bytes from s->br.buf_ to ring-buffer. */
				copyBytes(.ringbuffer[.pos:], &.br, uint())

				.pos += 
				.meta_block_remaining_len -= 
				if .pos < 1<<.window_bits {
					if .meta_block_remaining_len == 0 {
						return decoderSuccess
					}

					return decoderNeedsMoreInput
				}

				.substate_uncompressed = stateUncompressedWrite
			}
			fallthrough

		case stateUncompressedWrite:
			{
				 := writeRingBuffer(, , , , false)
				if  != decoderSuccess {
					return 
				}

				if .ringbuffer_size == 1<<.window_bits {
					.max_distance = .max_backward_distance
				}

				.substate_uncompressed = stateUncompressedNone
				break
			}
		}
	}
}

/* Calculates the smallest feasible ring buffer.

   If we know the data size is small, do not allocate more ring buffer
   size than needed to reduce memory usage.

   When this method is called, metablock size and flags MUST be decoded. */
func calculateRingBufferSize( *Reader) {
	var  int = 1 << .window_bits
	var  int = 
	var  int
	/* We need at least 2 bytes of ring buffer size to get the last two
	   bytes for context from there */
	if .ringbuffer_size != 0 {
		 = .ringbuffer_size
	} else {
		 = 1024
	}
	var  int

	/* If maximum is already reached, no further extension is retired. */
	if .ringbuffer_size ==  {
		return
	}

	/* Metadata blocks does not touch ring buffer. */
	if .is_metadata != 0 {
		return
	}

	if .ringbuffer == nil {
		 = 0
	} else {
		 = .pos
	}

	 += .meta_block_remaining_len
	if  <  {
		 = 
	}

	if !(.canny_ringbuffer_allocation == 0) {
		/* Reduce ring buffer size to save memory when server is unscrupulous.
		   In worst case memory usage might be 1.5x bigger for a short period of
		   ring buffer reallocation. */
		for >>1 >=  {
			 >>= 1
		}
	}

	.new_ringbuffer_size = 
}

/* Reads 1..256 2-bit context modes. */
func readContextModes( *Reader) int {
	var  *bitReader = &.br
	var  int = .loop_counter

	for  < int(.num_block_types[0]) {
		var  uint32
		if !safeReadBits(, 2, &) {
			.loop_counter = 
			return decoderNeedsMoreInput
		}

		.context_modes[] = byte()
		++
	}

	return decoderSuccess
}

func takeDistanceFromRingBuffer( *Reader) {
	if .distance_code == 0 {
		.dist_rb_idx--
		.distance_code = .dist_rb[.dist_rb_idx&3]

		/* Compensate double distance-ring-buffer roll for dictionary items. */
		.distance_context = 1
	} else {
		var  int = .distance_code << 1
		const  uint32 = 0xAAAFFF1B
		const  uint32 = 0xFA5FA500
		var  int = (.dist_rb_idx + int(>>uint())) & 0x3
		/* kDistanceShortCodeIndexOffset has 2-bit values from LSB:
		   3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */

		/* kDistanceShortCodeValueOffset has 2-bit values from LSB:
		   -0, 0,-0, 0,-1, 1,-2, 2,-3, 3,-1, 1,-2, 2,-3, 3 */
		.distance_code = .dist_rb[]

		 = int(>>uint()) & 0x3
		if &0x3 != 0 {
			.distance_code += 
		} else {
			.distance_code -= 
			if .distance_code <= 0 {
				/* A huge distance will cause a () soon.
				   This is a little faster than failing here. */
				.distance_code = 0x7FFFFFFF
			}
		}
	}
}

func safeReadBitsMaybeZero( *bitReader,  uint32,  *uint32) bool {
	if  != 0 {
		return safeReadBits(, , )
	} else {
		* = 0
		return true
	}
}

/* Precondition: s->distance_code < 0. */
func readDistanceInternal( int,  *Reader,  *bitReader) bool {
	var  int
	var  bitReaderState
	var  []huffmanCode = []huffmanCode(.distance_hgroup.htrees[.dist_htree_index])
	if  == 0 {
		.distance_code = int(readSymbol(, ))
	} else {
		var  uint32
		bitReaderSaveState(, &)
		if !safeReadSymbol(, , &) {
			return false
		}

		.distance_code = int()
	}

	/* Convert the distance code to the actual distance by possibly
	   looking up past distances from the s->ringbuffer. */
	.distance_context = 0

	if .distance_code&^0xF == 0 {
		takeDistanceFromRingBuffer()
		.block_length[2]--
		return true
	}

	 = .distance_code - int(.num_direct_distance_codes)
	if  >= 0 {
		var  uint32
		var  int
		var  int
		if  == 0 && (.distance_postfix_bits == 0) {
			 = (uint32() >> 1) + 1
			 = ((2 + ( & 1)) << ) - 4
			.distance_code = int(.num_direct_distance_codes) +  + int(readBits(, ))
		} else {
			/* This branch also works well when s->distance_postfix_bits == 0. */
			var  uint32
			 =  & .distance_postfix_mask
			 >>= .distance_postfix_bits
			 = (uint32() >> 1) + 1
			if  != 0 {
				if !safeReadBitsMaybeZero(, , &) {
					.distance_code = -1 /* Restore precondition. */
					bitReaderRestoreState(, &)
					return false
				}
			} else {
				 = readBits(, )
			}

			 = ((2 + ( & 1)) << ) - 4
			.distance_code = int(.num_direct_distance_codes) + (( + int()) << .distance_postfix_bits) + 
		}
	}

	.distance_code = .distance_code - numDistanceShortCodes + 1
	.block_length[2]--
	return true
}

func readDistance( *Reader,  *bitReader) {
	readDistanceInternal(0, , )
}

func safeReadDistance( *Reader,  *bitReader) bool {
	return readDistanceInternal(1, , )
}

func readCommandInternal( int,  *Reader,  *bitReader,  *int) bool {
	var  uint32
	var  uint32 = 0
	var  uint32
	var  cmdLutElement
	var  bitReaderState
	if  == 0 {
		 = readSymbol(.htree_command, )
	} else {
		bitReaderSaveState(, &)
		if !safeReadSymbol(.htree_command, , &) {
			return false
		}
	}

	 = kCmdLut[]
	.distance_code = int(.distance_code)
	.distance_context = int(.context)
	.dist_htree_index = .dist_context_map_slice[.distance_context]
	* = int(.insert_len_offset)
	if  == 0 {
		if .insert_len_extra_bits != 0 {
			 = readBits(, uint32(.insert_len_extra_bits))
		}

		 = readBits(, uint32(.copy_len_extra_bits))
	} else {
		if !safeReadBitsMaybeZero(, uint32(.insert_len_extra_bits), &) || !safeReadBitsMaybeZero(, uint32(.copy_len_extra_bits), &) {
			bitReaderRestoreState(, &)
			return false
		}
	}

	.copy_length = int() + int(.copy_len_offset)
	.block_length[1]--
	* += int()
	return true
}

func readCommand( *Reader,  *bitReader,  *int) {
	readCommandInternal(0, , , )
}

func safeReadCommand( *Reader,  *bitReader,  *int) bool {
	return readCommandInternal(1, , , )
}

func checkInputAmountMaybeSafe( int,  *bitReader,  uint) bool {
	if  != 0 {
		return true
	}

	return checkInputAmount(, )
}

func processCommandsInternal( int,  *Reader) int {
	var  int = .pos
	var  int = .loop_counter
	var  int = decoderSuccess
	var  *bitReader = &.br
	var  []huffmanCode

	if !checkInputAmountMaybeSafe(, , 28) {
		 = decoderNeedsMoreInput
		goto 
	}

	if  == 0 {
		warmupBitReader()
	}

	/* Jump into state machine. */
	if .state == stateCommandBegin {
		goto 
	} else if .state == stateCommandInner {
		goto 
	} else if .state == stateCommandPostDecodeLiterals {
		goto 
	} else if .state == stateCommandPostWrapCopy {
		goto 
	} else {
		return decoderErrorUnreachable
	}

:
	if  != 0 {
		.state = stateCommandBegin
	}

	if !checkInputAmountMaybeSafe(, , 28) { /* 156 bits + 7 bytes */
		.state = stateCommandBegin
		 = decoderNeedsMoreInput
		goto 
	}

	if .block_length[1] == 0 {
		if  != 0 {
			if !safeDecodeCommandBlockSwitch() {
				 = decoderNeedsMoreInput
				goto 
			}
		} else {
			decodeCommandBlockSwitch()
		}

		goto 
	}

	/* Read the insert/copy length in the command. */
	if  != 0 {
		if !safeReadCommand(, , &) {
			 = decoderNeedsMoreInput
			goto 
		}
	} else {
		readCommand(, , &)
	}

	if  == 0 {
		goto 
	}

	.meta_block_remaining_len -= 

:
	if  != 0 {
		.state = stateCommandInner
	}

	/* Read the literals in the command. */
	if .trivial_literal_context != 0 {
		var  uint32
		var  uint32
		preloadSymbol(, .literal_htree, , &, &)
		for {
			if !checkInputAmountMaybeSafe(, , 28) { /* 162 bits + 7 bytes */
				.state = stateCommandInner
				 = decoderNeedsMoreInput
				goto 
			}

			if .block_length[0] == 0 {
				if  != 0 {
					if !safeDecodeLiteralBlockSwitch() {
						 = decoderNeedsMoreInput
						goto 
					}
				} else {
					decodeLiteralBlockSwitch()
				}

				preloadSymbol(, .literal_htree, , &, &)
				if .trivial_literal_context == 0 {
					goto 
				}
			}

			if  == 0 {
				.ringbuffer[] = byte(readPreloadedSymbol(.literal_htree, , &, &))
			} else {
				var  uint32
				if !safeReadSymbol(.literal_htree, , &) {
					 = decoderNeedsMoreInput
					goto 
				}

				.ringbuffer[] = byte()
			}

			.block_length[0]--
			++
			if  == .ringbuffer_size {
				.state = stateCommandInnerWrite
				--
				goto 
			}
			--
			if  == 0 {
				break
			}
		}
	} else {
		var  byte = .ringbuffer[(-1)&.ringbuffer_mask]
		var  byte = .ringbuffer[(-2)&.ringbuffer_mask]
		for {
			var  byte
			if !checkInputAmountMaybeSafe(, , 28) { /* 162 bits + 7 bytes */
				.state = stateCommandInner
				 = decoderNeedsMoreInput
				goto 
			}

			if .block_length[0] == 0 {
				if  != 0 {
					if !safeDecodeLiteralBlockSwitch() {
						 = decoderNeedsMoreInput
						goto 
					}
				} else {
					decodeLiteralBlockSwitch()
				}

				if .trivial_literal_context != 0 {
					goto 
				}
			}

			 = getContext(, , .context_lookup)
			 = []huffmanCode(.literal_hgroup.htrees[.context_map_slice[]])
			 = 
			if  == 0 {
				 = byte(readSymbol(, ))
			} else {
				var  uint32
				if !safeReadSymbol(, , &) {
					 = decoderNeedsMoreInput
					goto 
				}

				 = byte()
			}

			.ringbuffer[] = 
			.block_length[0]--
			++
			if  == .ringbuffer_size {
				.state = stateCommandInnerWrite
				--
				goto 
			}
			--
			if  == 0 {
				break
			}
		}
	}

	if .meta_block_remaining_len <= 0 {
		.state = stateMetablockDone
		goto 
	}

:
	if  != 0 {
		.state = stateCommandPostDecodeLiterals
	}

	if .distance_code >= 0 {
		/* Implicit distance case. */
		if .distance_code != 0 {
			.distance_context = 0
		} else {
			.distance_context = 1
		}

		.dist_rb_idx--
		.distance_code = .dist_rb[.dist_rb_idx&3]
	} else {
		/* Read distance code in the command, unless it was implicitly zero. */
		if .block_length[2] == 0 {
			if  != 0 {
				if !safeDecodeDistanceBlockSwitch() {
					 = decoderNeedsMoreInput
					goto 
				}
			} else {
				decodeDistanceBlockSwitch()
			}
		}

		if  != 0 {
			if !safeReadDistance(, ) {
				 = decoderNeedsMoreInput
				goto 
			}
		} else {
			readDistance(, )
		}
	}

	if .max_distance != .max_backward_distance {
		if  < .max_backward_distance {
			.max_distance = 
		} else {
			.max_distance = .max_backward_distance
		}
	}

	 = .copy_length

	/* Apply copy of LZ77 back-reference, or static dictionary reference if
	   the distance is larger than the max LZ77 distance */
	if .distance_code > .max_distance {
		/* The maximum allowed distance is BROTLI_MAX_ALLOWED_DISTANCE = 0x7FFFFFFC.
		   With this choice, no signed overflow can occur after decoding
		   a special distance code (e.g., after adding 3 to the last distance). */
		if .distance_code > maxAllowedDistance {
			return decoderErrorFormatDistance
		}

		if  >= minDictionaryWordLength &&  <= maxDictionaryWordLength {
			var  int = .distance_code - .max_distance - 1
			var  *dictionary = .dictionary
			var  *transforms = .transforms
			var  int = int(.dictionary.offsets_by_length[])
			var  uint32 = uint32(.dictionary.size_bits_by_length[])
			var  int = int(bitMask())
			var  int =  & 
			var  int =  >> 

			/* Compensate double distance-ring-buffer roll. */
			.dist_rb_idx += .distance_context

			 +=  * 
			if .data == nil {
				return decoderErrorDictionaryNotSet
			}

			if  < int(.num_transforms) {
				 := .data[:]
				var  int = 
				if  == int(.cutOffTransforms[0]) {
					copy(.ringbuffer[:], [:uint()])
				} else {
					 = transformDictionaryWord(.ringbuffer[:], , int(), , )
				}

				 += int()
				.meta_block_remaining_len -= int()
				if  >= .ringbuffer_size {
					.state = stateCommandPostWrite1
					goto 
				}
			} else {
				return decoderErrorFormatTransform
			}
		} else {
			return decoderErrorFormatDictionary
		}
	} else {
		var  int = ( - .distance_code) & .ringbuffer_mask
		 := .ringbuffer[:]
		 := .ringbuffer[:]
		var  int =  + 
		var  int =  + 

		/* Update the recent distances cache. */
		.dist_rb[.dist_rb_idx&3] = .distance_code

		.dist_rb_idx++
		.meta_block_remaining_len -= 

		/* There are 32+ bytes of slack in the ring-buffer allocation.
		   Also, we have 16 short codes, that make these 16 bytes irrelevant
		   in the ring-buffer. Let's copy over them as a first guess. */
		copy(, [:16])

		if  >  &&  >  {
			/* Regions intersect. */
			goto 
		}

		if  >= .ringbuffer_size ||  >= .ringbuffer_size {
			/* At least one region wraps. */
			goto 
		}

		 += 
		if  > 16 {
			if  > 32 {
				copy([16:], [16:][:uint(-16)])
			} else {
				/* This branch covers about 45% cases.
				   Fixed size short copy allows more compiler optimizations. */
				copy([16:], [16:][:16])
			}
		}
	}

	if .meta_block_remaining_len <= 0 {
		/* Next metablock, if any. */
		.state = stateMetablockDone

		goto 
	} else {
		goto 
	}
:
	{
		var  int = .ringbuffer_size - 
		for {
			--
			if  < 0 {
				break
			}
			.ringbuffer[] = .ringbuffer[(-.distance_code)&.ringbuffer_mask]
			++
			--
			if  == 0 {
				.state = stateCommandPostWrite2
				goto 
			}
		}
	}

	if .meta_block_remaining_len <= 0 {
		/* Next metablock, if any. */
		.state = stateMetablockDone

		goto 
	} else {
		goto 
	}

:
	.pos = 
	.loop_counter = 
	return 
}

func processCommands( *Reader) int {
	return processCommandsInternal(0, )
}

func safeProcessCommands( *Reader) int {
	return processCommandsInternal(1, )
}

/* Returns the maximum number of distance symbols which can only represent
   distances not exceeding BROTLI_MAX_ALLOWED_DISTANCE. */

var maxDistanceSymbol_bound = [maxNpostfix + 1]uint32{0, 4, 12, 28}
var maxDistanceSymbol_diff = [maxNpostfix + 1]uint32{73, 126, 228, 424}

func maxDistanceSymbol( uint32,  uint32) uint32 {
	var  uint32 = 1 << 
	if  < maxDistanceSymbol_bound[] {
		return  + maxDistanceSymbol_diff[] + 
	} else if  > maxDistanceSymbol_bound[]+ {
		return  + maxDistanceSymbol_diff[]
	} else {
		return maxDistanceSymbol_bound[] + maxDistanceSymbol_diff[] + 
	}
}

/* Invariant: input stream is never overconsumed:
   - invalid input implies that the whole stream is invalid -> any amount of
     input could be read and discarded
   - when result is "needs more input", then at least one more byte is REQUIRED
     to complete decoding; all input data MUST be consumed by decoder, so
     client could swap the input buffer
   - when result is "needs more output" decoder MUST ensure that it doesn't
     hold more than 7 bits in bit reader; this saves client from swapping input
     buffer ahead of time
   - when result is "success" decoder MUST return all unused data back to input
     buffer; this is possible because the invariant is held on enter */
func decoderDecompressStream( *Reader,  *uint,  *[]byte,  *uint,  *[]byte) int {
	var  int = decoderSuccess
	var  *bitReader = &.br

	/* Do not try to process further in a case of unrecoverable error. */
	if int(.error_code) < 0 {
		return decoderResultError
	}

	if * != 0 && ( == nil || * == nil) {
		return saveErrorCode(, decoderErrorInvalidArguments)
	}

	if * == 0 {
		 = nil
	}
	if .buffer_length == 0 { /* Just connect bit reader to input stream. */
		.input_len = *
		.input = *
		.byte_pos = 0
	} else {
		/* At least one byte of input is required. More than one byte of input may
		   be required to complete the transaction -> reading more data must be
		   done in a loop -> do it in a main loop. */
		 = decoderNeedsMoreInput

		.input = .buffer.u8[:]
		.byte_pos = 0
	}

	/* State machine */
	for {
		if  != decoderSuccess {
			/* Error, needs more input/output. */
			if  == decoderNeedsMoreInput {
				if .ringbuffer != nil { /* Pro-actively push output. */
					var  int = writeRingBuffer(, , , nil, true)

					/* WriteRingBuffer checks s->meta_block_remaining_len validity. */
					if int() < 0 {
						 = 
						break
					}
				}

				if .buffer_length != 0 { /* Used with internal buffer. */
					if .byte_pos == .input_len {
						/* Successfully finished read transaction.
						   Accumulator contains less than 8 bits, because internal buffer
						   is expanded byte-by-byte until it is enough to complete read. */
						.buffer_length = 0

						/* Switch to input stream and restart. */
						 = decoderSuccess

						.input_len = *
						.input = *
						.byte_pos = 0
						continue
					} else if * != 0 {
						/* Not enough data in buffer, but can take one more byte from
						   input stream. */
						 = decoderSuccess

						.buffer.u8[.buffer_length] = (*)[0]
						.buffer_length++
						.input_len = uint(.buffer_length)
						* = (*)[1:]
						(*)--

						/* Retry with more data in buffer. */
						continue
					}

					/* Can't finish reading and no more input. */
					break
					/* Input stream doesn't contain enough input. */
				} else {
					/* Copy tail to internal buffer and return. */
					* = .input[.byte_pos:]

					* = .input_len - .byte_pos
					for * != 0 {
						.buffer.u8[.buffer_length] = (*)[0]
						.buffer_length++
						* = (*)[1:]
						(*)--
					}

					break
				}
			}

			/* Unreachable. */

			/* Fail or needs more output. */
			if .buffer_length != 0 {
				/* Just consumed the buffered input and produced some output. Otherwise
				   it would result in "needs more input". Reset internal buffer. */
				.buffer_length = 0
			} else {
				/* Using input stream in last iteration. When decoder switches to input
				   stream it has less than 8 bits in accumulator, so it is safe to
				   return unused accumulator bits there. */
				bitReaderUnload()

				* = .input_len - .byte_pos
				* = .input[.byte_pos:]
			}

			break
		}

		switch .state {
		/* Prepare to the first read. */
		case stateUninited:
			if !warmupBitReader() {
				 = decoderNeedsMoreInput
				break
			}

			/* Decode window size. */
			 = decodeWindowBits(, ) /* Reads 1..8 bits. */
			if  != decoderSuccess {
				break
			}

			if .large_window {
				.state = stateLargeWindowBits
				break
			}

			.state = stateInitialize

		case stateLargeWindowBits:
			if !safeReadBits(, 6, &.window_bits) {
				 = decoderNeedsMoreInput
				break
			}

			if .window_bits < largeMinWbits || .window_bits > largeMaxWbits {
				 = decoderErrorFormatWindowBits
				break
			}

			.state = stateInitialize
			fallthrough

			/* Maximum distance, see section 9.1. of the spec. */
		/* Fall through. */
		case stateInitialize:
			.max_backward_distance = (1 << .window_bits) - windowGap

			/* Allocate memory for both block_type_trees and block_len_trees. */
			.block_type_trees = make([]huffmanCode, (3 * (huffmanMaxSize258 + huffmanMaxSize26)))

			if .block_type_trees == nil {
				 = decoderErrorAllocBlockTypeTrees
				break
			}

			.block_len_trees = .block_type_trees[3*huffmanMaxSize258:]

			.state = stateMetablockBegin
			fallthrough

			/* Fall through. */
		case stateMetablockBegin:
			decoderStateMetablockBegin()

			.state = stateMetablockHeader
			fallthrough

			/* Fall through. */
		case stateMetablockHeader:
			 = decodeMetaBlockLength(, )
			/* Reads 2 - 31 bits. */
			if  != decoderSuccess {
				break
			}

			if .is_metadata != 0 || .is_uncompressed != 0 {
				if !bitReaderJumpToByteBoundary() {
					 = decoderErrorFormatPadding1
					break
				}
			}

			if .is_metadata != 0 {
				.state = stateMetadata
				break
			}

			if .meta_block_remaining_len == 0 {
				.state = stateMetablockDone
				break
			}

			calculateRingBufferSize()
			if .is_uncompressed != 0 {
				.state = stateUncompressed
				break
			}

			.loop_counter = 0
			.state = stateHuffmanCode0

		case stateUncompressed:
			 = copyUncompressedBlockToOutput(, , nil, )
			if  == decoderSuccess {
				.state = stateMetablockDone
			}

		case stateMetadata:
			for ; .meta_block_remaining_len > 0; .meta_block_remaining_len-- {
				var  uint32

				/* Read one byte and ignore it. */
				if !safeReadBits(, 8, &) {
					 = decoderNeedsMoreInput
					break
				}
			}

			if  == decoderSuccess {
				.state = stateMetablockDone
			}

		case stateHuffmanCode0:
			if .loop_counter >= 3 {
				.state = stateMetablockHeader2
				break
			}

			/* Reads 1..11 bits. */
			 = decodeVarLenUint8(, , &.num_block_types[.loop_counter])

			if  != decoderSuccess {
				break
			}

			.num_block_types[.loop_counter]++
			if .num_block_types[.loop_counter] < 2 {
				.loop_counter++
				break
			}

			.state = stateHuffmanCode1
			fallthrough

		case stateHuffmanCode1:
			{
				var  uint32 = .num_block_types[.loop_counter] + 2
				var  int = .loop_counter * huffmanMaxSize258
				 = readHuffmanCode(, , .block_type_trees[:], nil, )
				if  != decoderSuccess {
					break
				}
				.state = stateHuffmanCode2
			}
			fallthrough

		case stateHuffmanCode2:
			{
				var  uint32 = numBlockLenSymbols
				var  int = .loop_counter * huffmanMaxSize26
				 = readHuffmanCode(, , .block_len_trees[:], nil, )
				if  != decoderSuccess {
					break
				}
				.state = stateHuffmanCode3
			}
			fallthrough

		case stateHuffmanCode3:
			var  int = .loop_counter * huffmanMaxSize26
			if !safeReadBlockLength(, &.block_length[.loop_counter], .block_len_trees[:], ) {
				 = decoderNeedsMoreInput
				break
			}

			.loop_counter++
			.state = stateHuffmanCode0

		case stateMetablockHeader2:
			{
				var  uint32
				if !safeReadBits(, 6, &) {
					 = decoderNeedsMoreInput
					break
				}

				.distance_postfix_bits =  & bitMask(2)
				 >>= 2
				.num_direct_distance_codes = numDistanceShortCodes + ( << .distance_postfix_bits)
				.distance_postfix_mask = int(bitMask(.distance_postfix_bits))
				.context_modes = make([]byte, uint(.num_block_types[0]))
				if .context_modes == nil {
					 = decoderErrorAllocContextModes
					break
				}

				.loop_counter = 0
				.state = stateContextModes
			}
			fallthrough

		case stateContextModes:
			 = readContextModes()

			if  != decoderSuccess {
				break
			}

			.state = stateContextMap1
			fallthrough

		case stateContextMap1:
			 = decodeContextMap(.num_block_types[0]<<literalContextBits, &.num_literal_htrees, &.context_map, )

			if  != decoderSuccess {
				break
			}

			detectTrivialLiteralBlockTypes()
			.state = stateContextMap2
			fallthrough

		case stateContextMap2:
			{
				var  uint32 = .num_direct_distance_codes - numDistanceShortCodes
				var  uint32
				var  uint32
				if .large_window {
					 = uint32(distanceAlphabetSize(uint(.distance_postfix_bits), uint(), largeMaxDistanceBits))
					 = maxDistanceSymbol(, .distance_postfix_bits)
				} else {
					 = uint32(distanceAlphabetSize(uint(.distance_postfix_bits), uint(), maxDistanceBits))
					 = 
				}
				var  bool = true
				 = decodeContextMap(.num_block_types[2]<<distanceContextBits, &.num_dist_htrees, &.dist_context_map, )
				if  != decoderSuccess {
					break
				}

				if !decoderHuffmanTreeGroupInit(, &.literal_hgroup, numLiteralSymbols, numLiteralSymbols, .num_literal_htrees) {
					 = false
				}

				if !decoderHuffmanTreeGroupInit(, &.insert_copy_hgroup, numCommandSymbols, numCommandSymbols, .num_block_types[1]) {
					 = false
				}

				if !decoderHuffmanTreeGroupInit(, &.distance_hgroup, , , .num_dist_htrees) {
					 = false
				}

				if ! {
					return saveErrorCode(, decoderErrorAllocTreeGroups)
				}

				.loop_counter = 0
				.state = stateTreeGroup
			}
			fallthrough

		case stateTreeGroup:
			var  *huffmanTreeGroup = nil
			switch .loop_counter {
			case 0:
				 = &.literal_hgroup
			case 1:
				 = &.insert_copy_hgroup
			case 2:
				 = &.distance_hgroup
			default:
				return saveErrorCode(, decoderErrorUnreachable)
			}

			 = huffmanTreeGroupDecode(, )
			if  != decoderSuccess {
				break
			}
			.loop_counter++
			if .loop_counter >= 3 {
				prepareLiteralDecoding()
				.dist_context_map_slice = .dist_context_map
				.htree_command = []huffmanCode(.insert_copy_hgroup.htrees[0])
				if !ensureRingBuffer() {
					 = decoderErrorAllocRingBuffer2
					break
				}

				.state = stateCommandBegin
			}

		case stateCommandBegin, stateCommandInner, stateCommandPostDecodeLiterals, stateCommandPostWrapCopy:
			 = processCommands()

			if  == decoderNeedsMoreInput {
				 = safeProcessCommands()
			}

		case stateCommandInnerWrite, stateCommandPostWrite1, stateCommandPostWrite2:
			 = writeRingBuffer(, , , nil, false)

			if  != decoderSuccess {
				break
			}

			wrapRingBuffer()
			if .ringbuffer_size == 1<<.window_bits {
				.max_distance = .max_backward_distance
			}

			if .state == stateCommandPostWrite1 {
				if .meta_block_remaining_len == 0 {
					/* Next metablock, if any. */
					.state = stateMetablockDone
				} else {
					.state = stateCommandBegin
				}
			} else if .state == stateCommandPostWrite2 {
				.state = stateCommandPostWrapCopy /* BROTLI_STATE_COMMAND_INNER_WRITE */
			} else {
				if .loop_counter == 0 {
					if .meta_block_remaining_len == 0 {
						.state = stateMetablockDone
					} else {
						.state = stateCommandPostDecodeLiterals
					}

					break
				}

				.state = stateCommandInner
			}

		case stateMetablockDone:
			if .meta_block_remaining_len < 0 {
				 = decoderErrorFormatBlockLength2
				break
			}

			decoderStateCleanupAfterMetablock()
			if .is_last_metablock == 0 {
				.state = stateMetablockBegin
				break
			}

			if !bitReaderJumpToByteBoundary() {
				 = decoderErrorFormatPadding2
				break
			}

			if .buffer_length == 0 {
				bitReaderUnload()
				* = .input_len - .byte_pos
				* = .input[.byte_pos:]
			}

			.state = stateDone
			fallthrough

		case stateDone:
			if .ringbuffer != nil {
				 = writeRingBuffer(, , , nil, true)
				if  != decoderSuccess {
					break
				}
			}

			return saveErrorCode(, )
		}
	}

	return saveErrorCode(, )
}

func decoderHasMoreOutput( *Reader) bool {
	/* After unrecoverable error remaining output is considered nonsensical. */
	if int(.error_code) < 0 {
		return false
	}

	return .ringbuffer != nil && unwrittenBytes(, false) != 0
}

func decoderGetErrorCode( *Reader) int {
	return int(.error_code)
}

func decoderErrorString( int) string {
	switch  {
	case decoderNoError:
		return "NO_ERROR"
	case decoderSuccess:
		return "SUCCESS"
	case decoderNeedsMoreInput:
		return "NEEDS_MORE_INPUT"
	case decoderNeedsMoreOutput:
		return "NEEDS_MORE_OUTPUT"
	case decoderErrorFormatExuberantNibble:
		return "EXUBERANT_NIBBLE"
	case decoderErrorFormatReserved:
		return "RESERVED"
	case decoderErrorFormatExuberantMetaNibble:
		return "EXUBERANT_META_NIBBLE"
	case decoderErrorFormatSimpleHuffmanAlphabet:
		return "SIMPLE_HUFFMAN_ALPHABET"
	case decoderErrorFormatSimpleHuffmanSame:
		return "SIMPLE_HUFFMAN_SAME"
	case decoderErrorFormatClSpace:
		return "CL_SPACE"
	case decoderErrorFormatHuffmanSpace:
		return "HUFFMAN_SPACE"
	case decoderErrorFormatContextMapRepeat:
		return "CONTEXT_MAP_REPEAT"
	case decoderErrorFormatBlockLength1:
		return "BLOCK_LENGTH_1"
	case decoderErrorFormatBlockLength2:
		return "BLOCK_LENGTH_2"
	case decoderErrorFormatTransform:
		return "TRANSFORM"
	case decoderErrorFormatDictionary:
		return "DICTIONARY"
	case decoderErrorFormatWindowBits:
		return "WINDOW_BITS"
	case decoderErrorFormatPadding1:
		return "PADDING_1"
	case decoderErrorFormatPadding2:
		return "PADDING_2"
	case decoderErrorFormatDistance:
		return "DISTANCE"
	case decoderErrorDictionaryNotSet:
		return "DICTIONARY_NOT_SET"
	case decoderErrorInvalidArguments:
		return "INVALID_ARGUMENTS"
	case decoderErrorAllocContextModes:
		return "CONTEXT_MODES"
	case decoderErrorAllocTreeGroups:
		return "TREE_GROUPS"
	case decoderErrorAllocContextMap:
		return "CONTEXT_MAP"
	case decoderErrorAllocRingBuffer1:
		return "RING_BUFFER_1"
	case decoderErrorAllocRingBuffer2:
		return "RING_BUFFER_2"
	case decoderErrorAllocBlockTypeTrees:
		return "BLOCK_TYPE_TREES"
	case decoderErrorUnreachable:
		return "UNREACHABLE"
	default:
		return "INVALID"
	}
}