gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

punycode.go (4720B)


      1 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
      2 
      3 // Copyright 2016 The Go Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style
      5 // license that can be found in the LICENSE file.
      6 
      7 package idna
      8 
      9 // This file implements the Punycode algorithm from RFC 3492.
     10 
     11 import (
     12 	"math"
     13 	"strings"
     14 	"unicode/utf8"
     15 )
     16 
     17 // These parameter values are specified in section 5.
     18 //
     19 // All computation is done with int32s, so that overflow behavior is identical
     20 // regardless of whether int is 32-bit or 64-bit.
     21 const (
     22 	base        int32 = 36
     23 	damp        int32 = 700
     24 	initialBias int32 = 72
     25 	initialN    int32 = 128
     26 	skew        int32 = 38
     27 	tmax        int32 = 26
     28 	tmin        int32 = 1
     29 )
     30 
     31 func punyError(s string) error { return &labelError{s, "A3"} }
     32 
     33 // decode decodes a string as specified in section 6.2.
     34 func decode(encoded string) (string, error) {
     35 	if encoded == "" {
     36 		return "", nil
     37 	}
     38 	pos := 1 + strings.LastIndex(encoded, "-")
     39 	if pos == 1 {
     40 		return "", punyError(encoded)
     41 	}
     42 	if pos == len(encoded) {
     43 		return encoded[:len(encoded)-1], nil
     44 	}
     45 	output := make([]rune, 0, len(encoded))
     46 	if pos != 0 {
     47 		for _, r := range encoded[:pos-1] {
     48 			output = append(output, r)
     49 		}
     50 	}
     51 	i, n, bias := int32(0), initialN, initialBias
     52 	overflow := false
     53 	for pos < len(encoded) {
     54 		oldI, w := i, int32(1)
     55 		for k := base; ; k += base {
     56 			if pos == len(encoded) {
     57 				return "", punyError(encoded)
     58 			}
     59 			digit, ok := decodeDigit(encoded[pos])
     60 			if !ok {
     61 				return "", punyError(encoded)
     62 			}
     63 			pos++
     64 			i, overflow = madd(i, digit, w)
     65 			if overflow {
     66 				return "", punyError(encoded)
     67 			}
     68 			t := k - bias
     69 			if k <= bias {
     70 				t = tmin
     71 			} else if k >= bias+tmax {
     72 				t = tmax
     73 			}
     74 			if digit < t {
     75 				break
     76 			}
     77 			w, overflow = madd(0, w, base-t)
     78 			if overflow {
     79 				return "", punyError(encoded)
     80 			}
     81 		}
     82 		if len(output) >= 1024 {
     83 			return "", punyError(encoded)
     84 		}
     85 		x := int32(len(output) + 1)
     86 		bias = adapt(i-oldI, x, oldI == 0)
     87 		n += i / x
     88 		i %= x
     89 		if n < 0 || n > utf8.MaxRune {
     90 			return "", punyError(encoded)
     91 		}
     92 		output = append(output, 0)
     93 		copy(output[i+1:], output[i:])
     94 		output[i] = n
     95 		i++
     96 	}
     97 	return string(output), nil
     98 }
     99 
    100 // encode encodes a string as specified in section 6.3 and prepends prefix to
    101 // the result.
    102 //
    103 // The "while h < length(input)" line in the specification becomes "for
    104 // remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
    105 func encode(prefix, s string) (string, error) {
    106 	output := make([]byte, len(prefix), len(prefix)+1+2*len(s))
    107 	copy(output, prefix)
    108 	delta, n, bias := int32(0), initialN, initialBias
    109 	b, remaining := int32(0), int32(0)
    110 	for _, r := range s {
    111 		if r < 0x80 {
    112 			b++
    113 			output = append(output, byte(r))
    114 		} else {
    115 			remaining++
    116 		}
    117 	}
    118 	h := b
    119 	if b > 0 {
    120 		output = append(output, '-')
    121 	}
    122 	overflow := false
    123 	for remaining != 0 {
    124 		m := int32(0x7fffffff)
    125 		for _, r := range s {
    126 			if m > r && r >= n {
    127 				m = r
    128 			}
    129 		}
    130 		delta, overflow = madd(delta, m-n, h+1)
    131 		if overflow {
    132 			return "", punyError(s)
    133 		}
    134 		n = m
    135 		for _, r := range s {
    136 			if r < n {
    137 				delta++
    138 				if delta < 0 {
    139 					return "", punyError(s)
    140 				}
    141 				continue
    142 			}
    143 			if r > n {
    144 				continue
    145 			}
    146 			q := delta
    147 			for k := base; ; k += base {
    148 				t := k - bias
    149 				if k <= bias {
    150 					t = tmin
    151 				} else if k >= bias+tmax {
    152 					t = tmax
    153 				}
    154 				if q < t {
    155 					break
    156 				}
    157 				output = append(output, encodeDigit(t+(q-t)%(base-t)))
    158 				q = (q - t) / (base - t)
    159 			}
    160 			output = append(output, encodeDigit(q))
    161 			bias = adapt(delta, h+1, h == b)
    162 			delta = 0
    163 			h++
    164 			remaining--
    165 		}
    166 		delta++
    167 		n++
    168 	}
    169 	return string(output), nil
    170 }
    171 
    172 // madd computes a + (b * c), detecting overflow.
    173 func madd(a, b, c int32) (next int32, overflow bool) {
    174 	p := int64(b) * int64(c)
    175 	if p > math.MaxInt32-int64(a) {
    176 		return 0, true
    177 	}
    178 	return a + int32(p), false
    179 }
    180 
    181 func decodeDigit(x byte) (digit int32, ok bool) {
    182 	switch {
    183 	case '0' <= x && x <= '9':
    184 		return int32(x - ('0' - 26)), true
    185 	case 'A' <= x && x <= 'Z':
    186 		return int32(x - 'A'), true
    187 	case 'a' <= x && x <= 'z':
    188 		return int32(x - 'a'), true
    189 	}
    190 	return 0, false
    191 }
    192 
    193 func encodeDigit(digit int32) byte {
    194 	switch {
    195 	case 0 <= digit && digit < 26:
    196 		return byte(digit + 'a')
    197 	case 26 <= digit && digit < 36:
    198 		return byte(digit + ('0' - 26))
    199 	}
    200 	panic("idna: internal error in punycode encoding")
    201 }
    202 
    203 // adapt is the bias adaptation function specified in section 6.1.
    204 func adapt(delta, numPoints int32, firstTime bool) int32 {
    205 	if firstTime {
    206 		delta /= damp
    207 	} else {
    208 		delta /= 2
    209 	}
    210 	delta += delta / numPoints
    211 	k := int32(0)
    212 	for delta > ((base-tmin)*tmax)/2 {
    213 		delta /= base - tmin
    214 		k += base
    215 	}
    216 	return k + (base-tmin+1)*delta/(delta+skew)
    217 }