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

3
util/conversion_test.go

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

116
v2/frame.go

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

51
v2/frame_test.go

@ -49,3 +49,54 @@ func TestReadNextFrame(t *testing.T) {
"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