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. 238
      v2/frame.go

19
util/bits.go

@ -1,6 +1,19 @@
package util
// Tells if bit is set in given byte
func GetBit(n byte, bitN int) bool {
return n&byte(1<<bitN-1) != 0
// Tells if bit is set in given byte,
// if bitN <= 0 - always returns false
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))
}
}

238
v2/frame.go

@ -14,12 +14,14 @@ var ErrInvalidFHeaderSize error = fmt.Errorf("frame header must be 6 or 10 bytes
var ErrInvalidID error = fmt.Errorf("invalid identifier")
type FrameFlags struct {
TagAlterPreservation bool
FileAlterPreservation bool
ReadOnly bool
Compressed bool
Encrypted bool
InGroup bool
TagAlterPreservation bool
FileAlterPreservation bool
ReadOnly bool
Compressed bool
Encrypted bool
InGroup bool
Unsyrchronised bool
HasDataLengthIndicator bool
}
type FrameHeader struct {
@ -47,83 +49,174 @@ func isValidFrameID(frameID []byte) bool {
return true
}
// 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
func getV22FrameHeader(fHeaderbytes []byte) (FrameHeader, error) {
var header FrameHeader
if !isValidFrameID(fHeaderbytes[0:3]) {
return FrameHeader{}, ErrInvalidID
}
header.ID = string(fHeaderbytes[0:3])
framesizeBytes := util.BytesToIntSynchsafe(fHeaderbytes[3:6])
header.Size = framesizeBytes
return header, nil
}
func getV23FrameHeader(fHeaderbytes []byte) (FrameHeader, error) {
var header FrameHeader
switch version {
case V2_2:
if !isValidFrameID(fHeaderbytes[0:3]) {
return FrameHeader{}, ErrInvalidID
}
header.ID = string(fHeaderbytes[0:3])
// ID
if !isValidFrameID(fHeaderbytes[0:4]) {
return FrameHeader{}, ErrInvalidID
}
header.ID = string(fHeaderbytes[0:4])
framesizeBytes := util.BytesToIntSynchsafe(fHeaderbytes[3:6])
header.Size = framesizeBytes
// Size
framesizeBytes := fHeaderbytes[4:8]
case V2_3:
fallthrough
framesize := util.BytesToIntSynchsafe(framesizeBytes)
case V2_4:
fallthrough
header.Size = framesize
default:
// ID
if !isValidFrameID(fHeaderbytes[0:4]) {
return FrameHeader{}, ErrInvalidID
}
header.ID = string(fHeaderbytes[0:4])
// Flags
frameFlags1 := fHeaderbytes[8]
frameFlags2 := fHeaderbytes[9]
// Size
framesizeBytes := fHeaderbytes[4:8]
var flags FrameFlags
framesize := util.BytesToIntSynchsafe(framesizeBytes)
if util.GetBit(frameFlags1, 1) {
flags.TagAlterPreservation = true
} else {
flags.TagAlterPreservation = false
}
if util.GetBit(frameFlags1, 2) {
flags.FileAlterPreservation = true
} else {
flags.FileAlterPreservation = false
}
if util.GetBit(frameFlags1, 3) {
flags.ReadOnly = true
} else {
flags.ReadOnly = false
}
if util.GetBit(frameFlags2, 1) {
flags.Compressed = true
} else {
flags.Compressed = false
}
if util.GetBit(frameFlags2, 1) {
flags.Encrypted = true
} else {
flags.Encrypted = false
}
if util.GetBit(frameFlags2, 1) {
flags.InGroup = true
} else {
flags.InGroup = false
}
header.Size = framesize
header.Flags = flags
// Flags
frameFlags1 := fHeaderbytes[8]
frameFlags2 := fHeaderbytes[9]
return header, nil
}
var flags FrameFlags
func getV24FrameHeader(fHeaderbytes []byte) (FrameHeader, error) {
var header FrameHeader
if util.GetBit(frameFlags1, 1) {
flags.TagAlterPreservation = true
} else {
flags.TagAlterPreservation = false
}
if util.GetBit(frameFlags1, 2) {
flags.FileAlterPreservation = true
} else {
flags.FileAlterPreservation = false
}
if util.GetBit(frameFlags1, 3) {
flags.ReadOnly = true
} else {
flags.ReadOnly = false
}
if util.GetBit(frameFlags2, 1) {
flags.Compressed = true
} else {
flags.Compressed = false
}
if util.GetBit(frameFlags2, 1) {
flags.Encrypted = true
} else {
flags.Encrypted = false
// 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
}
if util.GetBit(frameFlags2, 1) {
flags.InGroup = true
} else {
flags.InGroup = false
case V2_3:
header, err = getV23FrameHeader(fHeaderbytes)
if err != nil {
return FrameHeader{}, err
}
header.Flags = flags
case V2_4:
header, err = getV24FrameHeader(fHeaderbytes)
if err != nil {
return FrameHeader{}, err
}
}
return header, nil
@ -174,6 +267,19 @@ func (f *Frame) Text() string {
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
// written into a file.
// func (f *Frame) Bytes() ([]byte, error) {

Loading…
Cancel
Save