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 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))
}
}

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") var ErrInvalidID error = fmt.Errorf("invalid identifier")
type FrameFlags struct { type FrameFlags struct {
TagAlterPreservation bool TagAlterPreservation bool
FileAlterPreservation bool FileAlterPreservation bool
ReadOnly bool ReadOnly bool
Compressed bool Compressed bool
Encrypted bool Encrypted bool
InGroup bool InGroup bool
Unsyrchronised bool
HasDataLengthIndicator bool
} }
type FrameHeader struct { type FrameHeader struct {
@ -47,83 +49,174 @@ 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) { var header FrameHeader
// validation check
if int(len(fHeaderbytes)) != int(10) && int(len(fHeaderbytes)) != int(6) { if !isValidFrameID(fHeaderbytes[0:3]) {
return FrameHeader{}, ErrInvalidFHeaderSize 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 var header FrameHeader
switch version { // ID
case V2_2: if !isValidFrameID(fHeaderbytes[0:4]) {
if !isValidFrameID(fHeaderbytes[0:3]) { return FrameHeader{}, ErrInvalidID
return FrameHeader{}, ErrInvalidID }
} header.ID = string(fHeaderbytes[0:4])
header.ID = string(fHeaderbytes[0:3])
framesizeBytes := util.BytesToIntSynchsafe(fHeaderbytes[3:6]) // Size
header.Size = framesizeBytes framesizeBytes := fHeaderbytes[4:8]
case V2_3: framesize := util.BytesToIntSynchsafe(framesizeBytes)
fallthrough
case V2_4: header.Size = framesize
fallthrough
default: // Flags
// ID frameFlags1 := fHeaderbytes[8]
if !isValidFrameID(fHeaderbytes[0:4]) { frameFlags2 := fHeaderbytes[9]
return FrameHeader{}, ErrInvalidID
}
header.ID = string(fHeaderbytes[0:4])
// Size var flags FrameFlags
framesizeBytes := fHeaderbytes[4:8]
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 return header, nil
frameFlags1 := fHeaderbytes[8] }
frameFlags2 := fHeaderbytes[9]
var flags FrameFlags func getV24FrameHeader(fHeaderbytes []byte) (FrameHeader, error) {
var header FrameHeader
if util.GetBit(frameFlags1, 1) { // ID
flags.TagAlterPreservation = true if !isValidFrameID(fHeaderbytes[0:4]) {
} else { return FrameHeader{}, ErrInvalidID
flags.TagAlterPreservation = false }
} header.ID = string(fHeaderbytes[0:4])
if util.GetBit(frameFlags1, 2) {
flags.FileAlterPreservation = true // Size
} else { framesizeBytes := fHeaderbytes[4:8]
flags.FileAlterPreservation = false
} framesize := util.BytesToIntSynchsafe(framesizeBytes)
if util.GetBit(frameFlags1, 3) {
flags.ReadOnly = true header.Size = framesize
} else {
flags.ReadOnly = false // Flags
} frameFlags1 := fHeaderbytes[8]
if util.GetBit(frameFlags2, 1) { frameFlags2 := fHeaderbytes[9]
flags.Compressed = true
} else { var flags FrameFlags
flags.Compressed = false
} if util.GetBit(frameFlags1, 2) {
if util.GetBit(frameFlags2, 1) { flags.TagAlterPreservation = true
flags.Encrypted = true } else {
} else { flags.TagAlterPreservation = false
flags.Encrypted = 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 case V2_3:
} else { header, err = getV23FrameHeader(fHeaderbytes)
flags.InGroup = false 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 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