// Copyright 2016 The Snappy-Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package snapref

// decode writes the decoding of src to dst. It assumes that the varint-encoded
// length of the decompressed bytes has already been read, and that len(dst)
// equals that length.
//
// It returns 0 on success or a decodeErrCodeXxx error code on failure.
func decode(,  []byte) int {
	var , , ,  int
	for  < len() {
		switch [] & 0x03 {
		case tagLiteral:
			 := uint32([] >> 2)
			switch {
			case  < 60:
				++
			case  == 60:
				 += 2
				if uint() > uint(len()) { // The uint conversions catch overflow from the previous line.
					return decodeErrCodeCorrupt
				}
				 = uint32([-1])
			case  == 61:
				 += 3
				if uint() > uint(len()) { // The uint conversions catch overflow from the previous line.
					return decodeErrCodeCorrupt
				}
				 = uint32([-2]) | uint32([-1])<<8
			case  == 62:
				 += 4
				if uint() > uint(len()) { // The uint conversions catch overflow from the previous line.
					return decodeErrCodeCorrupt
				}
				 = uint32([-3]) | uint32([-2])<<8 | uint32([-1])<<16
			case  == 63:
				 += 5
				if uint() > uint(len()) { // The uint conversions catch overflow from the previous line.
					return decodeErrCodeCorrupt
				}
				 = uint32([-4]) | uint32([-3])<<8 | uint32([-2])<<16 | uint32([-1])<<24
			}
			 = int() + 1
			if  <= 0 {
				return decodeErrCodeUnsupportedLiteralLength
			}
			if  > len()- ||  > len()- {
				return decodeErrCodeCorrupt
			}
			copy([:], [:+])
			 += 
			 += 
			continue

		case tagCopy1:
			 += 2
			if uint() > uint(len()) { // The uint conversions catch overflow from the previous line.
				return decodeErrCodeCorrupt
			}
			 = 4 + int([-2])>>2&0x7
			 = int(uint32([-2])&0xe0<<3 | uint32([-1]))

		case tagCopy2:
			 += 3
			if uint() > uint(len()) { // The uint conversions catch overflow from the previous line.
				return decodeErrCodeCorrupt
			}
			 = 1 + int([-3])>>2
			 = int(uint32([-2]) | uint32([-1])<<8)

		case tagCopy4:
			 += 5
			if uint() > uint(len()) { // The uint conversions catch overflow from the previous line.
				return decodeErrCodeCorrupt
			}
			 = 1 + int([-5])>>2
			 = int(uint32([-4]) | uint32([-3])<<8 | uint32([-2])<<16 | uint32([-1])<<24)
		}

		if  <= 0 ||  <  ||  > len()- {
			return decodeErrCodeCorrupt
		}
		// Copy from an earlier sub-slice of dst to a later sub-slice.
		// If no overlap, use the built-in copy:
		if  >=  {
			copy([:+], [-:])
			 += 
			continue
		}

		// Unlike the built-in copy function, this byte-by-byte copy always runs
		// forwards, even if the slices overlap. Conceptually, this is:
		//
		// d += forwardCopy(dst[d:d+length], dst[d-offset:])
		//
		// We align the slices into a and b and show the compiler they are the same size.
		// This allows the loop to run without bounds checks.
		 := [ : +]
		 := [-:]
		 = [:len()]
		for  := range  {
			[] = []
		}
		 += 
	}
	if  != len() {
		return decodeErrCodeCorrupt
	}
	return 0
}