|
|
@ -1,29 +1,31 @@ |
|
|
|
package v2 |
|
|
|
package v2 |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
|
|
|
|
"fmt" |
|
|
|
"io" |
|
|
|
"io" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/Unbewohnte/id3ed/util" |
|
|
|
"github.com/Unbewohnte/id3ed/util" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
type FrameFlags struct { |
|
|
|
//(ᗜˬᗜ)~⭐//Under construction//Please don`t use it in this verison//(ᗜ‸ᗜ)///
|
|
|
|
TagAlterPreservation bool |
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
FileAlterPreservation bool |
|
|
|
|
|
|
|
ReadOnly bool |
|
|
|
type FrameHeader struct { |
|
|
|
Compressed bool |
|
|
|
ID string |
|
|
|
Encrypted bool |
|
|
|
FrameSize int64 |
|
|
|
InGroup bool |
|
|
|
Flags int |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
type Frame struct { |
|
|
|
type Frame struct { |
|
|
|
Header FrameHeader |
|
|
|
ID string |
|
|
|
Contents string |
|
|
|
Size int64 |
|
|
|
|
|
|
|
Flags FrameFlags |
|
|
|
|
|
|
|
GroupByte byte |
|
|
|
|
|
|
|
Contents []byte |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Reads ID3v2.3.0 or ID3v2.4.0 frame
|
|
|
|
// Reads ID3v2.3.0 or ID3v2.4.0 frame
|
|
|
|
func ReadFrame(rs io.Reader, version uint) (*Frame, error) { |
|
|
|
func ReadFrame(rs io.Reader, version uint) (*Frame, error) { |
|
|
|
var frameHeader FrameHeader |
|
|
|
|
|
|
|
var frame Frame |
|
|
|
var frame Frame |
|
|
|
|
|
|
|
|
|
|
|
// ID
|
|
|
|
// ID
|
|
|
@ -31,7 +33,7 @@ func ReadFrame(rs io.Reader, version uint) (*Frame, error) { |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
frameHeader.ID = identifier |
|
|
|
frame.ID = identifier |
|
|
|
|
|
|
|
|
|
|
|
// Size
|
|
|
|
// Size
|
|
|
|
framesizeBytes, err := util.Read(rs, 4) |
|
|
|
framesizeBytes, err := util.Read(rs, 4) |
|
|
@ -44,20 +46,67 @@ func ReadFrame(rs io.Reader, version uint) (*Frame, error) { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
frameHeader.FrameSize = framesize |
|
|
|
frame.Size = framesize |
|
|
|
|
|
|
|
|
|
|
|
// Flags
|
|
|
|
// Flags
|
|
|
|
frameFlagsBytes, err := util.Read(rs, 2) |
|
|
|
|
|
|
|
|
|
|
|
frameFlagsByte1, err := util.Read(rs, 1) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
frameFlags, err := util.BytesToInt(frameFlagsBytes) |
|
|
|
frameFlagsByte2, err := util.Read(rs, 1) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
frameHeader.Flags = int(frameFlags) |
|
|
|
// I don`t have enough knowledge to handle this more elegantly
|
|
|
|
|
|
|
|
// Any pointers ?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
flagsByte1Bits := fmt.Sprintf("%08b", frameFlagsByte1) |
|
|
|
|
|
|
|
flagsByte2Bits := fmt.Sprintf("%08b", frameFlagsByte2) |
|
|
|
|
|
|
|
var flags FrameFlags |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if flagsByte1Bits[0] == 1 { |
|
|
|
|
|
|
|
flags.TagAlterPreservation = true |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
flags.TagAlterPreservation = false |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if flagsByte1Bits[1] == 1 { |
|
|
|
|
|
|
|
flags.FileAlterPreservation = true |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
flags.FileAlterPreservation = false |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if flagsByte1Bits[2] == 1 { |
|
|
|
|
|
|
|
flags.ReadOnly = true |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
flags.ReadOnly = false |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if flagsByte2Bits[0] == 1 { |
|
|
|
|
|
|
|
flags.Compressed = true |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
flags.Compressed = false |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if flagsByte2Bits[1] == 1 { |
|
|
|
|
|
|
|
flags.Encrypted = true |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
flags.Encrypted = false |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if flagsByte2Bits[2] == 1 { |
|
|
|
|
|
|
|
flags.InGroup = true |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
flags.InGroup = false |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
frame.Flags = flags |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if flags.InGroup { |
|
|
|
|
|
|
|
groupByte, err := util.Read(rs, 1) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
frame.GroupByte = groupByte[0] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Body
|
|
|
|
// Body
|
|
|
|
frameContents, err := util.Read(rs, uint64(framesize)) |
|
|
|
frameContents, err := util.Read(rs, uint64(framesize)) |
|
|
@ -65,8 +114,11 @@ func ReadFrame(rs io.Reader, version uint) (*Frame, error) { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
frame.Header = frameHeader |
|
|
|
frame.Contents = frameContents |
|
|
|
frame.Contents = string(frameContents) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return &frame, nil |
|
|
|
return &frame, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func WriteFlag() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|