Beispiel #1
0
func readRune(r io.RuneScanner) int {
	rune, _, err := r.ReadRune()
	if err != nil {
		return -1
	}
	return rune
}
Beispiel #2
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 #3
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 #4
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 #5
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 #6
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 #7
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 #8
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 #9
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 #10
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 #11
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 #12
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 #13
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 #14
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 #15
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 #16
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 #17
0
func readNumber(b int, r io.RuneScanner) interface{} {
	s := string(b)

	for {
		rune := readRune(r)
		if rune == -1 || isWhiteSpace(rune) || rune == ')' {
			r.UnreadRune()
			return s
		}
		s = s + string(rune)
	}

	return matchNumer(s)
}
Beispiel #18
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 #19
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 #20
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 #21
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 #22
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 #23
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 #24
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 #25
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 #26
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
		}
	}
}
Beispiel #27
0
// readSdParam reads an SD-PARAM as defined by RFC-5424
// 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 readSdParam(r io.RuneScanner) (sdp *SDParam, err error) {
	sdp = &SDParam{}
	sdp.Name, err = readSdParamName(r)
	if err != nil {
		return nil, err
	}
	ch, _, err := r.ReadRune()
	if err != nil {
		return nil, err // hard to reach
	}
	if ch != '=' {
		return nil, BadFormat("StructuredData[].Parameters") // not reachable
	}

	sdp.Value, err = readSdParamValue(r)
	if err != nil {
		return nil, err
	}
	return sdp, nil
}
Beispiel #28
0
func ReadList(in io.RuneScanner) Sexper {
	ch, _, _ := ReadChar(in)
	chstr := string(ch)

	switch chstr {
	case ")":
		return NIL
	case ".":
		list := ReadList(in)
		if list == NIL || fn_cdr(list) != NIL {
			panic(ERROR_DOT)
		}
		return fn_car(list)
	default:
		in.UnreadRune()
		scar := ReadSexp(in)
		scdr := ReadList(in)
		return List{scar, scdr}
	}
}
Beispiel #29
0
// scanEscapeCommand scans to the end of the current escape sequence. The scanner
// must be positioned at an escape rune (esc or the unicode CSI).
func scanEscapeCommand(s io.RuneScanner) (Command, error) {
	csi := false
	esc, _, err := s.ReadRune()
	if err != nil {
		return nil, err
	}
	if esc != escape && esc != monogramCsi {
		panic(fmt.Errorf("not positioned at beginning of escape sequence, saw: %v", esc))
	}
	if esc == monogramCsi {
		csi = true
	}

	var args bytes.Buffer
	quote := false
	for i := 0; ; i++ {
		r, _, err := s.ReadRune()
		if err != nil {
			return nil, err
		}
		if i == 0 && r == '[' {
			csi = true
			continue
		}

		if !csi {
			return escapeCommand{r, ""}, nil
		} else if quote == false && unicode.Is(csEnd, r) {
			return escapeCommand{r, args.String()}, nil
		}

		if r == '"' {
			quote = !quote
		}

		// Otherwise, we're still in the args, and this rune is one of those args.
		if _, err := args.WriteRune(r); err != nil {
			panic(err) // WriteRune cannot return an error from bytes.Buffer.
		}
	}
}
Beispiel #30
0
func ReadSexp(in io.RuneScanner) Sexper {
	ch, _, _ := ReadChar(in)

	switch string(ch) {
	case "\"":
		return ReadString(in)
	case "(":
		return ReadList(in)
	case "'":
		return fn_cons(Atom{"quote"}, fn_cons(ReadSexp(in), NIL))
	case ")":
		panic("unexcepted ')' found")
	default:
		in.UnreadRune()
		if unicode.IsDigit(ch) {
			return ReadNumber(in)
		} else {
			return ReadAtom(in)
		}
	}
}