From c38ea50729546844e2b70cf8b6b0651677043e2b Mon Sep 17 00:00:00 2001 From: Mario Salgado Date: Wed, 8 May 2024 15:23:12 +0200 Subject: [PATCH] feat: [FLAC] drop io.Closer element in Stream and Encoder types (#70) flac: simplify internal handling of io.Closer for io.Reader and io.Writer * flac: drop io.Closer element in Stream type; get it from io.Reader if implemented * encoder: drop io.Closer element in Encoder type; get it from io.Writer if implemented * encoder/frame: defer bitio.Writer's closure, instead of replacing the encoder's closer, since bitio.Writer does not close the underlying writer --- encode.go | 12 ++++-------- encode_frame.go | 4 +++- flac.go | 17 +++++++---------- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/encode.go b/encode.go index d97f25b..892d7a7 100644 --- a/encode.go +++ b/encode.go @@ -14,10 +14,8 @@ import ( type Encoder struct { // FLAC stream of encoder. *Stream - // Underlying io.Writer to the output stream. + // Underlying io.Writer or io.WriteCloser to the output stream. w io.Writer - // io.Closer to flush pending writes to output stream. - c io.Closer // Minimum and maximum block size (in samples) of frames written by encoder. blockSizeMin, blockSizeMax uint16 // Minimum and maximum frame size (in bytes) of frames written by encoder. @@ -43,9 +41,7 @@ func NewEncoder(w io.Writer, info *meta.StreamInfo, blocks ...*meta.Block) (*Enc w: w, md5sum: md5.New(), } - if c, ok := w.(io.Closer); ok { - enc.c = c - } + bw := bitio.NewWriter(w) if _, err := bw.Write(flacSignature); err != nil { return nil, errutil.Err(err) @@ -102,8 +98,8 @@ func (enc *Encoder) Close() error { return errutil.Err(err) } } - if enc.c != nil { - return enc.c.Close() + if closer, ok := enc.w.(io.Closer); ok { + return closer.Close() } return nil } diff --git a/encode_frame.go b/encode_frame.go index 209ac4a..8822af1 100644 --- a/encode_frame.go +++ b/encode_frame.go @@ -115,7 +115,9 @@ func (enc *Encoder) encodeFrameHeader(w io.Writer, hdr frame.Header) error { h := crc8.NewATM() hw := io.MultiWriter(h, w) bw := bitio.NewWriter(hw) - enc.c = bw + + // Closing the *bitio.Writer will not close the underlying writer + defer bw.Close() // Sync code: 11111111111110 if err := bw.WriteBits(0x3FFE, 14); err != nil { diff --git a/flac.go b/flac.go index 4b1ed69..e87fa9c 100644 --- a/flac.go +++ b/flac.go @@ -59,11 +59,8 @@ type Stream struct { // is relative to this position. dataStart int64 - // Underlying io.Reader. + // Underlying io.Reader, or io.ReadCloser. r io.Reader - // Underlying io.Closer of file if opened with Open and ParseFile, and nil - // otherwise. - c io.Closer } // New creates a new Stream for accessing the audio samples of r. It reads and @@ -264,7 +261,7 @@ func Open(path string) (stream *Stream, err error) { if err != nil { return nil, err } - stream.c = f + return stream, err } @@ -285,16 +282,16 @@ func ParseFile(path string) (stream *Stream, err error) { if err != nil { return nil, err } - stream.c = f + return stream, err } -// Close closes the stream if opened through a call to Open or ParseFile, and -// performs no operation otherwise. +// Close closes the stream gracefully if the underlying io.Reader also implements the io.Closer interface. func (stream *Stream) Close() error { - if stream.c != nil { - return stream.c.Close() + if closer, ok := stream.r.(io.Closer); ok { + return closer.Close() } + return nil }