OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / text / secure / precis / nickname.go
1 // Copyright 2015 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package precis
6
7 import (
8         "unicode"
9         "unicode/utf8"
10
11         "golang.org/x/text/transform"
12 )
13
14 type nickAdditionalMapping struct {
15         // TODO: This transformer needs to be stateless somehow…
16         notStart  bool
17         prevSpace bool
18 }
19
20 func (t *nickAdditionalMapping) Reset() {
21         t.prevSpace = false
22         t.notStart = false
23 }
24
25 func (t *nickAdditionalMapping) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
26         // RFC 7700 §2.1.  Rules
27         //
28         // 2.  Additional Mapping Rule: The additional mapping rule consists of
29         //                              the following sub-rules.
30         //
31         //        1.  Any instances of non-ASCII space MUST be mapped to ASCII
32         //            space (U+0020); a non-ASCII space is any Unicode code point
33         //            having a general category of "Zs", naturally with the
34         //            exception of U+0020.
35         //
36         //        2.  Any instances of the ASCII space character at the beginning
37         //            or end of a nickname MUST be removed (e.g., "stpeter " is
38         //            mapped to "stpeter").
39         //
40         //        3.  Interior sequences of more than one ASCII space character
41         //            MUST be mapped to a single ASCII space character (e.g.,
42         //            "St  Peter" is mapped to "St Peter").
43
44         for nSrc < len(src) {
45                 r, size := utf8.DecodeRune(src[nSrc:])
46                 if size == 0 { // Incomplete UTF-8 encoding
47                         if !atEOF {
48                                 return nDst, nSrc, transform.ErrShortSrc
49                         }
50                         size = 1
51                 }
52                 if unicode.Is(unicode.Zs, r) {
53                         t.prevSpace = true
54                 } else {
55                         if t.prevSpace && t.notStart {
56                                 dst[nDst] = ' '
57                                 nDst += 1
58                         }
59                         if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
60                                 nDst += size
61                                 return nDst, nSrc, transform.ErrShortDst
62                         }
63                         nDst += size
64                         t.prevSpace = false
65                         t.notStart = true
66                 }
67                 nSrc += size
68         }
69         return nDst, nSrc, nil
70 }