You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
1.8 KiB

  1. package main
  2. import (
  3. "bufio"
  4. "bytes"
  5. "io"
  6. "io/ioutil"
  7. "strings"
  8. )
  9. type SkipTillReader struct {
  10. rdr *bufio.Reader
  11. delim []byte
  12. found bool
  13. }
  14. func NewSkipTillReader(reader io.Reader, delim []byte) *SkipTillReader {
  15. return &SkipTillReader{
  16. rdr: bufio.NewReader(reader),
  17. delim: delim,
  18. found: false,
  19. }
  20. }
  21. func (str *SkipTillReader) Read(p []byte) (n int, err error) {
  22. if str.found {
  23. return str.rdr.Read(p)
  24. } else {
  25. // search byte by byte for the delimiter
  26. outer:
  27. for {
  28. for i := range str.delim {
  29. var c byte
  30. c, err = str.rdr.ReadByte()
  31. if err != nil {
  32. n = 0
  33. return
  34. }
  35. // doens't match so start over
  36. if str.delim[i] != c {
  37. continue outer
  38. }
  39. }
  40. str.found = true
  41. // we read the delimiter so add it back
  42. str.rdr = bufio.NewReader(io.MultiReader(bytes.NewReader(str.delim), str.rdr))
  43. return str.Read(p)
  44. }
  45. }
  46. }
  47. type ReadTillReader struct {
  48. rdr *bufio.Reader
  49. delim []byte
  50. found bool
  51. }
  52. func NewReadTillReader(reader io.Reader, delim []byte) *ReadTillReader {
  53. return &ReadTillReader{
  54. rdr: bufio.NewReader(reader),
  55. delim: delim,
  56. found: false,
  57. }
  58. }
  59. func (rtr *ReadTillReader) Read(p []byte) (n int, err error) {
  60. if rtr.found {
  61. return 0, io.EOF
  62. } else {
  63. outer:
  64. for n < len(p) {
  65. for i := range rtr.delim {
  66. var c byte
  67. c, err = rtr.rdr.ReadByte()
  68. if err != nil && n > 0 {
  69. err = nil
  70. return
  71. } else if err != nil {
  72. return
  73. }
  74. p[n] = c
  75. n++
  76. if rtr.delim[i] != c {
  77. continue outer
  78. }
  79. }
  80. rtr.found = true
  81. break
  82. }
  83. if n == 0 {
  84. err = io.EOF
  85. }
  86. return
  87. }
  88. }
  89. func extractText(original string, init string, fin string) string {
  90. contentReader := strings.NewReader(original)
  91. str := NewSkipTillReader(contentReader, []byte(init))
  92. rtr := NewReadTillReader(str, []byte(fin))
  93. bs, err := ioutil.ReadAll(rtr)
  94. check(err)
  95. return string(bs)
  96. }