Browse Source

※ Fixed a bug in utils, struggled a bit about frames ※

main
Unbewohnte 3 years ago
parent
commit
2091e02b52
  1. 17
      id3ed.go
  2. BIN
      testData/testwritev1.mp3
  3. 12
      util/conversion.go
  4. 14
      v1/id3v11_test.go
  5. 4
      v1/v11read.go
  6. 2
      v1/v1read.go
  7. 8
      v2/constants.go
  8. 36
      v2/frame.go
  9. 13
      v2/frame_test.go
  10. 33
      v2/header.go
  11. 34
      v2/read.go
  12. 13
      v2/read_test.go
  13. 34
      v2/v2tags.go

17
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)

BIN
testData/testwritev1.mp3

Binary file not shown.

12
util/conversion.go

@ -1,21 +1,17 @@
package util package util
import ( import (
"bytes"
"encoding/binary"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
) )
// Decodes given integer bytes into integer // Decodes given byte into integer
func BytesToInt(gBytes []byte) (int64, error) { func ByteToInt(gByte byte) (int64, error) {
buff := bytes.NewBuffer(gBytes) integer, err := strconv.ParseInt(fmt.Sprintf("%d", gByte), 10, 64)
integer, err := binary.ReadVarint(buff)
if err != nil { if err != nil {
return 0, fmt.Errorf("could not decode integer: %s", err) return 0, err
} }
buff = nil
return integer, nil return integer, nil
} }

14
v1/id3v11_test.go

@ -29,11 +29,11 @@ func TestGetID3v11Tags(t *testing.T) {
if mp3tags.Artist != "Artist" { if mp3tags.Artist != "Artist" {
fmt.Printf("%v", mp3tags.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 { if mp3tags.Track != 8 {
t.Errorf("GetID3v11Tags failed: expected %d; got %d", 4, mp3tags.Track) 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" { 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 { 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 { if readTags.Track != 10 {
t.Errorf("WriteID3v11Tags failed: expected %d; got %d", 5, readTags.Track) t.Errorf("WriteID3v11Tags failed: expected track %d; got %d", 10, readTags.Track)
} }
} }

4
v1/v11read.go

@ -67,7 +67,7 @@ func Getv11Tags(rs io.ReadSeeker) (*ID3v11Tags, error) {
return nil, err return nil, err
} }
track, err := util.BytesToInt(trackByte) track, err := util.ByteToInt(trackByte[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot convert bytes to int: %s", err) 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 { if err != nil {
return nil, err return nil, err
} }
genreInt, err := util.BytesToInt(genreByte) genreInt, err := util.ByteToInt(genreByte[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot convert bytes to int: %s", err) return nil, fmt.Errorf("cannot convert bytes to int: %s", err)
} }

2
v1/v1read.go

@ -60,7 +60,7 @@ func Getv1Tags(rs io.ReadSeeker) (*ID3v1Tags, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
genreInt, err := util.BytesToInt(genreByte) genreInt, err := util.ByteToInt(genreByte[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot convert bytes to int: %s", err) return nil, fmt.Errorf("cannot convert bytes to int: %s", err)
} }

8
v2/constants.go

@ -1,6 +1,12 @@
package v2 package v2
//ID3v2
const HEADERIDENTIFIER string = "ID3" const HEADERIDENTIFIER string = "ID3"
const HEADERSIZE int = 10 // bytes const HEADERSIZE int = 10 // bytes
const HEADERMAXSIZE int = 268435456 // bytes (256 MB) 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

36
v2/frame.go

@ -119,6 +119,40 @@ func ReadFrame(rs io.Reader) (*Frame, error) {
return &frame, nil 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
} }

13
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)) 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)
// }
// }

33
v2/header.go

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"strconv"
"github.com/Unbewohnte/id3ed/util" "github.com/Unbewohnte/id3ed/util"
) )
@ -20,7 +19,7 @@ type HeaderFlags struct {
type Header struct { type Header struct {
Identifier string Identifier string
Flags HeaderFlags Flags HeaderFlags
Version uint Version string
Size int64 // size of the whole tag - 10 header bytes 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) header.Identifier = string(identifier)
// version // version
majorVersionByte, err := util.Read(rs, 1) VersionBytes, err := util.Read(rs, 2)
if err != nil {
return nil, err
}
revisionNumberByte, err := util.Read(rs, 1)
if err != nil { if err != nil {
return nil, err return nil, err
} }
majorVersion, err := util.BytesToInt(majorVersionByte) majorVersion, err := util.ByteToInt(VersionBytes[0])
if err != nil { if err != nil {
return nil, err return nil, err
} }
revisionNumber, err := util.BytesToInt(revisionNumberByte) revisionNumber, err := util.ByteToInt(VersionBytes[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
version, err := strconv.Atoi(fmt.Sprintf("%d%d", majorVersion, revisionNumber)) var version string
if err != nil { switch majorVersion {
return nil, err 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
flags, err := util.Read(rs, 1) 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 // v3.0 and v4.0 have different amount of flags
switch version { switch version {
case 30: case V2_3:
if flagBits[0] == 1 { if flagBits[0] == 1 {
header.Flags.Unsynchronisated = true header.Flags.Unsynchronisated = true
} else { } else {
@ -94,7 +97,7 @@ func GetHeader(rs io.ReadSeeker) (*Header, error) {
// always false, because ID3v2.3.0 does not support footers // always false, because ID3v2.3.0 does not support footers
header.Flags.FooterPresent = false header.Flags.FooterPresent = false
case 40: case V2_4:
if flagBits[0] == 1 { if flagBits[0] == 1 {
header.Flags.Unsynchronisated = true header.Flags.Unsynchronisated = true
} else { } else {

34
v2/read.go

@ -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
// }

13
v2/read_test.go

@ -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)
// }
// }

34
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
// }
Loading…
Cancel
Save