Blame vendor/golang.org/x/net/idna/punycode.go

Packit 63bb0d
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
Packit 63bb0d
Packit 63bb0d
// Copyright 2016 The Go Authors. All rights reserved.
Packit 63bb0d
// Use of this source code is governed by a BSD-style
Packit 63bb0d
// license that can be found in the LICENSE file.
Packit 63bb0d
Packit 63bb0d
package idna
Packit 63bb0d
Packit 63bb0d
// This file implements the Punycode algorithm from RFC 3492.
Packit 63bb0d
Packit 63bb0d
import (
Packit 63bb0d
	"math"
Packit 63bb0d
	"strings"
Packit 63bb0d
	"unicode/utf8"
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
// These parameter values are specified in section 5.
Packit 63bb0d
//
Packit 63bb0d
// All computation is done with int32s, so that overflow behavior is identical
Packit 63bb0d
// regardless of whether int is 32-bit or 64-bit.
Packit 63bb0d
const (
Packit 63bb0d
	base        int32 = 36
Packit 63bb0d
	damp        int32 = 700
Packit 63bb0d
	initialBias int32 = 72
Packit 63bb0d
	initialN    int32 = 128
Packit 63bb0d
	skew        int32 = 38
Packit 63bb0d
	tmax        int32 = 26
Packit 63bb0d
	tmin        int32 = 1
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
func punyError(s string) error { return &labelError{s, "A3"} }
Packit 63bb0d
Packit 63bb0d
// decode decodes a string as specified in section 6.2.
Packit 63bb0d
func decode(encoded string) (string, error) {
Packit 63bb0d
	if encoded == "" {
Packit 63bb0d
		return "", nil
Packit 63bb0d
	}
Packit 63bb0d
	pos := 1 + strings.LastIndex(encoded, "-")
Packit 63bb0d
	if pos == 1 {
Packit 63bb0d
		return "", punyError(encoded)
Packit 63bb0d
	}
Packit 63bb0d
	if pos == len(encoded) {
Packit 63bb0d
		return encoded[:len(encoded)-1], nil
Packit 63bb0d
	}
Packit 63bb0d
	output := make([]rune, 0, len(encoded))
Packit 63bb0d
	if pos != 0 {
Packit 63bb0d
		for _, r := range encoded[:pos-1] {
Packit 63bb0d
			output = append(output, r)
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	i, n, bias := int32(0), initialN, initialBias
Packit 63bb0d
	for pos < len(encoded) {
Packit 63bb0d
		oldI, w := i, int32(1)
Packit 63bb0d
		for k := base; ; k += base {
Packit 63bb0d
			if pos == len(encoded) {
Packit 63bb0d
				return "", punyError(encoded)
Packit 63bb0d
			}
Packit 63bb0d
			digit, ok := decodeDigit(encoded[pos])
Packit 63bb0d
			if !ok {
Packit 63bb0d
				return "", punyError(encoded)
Packit 63bb0d
			}
Packit 63bb0d
			pos++
Packit 63bb0d
			i += digit * w
Packit 63bb0d
			if i < 0 {
Packit 63bb0d
				return "", punyError(encoded)
Packit 63bb0d
			}
Packit 63bb0d
			t := k - bias
Packit 63bb0d
			if t < tmin {
Packit 63bb0d
				t = tmin
Packit 63bb0d
			} else if t > tmax {
Packit 63bb0d
				t = tmax
Packit 63bb0d
			}
Packit 63bb0d
			if digit < t {
Packit 63bb0d
				break
Packit 63bb0d
			}
Packit 63bb0d
			w *= base - t
Packit 63bb0d
			if w >= math.MaxInt32/base {
Packit 63bb0d
				return "", punyError(encoded)
Packit 63bb0d
			}
Packit 63bb0d
		}
Packit 63bb0d
		x := int32(len(output) + 1)
Packit 63bb0d
		bias = adapt(i-oldI, x, oldI == 0)
Packit 63bb0d
		n += i / x
Packit 63bb0d
		i %= x
Packit 63bb0d
		if n > utf8.MaxRune || len(output) >= 1024 {
Packit 63bb0d
			return "", punyError(encoded)
Packit 63bb0d
		}
Packit 63bb0d
		output = append(output, 0)
Packit 63bb0d
		copy(output[i+1:], output[i:])
Packit 63bb0d
		output[i] = n
Packit 63bb0d
		i++
Packit 63bb0d
	}
Packit 63bb0d
	return string(output), nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// encode encodes a string as specified in section 6.3 and prepends prefix to
Packit 63bb0d
// the result.
Packit 63bb0d
//
Packit 63bb0d
// The "while h < length(input)" line in the specification becomes "for
Packit 63bb0d
// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
Packit 63bb0d
func encode(prefix, s string) (string, error) {
Packit 63bb0d
	output := make([]byte, len(prefix), len(prefix)+1+2*len(s))
Packit 63bb0d
	copy(output, prefix)
Packit 63bb0d
	delta, n, bias := int32(0), initialN, initialBias
Packit 63bb0d
	b, remaining := int32(0), int32(0)
Packit 63bb0d
	for _, r := range s {
Packit 63bb0d
		if r < 0x80 {
Packit 63bb0d
			b++
Packit 63bb0d
			output = append(output, byte(r))
Packit 63bb0d
		} else {
Packit 63bb0d
			remaining++
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	h := b
Packit 63bb0d
	if b > 0 {
Packit 63bb0d
		output = append(output, '-')
Packit 63bb0d
	}
Packit 63bb0d
	for remaining != 0 {
Packit 63bb0d
		m := int32(0x7fffffff)
Packit 63bb0d
		for _, r := range s {
Packit 63bb0d
			if m > r && r >= n {
Packit 63bb0d
				m = r
Packit 63bb0d
			}
Packit 63bb0d
		}
Packit 63bb0d
		delta += (m - n) * (h + 1)
Packit 63bb0d
		if delta < 0 {
Packit 63bb0d
			return "", punyError(s)
Packit 63bb0d
		}
Packit 63bb0d
		n = m
Packit 63bb0d
		for _, r := range s {
Packit 63bb0d
			if r < n {
Packit 63bb0d
				delta++
Packit 63bb0d
				if delta < 0 {
Packit 63bb0d
					return "", punyError(s)
Packit 63bb0d
				}
Packit 63bb0d
				continue
Packit 63bb0d
			}
Packit 63bb0d
			if r > n {
Packit 63bb0d
				continue
Packit 63bb0d
			}
Packit 63bb0d
			q := delta
Packit 63bb0d
			for k := base; ; k += base {
Packit 63bb0d
				t := k - bias
Packit 63bb0d
				if t < tmin {
Packit 63bb0d
					t = tmin
Packit 63bb0d
				} else if t > tmax {
Packit 63bb0d
					t = tmax
Packit 63bb0d
				}
Packit 63bb0d
				if q < t {
Packit 63bb0d
					break
Packit 63bb0d
				}
Packit 63bb0d
				output = append(output, encodeDigit(t+(q-t)%(base-t)))
Packit 63bb0d
				q = (q - t) / (base - t)
Packit 63bb0d
			}
Packit 63bb0d
			output = append(output, encodeDigit(q))
Packit 63bb0d
			bias = adapt(delta, h+1, h == b)
Packit 63bb0d
			delta = 0
Packit 63bb0d
			h++
Packit 63bb0d
			remaining--
Packit 63bb0d
		}
Packit 63bb0d
		delta++
Packit 63bb0d
		n++
Packit 63bb0d
	}
Packit 63bb0d
	return string(output), nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func decodeDigit(x byte) (digit int32, ok bool) {
Packit 63bb0d
	switch {
Packit 63bb0d
	case '0' <= x && x <= '9':
Packit 63bb0d
		return int32(x - ('0' - 26)), true
Packit 63bb0d
	case 'A' <= x && x <= 'Z':
Packit 63bb0d
		return int32(x - 'A'), true
Packit 63bb0d
	case 'a' <= x && x <= 'z':
Packit 63bb0d
		return int32(x - 'a'), true
Packit 63bb0d
	}
Packit 63bb0d
	return 0, false
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func encodeDigit(digit int32) byte {
Packit 63bb0d
	switch {
Packit 63bb0d
	case 0 <= digit && digit < 26:
Packit 63bb0d
		return byte(digit + 'a')
Packit 63bb0d
	case 26 <= digit && digit < 36:
Packit 63bb0d
		return byte(digit + ('0' - 26))
Packit 63bb0d
	}
Packit 63bb0d
	panic("idna: internal error in punycode encoding")
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// adapt is the bias adaptation function specified in section 6.1.
Packit 63bb0d
func adapt(delta, numPoints int32, firstTime bool) int32 {
Packit 63bb0d
	if firstTime {
Packit 63bb0d
		delta /= damp
Packit 63bb0d
	} else {
Packit 63bb0d
		delta /= 2
Packit 63bb0d
	}
Packit 63bb0d
	delta += delta / numPoints
Packit 63bb0d
	k := int32(0)
Packit 63bb0d
	for delta > ((base-tmin)*tmax)/2 {
Packit 63bb0d
		delta /= base - tmin
Packit 63bb0d
		k += base
Packit 63bb0d
	}
Packit 63bb0d
	return k + (base-tmin+1)*delta/(delta+skew)
Packit 63bb0d
}