package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"io"
|
|
"io/ioutil"
|
|
"strings"
|
|
)
|
|
|
|
type SkipTillReader struct {
|
|
rdr *bufio.Reader
|
|
delim []byte
|
|
found bool
|
|
}
|
|
|
|
func NewSkipTillReader(reader io.Reader, delim []byte) *SkipTillReader {
|
|
return &SkipTillReader{
|
|
rdr: bufio.NewReader(reader),
|
|
delim: delim,
|
|
found: false,
|
|
}
|
|
}
|
|
|
|
func (str *SkipTillReader) Read(p []byte) (n int, err error) {
|
|
if str.found {
|
|
return str.rdr.Read(p)
|
|
} else {
|
|
// search byte by byte for the delimiter
|
|
outer:
|
|
for {
|
|
for i := range str.delim {
|
|
var c byte
|
|
c, err = str.rdr.ReadByte()
|
|
if err != nil {
|
|
n = 0
|
|
return
|
|
}
|
|
// doens't match so start over
|
|
if str.delim[i] != c {
|
|
continue outer
|
|
}
|
|
}
|
|
str.found = true
|
|
// we read the delimiter so add it back
|
|
str.rdr = bufio.NewReader(io.MultiReader(bytes.NewReader(str.delim), str.rdr))
|
|
return str.Read(p)
|
|
}
|
|
}
|
|
}
|
|
|
|
type ReadTillReader struct {
|
|
rdr *bufio.Reader
|
|
delim []byte
|
|
found bool
|
|
}
|
|
|
|
func NewReadTillReader(reader io.Reader, delim []byte) *ReadTillReader {
|
|
return &ReadTillReader{
|
|
rdr: bufio.NewReader(reader),
|
|
delim: delim,
|
|
found: false,
|
|
}
|
|
}
|
|
|
|
func (rtr *ReadTillReader) Read(p []byte) (n int, err error) {
|
|
if rtr.found {
|
|
return 0, io.EOF
|
|
} else {
|
|
outer:
|
|
for n < len(p) {
|
|
for i := range rtr.delim {
|
|
var c byte
|
|
c, err = rtr.rdr.ReadByte()
|
|
if err != nil && n > 0 {
|
|
err = nil
|
|
return
|
|
} else if err != nil {
|
|
return
|
|
}
|
|
p[n] = c
|
|
n++
|
|
if rtr.delim[i] != c {
|
|
continue outer
|
|
}
|
|
}
|
|
rtr.found = true
|
|
break
|
|
}
|
|
if n == 0 {
|
|
err = io.EOF
|
|
}
|
|
return
|
|
}
|
|
}
|
|
|
|
func extractText(original string, init string, fin string) string {
|
|
contentReader := strings.NewReader(original)
|
|
str := NewSkipTillReader(contentReader, []byte(init))
|
|
rtr := NewReadTillReader(str, []byte(fin))
|
|
bs, err := ioutil.ReadAll(rtr)
|
|
check(err)
|
|
return string(bs)
|
|
}
|