1
0
mirror of https://github.com/garraflavatra/go-fmp.git synced 2025-06-28 04:25: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{} return &FmpDict{}
} }
func (dict *FmpDict) SetValue(path []uint64, value []byte) { func (dict *FmpDict) set(path []uint64, value []byte) {
for i, key := range path { for i, key := range path {
_, ok := (*dict)[key] _, ok := (*dict)[key]
if !ok { if !ok {

View File

@ -32,7 +32,7 @@ type FmpFile struct {
numSectors uint64 // Excludes the header sector numSectors uint64 // Excludes the header sector
currentSectorID uint64 currentSectorID uint64
stream io.ReadSeeker stream *os.File
} }
func OpenFile(path string) (*FmpFile, error) { func OpenFile(path string) (*FmpFile, error) {
@ -41,11 +41,10 @@ func OpenFile(path string) (*FmpFile, error) {
return nil, err return nil, err
} }
stream, err := os.Open(path) stream, err := os.OpenFile(path, os.O_RDWR, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer stream.Close()
ctx := &FmpFile{stream: stream, Dictionary: &FmpDict{}} ctx := &FmpFile{stream: stream, Dictionary: &FmpDict{}}
if err := ctx.readHeader(); err != nil { if err := ctx.readHeader(); err != nil {
@ -90,6 +89,10 @@ func OpenFile(path string) (*FmpFile, error) {
return ctx, nil return ctx, nil
} }
func (ctx *FmpFile) Close() {
ctx.stream.Close()
}
func (ctx *FmpFile) readHeader() error { func (ctx *FmpFile) readHeader() error {
buf := make([]byte, headerSize) buf := make([]byte, headerSize)
_, err := ctx.stream.Read(buf) _, err := ctx.stream.Read(buf)
@ -208,3 +211,43 @@ func (ctx *FmpFile) readTables() {
ctx.tables = tables 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: case FmpChunkSimpleData:
dict.SetValue(currentPath, chunk.Value) dict.set(currentPath, chunk.Value)
case FmpChunkSegmentedData: case FmpChunkSegmentedData:
// Todo: take index into account // Todo: take index into account
dict.SetValue( dict.set(
currentPath, currentPath,
append(dict.GetValue(currentPath...), chunk.Value...), append(dict.GetValue(currentPath...), chunk.Value...),
) )
case FmpChunkSimpleKeyValue: case FmpChunkSimpleKeyValue:
dict.SetValue( dict.set(
append(currentPath, uint64(chunk.Key)), append(currentPath, uint64(chunk.Key)),
chunk.Value, chunk.Value,
) )
case FmpChunkLongKeyValue: case FmpChunkLongKeyValue:
dict.SetValue( dict.set(
append(currentPath, uint64(chunk.Key)), // todo: ?? append(currentPath, uint64(chunk.Key)), // todo: ??
chunk.Value, chunk.Value,
) )

View File

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

View File

@ -24,3 +24,18 @@ func decodeString(payload []byte) string {
} }
return result 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]
}
}