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:
@ -232,16 +232,3 @@ func (ctx *FmpFile) readChunk(payload []byte) (*FmpChunk, error) {
|
|||||||
|
|
||||||
return nil, nil
|
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
|
|
||||||
}
|
|
||||||
|
@ -69,7 +69,7 @@ func OpenFile(path string) (*FmpFile, error) {
|
|||||||
// Todo: take index into account
|
// Todo: take index into account
|
||||||
ctx.Dictionary.set(
|
ctx.Dictionary.set(
|
||||||
currentPath,
|
currentPath,
|
||||||
append(ctx.Dictionary.get(currentPath), chunk.Value...),
|
append(ctx.Dictionary.getValue(currentPath), chunk.Value...),
|
||||||
)
|
)
|
||||||
|
|
||||||
case FMP_CHUNK_SIMPLE_KEY_VALUE:
|
case FMP_CHUNK_SIMPLE_KEY_VALUE:
|
||||||
|
12
fmp/fmp_table.go
Normal file
12
fmp/fmp_table.go
Normal 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
|
||||||
|
}
|
@ -19,6 +19,24 @@ 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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -39,7 +39,11 @@ type FmpDictEntry struct {
|
|||||||
Children *FmpDict
|
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 {
|
for i, key := range path {
|
||||||
_, ok := (*dict)[key]
|
_, ok := (*dict)[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -47,7 +51,7 @@ func (dict *FmpDict) get(path []uint16) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if i == len(path)-1 {
|
if i == len(path)-1 {
|
||||||
return (*dict)[key].Value
|
return (*dict)[key]
|
||||||
} else {
|
} else {
|
||||||
dict = (*dict)[key].Children
|
dict = (*dict)[key].Children
|
||||||
}
|
}
|
||||||
@ -55,6 +59,14 @@ func (dict *FmpDict) get(path []uint16) []byte {
|
|||||||
return nil
|
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) {
|
func (dict *FmpDict) set(path []uint16, value []byte) {
|
||||||
for i, key := range path {
|
for i, key := range path {
|
||||||
_, ok := (*dict)[key]
|
_, ok := (*dict)[key]
|
||||||
|
22
fmp/fmp_util.go
Normal file
22
fmp/fmp_util.go
Normal 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
|
||||||
|
}
|
Reference in New Issue
Block a user