func NewDecoder(r io.ReaderAt, size int64) *Decoder {
	return &Decoder{
		p:      &opcReader{ra: r, size: size},
		Strict: true,
	}
}
NewDecoder returns a new Decoder reading a 3mf file from r.
package go3mf
import (
	"bytes"
	"context"
	"encoding/xml"
	"errors"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"sync"
	"unsafe"
	specerr "github.com/hpinc/go3mf/errors"
	xml3mf "github.com/hpinc/go3mf/internal/xml"
	"github.com/hpinc/go3mf/spec"
)
var checkEveryTokens = 1000
type packageFile interface {
	Name() string
	ContentType() string
	FindFileFromName(string) (packageFile, bool)
	Relationships() []Relationship
	Open() (io.ReadCloser, error)
}
type packageReader interface {
	Open(func(r io.Reader) io.ReadCloser) error
	FindFileFromName(string) (packageFile, bool)
	Relationships() []Relationship
}
type ReadCloser struct {
	Decoder
	f *os.File
}
func OpenReader(name string) (*ReadCloser, error) {
	f, err := os.Open(name)
	if err != nil {
		return nil, err
	}
	fi, err := f.Stat()
	if err != nil {
		f.Close()
		return nil, err
	}
	return &ReadCloser{f: f, Decoder: *NewDecoder(f, fi.Size())}, nil
}
func (r *ReadCloser) Close() error {
	return r.f.Close()
}
func decodeModelFile(ctx context.Context, r io.Reader, model *Model, path string, isRoot, strict bool) error {
	x := xml3mf.NewDecoder(r)
	type stackElement struct {
		decoder spec.ElementDecoder
		name    xml.Name
		i       int
	}
	stack := make([]stackElement, 0, 10)
	var (
		currentDecoder spec.ElementDecoder
		currentName    xml.Name
		errs           specerr.List
	)
	currentDecoder = &topLevelDecoder{isRoot: isRoot, model: model, path: path}
	var err error
	x.OnStart = func(tp xml3mf.StartElement) {
		if childDecoder, ok := currentDecoder.(spec.ChildElementDecoder); ok {
			i, tmpDecoder := childDecoder.Child(tp.Name)
			if tmpDecoder != nil {
				stack = append(stack, stackElement{tmpDecoder, tp.Name, i})
				currentName = tp.Name
				currentDecoder = tmpDecoder
				err := currentDecoder.Start(*(*[]spec.XMLAttr)(unsafe.Pointer(&tp.Attr)))
				if err != nil {
					for j := len(stack) - 1; j >= 0; j-- {
						element := stack[j]
						err = specerr.WrapIndex(err, element.name.Local, element.i)
					}
					specerr.Append(&errs, err)
				}
			}
		} else if appendDecoder, ok := currentDecoder.(spec.AppendTokenElementDecoder); ok {
			var xattrs []xml.Attr
			if len(tp.Attr) > 0 {
				xattrs = make([]xml.Attr, len(tp.Attr))
				for i, att := range tp.Attr {
					xattrs[i] = xml.Attr{Name: att.Name, Value: string(att.Value)}
				}
			}
			appendDecoder.AppendToken(xml.StartElement{
				Name: tp.Name,
				Attr: xattrs,
			})
		}
	}
	x.OnEnd = func(tp xml.EndElement) {
		if currentName == tp.Name {
			currentDecoder.End()
			stack = stack[:len(stack)-1]
			if len(stack) > 0 {
				element := stack[len(stack)-1]
				currentDecoder = element.decoder
				currentName = element.name
			}
		} else if appendDecoder, ok := currentDecoder.(spec.AppendTokenElementDecoder); ok {
			appendDecoder.AppendToken(tp)
		}
	}
	x.OnChar = func(tp xml.CharData) {
		if currentDecoder, ok := currentDecoder.(spec.CharDataElementDecoder); ok {
			currentDecoder.CharData(tp)
		} else if appendDecoder, ok := currentDecoder.(spec.AppendTokenElementDecoder); ok {
			appendDecoder.AppendToken(tp)
		}
	}
	var i int
	for {
		err = x.RawToken()
		if err != nil || (strict && errs.Len() != 0) {
			break
		}
		if i%checkEveryTokens == 0 {
			select {
			case <-ctx.Done():
				err = ctx.Err()
			default:  
			}
			if err != nil {
				break
			}
		}
		i++
	}
	if err == io.EOF {
		err = nil
	}
	if err == nil && errs.Len() != 0 {
		if strict || errs.Len() == 1 {
			err = errs.Unwrap()
		} else {
			err = &errs
		}
	}
	return err
}
type Decoder struct {
	Strict        bool
	p             packageReader
	flate         func(r io.Reader) io.ReadCloser
	nonRootModels []packageFile
}