github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/golang/text/secure/precis/nickname.go (about) 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 "github.com/insionng/yougam/libraries/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 }