2025-06-12 11:44:57 +02:00
|
|
|
package fmp
|
|
|
|
|
2025-06-14 16:28:41 +02:00
|
|
|
type FmpTable struct {
|
2025-06-15 21:09:58 +02:00
|
|
|
ID uint64
|
|
|
|
Name string
|
2025-06-22 18:43:06 +02:00
|
|
|
Columns map[uint64]FmpColumn
|
|
|
|
Records map[uint64]FmpRecord
|
2025-06-15 21:09:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type FmpColumn struct {
|
2025-06-22 18:43:06 +02:00
|
|
|
Index uint64
|
2025-06-15 21:09:58 +02:00
|
|
|
Name string
|
|
|
|
Type FmpFieldType
|
|
|
|
DataType FmpDataType
|
|
|
|
StorageType FmpFieldStorageType
|
|
|
|
AutoEnter FmpAutoEnterOption
|
2025-06-16 11:29:48 +02:00
|
|
|
Repetitions uint8
|
2025-06-15 21:09:58 +02:00
|
|
|
Indexed bool
|
2025-06-14 16:28:41 +02:00
|
|
|
}
|
|
|
|
|
2025-06-22 18:43:06 +02:00
|
|
|
type FmpRecord struct {
|
|
|
|
Index uint64
|
|
|
|
Values map[uint64]string
|
|
|
|
}
|
|
|
|
|
2025-06-12 11:44:57 +02:00
|
|
|
func (ctx *FmpFile) Tables() []*FmpTable {
|
|
|
|
tables := make([]*FmpTable, 0)
|
2025-06-15 21:09:58 +02:00
|
|
|
ent := ctx.Dictionary.GetEntry(3, 16, 5)
|
2025-06-12 15:12:34 +02:00
|
|
|
|
2025-06-14 15:19:36 +02:00
|
|
|
for path, tableEnt := range *ent.Children {
|
|
|
|
if path < 128 {
|
2025-06-12 15:12:34 +02:00
|
|
|
continue
|
|
|
|
}
|
2025-06-15 21:09:58 +02:00
|
|
|
|
|
|
|
table := &FmpTable{
|
|
|
|
ID: path,
|
2025-06-22 18:43:06 +02:00
|
|
|
Name: decodeFmpString(tableEnt.Children.GetValue(16)),
|
|
|
|
Columns: map[uint64]FmpColumn{},
|
|
|
|
Records: map[uint64]FmpRecord{},
|
2025-06-15 21:09:58 +02:00
|
|
|
}
|
|
|
|
|
2025-06-14 15:19:36 +02:00
|
|
|
tables = append(tables, table)
|
2025-06-15 21:09:58 +02:00
|
|
|
|
2025-06-22 18:43:06 +02:00
|
|
|
for colPath, colEnt := range *ctx.Dictionary.GetChildren(table.ID, 3, 5) {
|
|
|
|
name := decodeFmpString(colEnt.Children.GetValue(16))
|
2025-06-15 21:09:58 +02:00
|
|
|
flags := colEnt.Children.GetValue(2)
|
|
|
|
|
|
|
|
column := FmpColumn{
|
2025-06-22 18:43:06 +02:00
|
|
|
Index: colPath,
|
2025-06-15 21:09:58 +02:00
|
|
|
Name: name,
|
|
|
|
Type: FmpFieldType(flags[0]),
|
|
|
|
DataType: FmpDataType(flags[1]),
|
|
|
|
StorageType: FmpFieldStorageType(flags[9]),
|
2025-06-16 11:29:48 +02:00
|
|
|
Repetitions: flags[25],
|
2025-06-15 21:09:58 +02:00
|
|
|
Indexed: flags[8] == 128,
|
|
|
|
}
|
|
|
|
|
|
|
|
if flags[11] == 1 {
|
|
|
|
column.AutoEnter = autoEnterPresetMap[flags[4]]
|
|
|
|
} else {
|
|
|
|
column.AutoEnter = autoEnterOptionMap[flags[11]]
|
|
|
|
}
|
|
|
|
|
2025-06-22 18:43:06 +02:00
|
|
|
table.Columns[column.Index] = column
|
|
|
|
}
|
|
|
|
|
|
|
|
for recPath, recEnt := range *ctx.Dictionary.GetChildren(table.ID, 5) {
|
|
|
|
record := FmpRecord{Index: recPath, Values: make(map[uint64]string)}
|
|
|
|
table.Records[record.Index] = record
|
|
|
|
|
|
|
|
for colIndex, value := range *recEnt.Children {
|
|
|
|
record.Values[colIndex] = decodeFmpString(value.Value)
|
|
|
|
}
|
2025-06-15 21:09:58 +02:00
|
|
|
}
|
2025-06-12 11:44:57 +02:00
|
|
|
}
|
2025-06-12 15:12:34 +02:00
|
|
|
|
2025-06-12 11:44:57 +02:00
|
|
|
return tables
|
|
|
|
}
|