github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgGoSource/kmgGoReader/reader.go (about)

     1  package kmgGoReader
     2  
     3  import (
     4  	"bytes"
     5  	"unicode"
     6  	"unicode/utf8"
     7  )
     8  
     9  type Reader struct {
    10  	buf     []byte //需要读入的数据
    11  	pos     int    //当前位置
    12  	filePos *FilePos
    13  }
    14  
    15  func NewReader(buf []byte, filePos *FilePos) *Reader {
    16  	return &Reader{
    17  		buf:     buf,
    18  		filePos: filePos,
    19  	}
    20  }
    21  
    22  func NewReaderWithPosFile(filename string, content []byte) *Reader {
    23  	pos := NewPosFile(filename, content)
    24  	return NewReader(content, pos)
    25  }
    26  
    27  func (r *Reader) Pos() int {
    28  	return r.pos
    29  }
    30  func (r *Reader) BufToCurrent(start int) []byte {
    31  	return r.buf[start:r.pos]
    32  }
    33  
    34  func (r *Reader) IsEof() bool {
    35  	return r.pos >= len(r.buf)
    36  }
    37  func (r *Reader) ReadByte() byte {
    38  	//if r.IsEof() {
    39  	//	panic(r.GetFileLineInfo() + " unexcept EOF")
    40  	//}
    41  	out := r.buf[r.pos]
    42  	r.pos++
    43  	return out
    44  }
    45  
    46  func (r *Reader) NextByte() byte {
    47  	return r.buf[r.pos]
    48  }
    49  
    50  func (r *Reader) IsMatchAfter(s []byte) bool {
    51  	return len(r.buf)-r.pos >= len(s) && r.buf[r.pos] == s[0] && bytes.Equal(r.buf[r.pos:r.pos+len(s)], s)
    52  }
    53  
    54  // 读取到某个字符,或者读取到结束(该字符会已经被读过)
    55  func (r *Reader) ReadUntilByte(b byte) []byte {
    56  	startPos := r.pos
    57  	for {
    58  		if r.IsEof() {
    59  			return r.buf[startPos:]
    60  		}
    61  		if r.ReadByte() == b {
    62  			return r.buf[startPos:r.pos]
    63  		}
    64  	}
    65  }
    66  
    67  // 回调返回真的时候,停止读取,(这个回调提到的字符串也包含在内)
    68  func (r *Reader) ReadUntilRuneCb(cb func(run rune) bool) []byte {
    69  	startPos := r.pos
    70  	for {
    71  		if r.IsEof() {
    72  			return r.buf[startPos:]
    73  		}
    74  		run, size := utf8.DecodeRune(r.buf[r.pos:])
    75  		r.pos += size
    76  		if cb(run) {
    77  			return r.buf[startPos:r.pos]
    78  		}
    79  	}
    80  }
    81  
    82  // 读取到某个字符串,或者读取到结束(该字符串会已经被读过)
    83  func (r *Reader) ReadUntilString(s []byte) []byte {
    84  	startPos := r.pos
    85  	for {
    86  		if r.IsEof() {
    87  			return r.buf[startPos:]
    88  		}
    89  		if r.IsMatchAfter(s) {
    90  			r.pos += len(s)
    91  			return r.buf[startPos:r.pos]
    92  		}
    93  		r.pos++
    94  	}
    95  }
    96  
    97  func (r *Reader) ReadAllSpace() {
    98  	for {
    99  		if r.IsEof() {
   100  			return
   101  		}
   102  		run, size := utf8.DecodeRune(r.buf[r.pos:])
   103  		if !unicode.IsSpace(run) {
   104  			return
   105  		}
   106  		r.pos += size
   107  	}
   108  }
   109  
   110  func (r *Reader) ReadAllSpaceWithoutLineBreak() {
   111  	for {
   112  		if r.IsEof() {
   113  			return
   114  		}
   115  		run, size := utf8.DecodeRune(r.buf[r.pos:])
   116  		if unicode.IsSpace(run) && run != '\n' {
   117  			r.pos += size
   118  		} else {
   119  			return
   120  		}
   121  	}
   122  }
   123  
   124  func (r *Reader) ReadRune() rune {
   125  	run, size := utf8.DecodeRune(r.buf[r.pos:])
   126  	r.pos += size
   127  	return run
   128  }
   129  
   130  func (r *Reader) UnreadRune() rune {
   131  	run, size := utf8.DecodeLastRune(r.buf[:r.pos])
   132  	if size == 0 {
   133  		panic(r.GetFileLineInfo() + " [UnreadRune] last is not valid utf8 code.")
   134  	}
   135  	r.pos -= size
   136  	return run
   137  }
   138  
   139  func (r *Reader) UnreadByte() {
   140  	r.pos -= 1
   141  }
   142  
   143  func (r *Reader) MustReadMatch(s []byte) {
   144  	if !r.IsMatchAfter(s) {
   145  		panic(r.GetFileLineInfo() + " [MustReadMatch] not match " + string(s))
   146  	}
   147  	r.pos += len(s)
   148  }
   149  
   150  func (r *Reader) MustReadWithSize(size int) []byte {
   151  	if r.IsEof() {
   152  		panic(r.GetFileLineInfo() + " unexpect EOF")
   153  	}
   154  	output := r.buf[r.pos : r.pos+size]
   155  	r.pos += size
   156  	return output
   157  }
   158  
   159  func (r *Reader) GetFileLineInfo() string {
   160  	return r.filePos.PosString(r.pos)
   161  }