Browse Source

❮ Fixed v2.Frame.toBytes(), some functions looks better now ❯

main
Unbewohnte 3 years ago
parent
commit
0c29801a70
  1. 17
      util/conversion.go
  2. 3
      util/conversion_test.go
  3. 116
      v2/frame.go
  4. 51
      v2/frame_test.go

17
util/conversion.go

@ -35,7 +35,7 @@ func BytesToIntSynchsafe(gBytes []byte) uint32 {
// Finally understood with the help of: https://github.com/bogem/id3v2/blob/master/size.go , // Finally understood with the help of: https://github.com/bogem/id3v2/blob/master/size.go ,
// thank you very much ! // thank you very much !
func IntToBytesSynchsafe(gInt uint32) []byte { func IntToBytesSynchsafe(gInt uint32) []byte {
synchsafeIBytes := make([]byte, 4) var synchsafeIBytes []byte
// skip 4 0`ed bits // skip 4 0`ed bits
gInt = gInt << 4 gInt = gInt << 4
@ -71,15 +71,22 @@ func ToStringLossy(gBytes []byte) string {
return strings.ToValidUTF8(string(runes), "") return strings.ToValidUTF8(string(runes), "")
} }
const (
EncodingISO8859 byte = iota
EncodingUTF16BOM
EncodingUTF16
EncodingUTF8
)
// Decodes the given frame`s contents // Decodes the given frame`s contents
func DecodeText(fContents []byte) string { func DecodeText(fContents []byte) string {
textEncoding := fContents[0] // the first byte is the encoding textEncoding := fContents[0] // the first byte is the encoding
switch textEncoding { switch textEncoding {
case 0: case EncodingISO8859:
// ISO-8859-1 // ISO-8859-1
return ToStringLossy(fContents[1:]) return ToStringLossy(fContents[1:])
case 1: case EncodingUTF16BOM:
// UTF-16 with BOM // UTF-16 with BOM
encoding := euni.UTF16(euni.BigEndian, euni.ExpectBOM) encoding := euni.UTF16(euni.BigEndian, euni.ExpectBOM)
decoder := encoding.NewDecoder() decoder := encoding.NewDecoder()
@ -92,7 +99,7 @@ func DecodeText(fContents []byte) string {
return string(decodedBytes) return string(decodedBytes)
case 2: case EncodingUTF16:
// UTF-16 // UTF-16
encoding := euni.UTF16(euni.BigEndian, euni.IgnoreBOM) encoding := euni.UTF16(euni.BigEndian, euni.IgnoreBOM)
decoder := encoding.NewDecoder() decoder := encoding.NewDecoder()
@ -105,7 +112,7 @@ func DecodeText(fContents []byte) string {
return string(decodedBytes) return string(decodedBytes)
case 3: case EncodingUTF8:
// UTF-8 // UTF-8
return ToStringLossy(fContents[1:]) return ToStringLossy(fContents[1:])
} }

3
util/conversion_test.go

@ -37,6 +37,9 @@ func TestIntToBytesSynchsafe(t *testing.T) {
for _, testInt := range testInts { for _, testInt := range testInts {
synchSafeBytes := IntToBytesSynchsafe(testInt) synchSafeBytes := IntToBytesSynchsafe(testInt)
if len(synchSafeBytes) != 4 {
t.Errorf("IntToBytesSynchsafe failed: expected len to be %d; got %d", 4, len(synchSafeBytes))
}
synchsafeInt := BytesToIntSynchsafe(synchSafeBytes) synchsafeInt := BytesToIntSynchsafe(synchSafeBytes)

116
v2/frame.go

@ -268,62 +268,66 @@ func (f *Frame) Text() string {
return util.DecodeText(f.Contents) return util.DecodeText(f.Contents)
} }
func v23FlagsToBytes(v23f FrameFlags) []byte { func frameFlagsToBytes(ff FrameFlags, version string) []byte {
var flags = []byte{0, 0} var flagBytes = []byte{0, 0}
if v23f.TagAlterPreservation { switch version {
flags[0] = util.SetBit(flags[0], 8) case V2_2:
} return nil
if v23f.FileAlterPreservation {
flags[0] = util.SetBit(flags[0], 7)
}
if v23f.ReadOnly {
flags[0] = util.SetBit(flags[0], 6)
}
if v23f.Compressed { case V2_3:
flags[1] = util.SetBit(flags[1], 8) if ff.TagAlterPreservation {
} flagBytes[0] = util.SetBit(flagBytes[0], 8)
if v23f.Encrypted { }
flags[1] = util.SetBit(flags[1], 7) if ff.FileAlterPreservation {
} flagBytes[0] = util.SetBit(flagBytes[0], 7)
if v23f.InGroup { }
flags[1] = util.SetBit(flags[1], 6) if ff.ReadOnly {
} flagBytes[0] = util.SetBit(flagBytes[0], 6)
}
return flags if ff.Compressed {
} flagBytes[1] = util.SetBit(flagBytes[1], 8)
}
if ff.Encrypted {
flagBytes[1] = util.SetBit(flagBytes[1], 7)
}
if ff.InGroup {
flagBytes[1] = util.SetBit(flagBytes[1], 6)
}
return flagBytes
func v24FlagsToBytes(v24f FrameFlags) []byte { case V2_4:
var flagBytes = []byte{0, 0} if ff.TagAlterPreservation {
flagBytes[0] = util.SetBit(flagBytes[0], 7)
}
if ff.FileAlterPreservation {
flagBytes[0] = util.SetBit(flagBytes[0], 6)
}
if ff.ReadOnly {
flagBytes[0] = util.SetBit(flagBytes[0], 5)
}
if v24f.TagAlterPreservation { if ff.InGroup {
flagBytes[0] = util.SetBit(flagBytes[0], 7) flagBytes[1] = util.SetBit(flagBytes[1], 7)
} }
if v24f.FileAlterPreservation { if ff.Compressed {
flagBytes[0] = util.SetBit(flagBytes[0], 6) flagBytes[1] = util.SetBit(flagBytes[1], 4)
} }
if v24f.ReadOnly { if ff.Encrypted {
flagBytes[0] = util.SetBit(flagBytes[0], 5) flagBytes[1] = util.SetBit(flagBytes[1], 3)
} }
if ff.Unsyrchronised {
flagBytes[1] = util.SetBit(flagBytes[1], 2)
}
if ff.HasDataLengthIndicator {
flagBytes[1] = util.SetBit(flagBytes[1], 1)
}
return flagBytes
if v24f.InGroup { default:
flagBytes[1] = util.SetBit(flagBytes[1], 7) return nil
}
if v24f.Compressed {
flagBytes[1] = util.SetBit(flagBytes[1], 4)
} }
if v24f.Encrypted {
flagBytes[1] = util.SetBit(flagBytes[1], 3)
}
if v24f.Unsyrchronised {
flagBytes[1] = util.SetBit(flagBytes[1], 2)
}
if v24f.HasDataLengthIndicator {
flagBytes[1] = util.SetBit(flagBytes[1], 1)
}
return flagBytes
} }
// Converts frame to ready-to-write bytes // Converts frame to ready-to-write bytes
@ -337,17 +341,13 @@ func (f *Frame) toBytes(version string) []byte {
buff.Write(util.IntToBytesSynchsafe(f.Header.Size)) buff.Write(util.IntToBytesSynchsafe(f.Header.Size))
// flags // flags
var flagBytes []byte flagBytes := frameFlagsToBytes(f.Header.Flags, version)
switch version { if flagBytes != nil {
case V2_2:
break
case V2_3:
flagBytes = v23FlagsToBytes(f.Header.Flags)
buff.Write(flagBytes)
case V2_4:
flagBytes = v24FlagsToBytes(f.Header.Flags)
buff.Write(flagBytes) buff.Write(flagBytes)
} }
// contents
buff.Write(f.Contents)
return buff.Bytes() return buff.Bytes()
} }

51
v2/frame_test.go

@ -49,3 +49,54 @@ func TestReadNextFrame(t *testing.T) {
"2006", secondFrame.Contents) "2006", secondFrame.Contents)
} }
} }
func TestFrameFlagsToBytes(t *testing.T) {
testFlags := FrameFlags{
TagAlterPreservation: true,
ReadOnly: true,
}
versions := []string{V2_2, V2_3, V2_4}
for _, version := range versions {
flagBytes := frameFlagsToBytes(testFlags, version)
if version == V2_2 && flagBytes != nil {
t.Errorf("frameFlagsToBytes failed: V2_2, expected flagbytes to be nil; got %v", flagBytes)
}
if version != V2_2 && len(flagBytes) != 2 {
t.Errorf("frameFlagsToBytes failed: expected flagbytes to be len of 2; got %v", len(flagBytes))
}
}
}
func TestFrameToBytes(t *testing.T) {
testframe := Frame{
Header: FrameHeader{
ID: "TEST",
Flags: FrameFlags{}, // all false
Size: 4,
},
Contents: []byte{util.EncodingUTF8, 60, 60, 60}, // 60 == <
}
frameBytes := testframe.toBytes(V2_4)
// t.Errorf("%+v", frameBytes)
// 84 69 83 84 0 0 0 4 0 0 3 60 60 60
// 84 69 83 84 - id (4)
// 0 0 - flags (2)
// 0 4 0 0 - size (4)
// header - 4 + 4 + 2 = 10 bytes (success)
// 3 60 60 60 - contents
if len(frameBytes)-int(testframe.Header.Size) != HEADERSIZE {
t.Errorf("FrameToBytes failed: expected header size to be %d; got %d",
HEADERSIZE, len(frameBytes)-int(testframe.Header.Size))
}
if util.DecodeText(frameBytes[10:]) != "<<<" {
t.Errorf("FrameToBytes failed: expected contents to be %v; got %v",
testframe.Contents, frameBytes[10:])
}
}

Loading…
Cancel
Save