github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/mahonia/convert_string.go (about)

     1  package mahonia
     2  
     3  import (
     4  	"unicode/utf8"
     5  )
     6  
     7  // ConvertString converts a  string from UTF-8 to e's encoding.
     8  func (e Encoder) ConvertString(s string) string {
     9  	dest := make([]byte, len(s)+10)
    10  	destPos := 0
    11  
    12  	for _, rune := range s {
    13  	retry:
    14  		size, status := e(dest[destPos:], rune)
    15  
    16  		if status == NO_ROOM {
    17  			newDest := make([]byte, len(dest)*2)
    18  			copy(newDest, dest)
    19  			dest = newDest
    20  			goto retry
    21  		}
    22  
    23  		if status == STATE_ONLY {
    24  			destPos += size
    25  			goto retry
    26  		}
    27  
    28  		destPos += size
    29  	}
    30  
    31  	return string(dest[:destPos])
    32  }
    33  
    34  // ConvertString converts a string from d's encoding to UTF-8.
    35  func (d Decoder) ConvertString(s string) string {
    36  	bytes := []byte(s)
    37  	runes := make([]rune, len(s))
    38  	destPos := 0
    39  
    40  	for len(bytes) > 0 {
    41  		c, size, status := d(bytes)
    42  
    43  		if status == STATE_ONLY {
    44  			bytes = bytes[size:]
    45  			continue
    46  		}
    47  
    48  		if status == NO_ROOM {
    49  			c = 0xfffd
    50  			size = len(bytes)
    51  			status = INVALID_CHAR
    52  		}
    53  
    54  		bytes = bytes[size:]
    55  		runes[destPos] = c
    56  		destPos++
    57  	}
    58  
    59  	return string(runes[:destPos])
    60  }
    61  
    62  // ConvertStringOK converts a  string from UTF-8 to e's encoding. It also
    63  // returns a boolean indicating whether every character was converted
    64  // successfully.
    65  func (e Encoder) ConvertStringOK(s string) (result string, ok bool) {
    66  	dest := make([]byte, len(s)+10)
    67  	destPos := 0
    68  	ok = true
    69  
    70  	for i, r := range s {
    71  		// The following test is copied from utf8.ValidString.
    72  		if r == utf8.RuneError && ok {
    73  			_, size := utf8.DecodeRuneInString(s[i:])
    74  			if size == 1 {
    75  				ok = false
    76  			}
    77  		}
    78  
    79  	retry:
    80  		size, status := e(dest[destPos:], r)
    81  
    82  		switch status {
    83  		case NO_ROOM:
    84  			newDest := make([]byte, len(dest)*2)
    85  			copy(newDest, dest)
    86  			dest = newDest
    87  			goto retry
    88  
    89  		case STATE_ONLY:
    90  			destPos += size
    91  			goto retry
    92  
    93  		case INVALID_CHAR:
    94  			ok = false
    95  		}
    96  
    97  		destPos += size
    98  	}
    99  
   100  	return string(dest[:destPos]), ok
   101  }
   102  
   103  // ConvertStringOK converts a string from d's encoding to UTF-8.
   104  // It also returns a boolean indicating whether every character was converted
   105  // successfully.
   106  func (d Decoder) ConvertStringOK(s string) (result string, ok bool) {
   107  	bytes := []byte(s)
   108  	runes := make([]rune, len(s))
   109  	destPos := 0
   110  	ok = true
   111  
   112  	for len(bytes) > 0 {
   113  		c, size, status := d(bytes)
   114  
   115  		switch status {
   116  		case STATE_ONLY:
   117  			bytes = bytes[size:]
   118  			continue
   119  
   120  		case NO_ROOM:
   121  			c = 0xfffd
   122  			size = len(bytes)
   123  			ok = false
   124  
   125  		case INVALID_CHAR:
   126  			ok = false
   127  		}
   128  
   129  		bytes = bytes[size:]
   130  		runes[destPos] = c
   131  		destPos++
   132  	}
   133  
   134  	return string(runes[:destPos]), ok
   135  }