github.com/kontera-technologies/go-supervisor/v2@v2.1.0/parsers.go (about) 1 package supervisor 2 3 import ( 4 "bufio" 5 "bytes" 6 "encoding/json" 7 "io" 8 "io/ioutil" 9 "strings" 10 ) 11 12 // MakeJsonLineParser is called with an io.Reader, and returns a function, that when called will output references to 13 // map[string]interface{} objects that contain the parsed json data. 14 // If an invalid json is encountered, all the characters up until a new-line will be dropped. 15 func MakeJsonLineParser(fromR io.Reader, bufferSize int) ProduceFn { 16 br := bufio.NewReaderSize(fromR, bufferSize) 17 dec := json.NewDecoder(br) 18 return func() (*interface{}, error) { 19 var v interface{} 20 if err := dec.Decode(&v); err == nil { 21 return &v, nil 22 } else if err == io.EOF { 23 return nil, err 24 } 25 26 rest, _ := ioutil.ReadAll(dec.Buffered()) 27 restLines := bytes.SplitAfterN(rest, []byte{'\n'}, 2) 28 if len(restLines) > 1 { 29 // todo: test memory consumption on many mistakes (which will happen) 30 dec = json.NewDecoder(io.MultiReader(bytes.NewReader(restLines[1]), br)) 31 } else { 32 dec = json.NewDecoder(br) 33 } 34 return nil, nil 35 } 36 } 37 38 // MakeLineParser is called with an io.Reader, and returns a function, that when called will output references to 39 // strings that contain the bytes read from the io.Reader (without the new-line suffix). 40 func MakeLineParser(fromR io.Reader, bufferSize int) ProduceFn { 41 br := bufio.NewReaderSize(fromR, bufferSize) 42 return func() (*interface{}, error) { 43 str, err := br.ReadString('\n') 44 if err == nil { 45 res := (interface{})(strings.TrimSuffix(str, string('\n'))) 46 return &res, nil 47 } 48 return nil, err 49 } 50 } 51 52 // MakeBytesParser is called with an io.Reader, and returns a function, that when called will output references to 53 // byte slices that contain the bytes read from the io.Reader. 54 func MakeBytesParser(fromR io.Reader, bufferSize int) ProduceFn { 55 br := bufio.NewReaderSize(fromR, bufferSize) 56 return func() (*interface{}, error) { 57 v, err := br.ReadBytes('\n') 58 if err == nil { 59 res := (interface{})(bytes.TrimSuffix(v, []byte{'\n'})) 60 return &res, nil 61 } 62 return nil, err 63 } 64 }