github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/network/debinterfaces/scanner.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package debinterfaces 5 6 import ( 7 "bufio" 8 "bytes" 9 "errors" 10 "io" 11 "io/ioutil" 12 "strings" 13 ) 14 15 type lineScanner struct { 16 filename string // underlying source of lines[], if any 17 lines []string // all lines; never mutated 18 line string // current line 19 n int // current index into lines[] 20 max int // len(lines) 21 } 22 23 func newScanner(filename string, src interface{}) (*lineScanner, error) { 24 if filename == "" && src == nil { 25 return nil, errors.New("filename and input is nil") 26 } 27 28 content, err := readSource(filename, src) 29 30 if err != nil { 31 return nil, err 32 } 33 34 lines := readLines(bytes.NewReader(content)) 35 36 return &lineScanner{ 37 filename: filename, 38 lines: lines, 39 max: len(lines), 40 }, nil 41 } 42 43 // If src != nil, readSource converts src to a []byte if possible, 44 // otherwise it returns an error. If src == nil, readSource returns 45 // the result of reading the file specified by filename. 46 func readSource(filename string, src interface{}) ([]byte, error) { 47 if src == nil { 48 return ioutil.ReadFile(filename) 49 } 50 switch s := src.(type) { 51 case string: 52 return []byte(s), nil 53 } 54 return nil, errors.New("invalid source type") 55 } 56 57 func readLines(rdr io.Reader) []string { 58 lines := make([]string, 0) 59 scanner := bufio.NewScanner(rdr) 60 61 for scanner.Scan() { 62 lines = append(lines, scanner.Text()) 63 } 64 65 return lines 66 } 67 68 func (s *lineScanner) nextLine() bool { 69 for { 70 if s.n == s.max { 71 return false 72 } 73 s.line = strings.TrimSpace(s.lines[s.n]) 74 s.n++ 75 if strings.HasPrefix(s.line, "#") || s.line == "" { 76 continue 77 } 78 return true 79 } 80 }