go-hep.org/x/hep@v0.38.1/rio/reader.go (about) 1 // Copyright ©2015 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package rio 6 7 import ( 8 "bufio" 9 "fmt" 10 "io" 11 12 riobin "codeberg.org/gonuts/binary" 13 ) 14 15 // Reader is a rio read-only stream 16 type Reader struct { 17 r io.Reader 18 19 options Options 20 version Version 21 22 recs map[string]*Record // map of all connected records 23 } 24 25 type bufioReader struct { 26 *bufio.Reader 27 } 28 29 func (r *bufioReader) Read(p []byte) (int, error) { 30 n, err := r.Reader.Read(p) 31 if n < len(p) && err == nil { 32 // retry. buffer was perhaps depleted. 33 var nn int 34 nn, err = r.Reader.Read(p[n:]) 35 if nn > 0 { 36 n += nn 37 } 38 } 39 return n, err 40 } 41 42 // NewReader returns a new read-only rio stream 43 func NewReader(r io.Reader) (*Reader, error) { 44 // a rio stream starts with rio magic 45 hdr := [4]byte{} 46 _, err := r.Read(hdr[:]) 47 if err != nil { 48 return nil, fmt.Errorf("rio: error reading magic-header: %w", err) 49 } 50 if hdr != rioMagic { 51 return nil, fmt.Errorf("rio: not a rio-stream. magic-header=%q. want=%q", 52 string(hdr[:]), 53 string(rioMagic[:]), 54 ) 55 } 56 return newReader(r) 57 } 58 59 // newReader returns a new read-only rio stream 60 func newReader(r io.Reader) (*Reader, error) { 61 //r = bufio.NewReaderSize(r, 10*1024*1024) 62 //r = bufio.NewReader(r) 63 r = &bufioReader{bufio.NewReader(r)} 64 return &Reader{ 65 r: r, 66 options: 0, 67 version: rioHdrVersion, 68 recs: make(map[string]*Record), 69 }, nil 70 } 71 72 // Record adds a Record to the list of records to read or 73 // returns the Record with that name. 74 func (r *Reader) Record(name string) *Record { 75 rec, ok := r.recs[name] 76 if !ok { 77 rec = newRecord(name, r.options) 78 rec.r = r 79 rec.unpack = true 80 r.recs[name] = rec 81 } 82 return rec 83 } 84 85 // Records returns the list of connected Records 86 func (r *Reader) Records() []*Record { 87 recs := make([]*Record, 0, len(r.recs)) 88 for _, rec := range r.recs { 89 recs = append(recs, rec) 90 } 91 return recs 92 } 93 94 // Close finishes reading the rio read-only stream. 95 // It does not (and can not) close the underlying reader. 96 func (r *Reader) Close() error { 97 var err error 98 return err 99 } 100 101 // decoder manages the decoding of data values from rioRecords 102 type decoder struct { 103 r io.Reader 104 } 105 106 func (dec *decoder) Decode(v any) error { 107 switch v := v.(type) { 108 case Unmarshaler: 109 return v.RioUnmarshal(dec.r) 110 } 111 112 d := riobin.NewDecoder(dec.r) 113 d.Order = Endian 114 return d.Decode(v) 115 }