package sdp
import (
"errors"
"fmt"
"io"
"strconv"
)
var errDocumentStart = errors .New ("already on document start" )
type syntaxError struct {
s string
i int
}
func (e syntaxError ) Error () string {
if e .i < 0 {
e .i = 0
}
return fmt .Sprintf ("sdp: syntax error at pos %d: %s" , e .i , strconv .QuoteToASCII (e .s [e .i :e .i +1 ]))
}
type baseLexer struct {
value string
pos int
}
func (l baseLexer ) syntaxError () error {
return syntaxError {s : l .value , i : l .pos - 1 }
}
func (l *baseLexer ) unreadByte () error {
if l .pos <= 0 {
return errDocumentStart
}
l .pos --
return nil
}
func (l *baseLexer ) readByte () (byte , error ) {
if l .pos >= len (l .value ) {
return byte (0 ), io .EOF
}
ch := l .value [l .pos ]
l .pos ++
return ch , nil
}
func (l *baseLexer ) nextLine () error {
for {
ch , err := l .readByte ()
if errors .Is (err , io .EOF ) {
return nil
} else if err != nil {
return err
}
if !isNewline (ch ) {
return l .unreadByte ()
}
}
}
func (l *baseLexer ) readWhitespace () error {
for {
ch , err := l .readByte ()
if errors .Is (err , io .EOF ) {
return nil
} else if err != nil {
return err
}
if !isWhitespace (ch ) {
return l .unreadByte ()
}
}
}
func (l *baseLexer ) readUint64Field () (i uint64 , err error ) {
for {
ch , err := l .readByte ()
if errors .Is (err , io .EOF ) && i > 0 {
break
} else if err != nil {
return i , err
}
if isNewline (ch ) {
if err := l .unreadByte (); err != nil {
return i , err
}
break
}
if isWhitespace (ch ) {
if err := l .readWhitespace (); err != nil {
return i , err
}
break
}
switch ch {
case '0' :
i *= 10
case '1' :
i = i *10 + 1
case '2' :
i = i *10 + 2
case '3' :
i = i *10 + 3
case '4' :
i = i *10 + 4
case '5' :
i = i *10 + 5
case '6' :
i = i *10 + 6
case '7' :
i = i *10 + 7
case '8' :
i = i *10 + 8
case '9' :
i = i *10 + 9
default :
return i , l .syntaxError ()
}
}
return i , nil
}
func (l *baseLexer ) readField () (string , error ) {
start := l .pos
var stop int
for {
stop = l .pos
ch , err := l .readByte ()
if errors .Is (err , io .EOF ) && stop > start {
break
} else if err != nil {
return "" , err
}
if isNewline (ch ) {
if err := l .unreadByte (); err != nil {
return "" , err
}
break
}
if isWhitespace (ch ) {
if err := l .readWhitespace (); err != nil {
return "" , err
}
break
}
}
return l .value [start :stop ], nil
}
func (l *baseLexer ) readLine () (string , error ) {
start := l .pos
trim := 1
for {
ch , err := l .readByte ()
if err != nil {
return "" , err
}
if ch == '\r' {
trim ++
}
if ch == '\n' {
return l .value [start : l .pos -trim ], nil
}
}
}
func (l *baseLexer ) readType () (byte , error ) {
for {
firstByte , err := l .readByte ()
if err != nil {
return 0 , err
}
if isNewline (firstByte ) {
continue
}
secondByte , err := l .readByte ()
if err != nil {
return 0 , err
}
if secondByte != '=' {
return firstByte , l .syntaxError ()
}
return firstByte , nil
}
}
func isNewline(ch byte ) bool { return ch == '\n' || ch == '\r' }
func isWhitespace(ch byte ) bool { return ch == ' ' || ch == '\t' }
func anyOf(element string , data ...string ) bool {
for _ , v := range data {
if element == v {
return true
}
}
return false
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .