1
0
Fork 0
mirror of https://github.com/Luzifer/sii.git synced 2024-10-18 05:14:19 +00:00

Add writing of unit files

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2019-12-10 23:20:25 +01:00
parent 426e54f372
commit ccb5be1dbe
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E
11 changed files with 457 additions and 179 deletions

View file

@ -11,7 +11,7 @@ type Company struct {
JobOffer []Ptr `sii:"job_offer"`
CargoOfferSeeds []int64 `sii:"cargo_offer_seeds"`
Discovered bool `sii:"discovered"`
ReservedTrailerSlot int64 `sii:"reserved_trailer_slot"` // TODO: Maybe wrong type, haven't seen other than "nil"
ReservedTrailerSlot Ptr `sii:"reserved_trailer_slot"` // TODO: Maybe wrong type, haven't seen other than "nil"
blockName string
}

View file

@ -5,19 +5,19 @@ func init() {
}
type JobOfferData struct {
Target string `sii:"target"`
ExpirationTime int64 `sii:"expiration_time"`
Urgency int64 `sii:"urgency"`
ShortestDistanceKM int64 `sii:"shortest_distance_km"`
FerryTime int64 `sii:"ferry_time"`
FerryPrice int64 `sii:"ferry_price"`
Cargo Ptr `sii:"cargo"` // External pointer
CompanyTruck Ptr `sii:"company_truck"` // Partial external pointer?
TrailerVariant Ptr `sii:"trailer_variant"` // External pointer
TrailerDefinition Ptr `sii:"trailer_definition"` // External pointer
UnitsCount int64 `sii:"units_count"`
FillRatio float32 `sii:"fill_ratio"`
TrailerPlace int64 `sii:"trailer_place"` // TODO: What's this? Seems to be "0" in all jobs
Target string `sii:"target"`
ExpirationTime *int64 `sii:"expiration_time"`
Urgency *int64 `sii:"urgency"`
ShortestDistanceKM int64 `sii:"shortest_distance_km"`
FerryTime int64 `sii:"ferry_time"`
FerryPrice int64 `sii:"ferry_price"`
Cargo Ptr `sii:"cargo"` // External pointer
CompanyTruck Ptr `sii:"company_truck"` // Partial external pointer?
TrailerVariant Ptr `sii:"trailer_variant"` // External pointer
TrailerDefinition Ptr `sii:"trailer_definition"` // External pointer
UnitsCount int64 `sii:"units_count"`
FillRatio float32 `sii:"fill_ratio"`
TrailerPlace []Placement `sii:"trailer_place"`
blockName string
}

View file

@ -5,7 +5,7 @@ func init() {
}
type Player struct {
HQCity string `sii:"hq_city"`
HQCity Ptr `sii:"hq_city"`
Trailers []Ptr `sii:"trailers"`
TrailerUtilizationLogs []Ptr `sii:"trailer_utilization_logs"`
TrailerDefs []Ptr `sii:"trailer_defs"`

View file

@ -21,24 +21,24 @@ var placementRegexp = regexp.MustCompile(`^\(([0-9.]+|&[0-9a-f]+), ([0-9.]+|&[0-
type Placement [7]float32
func (p Placement) MarshalSII() ([]byte, error) {
var siiFloats = [][]byte{}
var siiFloats = make([][]byte, 7)
for _, f := range p {
for i, f := range p {
b, err := float2sii(f)
if err != nil {
return nil, errors.Wrap(err, "Unable to encode float")
}
siiFloats = append(siiFloats, b)
siiFloats[i] = b
}
var buf = new(bytes.Buffer)
buf.Write([]byte("("))
bytes.Join(siiFloats[0:3], []byte(", "))
buf.Write(bytes.Join(siiFloats[0:3], []byte(", ")))
buf.Write([]byte(") ("))
buf.Write(siiFloats[3])
buf.Write([]byte("; "))
bytes.Join(siiFloats[4:7], []byte(", "))
buf.Write(bytes.Join(siiFloats[4:7], []byte(", ")))
buf.Write([]byte(")"))
return buf.Bytes(), nil

59
generator.go Normal file
View file

@ -0,0 +1,59 @@
package sii
import (
"bytes"
"fmt"
"io"
"reflect"
"github.com/pkg/errors"
)
func writeSIIPlainFile(unit *Unit, w io.Writer) error {
var err error
// Write file header
if _, err = fmt.Fprintln(w, "SiiNunit\n{"); err != nil {
return errors.Wrap(err, "Unable to write header")
}
for _, block := range unit.Entries {
// Write block header
if _, err = fmt.Fprintf(w, "%s : %s {\n", block.Class(), block.Name()); err != nil {
return errors.Wrap(err, "Unable to write block header")
}
// Obtain and write block content
var raw []byte
if reflect.TypeOf(block).Elem().Implements(reflect.TypeOf((*Marshaler)(nil)).Elem()) {
raw, err = block.(Marshaler).MarshalSII()
} else {
raw, err = genericMarshal(block)
}
if err != nil {
return errors.Wrap(err, "Unable to marshal block")
}
if len(raw) > 0 {
raw = append(bytes.TrimRight(raw, "\n"), '\n')
}
if _, err = w.Write(raw); err != nil {
return errors.Wrap(err, "Unable to write block data")
}
// Close block
if _, err = fmt.Fprintf(w, "}\n\n"); err != nil {
return errors.Wrap(err, "Unable to close block")
}
}
// Write file footer
if _, err = fmt.Fprintln(w, "}"); err != nil {
return errors.Wrap(err, "Unable to write footer")
}
return nil
}

View file

@ -1,36 +1,26 @@
package sii
import (
"bufio"
"bytes"
"fmt"
"reflect"
"regexp"
"strconv"
"strings"
"github.com/pkg/errors"
)
var (
singleLineValue = `^\s*%s\s?:\s?(.+)$`
arrayLineValue = `^\s*%s(\[([0-9]*)\])?\s?:\s?(.+)$`
)
func genericMarshal(in interface{}) ([]byte, error) {
return nil, errors.New("Not implemented")
}
func genericUnmarshal(in []byte, out interface{}, unit *Unit) error {
if reflect.TypeOf(out).Kind() != reflect.Ptr {
return errors.New("Calling parser with non-pointer")
if reflect.TypeOf(in).Kind() == reflect.Ptr {
in = reflect.ValueOf(in).Elem().Interface()
}
if reflect.ValueOf(out).Elem().Kind() != reflect.Struct {
return errors.New("Calling parser with pointer to non-struct")
if reflect.TypeOf(in).Kind() != reflect.Struct {
return nil, errors.New("Calling marshaller with non-struct")
}
st := reflect.ValueOf(out).Elem()
var buf = new(bytes.Buffer)
st := reflect.ValueOf(in)
for i := 0; i < st.NumField(); i++ {
valField := st.Field(i)
typeField := st.Type().Field(i)
@ -44,208 +34,146 @@ func genericUnmarshal(in []byte, out interface{}, unit *Unit) error {
switch typeField.Type {
case reflect.TypeOf(Ptr{}):
data := getSingleValue(in, attributeName)
v := Ptr{unit: unit}
if err := v.UnmarshalSII(data); err != nil {
return errors.Wrapf(err, "Unable to parse Ptr for attribute %q", attributeName)
}
valField.Set(reflect.ValueOf(v))
v := valField.Interface().(Ptr).MarshalSII()
buf.WriteString(fmt.Sprintf(" %s: %s\n", attributeName, v))
continue
case reflect.TypeOf(Placement{}):
data := getSingleValue(in, attributeName)
v := Placement{}
if err := v.UnmarshalSII(data); err != nil {
return errors.Wrapf(err, "Unable to parse Placement for attribute %q", attributeName)
v, err := valField.Interface().(Placement).MarshalSII()
if err != nil {
return nil, errors.Wrap(err, "Unable to encode Placement")
}
valField.Set(reflect.ValueOf(v))
buf.WriteString(fmt.Sprintf(" %s: %s\n", attributeName, v))
continue
}
switch typeField.Type.Kind() {
case reflect.Bool:
v, err := strconv.ParseBool(string(getSingleValue(in, attributeName)))
if err != nil {
return errors.Wrapf(err, "Unable to parse boolean for attribute %q", attributeName)
}
valField.SetBool(v)
v := valField.Bool()
buf.WriteString(fmt.Sprintf(" %s: %s\n", attributeName, strconv.FormatBool(v)))
case reflect.Float32:
v, err := sii2float(getSingleValue(in, attributeName))
v, err := float2sii(float32(valField.Float()))
if err != nil {
return errors.Wrapf(err, "Unable to parse float for attribute %q", attributeName)
return nil, errors.Wrap(err, "Unable to encode float32")
}
valField.Set(reflect.ValueOf(v))
buf.WriteString(fmt.Sprintf(" %s: %s\n", attributeName, v))
case reflect.Int, reflect.Int64:
bv := getSingleValue(in, attributeName)
if isNilValue(bv) {
continue
}
v, err := strconv.ParseInt(string(bv), 10, 64)
if err != nil {
return errors.Wrapf(err, "Unable to parse int for attribute %q", attributeName)
}
valField.SetInt(v)
buf.WriteString(fmt.Sprintf(" %s: %d\n", attributeName, valField.Int()))
case reflect.String:
v := strings.Trim(string(getSingleValue(in, attributeName)), `"`)
valField.SetString(v)
buf.WriteString(fmt.Sprintf(" %s: %q\n", attributeName, valField.String()))
case reflect.Uint64:
v, err := strconv.ParseUint(string(getSingleValue(in, attributeName)), 10, 64)
if err != nil {
return errors.Wrapf(err, "Unable to parse uint for attribute %q", attributeName)
v := strconv.FormatUint(valField.Uint(), 10)
buf.WriteString(fmt.Sprintf(" %s: %s\n", attributeName, v))
case reflect.Ptr:
switch typeField.Type.Elem().Kind() {
case reflect.Int64:
var v string
if valField.IsNil() {
v = "nil"
} else {
v = strconv.FormatInt(valField.Elem().Int(), 10)
}
buf.WriteString(fmt.Sprintf(" %s: %s\n", attributeName, v))
default:
return nil, errors.Errorf("Unsupported type: *%s", typeField.Type.Elem().Kind())
}
valField.SetUint(v)
case reflect.Slice:
ba, err := getArrayValues(in, attributeName)
if err != nil {
return errors.Wrapf(err, "Unable to fetch array values for attribute %q", attributeName)
}
var values []string
switch typeField.Type.Elem() {
case reflect.TypeOf(Ptr{}):
var v []Ptr
for _, bv := range ba {
e := Ptr{unit: unit}
if err := e.UnmarshalSII(bv); err != nil {
return errors.Wrapf(err, "Unable to parse Ptr for attribute %q", attributeName)
}
v = append(v, e)
for _, val := range valField.Interface().([]Ptr) {
values = append(values, string(val.MarshalSII()))
}
valField.Set(reflect.ValueOf(v))
buf.Write(encodeSliceValue(attributeName, values))
continue
case reflect.TypeOf(Placement{}):
var v []Placement
for _, bv := range ba {
e := Placement{}
if err := e.UnmarshalSII(bv); err != nil {
return errors.Wrapf(err, "Unable to parse Placement for attribute %q", attributeName)
for _, val := range valField.Interface().([]Placement) {
ev, err := val.MarshalSII()
if err != nil {
return nil, errors.Wrap(err, "Unable to encode Placement")
}
v = append(v, e)
values = append(values, string(ev))
}
valField.Set(reflect.ValueOf(v))
buf.Write(encodeSliceValue(attributeName, values))
continue
case reflect.TypeOf(RawValue{}):
var v []RawValue
for _, bv := range ba {
e := RawValue{}
if err := e.UnmarshalSII(bv); err != nil {
return errors.Wrapf(err, "Unable to parse RawValue for attribute %q", attributeName)
for _, val := range valField.Interface().([]RawValue) {
ev, err := val.MarshalSII()
if err != nil {
return nil, errors.Wrap(err, "Unable to encode RawValue")
}
v = append(v, e)
values = append(values, string(ev))
}
valField.Set(reflect.ValueOf(v))
buf.Write(encodeSliceValue(attributeName, values))
continue
}
switch typeField.Type.Elem().Kind() {
case reflect.Bool:
var v []bool
for _, bv := range ba {
pbv, err := strconv.ParseBool(string(bv))
if err != nil {
return errors.Wrapf(err, "Unable to parse boolean for attribute %q", attributeName)
}
v = append(v, pbv)
for _, val := range valField.Interface().([]bool) {
values = append(values, strconv.FormatBool(val))
}
valField.Set(reflect.ValueOf(v))
buf.Write(encodeSliceValue(attributeName, values))
case reflect.Int:
var v []int
for _, bv := range ba {
pbv, err := strconv.Atoi(string(bv))
if err != nil {
return errors.Wrapf(err, "Unable to parse int for attribute %q", attributeName)
}
v = append(v, pbv)
for _, val := range valField.Interface().([]int) {
values = append(values, strconv.FormatInt(int64(val), 10))
}
valField.Set(reflect.ValueOf(v))
buf.Write(encodeSliceValue(attributeName, values))
case reflect.Int64:
var v []int64
for _, bv := range ba {
pbv, err := strconv.ParseInt(string(bv), 10, 64)
if err != nil {
return errors.Wrapf(err, "Unable to parse int for attribute %q", attributeName)
}
v = append(v, pbv)
for _, val := range valField.Interface().([]int64) {
values = append(values, strconv.FormatInt(val, 10))
}
valField.Set(reflect.ValueOf(v))
buf.Write(encodeSliceValue(attributeName, values))
case reflect.String:
var v []string
for _, bv := range ba {
v = append(v, strings.Trim(string(bv), `"`))
for _, val := range valField.Interface().([]string) {
values = append(values, val)
}
valField.Set(reflect.ValueOf(v))
buf.Write(encodeSliceValue(attributeName, values))
default:
return errors.Errorf("Unsupported type: []%s", typeField.Type.Elem().Kind())
return nil, errors.Errorf("Unsupported type: []%s", typeField.Type.Elem().Kind())
}
default:
return errors.Errorf("Unsupported type: %s", typeField.Type.Kind())
return nil, errors.Errorf("Unsupported type: %s", typeField.Type.Kind())
}
}
return nil
return buf.Bytes(), nil
}
func getSingleValue(in []byte, name string) []byte {
rex := regexp.MustCompile(fmt.Sprintf(singleLineValue, name))
func encodeSliceValue(attributeName string, values []string) []byte {
var buf = new(bytes.Buffer)
var scanner = bufio.NewScanner(bytes.NewReader(in))
for scanner.Scan() {
if rex.Match(scanner.Bytes()) {
grp := rex.FindSubmatch(scanner.Bytes())
return grp[1]
}
}
return nil
}
fmt.Fprintf(buf, " %s: %d\n", attributeName, len(values))
func getArrayValues(in []byte, name string) ([][]byte, error) {
rex := regexp.MustCompile(fmt.Sprintf(arrayLineValue, name))
var out [][]byte
var scanner = bufio.NewScanner(bytes.NewReader(in))
for scanner.Scan() {
if rex.Match(scanner.Bytes()) {
grp := rex.FindSubmatch(scanner.Bytes())
if len(grp[1]) == 0 {
arrayLen, err := strconv.Atoi(string(grp[3]))
if err != nil {
return nil, errors.Wrap(err, "Unable to parse array capacity")
}
out = make([][]byte, arrayLen)
continue
}
if len(grp[2]) == 0 {
out = append(out, grp[3])
continue
}
idx, err := strconv.Atoi(string(grp[2]))
if err != nil {
return nil, errors.Wrap(err, "Unable to parse array index")
}
out[idx] = grp[3]
}
for i, v := range values {
fmt.Fprintf(buf, " %s[%d]: %s\n", attributeName, i, v)
}
return out, nil
}
func isNilValue(in []byte) bool {
return reflect.DeepEqual(in, []byte("nil"))
return buf.Bytes()
}

270
genericUnmarshaller.go Normal file
View file

@ -0,0 +1,270 @@
package sii
import (
"bufio"
"bytes"
"fmt"
"reflect"
"regexp"
"strconv"
"strings"
"github.com/pkg/errors"
)
var (
singleLineValue = `^\s*%s\s?:\s?(.+)$`
arrayLineValue = `^\s*%s(\[([0-9]*)\])?\s?:\s?(.+)$`
)
func genericUnmarshal(in []byte, out interface{}, unit *Unit) error {
if reflect.TypeOf(out).Kind() != reflect.Ptr {
return errors.New("Calling parser with non-pointer")
}
if reflect.ValueOf(out).Elem().Kind() != reflect.Struct {
return errors.New("Calling parser with pointer to non-struct")
}
st := reflect.ValueOf(out).Elem()
for i := 0; i < st.NumField(); i++ {
valField := st.Field(i)
typeField := st.Type().Field(i)
attributeName := typeField.Tag.Get("sii")
if attributeName == "" {
// Names must be explicitly defined, library does not support name guessing
continue
}
switch typeField.Type {
case reflect.TypeOf(Ptr{}):
data := getSingleValue(in, attributeName)
v := Ptr{unit: unit}
if err := v.UnmarshalSII(data); err != nil {
return errors.Wrapf(err, "Unable to parse Ptr for attribute %q", attributeName)
}
valField.Set(reflect.ValueOf(v))
continue
case reflect.TypeOf(Placement{}):
data := getSingleValue(in, attributeName)
v := Placement{}
if err := v.UnmarshalSII(data); err != nil {
return errors.Wrapf(err, "Unable to parse Placement for attribute %q", attributeName)
}
valField.Set(reflect.ValueOf(v))
continue
}
switch typeField.Type.Kind() {
case reflect.Bool:
v, err := strconv.ParseBool(string(getSingleValue(in, attributeName)))
if err != nil {
return errors.Wrapf(err, "Unable to parse boolean for attribute %q", attributeName)
}
valField.SetBool(v)
case reflect.Float32:
v, err := sii2float(getSingleValue(in, attributeName))
if err != nil {
return errors.Wrapf(err, "Unable to parse float for attribute %q", attributeName)
}
valField.Set(reflect.ValueOf(v))
case reflect.Int, reflect.Int64:
bv := getSingleValue(in, attributeName)
if isNilValue(bv) {
continue
}
v, err := strconv.ParseInt(string(bv), 10, 64)
if err != nil {
return errors.Wrapf(err, "Unable to parse int for attribute %q", attributeName)
}
valField.SetInt(v)
case reflect.String:
v := strings.Trim(string(getSingleValue(in, attributeName)), `"`)
valField.SetString(v)
case reflect.Uint64:
v, err := strconv.ParseUint(string(getSingleValue(in, attributeName)), 10, 64)
if err != nil {
return errors.Wrapf(err, "Unable to parse uint for attribute %q", attributeName)
}
valField.SetUint(v)
case reflect.Ptr:
switch typeField.Type.Elem().Kind() {
case reflect.Int64:
bv := getSingleValue(in, attributeName)
if !isNilValue(bv) {
v, err := strconv.ParseInt(string(bv), 10, 64)
if err != nil {
return errors.Wrapf(err, "Unable to parse int for attribute %q", attributeName)
}
valField.Set(reflect.ValueOf(&v))
}
default:
return errors.Errorf("Unsupported type: *%s", typeField.Type.Elem().Kind())
}
case reflect.Slice:
ba, err := getArrayValues(in, attributeName)
if err != nil {
return errors.Wrapf(err, "Unable to fetch array values for attribute %q", attributeName)
}
switch typeField.Type.Elem() {
case reflect.TypeOf(Ptr{}):
var v []Ptr
for _, bv := range ba {
e := Ptr{unit: unit}
if err := e.UnmarshalSII(bv); err != nil {
return errors.Wrapf(err, "Unable to parse Ptr for attribute %q", attributeName)
}
v = append(v, e)
}
valField.Set(reflect.ValueOf(v))
continue
case reflect.TypeOf(Placement{}):
var v []Placement
for _, bv := range ba {
e := Placement{}
if err := e.UnmarshalSII(bv); err != nil {
return errors.Wrapf(err, "Unable to parse Placement for attribute %q", attributeName)
}
v = append(v, e)
}
valField.Set(reflect.ValueOf(v))
continue
case reflect.TypeOf(RawValue{}):
var v []RawValue
for _, bv := range ba {
e := RawValue{}
if err := e.UnmarshalSII(bv); err != nil {
return errors.Wrapf(err, "Unable to parse RawValue for attribute %q", attributeName)
}
v = append(v, e)
}
valField.Set(reflect.ValueOf(v))
continue
}
switch typeField.Type.Elem().Kind() {
case reflect.Bool:
var v []bool
for _, bv := range ba {
pbv, err := strconv.ParseBool(string(bv))
if err != nil {
return errors.Wrapf(err, "Unable to parse boolean for attribute %q", attributeName)
}
v = append(v, pbv)
}
valField.Set(reflect.ValueOf(v))
case reflect.Int:
var v []int
for _, bv := range ba {
pbv, err := strconv.Atoi(string(bv))
if err != nil {
return errors.Wrapf(err, "Unable to parse int for attribute %q", attributeName)
}
v = append(v, pbv)
}
valField.Set(reflect.ValueOf(v))
case reflect.Int64:
var v []int64
for _, bv := range ba {
pbv, err := strconv.ParseInt(string(bv), 10, 64)
if err != nil {
return errors.Wrapf(err, "Unable to parse int for attribute %q", attributeName)
}
v = append(v, pbv)
}
valField.Set(reflect.ValueOf(v))
case reflect.String:
var v []string
for _, bv := range ba {
v = append(v, strings.Trim(string(bv), `"`))
}
valField.Set(reflect.ValueOf(v))
default:
return errors.Errorf("Unsupported type: []%s", typeField.Type.Elem().Kind())
}
default:
return errors.Errorf("Unsupported type: %s", typeField.Type.Kind())
}
}
return nil
}
func getSingleValue(in []byte, name string) []byte {
rex := regexp.MustCompile(fmt.Sprintf(singleLineValue, name))
var scanner = bufio.NewScanner(bytes.NewReader(in))
for scanner.Scan() {
if rex.Match(scanner.Bytes()) {
grp := rex.FindSubmatch(scanner.Bytes())
return grp[1]
}
}
return nil
}
func getArrayValues(in []byte, name string) ([][]byte, error) {
rex := regexp.MustCompile(fmt.Sprintf(arrayLineValue, name))
var out [][]byte
var scanner = bufio.NewScanner(bytes.NewReader(in))
for scanner.Scan() {
if rex.Match(scanner.Bytes()) {
grp := rex.FindSubmatch(scanner.Bytes())
if len(grp[1]) == 0 {
arrayLen, err := strconv.Atoi(string(grp[3]))
if err != nil {
return nil, errors.Wrap(err, "Unable to parse array capacity")
}
out = make([][]byte, arrayLen)
continue
}
if len(grp[2]) == 0 {
out = append(out, grp[3])
continue
}
idx, err := strconv.Atoi(string(grp[2]))
if err != nil {
return nil, errors.Wrap(err, "Unable to parse array index")
}
out[idx] = make([]byte, len(grp[3]))
for i, b := range grp[3] {
out[idx][i] = b
}
}
}
return out, errors.Wrap(scanner.Err(), "Unable to parse array lines")
}
func isNilValue(in []byte) bool {
return reflect.DeepEqual(in, []byte("nil"))
}

View file

@ -4,6 +4,8 @@ import (
"bytes"
"encoding/binary"
"encoding/hex"
"fmt"
"math"
"strconv"
"github.com/pkg/errors"
@ -15,6 +17,10 @@ func float2sii(f float32) ([]byte, error) {
err error
)
if math.Floor(float64(f)) == float64(f) {
return []byte(fmt.Sprintf("%.0f", f)), nil
}
err = binary.Write(buf, binary.BigEndian, f)
if err != nil {
return nil, errors.Wrap(err, "Unable to encode float")

View file

@ -49,7 +49,7 @@ func parseSIIPlainFile(r io.Reader) (*Unit, error) {
case line == "}":
if inBlock {
if err := processBlock(unit, blockClass, blockName, blockContent); err != nil {
if err := processBlock(unit, blockClass, blockName, bytes.Trim(blockContent, "\n")); err != nil {
return nil, errors.Wrap(err, "Unable to process block")
}

19
sii.go
View file

@ -117,8 +117,23 @@ func WriteUnitFile(filename string, encrypt bool, data *Unit) error {
return ErrNoEncryptionKeySet
}
// FIXME: Implement this
return errors.New("Not implemented")
var buf = new(bytes.Buffer)
if err := writeSIIPlainFile(data, buf); err != nil {
return errors.Wrap(err, "Unable to create SII file content")
}
// FIXME: Implement encryption
// Create output file
f, err := os.Create(filename)
if err != nil {
return errors.Wrap(err, "Unable to open output file")
}
defer f.Close()
_, err = buf.WriteTo(f)
return errors.Wrap(err, "Unable to write buffer")
}
func readFTHeader(f io.ReaderAt) ([]byte, error) {

View file

@ -25,9 +25,9 @@ func (r *RawBlock) Init(class, name string) {
r.blockClass = class
r.blockName = name
}
func (r RawBlock) MarshalSII() []byte { return r.Data }
func (r RawBlock) Name() string { return r.blockName }
func (r RawBlock) Class() string { return r.blockClass }
func (r RawBlock) MarshalSII() ([]byte, error) { return r.Data, nil }
func (r RawBlock) Name() string { return r.blockName }
func (r RawBlock) Class() string { return r.blockClass }
func (r *RawBlock) UnmarshalSII(in []byte) error {
r.Data = in
return nil