mirror of
https://github.com/garraflavatra/go-fmp.git
synced 2025-06-27 12:05:11 +00:00
Tables
This commit is contained in:
@ -21,6 +21,7 @@ const (
|
||||
FMP_CHUNK_SIMPLE_KEY_VALUE
|
||||
FMP_CHUNK_LONG_KEY_VALUE
|
||||
FMP_CHUNK_PATH_PUSH
|
||||
FMP_CHUNK_PATH_PUSH_LONG
|
||||
FMP_CHUNK_PATH_POP
|
||||
FMP_CHUNK_NOOP
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func debug(str string, args ...interface{}) {
|
||||
fmt.Printf(str+"\n", args...)
|
||||
// fmt.Printf(str+"\n", args...)
|
||||
}
|
||||
|
||||
func (f *FmpFile) ToDebugFile(fname string) {
|
||||
|
@ -40,7 +40,6 @@ func OpenFile(path string) (*FmpFile, error) {
|
||||
ctx.FileSize = uint(info.Size())
|
||||
ctx.numSectors = uint64((ctx.FileSize / sectorSize) - 1)
|
||||
ctx.Sectors = make([]*FmpSector, 0)
|
||||
currentPath := make([]uint64, 0)
|
||||
ctx.stream.Seek(2*sectorSize, io.SeekStart)
|
||||
|
||||
for {
|
||||
@ -55,7 +54,7 @@ func OpenFile(path string) (*FmpFile, error) {
|
||||
ctx.Sectors = append(ctx.Sectors, sector)
|
||||
|
||||
if sector.ID != 0 {
|
||||
err = sector.processChunks(ctx.Dictionary, ¤tPath)
|
||||
err = sector.processChunks(ctx.Dictionary)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package fmp
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
@ -48,41 +49,48 @@ func (sect *FmpSector) readChunks() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sect *FmpSector) processChunks(dict *FmpDict, currentPath *[]uint64) error {
|
||||
func (sect *FmpSector) processChunks(dict *FmpDict) error {
|
||||
err := sect.readChunks()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
currentPath := make([]uint64, 0)
|
||||
for _, chunk := range sect.Chunks {
|
||||
switch chunk.Type {
|
||||
case FMP_CHUNK_PATH_PUSH:
|
||||
*currentPath = append(*currentPath, uint64(chunk.Value[0]))
|
||||
case FMP_CHUNK_PATH_PUSH, FMP_CHUNK_PATH_PUSH_LONG:
|
||||
currentPath = append(currentPath, parseVarUint64(chunk.Value))
|
||||
|
||||
s := ""
|
||||
for _, ent := range currentPath {
|
||||
s += fmt.Sprintf("%v. ", ent)
|
||||
}
|
||||
debug("path: %s", s)
|
||||
|
||||
case FMP_CHUNK_PATH_POP:
|
||||
if len(*currentPath) > 0 {
|
||||
*currentPath = (*currentPath)[:len(*currentPath)-1]
|
||||
if len(currentPath) > 0 {
|
||||
currentPath = (currentPath)[:len(currentPath)-1]
|
||||
}
|
||||
|
||||
case FMP_CHUNK_SIMPLE_DATA:
|
||||
dict.set(*currentPath, chunk.Value)
|
||||
dict.SetValue(currentPath, chunk.Value)
|
||||
|
||||
case FMP_CHUNK_SEGMENTED_DATA:
|
||||
// Todo: take index into account
|
||||
dict.set(
|
||||
*currentPath,
|
||||
append(dict.getValue(*currentPath), chunk.Value...),
|
||||
dict.SetValue(
|
||||
currentPath,
|
||||
append(dict.GetValue(currentPath), chunk.Value...),
|
||||
)
|
||||
|
||||
case FMP_CHUNK_SIMPLE_KEY_VALUE:
|
||||
dict.set(
|
||||
append(*currentPath, uint64(chunk.Key)),
|
||||
dict.SetValue(
|
||||
append(currentPath, uint64(chunk.Key)),
|
||||
chunk.Value,
|
||||
)
|
||||
|
||||
case FMP_CHUNK_LONG_KEY_VALUE:
|
||||
dict.set(
|
||||
append(*currentPath, uint64(chunk.Key)), // todo: ??
|
||||
dict.SetValue(
|
||||
append(currentPath, uint64(chunk.Key)), // todo: ??
|
||||
chunk.Value,
|
||||
)
|
||||
|
||||
@ -235,7 +243,7 @@ func (sect *FmpSector) readChunk(payload []byte) (*FmpChunk, error) {
|
||||
case 0x38:
|
||||
valueLength := uint64(payload[1])
|
||||
chunk.Length = 2 + valueLength
|
||||
chunk.Type = FMP_CHUNK_PATH_PUSH
|
||||
chunk.Type = FMP_CHUNK_PATH_PUSH_LONG
|
||||
chunk.Value = payload[2:chunk.Length]
|
||||
|
||||
case 0x3D, 0x40:
|
||||
|
@ -2,46 +2,16 @@ package fmp
|
||||
|
||||
func (ctx *FmpFile) Tables() []*FmpTable {
|
||||
tables := make([]*FmpTable, 0)
|
||||
ent := ctx.Dictionary.GetEntry([]uint64{3, 16, 5})
|
||||
|
||||
for key, ent := range *ctx.Dictionary {
|
||||
if key != 3 {
|
||||
for path, tableEnt := range *ent.Children {
|
||||
if path < 128 {
|
||||
continue
|
||||
}
|
||||
debug("Found a 3")
|
||||
|
||||
for key, ent = range *ent.Children {
|
||||
if key != 16 {
|
||||
continue
|
||||
}
|
||||
debug("Found a 3.16")
|
||||
|
||||
for key, ent = range *ent.Children {
|
||||
if key != 5 {
|
||||
continue
|
||||
}
|
||||
debug("Found a 3.16.5")
|
||||
|
||||
for tablePath := range *ent.Children {
|
||||
if key >= 128 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Found a table!
|
||||
debug("Found a table at 3.16.5.%d", tablePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
name := decodeByteSeq(tableEnt.Children.GetValue([]uint64{16}))
|
||||
table := &FmpTable{ID: path, Name: name}
|
||||
tables = append(tables, table)
|
||||
}
|
||||
|
||||
// metaDict := ctx.Dictionary.get([]uint64{4, 1, 7})
|
||||
// if metaDict == nil {
|
||||
// return tables
|
||||
// }
|
||||
// for _, meta := range *metaDict.Children {
|
||||
// name := decodeByteSeq(meta.Children.get([]uint64{16}).Value)
|
||||
// table := &FmpTable{Name: name}
|
||||
// tables = append(tables, table)
|
||||
// }
|
||||
|
||||
return tables
|
||||
}
|
||||
|
@ -29,14 +29,16 @@ func TestTables(t *testing.T) {
|
||||
}
|
||||
tables := f.Tables()
|
||||
|
||||
if len(tables) != 1 || tables[0].Name != "Untitled" {
|
||||
tablesString := ""
|
||||
for i, table := range tables {
|
||||
tablesString += table.Name
|
||||
if i < len(tables)-1 {
|
||||
tablesString += ", "
|
||||
}
|
||||
expected := "WayDomains, WayProcesses, Untitled"
|
||||
tablesString := ""
|
||||
for i, table := range tables {
|
||||
tablesString += table.Name
|
||||
if i < len(tables)-1 {
|
||||
tablesString += ", "
|
||||
}
|
||||
t.Errorf("expected tables to be 'Untitled', got '%s'", tablesString)
|
||||
}
|
||||
|
||||
if tablesString != expected {
|
||||
t.Errorf("expected tables to be '%s', got '%s'", expected, tablesString)
|
||||
}
|
||||
}
|
||||
|
@ -47,10 +47,11 @@ type FmpDictEntry struct {
|
||||
}
|
||||
|
||||
type FmpTable struct {
|
||||
ID uint64
|
||||
Name string
|
||||
}
|
||||
|
||||
func (dict *FmpDict) get(path []uint64) *FmpDictEntry {
|
||||
func (dict *FmpDict) GetEntry(path []uint64) *FmpDictEntry {
|
||||
for i, key := range path {
|
||||
_, ok := (*dict)[key]
|
||||
if !ok {
|
||||
@ -61,20 +62,23 @@ func (dict *FmpDict) get(path []uint64) *FmpDictEntry {
|
||||
return (*dict)[key]
|
||||
} else {
|
||||
dict = (*dict)[key].Children
|
||||
if dict == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dict *FmpDict) getValue(path []uint64) []byte {
|
||||
ent := dict.get(path)
|
||||
func (dict *FmpDict) GetValue(path []uint64) []byte {
|
||||
ent := dict.GetEntry(path)
|
||||
if ent != nil {
|
||||
return ent.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dict *FmpDict) set(path []uint64, value []byte) {
|
||||
func (dict *FmpDict) SetValue(path []uint64, value []byte) {
|
||||
for i, key := range path {
|
||||
_, ok := (*dict)[key]
|
||||
if !ok {
|
||||
|
Reference in New Issue
Block a user