Beispiel #1
0
// ParseNumber parses and returns a positive integer.
// Leading spaces are ignored.
// If EOF is reached before any digits are encountered, 1 is returned.
func parseNumber(rs io.RuneScanner) (int, error) {
	if err := skipSpace(rs); err != nil {
		return 0, err
	}
	var s string
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			break
		case err != nil:
			return 0, err
		case unicode.IsDigit(r):
			s += string(r)
			continue
		default:
			if err := rs.UnreadRune(); err != nil {
				return 0, err
			}
		}

		if len(s) == 0 {
			return 1, nil
		}
		return strconv.Atoi(s)
	}
}
Beispiel #2
0
// ParseDelimited returns the string
// up to the first unescaped delimiter,
// raw newline (rune 0xA),
// or the end of input.
// A delimiter preceeded by \ is escaped and is non-terminating.
// The letter n preceeded by \ is a newline literal.
func parseDelimited(delim rune, rs io.RuneScanner) (string, error) {
	var s string
	var esc bool
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return s, nil
		case err != nil:
			return "", err
		case esc && r == delim:
			s += string(delim)
			esc = false
		case r == delim || r == '\n':
			return s, nil
		case !esc && r == '\\':
			esc = true
		case esc && r == 'n':
			s += "\n"
			esc = false
		default:
			if esc {
				s += "\\"
			}
			s += string(r)
			esc = false
		}
	}
}
Beispiel #3
0
// readStructuredData reads a STRUCTURED-DATA (as defined in RFC-5424)
// from `r` and assigns the StructuredData member.
//
// STRUCTURED-DATA = NILVALUE / 1*SD-ELEMENT
// SD-ELEMENT      = "[" SD-ID *(SP SD-PARAM) "]"
// SD-PARAM        = PARAM-NAME "=" %d34 PARAM-VALUE %d34
// SD-ID           = SD-NAME
// PARAM-NAME      = SD-NAME
// PARAM-VALUE     = UTF-8-STRING ; characters '"', '\' and ']' MUST be escaped.
// SD-NAME         = 1*32PRINTUSASCII except '=', SP, ']', %d34 (")
func (m *Message) readStructuredData(r io.RuneScanner) (err error) {
	m.StructuredData = []StructuredData{}

	ch, _, err := r.ReadRune()
	if err != nil {
		return err
	}
	if ch == '-' {
		return nil
	}
	r.UnreadRune()

	for {
		ch, _, err := r.ReadRune()
		if err == io.EOF {
			return nil
		} else if err != nil {
			return err // hard to reach without underlying IO error
		} else if ch == ' ' {
			r.UnreadRune()
			return nil
		} else if ch == '[' {
			r.UnreadRune()
			sde, err := readSDElement(r)
			if err != nil {
				return err
			}
			m.StructuredData = append(m.StructuredData, sde)
		} else {
			return BadFormat("StructuredData")
		}
	}
}
Beispiel #4
0
func parseCmd(rs io.RuneScanner) (string, error) {
	if err := skipSpace(rs); err != nil {
		return "", err
	}
	var esc bool
	var cmd string
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return cmd, nil
		case err != nil:
			return "", nil
		case r == '\n':
			return cmd, nil
		case r == '\\':
			esc = true
		case esc && r == 'n':
			cmd += "\n"
			esc = false
		default:
			if esc {
				cmd += "\\"
			}
			cmd += string(r)
			esc = false
		}
	}
}
Beispiel #5
0
// like in.ReadRune() but ignore all leading whitespace.
func ReadChar(in io.RuneScanner) (r rune, size int, err error) {
	r, size, err = in.ReadRune()
	for unicode.IsSpace(r) && err == nil {
		r, size, err = in.ReadRune()
	}
	return
}
Beispiel #6
0
// readSDElement reads an SD-ELEMENT as defined by RFC-5424
//
// SD-ELEMENT      = "[" SD-ID *(SP SD-PARAM) "]"
// SD-PARAM        = PARAM-NAME "=" %d34 PARAM-VALUE %d34
// SD-ID           = SD-NAME
// PARAM-NAME      = SD-NAME
// PARAM-VALUE     = UTF-8-STRING ; characters '"', '\' and ']' MUST be escaped.
// SD-NAME         = 1*32PRINTUSASCII except '=', SP, ']', %d34 (")
func readSDElement(r io.RuneScanner) (element StructuredData, err error) {
	ch, _, err := r.ReadRune()
	if err != nil {
		return element, err // hard to reach without underlying IO error
	}
	if ch != '[' {
		return element, BadFormat("StructuredData[]") // unreachable
	}
	element.ID, err = readSdID(r)
	if err != nil {
		return element, err
	}
	for {
		ch, _, err := r.ReadRune()
		if err != nil {
			return element, err
		} else if ch == ']' {
			return element, nil
		} else if ch == ' ' {
			param, err := readSdParam(r)
			if err != nil {
				return element, err
			}
			element.Parameters = append(element.Parameters, *param)
		} else {
			return element, BadFormat("StructuredData[]")
		}
	}
}
Beispiel #7
0
// readPriority reads the PRI as defined in RFC-5424 and assigns Severity and
// Facility accordingly.
func (m *Message) readPriority(r io.RuneScanner) error {
	ch, _, err := r.ReadRune()
	if err != nil {
		return err
	}
	if ch != '<' {
		return BadFormat("Priority")
	}

	rv := &bytes.Buffer{}
	for {
		ch, _, err := r.ReadRune()
		if err != nil {
			return err
		}
		if unicode.IsDigit(ch) {
			rv.WriteRune(ch)
			continue
		}
		if ch != '>' {
			return BadFormat("Priority")
		}

		// We have a complete integer expression
		priority, err := strconv.ParseInt(string(rv.Bytes()), 10, 32)
		if err != nil {
			return BadFormat("Priority")
		}
		m.Priority = int(priority)
		return nil

	}
}
Beispiel #8
0
func readRune(r io.RuneScanner) int {
	rune, _, err := r.ReadRune()
	if err != nil {
		return -1
	}
	return rune
}
Beispiel #9
0
func parseCompoundAddr(rs io.RuneScanner) (Address, error) {
	var a1 Address
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return a1, nil
		case err != nil:
			return nil, err
		case strings.ContainsRune(simpleFirst, r):
			if err := rs.UnreadRune(); err != nil {
				return nil, err
			}
			switch a2, err := parseSimpleAddr(rs); {
			case err != nil:
				return nil, err
			case a1 != nil:
				a1 = a1.Plus(a2)
			default:
				a1 = a2
			}
		case r == '+' || r == '-':
			if a1 == nil {
				a1 = Dot
			}
			a2, err := parseSimpleAddr(rs)
			if a2 == nil {
				a2 = Line(1)
			}
			switch {
			case err != nil:
				return nil, err
			case r == '+':
				a1 = a1.Plus(a2)
			default:
				a1 = a1.Minus(a2)
			}
		case r == ',' || r == ';':
			if a1 == nil {
				a1 = Line(0)
			}
			a2, err := parseCompoundAddr(rs)
			if a2 == nil {
				a2 = End
			}
			switch {
			case err != nil:
				return nil, err
			case r == ',':
				a1 = a1.To(a2)
			default:
				a1 = a1.Then(a2)
			}
		case unicode.IsSpace(r) && r != '\n':
			continue
		default:
			return a1, rs.UnreadRune()
		}
	}
}
Beispiel #10
0
// readSpace reads a single space
func readSpace(r io.RuneScanner) error {
	ch, _, err := r.ReadRune()
	if err != nil {
		return err
	}
	if ch != ' ' {
		return BadFormat("expected space")
	}
	return nil
}
Beispiel #11
0
// readVersion reads the version string fails if it isn't `1`
func (m *Message) readVersion(r io.RuneScanner) error {
	ch, _, err := r.ReadRune()
	if err != nil {
		return err
	}
	if ch != '1' {
		return BadFormat("Version")
	}
	return nil
}
Beispiel #12
0
func chompBOM(r io.RuneScanner) (err error) {
	for {
		c, _, err := r.ReadRune()
		if err != nil {
			return err
		}
		if c != BOM {
			r.UnreadRune()
			return nil
		}
	}
}
Beispiel #13
0
func chompWhitespace(r io.RuneScanner) (err error) {
	for {
		c, _, err := r.ReadRune()
		if err != nil {
			return err
		}
		if !unicode.IsSpace(c) {
			r.UnreadRune()
			return nil
		}
	}
}
Beispiel #14
0
func skipSingleNewline(rs io.RuneScanner) error {
	// Eat a single trailing newline.
	switch r, _, err := rs.ReadRune(); {
	case err == io.EOF:
		return nil
	case err != nil:
		return err
	case r == '\n':
		return nil
	default:
		return rs.UnreadRune()
	}
}
Beispiel #15
0
func readNumber(b int, r io.RuneScanner) string {
	s := string(b)
	rune, _, err := r.ReadRune()
	for err == nil && string(rune) != " " && string(rune) != "(" && string(rune) != ")" {
		s = s + string(rune)
		rune, _, err = r.ReadRune()
	}
	if err == nil {
		r.UnreadRune()
	}

	return s
}
Beispiel #16
0
func (d *Dec) scan(r io.RuneScanner) error {
	d.coef.hi = 0
	d.coef.lo = 0
	d.scale = 0
	ch, _, err := r.ReadRune()
	if err != nil {
		return err
	}
	var neg bool
	switch ch {
	case '-':
		neg = true
	case '+':
	default:
		r.UnreadRune()
	}
	var dec bool
	for {
		ch, _, err = r.ReadRune()
		if err == io.EOF {
			goto ExitLoop
		}
		if err != nil {
			return err
		}
		switch {
		case ch == '.':
			if dec {
				r.UnreadRune()
				goto ExitLoop
			}
			dec = true
		case ch >= '0' && ch <= '9':
			d.coef.Mul(&d.coef, intTen)
			var z Int128
			z.SetInt64(int64(ch - '0'))
			d.coef.Add(&d.coef, &z)
			if dec {
				d.scale++
			}
		default:
			r.UnreadRune()
			goto ExitLoop
		}
	}
ExitLoop:
	if neg {
		d.Neg(d)
	}
	return nil
}
Beispiel #17
0
// readSdParam reads a PARAM-NAME as defined by RFC-5424
// SD-PARAM        = PARAM-NAME "=" %d34 PARAM-VALUE %d34
// PARAM-NAME      = SD-NAME
// SD-NAME         = 1*32PRINTUSASCII except '=', SP, ']', %d34 (")
func readSdParamName(r io.RuneScanner) (string, error) {
	rv := &bytes.Buffer{}
	for {
		ch, _, err := r.ReadRune()
		if err != nil {
			return "", err
		}
		if ch == '=' {
			r.UnreadRune()
			return string(rv.Bytes()), nil
		}
		rv.WriteRune(ch)
	}
}
Beispiel #18
0
func parseNegation(r io.RuneScanner, glob *globImpl) error {
	for {
		char, _, err := r.ReadRune()

		if err != nil {
			return err
		} else if char == '!' {
			glob.negated = !glob.negated
		} else {
			r.UnreadRune()
			return nil
		}
	}
}
Beispiel #19
0
// SkipSpace consumes and ignores non-newline whitespace.
// Terminates if a newline is encountered.
// The terminating newline remains consumed.
func skipSpace(rs io.RuneScanner) error {
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return nil
		case err != nil:
			return err
		case r != '\n' && unicode.IsSpace(r):
			continue
		default:
			return rs.UnreadRune()
		}
	}
}
Beispiel #20
0
func readword(f *Xfile, isnum bool) string {
	var (
		barr [512]rune
		sp   int
		c    rune
		err  error
		sc   io.RuneScanner
	)
	if f.isgraphic() {
		sc = f.graph
	} else {
		sc = f.b
	}
	buf := barr[0:0]
	sp = 0
	for {
		c, _, err = sc.ReadRune()
		if err!=nil || !unicode.IsSpace(c) {
			break
		}
	}
	for {
		if err!=nil && sp==0 {
			panic("read: eof met")
		}
		buf = append(buf, c)
		sp++
		c, _, err = sc.ReadRune()
		if err!=nil || (isnum && !strings.ContainsRune("0123456789+-eE.", c)) {
			break
		}
		if err!=nil || unicode.IsSpace(c) {
			break
		}
	}
	if err != nil {
		if iseof(c, err) {
			f.eof = true
		}
	} else {
		f.eol = (c == rune(paminstr.EOL[0]))
		if !f.eol {
			sc.UnreadRune()
		}
	}
	if len(buf) == 0 {
		panic("read: eof met")
	}
	return string(buf)
}
Beispiel #21
0
func parseMarkRune(rs io.RuneScanner) (rune, error) {
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return '.', nil
		case err != nil:
			return 0, err
		case unicode.IsSpace(r):
			continue
		default:
			return r, nil
		}
	}
}
Beispiel #22
0
func stringReader(flag int, r io.RuneScanner) interface{} {
	var s string = ""
	for {
		rune, _, err := r.ReadRune()
		if err != nil {
			panic("err")
		}
		if rune == '"' {
			return s
		}
		s = s + string(rune)
	}
	return s
}
Beispiel #23
0
func (z *Dec) scan(r io.RuneScanner) (*Dec, error) {
	unscaled := make([]byte, 0, 256) // collects chars of unscaled as bytes
	dp, dg := -1, -1                 // indexes of decimal point, first digit
loop:
	for {
		ch, _, err := r.ReadRune()
		if err == io.EOF {
			break loop
		}
		if err != nil {
			return nil, err
		}
		switch {
		case ch == '+' || ch == '-':
			if len(unscaled) > 0 || dp >= 0 { // must be first character
				r.UnreadRune()
				break loop
			}
		case ch == '.':
			if dp >= 0 {
				r.UnreadRune()
				break loop
			}
			dp = len(unscaled)
			continue // don't add to unscaled
		case ch >= '0' && ch <= '9':
			if dg == -1 {
				dg = len(unscaled)
			}
		default:
			r.UnreadRune()
			break loop
		}
		unscaled = append(unscaled, byte(ch))
	}
	if dg == -1 {
		return nil, fmt.Errorf("no digits read")
	}
	if dp >= 0 {
		z.SetScale(Scale(len(unscaled) - dp))
	} else {
		z.SetScale(0)
	}
	_, ok := z.UnscaledBig().SetString(string(unscaled), 10)
	if !ok {
		return nil, fmt.Errorf("invalid decimal: %s", string(unscaled))
	}
	return z, nil
}
Beispiel #24
0
func parseMarkAddr(rs io.RuneScanner) (SimpleAddress, error) {
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return nil, errors.New("bad mark: EOF")
		case err != nil:
			return nil, err
		case !unicode.IsSpace(r) || r == '\n':
			if !isMarkRune(r) {
				return nil, errors.New("bad mark: " + string(r))
			}
			return Mark(r), nil
		}
	}
}
Beispiel #25
0
func scanDigits(rs io.RuneScanner) (string, error) {
	var s string
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return s, nil
		case err != nil:
			return "", err
		case !unicode.IsDigit(r):
			return s, rs.UnreadRune()
		default:
			s += string(r)
		}
	}
}
Beispiel #26
0
func parseText(rs io.RuneScanner) (string, error) {
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return "", nil
		case err != nil:
			return "", err
		case r == '\n':
			return parseLines(rs)
		case unicode.IsSpace(r):
			continue
		default:
			return parseDelimited(r, rs)
		}
	}
}
Beispiel #27
0
func seqReader(rune int, r io.RuneScanner) interface{} {
	seq := make([]interface{}, 0)
	for {
		nrune, _, err := r.ReadRune()
		for isWhiteSpace(nrune) {
			nrune, _, err = r.ReadRune()
		}
		if err != nil || string(nrune) == ")" {
			return seq
		}
		r.UnreadRune()
		fmt.Println(seq)
		seq = append(seq, read(r))
	}
	return seq
}
Beispiel #28
0
// ScanBareIdent reads bare identifier from a rune reader.
func ScanBareIdent(r io.RuneScanner) string {
	// Read every ident character into the buffer.
	// Non-ident characters and EOF will cause the loop to exit.
	var buf bytes.Buffer
	for {
		ch, _, err := r.ReadRune()
		if err != nil {
			break
		} else if !isIdentChar(ch) {
			r.UnreadRune()
			break
		} else {
			_, _ = buf.WriteRune(ch)
		}
	}
	return buf.String()
}
Beispiel #29
0
func parseLines(rs io.RuneScanner) (string, error) {
	var s string
	var nl bool
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return s, nil
		case err != nil:
			return "", err
		case nl && r == '.':
			return s, nil
		default:
			s += string(r)
			nl = r == '\n'
		}
	}
}
Beispiel #30
0
// readWord reads `r` until it encounters a space (0x20)
func readWord(r io.RuneScanner) (string, error) {
	rv := &bytes.Buffer{}
	for {
		ch, _, err := r.ReadRune()
		if err != nil {
			return "", err
		} else if ch != ' ' {
			rv.WriteRune(ch)
		} else {
			r.UnreadRune()
			rvString := string(rv.Bytes())
			if rvString == "-" {
				rvString = ""
			}
			return rvString, nil
		}
	}
}