github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/third_party/code.google.com/p/go-charset/charset/big5.go (about)

     1  package charset
     2  
     3  import (
     4  	"fmt"
     5  	"unicode/utf8"
     6  )
     7  
     8  func init() {
     9  	registerClass("big5", fromBig5, nil)
    10  }
    11  
    12  // Big5 consists of 89 fonts of 157 chars each
    13  const (
    14  	big5Max  = 13973
    15  	big5Font = 157
    16  	big5Data = "big5.dat"
    17  )
    18  
    19  type translateFromBig5 struct {
    20  	font    int
    21  	scratch []byte
    22  	big5map []rune
    23  }
    24  
    25  func (p *translateFromBig5) Translate(data []byte, eof bool) (int, []byte, error) {
    26  	p.scratch = p.scratch[:0]
    27  	n := 0
    28  	for len(data) > 0 {
    29  		c := int(data[0])
    30  		data = data[1:]
    31  		n++
    32  		if p.font == -1 {
    33  			// idle state
    34  			if c >= 0xa1 {
    35  				p.font = c
    36  				continue
    37  			}
    38  			if c == 26 {
    39  				c = '\n'
    40  			}
    41  			continue
    42  		}
    43  		f := p.font
    44  		p.font = -1
    45  		r := utf8.RuneError
    46  		switch {
    47  		case c >= 64 && c <= 126:
    48  			c -= 64
    49  		case c >= 161 && c <= 254:
    50  			c = c - 161 + 63
    51  		default:
    52  			// bad big5 char
    53  			f = 255
    54  		}
    55  		if f <= 254 {
    56  			f -= 161
    57  			ix := f*big5Font + c
    58  			if ix < len(p.big5map) {
    59  				r = p.big5map[ix]
    60  			}
    61  			if r == -1 {
    62  				r = utf8.RuneError
    63  			}
    64  		}
    65  		p.scratch = appendRune(p.scratch, r)
    66  	}
    67  	return n, p.scratch, nil
    68  }
    69  
    70  type big5Key bool
    71  
    72  func fromBig5(arg string) (Translator, error) {
    73  	big5map, err := cache(big5Key(false), func() (interface{}, error) {
    74  		data, err := readFile(big5Data)
    75  		if err != nil {
    76  			return nil, fmt.Errorf("charset: cannot open big5 data file: %v", err)
    77  		}
    78  		big5map := []rune(string(data))
    79  		if len(big5map) != big5Max {
    80  			return nil, fmt.Errorf("charset: corrupt big5 data")
    81  		}
    82  		return big5map, nil
    83  	})
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  	return &translateFromBig5{big5map: big5map.([]rune), font: -1}, nil
    88  }