1
0
mirror of https://github.com/garraflavatra/go-fmp.git synced 2025-06-28 04:25:11 +00:00

Table parsing (WIP)

This commit is contained in:
2025-06-12 11:44:57 +02:00
parent 43523c458a
commit 8562e1147b
6 changed files with 68 additions and 17 deletions

View File

@ -232,16 +232,3 @@ func (ctx *FmpFile) readChunk(payload []byte) (*FmpChunk, error) {
return nil, nil
}
func parseVarUint32(payload []byte) uint32 {
var length uint32
n := len(payload)
if n > 4 {
n = 4 // clamp to max uint32
}
for i := range n {
length <<= 8
length |= uint32(payload[i])
}
return length
}

View File

@ -69,7 +69,7 @@ func OpenFile(path string) (*FmpFile, error) {
// Todo: take index into account
ctx.Dictionary.set(
currentPath,
append(ctx.Dictionary.get(currentPath), chunk.Value...),
append(ctx.Dictionary.getValue(currentPath), chunk.Value...),
)
case FMP_CHUNK_SIMPLE_KEY_VALUE:

12
fmp/fmp_table.go Normal file
View File

@ -0,0 +1,12 @@
package fmp
func (ctx *FmpFile) Tables() []*FmpTable {
tables := make([]*FmpTable, 0)
metaDict := ctx.Dictionary.get([]uint16{4, 1, 7})
for _, meta := range *metaDict.Children {
name := decodeByteSeq(meta.Children.get([]uint16{16}).Value)
table := &FmpTable{Name: name}
tables = append(tables, table)
}
return tables
}

View File

@ -19,6 +19,24 @@ 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")
}
func TestTables(t *testing.T) {
f, err := OpenFile("../files/Untitled.fmp12")
if err != nil {
t.Fatal(err)
}
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 += ", "
}
}
t.Errorf("expected tables to be 'Untitled', got '%s'", tablesString)
}
}

View File

@ -39,7 +39,11 @@ type FmpDictEntry struct {
Children *FmpDict
}
func (dict *FmpDict) get(path []uint16) []byte {
type FmpTable struct {
Name string
}
func (dict *FmpDict) get(path []uint16) *FmpDictEntry {
for i, key := range path {
_, ok := (*dict)[key]
if !ok {
@ -47,7 +51,7 @@ func (dict *FmpDict) get(path []uint16) []byte {
}
if i == len(path)-1 {
return (*dict)[key].Value
return (*dict)[key]
} else {
dict = (*dict)[key].Children
}
@ -55,6 +59,14 @@ func (dict *FmpDict) get(path []uint16) []byte {
return nil
}
func (dict *FmpDict) getValue(path []uint16) []byte {
ent := dict.get(path)
if ent != nil {
return ent.Value
}
return nil
}
func (dict *FmpDict) set(path []uint16, value []byte) {
for i, key := range path {
_, ok := (*dict)[key]

22
fmp/fmp_util.go Normal file
View File

@ -0,0 +1,22 @@
package fmp
func parseVarUint32(payload []byte) uint32 {
var length uint32
n := len(payload)
if n > 4 {
n = 4 // clamp to max uint32
}
for i := range n {
length <<= 8
length |= uint32(payload[i])
}
return length
}
func decodeByteSeq(payload []byte) string {
result := ""
for i := range payload {
result += string(payload[i] ^ 0x5A)
}
return result
}