OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / idna / punycode.go
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         for pos < len(encoded) {
53                 oldI, w := i, int32(1)
54                 for k := base; ; k += base {
55                         if pos == len(encoded) {
56                                 return "", punyError(encoded)
57                         }
58                         digit, ok := decodeDigit(encoded[pos])
59                         if !ok {
60                                 return "", punyError(encoded)
61                         }
62                         pos++
63                         i += digit * w
64                         if i < 0 {
65                                 return "", punyError(encoded)
66                         }
67                         t := k - bias
68                         if t < tmin {
69                                 t = tmin
70                         } else if t > tmax {
71                                 t = tmax
72                         }
73                         if digit < t {
74                                 break
75                         }
76                         w *= base - t
77                         if w >= math.MaxInt32/base {
78                                 return "", punyError(encoded)
79                         }
80                 }
81                 x := int32(len(output) + 1)
82                 bias = adapt(i-oldI, x, oldI == 0)
83                 n += i / x
84                 i %= x
85                 if n > utf8.MaxRune || len(output) >= 1024 {
86                         return "", punyError(encoded)
87                 }
88                 output = append(output, 0)
89                 copy(output[i+1:], output[i:])
90                 output[i] = n
91                 i++
92         }
93         return string(output), nil
94 }
95
96 // encode encodes a string as specified in section 6.3 and prepends prefix to
97 // the result.
98 //
99 // The "while h < length(input)" line in the specification becomes "for
100 // remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
101 func encode(prefix, s string) (string, error) {
102         output := make([]byte, len(prefix), len(prefix)+1+2*len(s))
103         copy(output, prefix)
104         delta, n, bias := int32(0), initialN, initialBias
105         b, remaining := int32(0), int32(0)
106         for _, r := range s {
107                 if r < 0x80 {
108                         b++
109                         output = append(output, byte(r))
110                 } else {
111                         remaining++
112                 }
113         }
114         h := b
115         if b > 0 {
116                 output = append(output, '-')
117         }
118         for remaining != 0 {
119                 m := int32(0x7fffffff)
120                 for _, r := range s {
121                         if m > r && r >= n {
122                                 m = r
123                         }
124                 }
125                 delta += (m - n) * (h + 1)
126                 if delta < 0 {
127                         return "", punyError(s)
128                 }
129                 n = m
130                 for _, r := range s {
131                         if r < n {
132                                 delta++
133                                 if delta < 0 {
134                                         return "", punyError(s)
135                                 }
136                                 continue
137                         }
138                         if r > n {
139                                 continue
140                         }
141                         q := delta
142                         for k := base; ; k += base {
143                                 t := k - bias
144                                 if t < tmin {
145                                         t = tmin
146                                 } else if t > tmax {
147                                         t = tmax
148                                 }
149                                 if q < t {
150                                         break
151                                 }
152                                 output = append(output, encodeDigit(t+(q-t)%(base-t)))
153                                 q = (q - t) / (base - t)
154                         }
155                         output = append(output, encodeDigit(q))
156                         bias = adapt(delta, h+1, h == b)
157                         delta = 0
158                         h++
159                         remaining--
160                 }
161                 delta++
162                 n++
163         }
164         return string(output), nil
165 }
166
167 func decodeDigit(x byte) (digit int32, ok bool) {
168         switch {
169         case '0' <= x && x <= '9':
170                 return int32(x - ('0' - 26)), true
171         case 'A' <= x && x <= 'Z':
172                 return int32(x - 'A'), true
173         case 'a' <= x && x <= 'z':
174                 return int32(x - 'a'), true
175         }
176         return 0, false
177 }
178
179 func encodeDigit(digit int32) byte {
180         switch {
181         case 0 <= digit && digit < 26:
182                 return byte(digit + 'a')
183         case 26 <= digit && digit < 36:
184                 return byte(digit + ('0' - 26))
185         }
186         panic("idna: internal error in punycode encoding")
187 }
188
189 // adapt is the bias adaptation function specified in section 6.1.
190 func adapt(delta, numPoints int32, firstTime bool) int32 {
191         if firstTime {
192                 delta /= damp
193         } else {
194                 delta /= 2
195         }
196         delta += delta / numPoints
197         k := int32(0)
198         for delta > ((base-tmin)*tmax)/2 {
199                 delta /= base - tmin
200                 k += base
201         }
202         return k + (base-tmin+1)*delta/(delta+skew)
203 }