11// IMAP4rev1 uses a modified version of UTF-7.
 
15const utf7chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"
 
17var utf7encoding = base64.NewEncoding(utf7chars).WithPadding(base64.NoPadding)
 
20	errUTF7SuperfluousShift = errors.New("utf7: superfluous unshift+shift")
 
21	errUTF7Base64           = errors.New("utf7: bad base64")
 
22	errUTF7OddSized         = errors.New("utf7: odd-sized data")
 
23	errUTF7UnneededShift    = errors.New("utf7: unneeded shift")
 
24	errUTF7UnfinishedShift  = errors.New("utf7: unfinished shift")
 
25	errUTF7BadSurrogate     = errors.New("utf7: bad utf16 surrogates")
 
28func utf7decode(s string) (string, error) {
 
37				if lastunshift == i-1 {
 
38					return "", errUTF7SuperfluousShift
 
58		buf, err := utf7encoding.DecodeString(b)
 
60			return "", fmt.Errorf("%w: %q: %v", errUTF7Base64, b, err)
 
65			return "", errUTF7OddSized
 
68		x := make([]rune, len(buf)/2)
 
71		for i := 0; i < len(buf); i += 2 {
 
72			x[j] = rune(buf[i])<<8 | rune(buf[i+1])
 
74				s0 := utf16.IsSurrogate(x[j-1])
 
75				s1 := utf16.IsSurrogate(x[j])
 
77					c := utf16.DecodeRune(x[j-1], x[j])
 
79						return "", fmt.Errorf("%w: decoding %x %x", errUTF7BadSurrogate, x[j-1], x[j])
 
85					return "", fmt.Errorf("%w: not both surrogate: %x %x", errUTF7BadSurrogate, x[j-1], x[j])
 
94			if c < 0x20 || c > 0x7e || c == '&' {
 
98				return "", errUTF7UnneededShift
 
103		return "", errUTF7UnfinishedShift
 
108func utf7encode(s string) string {
 
112	flushcode := func() {
 
117		for _, c := range code {
 
118			high, low := utf16.EncodeRune(c)
 
119			if high == 0xfffd && low == 0xfffd {
 
120				b.WriteByte(byte(c >> 8))
 
121				b.WriteByte(byte(c >> 0))
 
123				b.WriteByte(byte(high >> 8))
 
124				b.WriteByte(byte(high >> 0))
 
125				b.WriteByte(byte(low >> 8))
 
126				b.WriteByte(byte(low >> 0))
 
129		r += "&" + utf7encoding.EncodeToString(b.Bytes()) + "-"
 
133	for _, c := range s {
 
137		} else if c >= ' ' && c < 0x7f {