1
0
mirror of https://github.com/garraflavatra/go-fmp.git synced 2025-06-27 20:15:11 +00:00

Add NewSector function

This commit is contained in:
2025-06-22 20:08:53 +02:00
parent 4ab7f0a588
commit c08c429b99
5 changed files with 71 additions and 9 deletions

View File

@ -42,7 +42,7 @@ func (dict *FmpDict) GetChildren(path ...uint64) *FmpDict {
return &FmpDict{}
}
func (dict *FmpDict) SetValue(path []uint64, value []byte) {
func (dict *FmpDict) set(path []uint64, value []byte) {
for i, key := range path {
_, ok := (*dict)[key]
if !ok {

View File

@ -32,7 +32,7 @@ type FmpFile struct {
numSectors uint64 // Excludes the header sector
currentSectorID uint64
stream io.ReadSeeker
stream *os.File
}
func OpenFile(path string) (*FmpFile, error) {
@ -41,11 +41,10 @@ func OpenFile(path string) (*FmpFile, error) {
return nil, err
}
stream, err := os.Open(path)
stream, err := os.OpenFile(path, os.O_RDWR, 0)
if err != nil {
return nil, err
}
defer stream.Close()
ctx := &FmpFile{stream: stream, Dictionary: &FmpDict{}}
if err := ctx.readHeader(); err != nil {
@ -90,6 +89,10 @@ func OpenFile(path string) (*FmpFile, error) {
return ctx, nil
}
func (ctx *FmpFile) Close() {
ctx.stream.Close()
}
func (ctx *FmpFile) readHeader() error {
buf := make([]byte, headerSize)
_, err := ctx.stream.Read(buf)
@ -208,3 +211,43 @@ func (ctx *FmpFile) readTables() {
ctx.tables = tables
}
func (ctx *FmpFile) NewSector() (*FmpSector, error) {
id := uint64(len(ctx.Sectors)) + 1
prevID := id - 2
ctx.Sectors[prevID].NextID = uint64(id)
_, err := ctx.stream.WriteAt(encodeUint(4, int(id)), int64((id-1)*sectorSize)+4)
if err != nil {
return nil, err
}
sector := &FmpSector{
ID: uint64(id),
Deleted: false,
Level: 0,
PrevID: prevID,
NextID: 0,
Chunks: make([]*FmpChunk, 0),
}
ctx.Sectors = append(ctx.Sectors, sector)
sectorBuf := make([]byte, sectorSize)
sectorBuf[0] = 0 // deleted
sectorBuf[1] = 0 // level
writeToSlice(sectorBuf, 4, encodeUint(4, int(prevID))...)
writeToSlice(sectorBuf, 8, encodeUint(4, int(id))...)
_, err = ctx.stream.WriteAt(sectorBuf, int64((id+1)*sectorSize))
if err != nil {
return nil, err
}
return sector, nil
}
func (ctx *FmpFile) setValue(path []uint64, value []byte) {
// ctx.Dictionary.set(path, value)
}

View File

@ -79,23 +79,23 @@ func (sect *FmpSector) processChunks(dict *FmpDict) error {
}
case FmpChunkSimpleData:
dict.SetValue(currentPath, chunk.Value)
dict.set(currentPath, chunk.Value)
case FmpChunkSegmentedData:
// Todo: take index into account
dict.SetValue(
dict.set(
currentPath,
append(dict.GetValue(currentPath...), chunk.Value...),
)
case FmpChunkSimpleKeyValue:
dict.SetValue(
dict.set(
append(currentPath, uint64(chunk.Key)),
chunk.Value,
)
case FmpChunkLongKeyValue:
dict.SetValue(
dict.set(
append(currentPath, uint64(chunk.Key)), // todo: ??
chunk.Value,
)

View File

@ -10,8 +10,10 @@ func TestOpenFile(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer f.Close()
if f.FileSize != 229376 {
t.Errorf("expected file size to be 393216, got %d", f.FileSize)
t.Errorf("expected file size to be 229376, got %d", f.FileSize)
}
if f.numSectors != 55 {
t.Errorf("expected number of sectors to be 55, got %d", f.numSectors)
@ -22,6 +24,7 @@ func TestOpenFile(t *testing.T) {
if f.VersionDate.Format("2006-01-02") != "2025-01-11" {
t.Errorf("expected version date to be '2025-01-11', got '%s'", f.VersionDate.Format("2006-01-02"))
}
f.ToDebugFile("../private/output")
}
@ -30,6 +33,7 @@ func TestTables(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer f.Close()
expectedNames := []string{"Untitled"}
tableNames := []string{}

View File

@ -24,3 +24,18 @@ func decodeString(payload []byte) string {
}
return result
}
func encodeUint(size uint, value int) []byte {
result := make([]byte, size)
for i := range size {
result[i] = byte(value & 0xFF)
value >>= 8
}
return result
}
func writeToSlice(slice []byte, start int, payload ...byte) {
for i := range payload {
slice[start+i] = payload[i]
}
}