github.com/yandex/pandora@v0.5.32/components/providers/http/decoders/decoder.go (about) 1 package decoders 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "io" 8 "net/http" 9 10 "github.com/yandex/pandora/components/providers/http/config" 11 "github.com/yandex/pandora/components/providers/http/util" 12 "github.com/yandex/pandora/core" 13 ) 14 15 //go:generate go run github.com/vektra/mockery/v2@v2.22.1 --inpackage --name=Decoder --filename=mock_decoder.go 16 17 func filePosition(file io.ReadSeeker) (position int64) { 18 position, _ = file.Seek(0, io.SeekCurrent) 19 return 20 } 21 22 var ( 23 ErrUnknown = fmt.Errorf("unknown decoder faced") 24 ErrNoAmmo = fmt.Errorf("no ammo in file") 25 ErrAmmoLimit = fmt.Errorf("ammo limit faced") 26 ErrPassLimit = fmt.Errorf("passes limit faced") 27 ) 28 29 type Decoder interface { 30 Scan(context.Context) (DecodedAmmo, error) 31 Release(a core.Ammo) 32 LoadAmmo(context.Context) ([]DecodedAmmo, error) 33 } 34 35 type protoDecoder struct { 36 file io.ReadSeeker 37 config config.Config 38 decodedConfigHeaders http.Header 39 ammoNum uint // number of ammo reads 40 passNum uint // number of file reads 41 } 42 43 func (d *protoDecoder) LoadAmmo(ctx context.Context, scan func(ctx context.Context) (DecodedAmmo, error)) ([]DecodedAmmo, error) { 44 passes := d.config.Passes 45 limit := d.config.Limit 46 d.config.Passes = 1 47 d.config.Limit = 0 48 var result []DecodedAmmo 49 var err error 50 var ammo DecodedAmmo 51 for err == nil { 52 ammo, err = scan(ctx) 53 if ammo != nil { 54 result = append(result, ammo) 55 } 56 } 57 d.config.Passes = passes 58 d.config.Limit = limit 59 if errors.Is(err, ErrPassLimit) { 60 err = nil 61 } 62 63 return result, err 64 } 65 66 func NewDecoder(conf config.Config, file io.ReadSeeker) (d Decoder, err error) { 67 decodedConfigHeaders, err := util.DecodeHTTPConfigHeaders(conf.Headers) 68 if err != nil { 69 return 70 } 71 72 switch conf.Decoder { 73 case config.DecoderJSONLine: 74 d, err = newJsonlineDecoder(file, conf, decodedConfigHeaders) 75 case config.DecoderRaw: 76 d = newRawDecoder(file, conf, decodedConfigHeaders) 77 case config.DecoderURI: 78 d = newURIDecoder(file, conf, decodedConfigHeaders) 79 case config.DecoderURIPost: 80 d = newURIPostDecoder(file, conf, decodedConfigHeaders) 81 default: 82 err = ErrUnknown 83 } 84 return 85 }