just unfold everything beforehand and use a scanner
This commit is contained in:
parent
0e4994ee56
commit
102fc57c2a
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -11,10 +12,6 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func complain(s string) {
|
||||
fmt.Fprintln(os.Stderr, s)
|
||||
}
|
||||
|
||||
func optExit(err error) {
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
|
@ -22,46 +19,8 @@ func optExit(err error) {
|
|||
}
|
||||
}
|
||||
|
||||
// the vCard RFC says, a single logical line can be "folded" to multiple physical lines,
|
||||
// so this shit must be done
|
||||
type UnfoldingReader struct {
|
||||
buf []byte
|
||||
i int
|
||||
j int
|
||||
}
|
||||
|
||||
func NewUnfoldingReader(buf []byte) *UnfoldingReader {
|
||||
return &UnfoldingReader{buf, 0, 0}
|
||||
}
|
||||
|
||||
func replaceFold(s string) string {
|
||||
// Yes, I know and I don't care
|
||||
return strings.TrimSpace(strings.ReplaceAll(strings.ReplaceAll(s, "\r\n ", ""), "\r\n\t", ""))
|
||||
}
|
||||
|
||||
func (r *UnfoldingReader) ReadLine() (string, bool) {
|
||||
readCR := false
|
||||
readCRLF := false
|
||||
for r.j = r.i; r.j < len(r.buf); r.j++ {
|
||||
if r.buf[r.j] == '\r' {
|
||||
readCR = true
|
||||
} else if readCR && r.buf[r.j] == '\n' {
|
||||
readCRLF = true
|
||||
} else if readCRLF && r.buf[r.j] != ' ' && r.buf[r.j] != '\t' {
|
||||
break
|
||||
} else {
|
||||
readCRLF = false
|
||||
}
|
||||
}
|
||||
var s string
|
||||
if r.i < len(r.buf) {
|
||||
s = replaceFold(string(r.buf[r.i:r.j]))
|
||||
} else {
|
||||
s = ""
|
||||
}
|
||||
notEOB := (r.i < len(r.buf))
|
||||
r.i = r.j
|
||||
return s, notEOB
|
||||
func unfold(s string) string {
|
||||
return strings.ReplaceAll(strings.ReplaceAll(s, "\r\n ", ""), "\r\n\t", "")
|
||||
}
|
||||
|
||||
func vCardValue(line string) string {
|
||||
|
@ -185,9 +144,11 @@ func (n *Number) WriteFritzboxXML(s io.Writer, i int) {
|
|||
}
|
||||
|
||||
func GetContacts(buf []byte) (c ContactSet) {
|
||||
r := NewUnfoldingReader(buf)
|
||||
s := unfold(string(buf))
|
||||
scanner := bufio.NewScanner(strings.NewReader(s))
|
||||
var current *Contact
|
||||
for l, ok := r.ReadLine(); ok; l, ok = r.ReadLine() {
|
||||
for scanner.Scan() {
|
||||
l := strings.TrimSpace(scanner.Text())
|
||||
if l == "BEGIN:VCARD" {
|
||||
current = &Contact{}
|
||||
} else if l == "END:VCARD" {
|
||||
|
@ -197,6 +158,7 @@ func GetContacts(buf []byte) (c ContactSet) {
|
|||
current.setValue(l)
|
||||
}
|
||||
}
|
||||
optExit(scanner.Err())
|
||||
if current != nil {
|
||||
c = append(c, *current)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user