Browse Source

Little progress towards writing support

main
Unbewohnte 3 years ago
parent
commit
307feeb13f
  1. 19
      util/bits.go
  2. 12
      util/bits_test.go
  3. 134
      v2/frame.go

19
util/bits.go

@ -1,6 +1,19 @@
package util package util
// Tells if bit is set in given byte // Tells if bit is set in given byte,
func GetBit(n byte, bitN int) bool { // if bitN <= 0 - always returns false
return n&byte(1<<bitN-1) != 0 func GetBit(b byte, bitN int) bool {
if bitN == 0 {
return false
}
return b&byte(1<<bitN-1) != 0
}
// Sets bit to 1 in provided byte, if bitN <= 0
// returns original b without modifications
func SetBit(b byte, bitN int) byte {
if bitN == 0 {
return b
}
return b | byte(1<<byte(bitN)-1)
} }

12
util/bits_test.go

@ -12,3 +12,15 @@ func TestGetBit(t *testing.T) {
} }
} }
} }
func TestSetBit(t *testing.T) {
var testByte byte = 0
if SetBit(testByte, 1) != 1 {
t.Errorf("SetBit failed: expected output %d; got %d", 1, SetBit(testByte, 1))
}
if SetBit(testByte, 8) != 255 {
t.Errorf("SetBit failed: expected output %d; got %d", 255, SetBit(testByte, 8))
}
}

134
v2/frame.go

@ -20,6 +20,8 @@ type FrameFlags struct {
Compressed bool Compressed bool
Encrypted bool Encrypted bool
InGroup bool InGroup bool
Unsyrchronised bool
HasDataLengthIndicator bool
} }
type FrameHeader struct { type FrameHeader struct {
@ -47,17 +49,9 @@ func isValidFrameID(frameID []byte) bool {
return true return true
} }
// Structuralises frame header from given bytes. For versions see: constants. func getV22FrameHeader(fHeaderbytes []byte) (FrameHeader, error) {
func getFrameHeader(fHeaderbytes []byte, version string) (FrameHeader, error) {
// validation check
if int(len(fHeaderbytes)) != int(10) && int(len(fHeaderbytes)) != int(6) {
return FrameHeader{}, ErrInvalidFHeaderSize
}
var header FrameHeader var header FrameHeader
switch version {
case V2_2:
if !isValidFrameID(fHeaderbytes[0:3]) { if !isValidFrameID(fHeaderbytes[0:3]) {
return FrameHeader{}, ErrInvalidID return FrameHeader{}, ErrInvalidID
} }
@ -66,13 +60,12 @@ func getFrameHeader(fHeaderbytes []byte, version string) (FrameHeader, error) {
framesizeBytes := util.BytesToIntSynchsafe(fHeaderbytes[3:6]) framesizeBytes := util.BytesToIntSynchsafe(fHeaderbytes[3:6])
header.Size = framesizeBytes header.Size = framesizeBytes
case V2_3: return header, nil
fallthrough }
case V2_4: func getV23FrameHeader(fHeaderbytes []byte) (FrameHeader, error) {
fallthrough var header FrameHeader
default:
// ID // ID
if !isValidFrameID(fHeaderbytes[0:4]) { if !isValidFrameID(fHeaderbytes[0:4]) {
return FrameHeader{}, ErrInvalidID return FrameHeader{}, ErrInvalidID
@ -124,6 +117,106 @@ func getFrameHeader(fHeaderbytes []byte, version string) (FrameHeader, error) {
} }
header.Flags = flags header.Flags = flags
return header, nil
}
func getV24FrameHeader(fHeaderbytes []byte) (FrameHeader, error) {
var header FrameHeader
// ID
if !isValidFrameID(fHeaderbytes[0:4]) {
return FrameHeader{}, ErrInvalidID
}
header.ID = string(fHeaderbytes[0:4])
// Size
framesizeBytes := fHeaderbytes[4:8]
framesize := util.BytesToIntSynchsafe(framesizeBytes)
header.Size = framesize
// Flags
frameFlags1 := fHeaderbytes[8]
frameFlags2 := fHeaderbytes[9]
var flags FrameFlags
if util.GetBit(frameFlags1, 2) {
flags.TagAlterPreservation = true
} else {
flags.TagAlterPreservation = false
}
if util.GetBit(frameFlags1, 3) {
flags.FileAlterPreservation = true
} else {
flags.FileAlterPreservation = false
}
if util.GetBit(frameFlags1, 4) {
flags.ReadOnly = true
} else {
flags.ReadOnly = false
}
if util.GetBit(frameFlags2, 2) {
flags.InGroup = true
} else {
flags.InGroup = false
}
if util.GetBit(frameFlags2, 5) {
flags.Compressed = true
} else {
flags.Compressed = false
}
if util.GetBit(frameFlags2, 6) {
flags.Encrypted = true
} else {
flags.Encrypted = false
}
if util.GetBit(frameFlags2, 7) {
flags.Unsyrchronised = true
} else {
flags.Unsyrchronised = false
}
if util.GetBit(frameFlags2, 8) {
flags.HasDataLengthIndicator = true
} else {
flags.HasDataLengthIndicator = false
}
header.Flags = flags
return header, nil
}
// Structuralises frame header from given bytes. For versions see: constants.
func getFrameHeader(fHeaderbytes []byte, version string) (FrameHeader, error) {
// validation check
if int(len(fHeaderbytes)) != int(10) && int(len(fHeaderbytes)) != int(6) {
return FrameHeader{}, ErrInvalidFHeaderSize
}
var header FrameHeader
var err error
switch version {
case V2_2:
header, err = getV22FrameHeader(fHeaderbytes)
if err != nil {
return FrameHeader{}, err
}
case V2_3:
header, err = getV23FrameHeader(fHeaderbytes)
if err != nil {
return FrameHeader{}, err
}
case V2_4:
header, err = getV24FrameHeader(fHeaderbytes)
if err != nil {
return FrameHeader{}, err
}
} }
return header, nil return header, nil
@ -174,6 +267,19 @@ func (f *Frame) Text() string {
return util.DecodeText(f.Contents) return util.DecodeText(f.Contents)
} }
// Converts frame to ready-to-write bytes
// func (f *Frame) ToBytes() []byte {
// buff := new(bytes.Buffer)
// // identifier
// buff.Write([]byte(f.Header.ID))
// // size
// buff.Write(util.IntToBytesSynchsafe(f.Header.Size))
// // flags
// return buff.Bytes()
// }
// Returns bytes of the frame that can be // Returns bytes of the frame that can be
// written into a file. // written into a file.
// func (f *Frame) Bytes() ([]byte, error) { // func (f *Frame) Bytes() ([]byte, error) {

Loading…
Cancel
Save