You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: unpack.go
    path of file: ./repos/go-ethereum/accounts/abi
    
    the code of the file until where you have to start completion: // Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//

    
func ReadInteger(typ Type, b []byte) (interface{}, error) {
	ret := new(big.Int).SetBytes(b)

	if typ.T == UintTy {
		u64, isu64 := ret.Uint64(), ret.IsUint64()
		switch typ.Size {
		case 8:
			if !isu64 || u64 > math.MaxUint8 {
				return nil, errBadUint8
			}
			return byte(u64), nil
		case 16:
			if !isu64 || u64 > math.MaxUint16 {
				return nil, errBadUint16
			}
			return uint16(u64), nil
		case 32:
			if !isu64 || u64 > math.MaxUint32 {
				return nil, errBadUint32
			}
			return uint32(u64), nil
		case 64:
			if !isu64 {
				return nil, errBadUint64
			}
			return u64, nil
		default:
			// the only case left for unsigned integer is uint256.
			return ret, nil
		}
	}

	// big.SetBytes can't tell if a number is negative or positive in itself.
	// On EVM, if the returned number > max int256, it is negative.
	// A number is > max int256 if the bit at position 255 is set.
	if ret.Bit(255) == 1 {
		ret.Add(MaxUint256, new(big.Int).Neg(ret))
		ret.Add(ret, common.Big1)
		ret.Neg(ret)
	}
	i64, isi64 := ret.Int64(), ret.IsInt64()
	switch typ.Size {
	case 8:
		if !isi64 || i64 < math.MinInt8 || i64 > math.MaxInt8 {
			return nil, errBadInt8
		}
		return int8(i64), nil
	case 16:
		if !isi64 || i64 < math.MinInt16 || i64 > math.MaxInt16 {
			return nil, errBadInt16
		}
		return int16(i64), nil
	case 32:
		if !isi64 || i64 < math.MinInt32 || i64 > math.MaxInt32 {
			return nil, errBadInt32
		}
		return int32(i64), nil
	case 64:
		if !isi64 {
			return nil, errBadInt64
		}
		return i64, nil
	default:
		// the only case left for integer is int256

		return ret, nil
	}
}