txtreader.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package reader
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "regexp"
  7. "strings"
  8. )
  9. type TXTBlockReader struct {
  10. *LineReader
  11. classname string
  12. firstline string
  13. nextline string
  14. }
  15. func NewTXTBlockReader(filename string, classname string, reader io.Reader) *TXTBlockReader {
  16. return &TXTBlockReader{
  17. LineReader: NewLineReader(filename, reader),
  18. classname: classname,
  19. }
  20. }
  21. var regrecordstart = regexp.MustCompile(`^(?:[\.\/a-zA-Z0-9_]*:)?V:(\{.*)`)
  22. var regrecordend = regexp.MustCompile(`\}\s*$`)
  23. func (br *TXTBlockReader) ReadBlock(skiplines int) (block map[string]any, line string, linecount int, err error) {
  24. eof := false
  25. line = br.nextline
  26. for {
  27. for {
  28. br.nextline, linecount, eof, err = br.ReadLine()
  29. if err != nil {
  30. return
  31. }
  32. if br.nextline == "" && eof {
  33. if line == "" {
  34. return
  35. }
  36. break
  37. }
  38. if linecount <= skiplines {
  39. continue
  40. }
  41. if regrecordend.MatchString(line) {
  42. break
  43. }
  44. if regrecordstart.MatchString(br.nextline) {
  45. break
  46. }
  47. line += br.nextline
  48. }
  49. linecount--
  50. if !regrecordstart.MatchString(line) || !regrecordend.MatchString(line) {
  51. if line != "" {
  52. logger.Info(fmt.Sprint("skip non-json line ", br.filename, ":", linecount, " ", line))
  53. }
  54. if linecount == 1 {
  55. br.firstline = line
  56. }
  57. line = br.nextline
  58. continue
  59. }
  60. line = regrecordstart.ReplaceAllString(line, "$1")
  61. line = strings.ReplaceAll(line, `\`, `\\`)
  62. line = strings.ReplaceAll(line, "\t", `\t`)
  63. line = strings.ReplaceAll(line, "\r", `\r`)
  64. line = strings.ReplaceAll(line, "\n", `\n`)
  65. block = map[string]any{}
  66. err = json.Unmarshal([]byte(line), &block)
  67. if err != nil {
  68. return
  69. }
  70. return
  71. }
  72. }