at-wat/ebml-go

Record position when unmarshalling WebM file

kamatama41 opened this issue · 2 comments

I want to modify a WebM file to make it seekable.
In order to do that, I need positions of each element in the unmarshalled struct.

Hi @at-wat
I have reconsidered the design to achieve what I want. How about the following one?

  • Unmarshal method can be allowed to add hooks
  • A hook is a function that has a metadata (Name, Value, Position, Size) of the element as argument.
  • Users are able to know positions of elements and do anything via the hooks.
type UnmarshalHook func(elem *Element)

type Element struct {
	Value    interface{}
	Name     string
	Position uint64
	Size     uint64
}

func Unmarshal(r io.Reader, val interface{}, hooks ...UnmarshalHook) error {
   ...
}

Example usage

func main() {
	type EBML struct {
		Header  webm.EBMLHeader `ebml:"EBML"`
		Segment webm.Segment    `ebml:"Segment"`
	}

	hook := func(elem *Element) {
		log.Printf("An element detected (name: %s position: %d)", elem.Name, elem.Position)
	}

	var ret EBML
	if err := ebml.Unmarshal(r, &ret, hook); err != nil {
		t.Fatalf("error: %+v\n", err)
	}
}

@kamatama41 using a hook sounds good.

my suggestions:

  • add a pointer to its parent Element in Element struct
  • pass hooks via functional options pattern to allow different kind of options in future