gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

extract.go (2088B)


      1 package mp4
      2 
      3 import (
      4 	"errors"
      5 	"io"
      6 )
      7 
      8 type BoxInfoWithPayload struct {
      9 	Info    BoxInfo
     10 	Payload IBox
     11 }
     12 
     13 func ExtractBoxWithPayload(r io.ReadSeeker, parent *BoxInfo, path BoxPath) ([]*BoxInfoWithPayload, error) {
     14 	return ExtractBoxesWithPayload(r, parent, []BoxPath{path})
     15 }
     16 
     17 func ExtractBoxesWithPayload(r io.ReadSeeker, parent *BoxInfo, paths []BoxPath) ([]*BoxInfoWithPayload, error) {
     18 	bis, err := ExtractBoxes(r, parent, paths)
     19 	if err != nil {
     20 		return nil, err
     21 	}
     22 
     23 	bs := make([]*BoxInfoWithPayload, 0, len(bis))
     24 	for _, bi := range bis {
     25 		if _, err := bi.SeekToPayload(r); err != nil {
     26 			return nil, err
     27 		}
     28 
     29 		var ctx Context
     30 		if parent != nil {
     31 			ctx = parent.Context
     32 		}
     33 		box, _, err := UnmarshalAny(r, bi.Type, bi.Size-bi.HeaderSize, ctx)
     34 		if err != nil {
     35 			return nil, err
     36 		}
     37 		bs = append(bs, &BoxInfoWithPayload{
     38 			Info:    *bi,
     39 			Payload: box,
     40 		})
     41 	}
     42 	return bs, nil
     43 }
     44 
     45 func ExtractBox(r io.ReadSeeker, parent *BoxInfo, path BoxPath) ([]*BoxInfo, error) {
     46 	return ExtractBoxes(r, parent, []BoxPath{path})
     47 }
     48 
     49 func ExtractBoxes(r io.ReadSeeker, parent *BoxInfo, paths []BoxPath) ([]*BoxInfo, error) {
     50 	if len(paths) == 0 {
     51 		return nil, nil
     52 	}
     53 
     54 	for i := range paths {
     55 		if len(paths[i]) == 0 {
     56 			return nil, errors.New("box path must not be empty")
     57 		}
     58 	}
     59 
     60 	boxes := make([]*BoxInfo, 0, 8)
     61 
     62 	handler := func(handle *ReadHandle) (interface{}, error) {
     63 		path := handle.Path
     64 		if parent != nil {
     65 			path = path[1:]
     66 		}
     67 		if handle.BoxInfo.Type == BoxTypeAny() {
     68 			return nil, nil
     69 		}
     70 		fm, m := matchPath(paths, path)
     71 		if m {
     72 			boxes = append(boxes, &handle.BoxInfo)
     73 		}
     74 
     75 		if fm {
     76 			if _, err := handle.Expand(); err != nil {
     77 				return nil, err
     78 			}
     79 		}
     80 		return nil, nil
     81 	}
     82 
     83 	if parent != nil {
     84 		_, err := ReadBoxStructureFromInternal(r, parent, handler)
     85 		return boxes, err
     86 	}
     87 	_, err := ReadBoxStructure(r, handler)
     88 	return boxes, err
     89 }
     90 
     91 func matchPath(paths []BoxPath, path BoxPath) (forwardMatch bool, match bool) {
     92 	for i := range paths {
     93 		fm, m := path.compareWith(paths[i])
     94 		forwardMatch = forwardMatch || fm
     95 		match = match || m
     96 	}
     97 	return
     98 }