func dictRepeat(dict *dictionary, len *uint32, dist uint32) bool {
	var back uint32
	var left uint32
	if dist >= dict.full || dist >= dict.size {
		return false
	}
	left = dict.limit - dict.pos
	if left > *len {
		left = *len
	}
	*len -= left
	back = dict.pos - dist - 1
	if dist >= dict.pos {
		back += dict.end
	}
	for {
		dict.buf[dict.pos] = dict.buf[back]
		dict.pos++
		back++
		if back == dict.end {
			back = 0
		}
		left--
		if !(left > 0) {
			break
		}
	}
	if dict.full < dict.pos {
		dict.full = dict.pos
	}
	return true
}
/*
Repeat given number of bytes from the given distance. If the distance is
invalid, false is returned. On success, true is returned and *len is
updated to indicate how many bytes were left to be repeated.
package xz
const (
	rcShiftBits         = 8
	rcTopBits           = 24
	rcTopValue          = 1 << rcTopBits
	rcBitModelTotalBits = 11
	rcBitModelTotal     = 1 << rcBitModelTotalBits
	rcMoveBits          = 5
)
const posStatesMax = 1 << 4
type lzmaState int
const (
	stateLitLit lzmaState = iota
	stateMatchLitLit
	stateRepLitLit
	stateShortrepLitLit
	stateMatchLit
	stateRepList
	stateShortrepLit
	stateLitMatch
	stateLitLongrep
	stateLitShortrep
	stateNonlitMatch
	stateNonlitRep
)
const states = 12
const litStates = 7
func lzmaStateLiteral(state *lzmaState) {
	switch {
	case *state <= stateShortrepLitLit:
		*state = stateLitLit
	case *state <= stateLitShortrep:
		*state -= 3
	default:
		*state -= 6
	}
}
func lzmaStateMatch(state *lzmaState) {
	if *state < litStates {
		*state = stateLitMatch
	} else {
		*state = stateNonlitMatch
	}
}
func lzmaStateLongRep(state *lzmaState) {
	if *state < litStates {
		*state = stateLitLongrep
	} else {
		*state = stateNonlitRep
	}
}
func lzmaStateShortRep(state *lzmaState) {
	if *state < litStates {
		*state = stateLitShortrep
	} else {
		*state = stateNonlitRep
	}
}
func lzmaStateIsLiteral(state lzmaState) bool {
	return state < litStates
}
const literalCoderSize = 0x300
const literalCodersMax = 1 << 4
const matchLenMin = 2
const (
	lenLowBits     = 3
	lenLowSymbols  = 1 << lenLowBits
	lenMidBits     = 3
	lenMidSymbols  = 1 << lenMidBits
	lenHighBits    = 8
	lenHighSymbols = 1 << lenHighBits
)
const distStates = 4
func lzmaGetDistState(len uint32) uint32 {
	if len < distStates+matchLenMin {
		return len - matchLenMin
	} else {
		return distStates - 1
	}
}
const (
	distSlotBits = 6
	distSlots    = 1 << distSlotBits
)
const distModelStart = 4
const distModelEnd = 14
const (
	fullDistancesBits = distModelEnd / 2
	fullDistances     = 1 << fullDistancesBits
)
const (
	alignBits = 4
	alignSize = 1 << alignBits
)
const rcInitBytes = 5
const lzmaInRequired = 21
type dictionary struct {
	buf []byte
	start uint32
	pos uint32
	full uint32
	limit uint32
	end uint32
	size uint32
	sizeMax uint32
}
type rcDec struct {
	rnge uint32
	code uint32
	initBytesLeft uint32
	in      []byte
	inPos   int
	inLimit int
}
type lzmaLenDec struct {
	choice uint16
	choice2 uint16
	low [posStatesMax][lenLowSymbols]uint16
	mid [posStatesMax][lenMidSymbols]uint16
	high [lenHighSymbols]uint16
}
type lzmaDec struct {
	rep0 uint32
	rep1 uint32
	rep2 uint32
	rep3 uint32
	state lzmaState
	len uint32
	lc             uint32
	literalPosMask uint32
	posMask        uint32
	isMatch [states][posStatesMax]uint16
	isRep [states]uint16
	isRep0 [states]uint16
	isRep1 [states]uint16
	isRep2 [states]uint16
	isRep0Long [states][posStatesMax]uint16
	distSlot [distStates][distSlots]uint16
	distSpecial [fullDistances - distModelEnd]uint16
	distAlign [alignSize]uint16
	matchLenDec lzmaLenDec
	repLenDec lzmaLenDec
	literal [literalCodersMax][literalCoderSize]uint16
}
type lzma2Seq int
const (
	seqControl lzma2Seq = iota
	seqUncompressed1
	seqUncompressed2
	seqCompressed0
	seqCompressed1
	seqProperties
	seqLZMAPrepare
	seqLZMARun
	seqCopy
)
type lzma2Dec struct {
	sequence lzma2Seq
	nextSequence lzma2Seq
	uncompressed int
	compressed int
	needDictReset bool
	needProps bool
}
type xzDecLZMA2 struct {
	rc    rcDec
	dict  dictionary
	lzma2 lzma2Dec
	lzma  lzmaDec
	temp struct {
		buf      []byte  
		bufArray [3 * lzmaInRequired]byte
	}
}
func dictReset(dict *dictionary, b *xzBuf) {
	dict.start = 0
	dict.pos = 0
	dict.limit = 0
	dict.full = 0
}
func dictLimit(dict *dictionary, outMax int) {
	if dict.end-dict.pos <= uint32(outMax) {
		dict.limit = dict.end
	} else {
		dict.limit = dict.pos + uint32(outMax)
	}
}
func dictHasSpace(dict *dictionary) bool {
	return dict.pos < dict.limit
}
func dictGet(dict *dictionary, dist uint32) uint32 {
	var offset uint32 = dict.pos - dist - 1
	if dist >= dict.pos {
		offset += dict.end
	}
	if dict.full > 0 {
		return uint32(dict.buf[offset])
	}
	return 0
}
func dictPut(dict *dictionary, byte byte) {
	dict.buf[dict.pos] = byte
	dict.pos++
	if dict.full < dict.pos {
		dict.full = dict.pos
	}
}