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  }