package v2 import ( "fmt" "io" ) // Reads the whole ID3v2 tag from rs func ReadV2Tag(rs io.ReadSeeker) (*ID3v2Tag, error) { header, err := readHeader(rs) if err == ErrDoesNotUseID3v2 { return nil, err } else if err != nil { return nil, fmt.Errorf("could not get header: %s", err) } var read uint64 = 0 var frames []Frame var padding uint32 = 0 for { if read == uint64(header.Size()) { break } frame, err := readNextFrame(rs, header.Version()) switch err { case nil: case ErrGotPadding: // take a note how many padding bytes are left and // return collected frames padding += header.Size() - uint32(read) return &ID3v2Tag{ Header: header, Frames: frames, Padding: padding, }, nil case ErrInvalidID: // return what has been collected return &ID3v2Tag{ Header: header, Frames: frames, }, nil default: return nil, err } frames = append(frames, frame) // counting how many bytes read if header.Version() == V2_2 { read += uint64(V2_2FrameHeaderSize) + uint64(frame.Header.Size()) } else { read += uint64(V2_3FrameHeaderSize) + uint64(frame.Header.Size()) } } return &ID3v2Tag{ Header: header, Frames: frames, Padding: padding, }, nil }