R
R
Roman Mirilaczvili2021-03-07 11:57:30
go
Roman Mirilaczvili, 2021-03-07 11:57:30

How to apply multiple filters to the incoming stream?

There is a code that processes the input stream stdin and outputs to stdout.

var input io.ReadCloser

  reader := bufio.NewReader(input)
 
  for {
    in, _, err := reader.ReadLine()
    if err != nil && err == io.EOF {
      break
    }
 
    in = append(in, []byte("\n")...)
    if _, err := w.Write(in); err != nil {
      log.Fatalln(err)
    }
  }

I want to add additional filters to the incoming stream.
The filter will implement an interface with the function Filter(io.Reader, io.Writer) error
How, having an array of filters, to process the incoming stream so that there are no blockings and there is inputa processed stream after the last filter is applied?
That is, by analogy with using pipe on the command line.
It is desirable to be able to use the function type applyFilters(input io.Reader) (io.Reader, error). Then I could write
filteredInput, err = applyFilters(input)
reader := bufio.NewReader(filteredInput)

Use io.Pipe? If so, how?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
U
uvelichitel, 2021-03-08
@2ord

Another example is how you can

type FReader struct {
  reader io.Reader
  filter func([]byte) (int, error)
}
func NewFReader(r io.Reader) *FReader {
  return &FReader{r, func(p []byte) (int, error) { return len(p), nil }}
}
func (fr *FReader) Filter(filter func([]byte) (int, error)) *FReader {
  return &FReader{fr, filter}
}
func (fr *FReader) Read(p []byte) (n int, err error) {
  n, err = fr.reader.Read(p)
  if err == nil && fr.filter != nil {
    n, err = fr.filter(p)
  }
  return
}

then you can write
chainreader := NewFReader(myreader).Filter(myfilter1).Filter(myfilter2).Filter(myfilter3)
https://play.golang.org/p/rakSV5kgqR9

S
Stanislav Bodrov, 2021-03-08
@jenki

having an array of filters
No need to put filters in an array)
process the incoming stream so that there are no blockings and input contains the processed stream after applying the last filter?
Channels are here to help.
That is, by analogy with using pipe on the command line.
Yes, yes, the channels will help you) They work like this.
In general, in the body of your function for reading the contents of a file, you can add calls to anonymous functions that describe filtering, or pull other functions, you can write a method (depending on how you are going to filter), you can go "through channels". In theory, blocking should not occur.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question