encode encodes a string as specified in section 6.3 and prepends prefix to the result. The "while h < length(input)" line in the specification becomes "for remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
(prefix, s string)
| 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 unicode16 && r == 0xfffd { |
| 112 | return s, &labelError{s, "A3"} |
| 113 | } |
| 114 | if r < 0x80 { |
| 115 | b++ |
| 116 | output = append(output, byte(r)) |
| 117 | } else { |
| 118 | remaining++ |
| 119 | } |
| 120 | } |
| 121 | h := b |
| 122 | if b > 0 { |
| 123 | output = append(output, '-') |
| 124 | } |
| 125 | overflow := false |
| 126 | for remaining != 0 { |
| 127 | m := int32(0x7fffffff) |
| 128 | for _, r := range s { |
| 129 | if m > r && r >= n { |
| 130 | m = r |
| 131 | } |
| 132 | } |
| 133 | delta, overflow = madd(delta, m-n, h+1) |
| 134 | if overflow { |
| 135 | return "", punyError(s) |
| 136 | } |
| 137 | n = m |
| 138 | for _, r := range s { |
| 139 | if r < n { |
| 140 | delta++ |
| 141 | if delta < 0 { |
| 142 | return "", punyError(s) |
| 143 | } |
| 144 | continue |
| 145 | } |
| 146 | if r > n { |
| 147 | continue |
| 148 | } |
| 149 | q := delta |
| 150 | for k := base; ; k += base { |
| 151 | t := k - bias |
| 152 | if k <= bias { |
| 153 | t = tmin |
| 154 | } else if k >= bias+tmax { |
| 155 | t = tmax |
| 156 | } |
| 157 | if q < t { |
| 158 | break |
| 159 | } |
| 160 | output = append(output, encodeDigit(t+(q-t)%(base-t))) |
| 161 | q = (q - t) / (base - t) |
| 162 | } |
searching dependent graphs…