diff --git a/README b/README index e577e2d..69d1689 100644 --- a/README +++ b/README @@ -30,7 +30,7 @@ type = bytefield | "float32" | "float64" . -bytefield = "byte[" ( INTEGER | IDENT ) "]". +bytefield = "byte[" ( INTEGER | IDENT [ "*" INTEGER ]) "]". ``` The identifier of a definition line can be left empty to ignore that particular value. @@ -59,7 +59,7 @@ element of the sequence at a certain offset: ``` little endian - : byte[offset] + : byte[offset*32] value : int32 ``` diff --git a/laymanshex.go b/laymanshex.go index ab1c646..9de2253 100644 --- a/laymanshex.go +++ b/laymanshex.go @@ -168,17 +168,30 @@ type formatAssignment struct { used bool } +func splitVariableExpression(s string) (string, int64) { + split := strings.Split(s, "*") + name := trim(split[0]) + if len(split) == 2 { + factor, err := strconv.ParseInt(split[1], 0, 64) + optPanic("parsing definition: "+s, err) + return name, factor + } + return name, 1 +} + func (part *filePart) setByteFieldHandling(assignments map[string]*formatAssignment) { tmp := trim(strings.TrimSuffix(strings.TrimPrefix(part.parttype, "byte["), "]")) var bytes int64 var err error if bytes, err = strconv.ParseInt(tmp, 10, 64); err != nil { - if ass, ok := assignments[tmp]; ok { - bytes = ass.val + variable, factor := splitVariableExpression(tmp) + if ass, ok := assignments[variable]; ok { + bytes = ass.val * factor ass.used = true err = nil } else { - msg := "byte field definition in format description: could neither parse size to int64 nor obtain value from -fvar" + msg := "byte field definition in format description: could neither parse size to int64 nor obtain value from -fvar" + + " (" + part.parttype + ")" if part.name != "" { msg += " - definition of " + part.name }