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  }