From 2091e02b52f8ea627cc4895fe4cb609a0d1a4309 Mon Sep 17 00:00:00 2001 From: Unbewohnte Date: Mon, 5 Jul 2021 18:35:43 +0300 Subject: [PATCH] =?UTF-8?q?=E2=80=BB=20Fixed=20a=20bug=20in=20utils,=20str?= =?UTF-8?q?uggled=20a=20bit=20about=20frames=20=E2=80=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- id3ed.go | 17 +++++++++++++++++ testData/testwritev1.mp3 | Bin 6815 -> 672 bytes util/conversion.go | 12 ++++-------- v1/id3v11_test.go | 14 +++++++------- v1/v11read.go | 4 ++-- v1/v1read.go | 2 +- v2/constants.go | 8 +++++++- v2/frame.go | 36 +++++++++++++++++++++++++++++++++++- v2/frame_test.go | 13 +++++++++++++ v2/header.go | 33 ++++++++++++++++++--------------- v2/read.go | 34 ---------------------------------- v2/read_test.go | 13 ------------- v2/v2tags.go | 34 ++++++++++++++++++++++++++++++++++ 13 files changed, 138 insertions(+), 82 deletions(-) create mode 100644 id3ed.go delete mode 100644 v2/read.go delete mode 100644 v2/read_test.go create mode 100644 v2/v2tags.go diff --git a/id3ed.go b/id3ed.go new file mode 100644 index 0000000..3e167f2 --- /dev/null +++ b/id3ed.go @@ -0,0 +1,17 @@ +package id3ed + +// type File struct { +// Filename string +// ContainsV1 bool +// ContainsV2 bool +// } + +// type Metadata interface { +// Write() error +// } + +// func Open(path string) (*File, error) { +// return &File{}, nil +// } + +// func (f *File) GetMetadata() (*Metadata, error) diff --git a/testData/testwritev1.mp3 b/testData/testwritev1.mp3 index 784e19a1fc7a15b8dd3310d88c20f50fde91af72..a8c312d295b4fce41937e00d619e7f847163343c 100644 GIT binary patch delta 12 TcmbPlx`1_q9OGtLrY1%J8;S#- delta 110 acmZ3$I^T4I93vywW(CFu#>ER5X^H`3$08vB diff --git a/util/conversion.go b/util/conversion.go index 1a0ca95..1901e26 100644 --- a/util/conversion.go +++ b/util/conversion.go @@ -1,21 +1,17 @@ package util import ( - "bytes" - "encoding/binary" "fmt" "strconv" "strings" ) -// Decodes given integer bytes into integer -func BytesToInt(gBytes []byte) (int64, error) { - buff := bytes.NewBuffer(gBytes) - integer, err := binary.ReadVarint(buff) +// Decodes given byte into integer +func ByteToInt(gByte byte) (int64, error) { + integer, err := strconv.ParseInt(fmt.Sprintf("%d", gByte), 10, 64) if err != nil { - return 0, fmt.Errorf("could not decode integer: %s", err) + return 0, err } - buff = nil return integer, nil } diff --git a/v1/id3v11_test.go b/v1/id3v11_test.go index d42f46e..57b6543 100644 --- a/v1/id3v11_test.go +++ b/v1/id3v11_test.go @@ -29,11 +29,11 @@ func TestGetID3v11Tags(t *testing.T) { if mp3tags.Artist != "Artist" { fmt.Printf("%v", mp3tags.Artist) - t.Errorf("GetID3v11Tags failed: expected %s; got %s", "Artist", mp3tags.Artist) + t.Errorf("GetID3v11Tags failed: expected artist %s; got %s", "Artist", mp3tags.Artist) } - if mp3tags.Track != 4 { - t.Errorf("GetID3v11Tags failed: expected %d; got %d", 4, mp3tags.Track) + if mp3tags.Track != 8 { + t.Errorf("GetID3v11Tags failed: expected track %d; got %d", 8, mp3tags.Track) } } @@ -58,15 +58,15 @@ func TestWriteID3v11Tags(t *testing.T) { } if readTags.Album != "testalbum" { - t.Errorf("WriteID3v11Tags failed: expected %s; got %s", "testalbum", readTags.Album) + t.Errorf("WriteID3v11Tags failed: expected album %s; got %s", "testalbum", readTags.Album) } if readTags.Year != 727 { - t.Errorf("WriteID3v11Tags failed: expected %d; got %d", 727, readTags.Year) + t.Errorf("WriteID3v11Tags failed: expected year %d; got %d", 727, readTags.Year) } - if readTags.Track != 5 { - t.Errorf("WriteID3v11Tags failed: expected %d; got %d", 5, readTags.Track) + if readTags.Track != 10 { + t.Errorf("WriteID3v11Tags failed: expected track %d; got %d", 10, readTags.Track) } } diff --git a/v1/v11read.go b/v1/v11read.go index 84c95d9..a8cbfc9 100644 --- a/v1/v11read.go +++ b/v1/v11read.go @@ -67,7 +67,7 @@ func Getv11Tags(rs io.ReadSeeker) (*ID3v11Tags, error) { return nil, err } - track, err := util.BytesToInt(trackByte) + track, err := util.ByteToInt(trackByte[0]) if err != nil { return nil, fmt.Errorf("cannot convert bytes to int: %s", err) } @@ -76,7 +76,7 @@ func Getv11Tags(rs io.ReadSeeker) (*ID3v11Tags, error) { if err != nil { return nil, err } - genreInt, err := util.BytesToInt(genreByte) + genreInt, err := util.ByteToInt(genreByte[0]) if err != nil { return nil, fmt.Errorf("cannot convert bytes to int: %s", err) } diff --git a/v1/v1read.go b/v1/v1read.go index 976591d..9aafcf2 100644 --- a/v1/v1read.go +++ b/v1/v1read.go @@ -60,7 +60,7 @@ func Getv1Tags(rs io.ReadSeeker) (*ID3v1Tags, error) { if err != nil { return nil, err } - genreInt, err := util.BytesToInt(genreByte) + genreInt, err := util.ByteToInt(genreByte[0]) if err != nil { return nil, fmt.Errorf("cannot convert bytes to int: %s", err) } diff --git a/v2/constants.go b/v2/constants.go index ec81cf5..2aa3f6c 100644 --- a/v2/constants.go +++ b/v2/constants.go @@ -1,6 +1,12 @@ package v2 -//ID3v2 const HEADERIDENTIFIER string = "ID3" const HEADERSIZE int = 10 // bytes const HEADERMAXSIZE int = 268435456 // bytes (256 MB) +const V2_2 string = "ID3v2.2" +const V2_3 string = "ID3v2.3" +const V2_4 string = "ID3v2.4" + +const V2_2FrameNameSize uint = 3 +const V2_3FrameNameSize uint = 4 +const V2_4FrameNameSize uint = 4 diff --git a/v2/frame.go b/v2/frame.go index 6dc3084..669eace 100644 --- a/v2/frame.go +++ b/v2/frame.go @@ -119,6 +119,40 @@ func ReadFrame(rs io.Reader) (*Frame, error) { return &frame, nil } -func WriteFlag() { +// Reads ID3v2 frames from rs. NOT TESTED !!!! +func GetFrames(rs io.ReadSeeker) ([]*Frame, error) { + header, err := GetHeader(rs) + if err != nil { + return nil, err + } + + tagsize := header.Size + + fmt.Println("NEED TO READ ", tagsize) + + var frames []*Frame + var read uint64 = 0 + for { + if read == uint64(tagsize) { + break + } + + frame, err := ReadFrame(rs) + if err != nil { + return frames, fmt.Errorf("could not read frame: %s", err) + } + frames = append(frames, frame) + + // counting how many bytes has been read + read += 10 // frame header + if frame.Flags.InGroup { + // header has 1 additional byte + read += 1 + } + read += uint64(frame.Size) // and the contents itself + + fmt.Println("Read: ", read, " ", frame.ID) + } + return frames, nil } diff --git a/v2/frame_test.go b/v2/frame_test.go index 1c536de..5a1ed3c 100644 --- a/v2/frame_test.go +++ b/v2/frame_test.go @@ -44,3 +44,16 @@ func TestReadFrame(t *testing.T) { t.Errorf("ReadFrame failed: expected contents to be %s; got %s", "2006", util.ToString(secondFrame.Contents)) } } + + +// func TestGetFrames(t *testing.T) { +// f, err := os.Open(filepath.Join(TESTDATAPATH, "testreadv2.mp3")) +// if err != nil { +// t.Errorf("%s", err) +// } + +// _, err = GetFrames(f) +// if err != nil { +// t.Errorf("GetFrames failed: %s", err) +// } +// } \ No newline at end of file diff --git a/v2/header.go b/v2/header.go index 86b5a83..d96c580 100644 --- a/v2/header.go +++ b/v2/header.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "io" - "strconv" "github.com/Unbewohnte/id3ed/util" ) @@ -20,7 +19,7 @@ type HeaderFlags struct { type Header struct { Identifier string Flags HeaderFlags - Version uint + Version string Size int64 // size of the whole tag - 10 header bytes } @@ -41,29 +40,33 @@ func GetHeader(rs io.ReadSeeker) (*Header, error) { header.Identifier = string(identifier) // version - majorVersionByte, err := util.Read(rs, 1) - if err != nil { - return nil, err - } - revisionNumberByte, err := util.Read(rs, 1) + VersionBytes, err := util.Read(rs, 2) if err != nil { return nil, err } - majorVersion, err := util.BytesToInt(majorVersionByte) + majorVersion, err := util.ByteToInt(VersionBytes[0]) if err != nil { return nil, err } - revisionNumber, err := util.BytesToInt(revisionNumberByte) + revisionNumber, err := util.ByteToInt(VersionBytes[1]) if err != nil { return nil, err } - version, err := strconv.Atoi(fmt.Sprintf("%d%d", majorVersion, revisionNumber)) - if err != nil { - return nil, err + var version string + switch majorVersion { + case 2: + version = V2_2 + case 3: + version = V2_3 + case 4: + version = V2_4 + default: + return nil, fmt.Errorf("ID3v2.%d.%d is not supported", majorVersion, revisionNumber) } - header.Version = uint(version) + + header.Version = version // flags flags, err := util.Read(rs, 1) @@ -75,7 +78,7 @@ func GetHeader(rs io.ReadSeeker) (*Header, error) { // v3.0 and v4.0 have different amount of flags switch version { - case 30: + case V2_3: if flagBits[0] == 1 { header.Flags.Unsynchronisated = true } else { @@ -94,7 +97,7 @@ func GetHeader(rs io.ReadSeeker) (*Header, error) { // always false, because ID3v2.3.0 does not support footers header.Flags.FooterPresent = false - case 40: + case V2_4: if flagBits[0] == 1 { header.Flags.Unsynchronisated = true } else { diff --git a/v2/read.go b/v2/read.go deleted file mode 100644 index 7898d62..0000000 --- a/v2/read.go +++ /dev/null @@ -1,34 +0,0 @@ -package v2 - -// Reads ID3v2 frames from rs. NOT TESTED !!!! -// func GetFrames(rs io.ReadSeeker) ([]*Frame, error) { -// header, err := GetHeader(rs) -// if err != nil { -// return nil, fmt.Errorf("could not get header: %s", err) -// } -// tagsize := header.Size - -// var frames []*Frame -// var read uint64 = 0 -// for { -// if read == uint64(tagsize) { -// break -// } - -// frame, err := ReadFrame(rs) -// if err != nil { -// return frames, fmt.Errorf("could not read frame: %s", err) -// } -// frames = append(frames, frame) - -// // counting how many bytes has been read -// read += 10 // frame header -// if frame.Flags.InGroup { -// // header has 1 additional byte -// read += 1 -// } -// read += uint64(frame.Size) // and the contents itself -// } - -// return frames, nil -// } diff --git a/v2/read_test.go b/v2/read_test.go deleted file mode 100644 index 736c351..0000000 --- a/v2/read_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package v2 - -// func TestGetFrames(t *testing.T) { -// f, err := os.Open(filepath.Join(TESTDATAPATH, "testreadv2.mp3")) -// if err != nil { -// t.Errorf("%s", err) -// } - -// _, err = GetFrames(f) -// if err != nil { -// t.Errorf("GetFrames failed: %s", err) -// } -// } diff --git a/v2/v2tags.go b/v2/v2tags.go new file mode 100644 index 0000000..924a515 --- /dev/null +++ b/v2/v2tags.go @@ -0,0 +1,34 @@ +package v2 + +// type ID3v2Tag struct { +// Header *Header +// Frames []*Frame +// } + +// type V2TagReader interface { +// ReadFrames(io.ReadSeeker) ([]*Frame, error) +// GetHeader(io.ReadSeeker) (*Header, error) +// HasPadding(io.ReadSeeker) (bool, error) +// } + +// type V2TagWriter interface { +// Write(*os.File) error +// } + +// func Get(f *os.File) (*ID3v2Tag, error) { +// var tag ID3v2Tag + +// header, err := GetHeader(f) +// if err != nil { +// return nil, err +// } +// frames, err := GetFrames(f) +// if err != nil { +// return nil, err +// } + +// tag.Header = header +// tag.Frames = frames + +// return &tag, nil +// }