@@ -26,7 +26,8 @@ defmodule Membrane.MP4.Container.ParseHelper do
2626 try:
2727 { :ok , { fields , rest } , context } <- parse_fields ( content , box_schema . fields , context ) ,
2828 try:
29- { :ok , children , << >> , context } <- parse_boxes ( rest , box_schema . children , context , [ ] ) do
29+ { :ok , children , rest , context } <- parse_boxes ( rest , box_schema . children , context , [ ] ) ,
30+ leftover: << >> <- rest do
3031 box = % { fields: fields , children: children , size: content_size , header_size: header_size }
3132 parse_boxes ( data , schema , context , [ { name , box } | acc ] )
3233 else
@@ -38,19 +39,33 @@ defmodule Membrane.MP4.Container.ParseHelper do
3839 box = % { content: content , size: content_size , header_size: header_size }
3940 parse_boxes ( data , schema , context , [ { name , box } | acc ] )
4041
42+ leftover: leftover ->
43+ { :error , [ box: name , reason: { :non_empty_leftover , leftover } ] }
44+
4145 try: { :error , context } ->
4246 { :error , [ box: name ] ++ context }
4347 end
4448 end
4549
46- defp parse_fields ( data , [ ] , context ) do
47- { :ok , { % { } , data } , context }
50+ defp parse_fields ( data , fields , context ) do
51+ do_parse_fields ( data , fields , context , % { } )
4852 end
4953
50- defp parse_fields ( data , [ { name , type } | fields ] , context ) do
51- with { :ok , { term , rest } , context } <- parse_field ( data , { name , type } , context ) ,
52- { :ok , { terms , rest } , context } <- parse_fields ( rest , fields , context ) do
53- { :ok , { Map . put ( terms , name , term ) , rest } , context }
54+ defp do_parse_fields ( data , [ ] , context , acc ) do
55+ { :ok , { acc , data } , context }
56+ end
57+
58+ defp do_parse_fields ( data , [ { name , type } | fields ] , context , acc ) do
59+ case parse_field ( data , { name , type } , context ) do
60+ { :ok , { term , rest } , context } ->
61+ acc = Map . put ( acc , name , term )
62+ do_parse_fields ( rest , fields , context , acc )
63+
64+ { :ok , :ignore , context } ->
65+ do_parse_fields ( data , fields , context , acc )
66+
67+ { :error , context } ->
68+ { :error , context }
5469 end
5570 end
5671
@@ -63,27 +78,11 @@ defmodule Membrane.MP4.Container.ParseHelper do
6378 end
6479 end
6580
66- defp parse_field ( data , { name , { type , store: context_name , when: { key , [ mask: mask ] } } } , context ) do
67- context_object = Map . get ( context , key , 0 )
68-
69- if ( mask &&& context_object ) == mask do
70- parse_field ( data , { name , { type , store: context_name } } , context )
71- else
72- { :ok , { [ ] , data } , context }
73- end
74- end
75-
76- defp parse_field (
77- data ,
78- { name , { type , store: context_name , when: { key , [ value: value ] } } } ,
79- context
80- ) do
81- context_object = Map . get ( context , key , 0 )
82-
83- if context_object == value do
81+ defp parse_field ( data , { name , { type , store: context_name , when: when_clause } } , context ) do
82+ if handle_when ( when_clause , context ) do
8483 parse_field ( data , { name , { type , store: context_name } } , context )
8584 else
86- { :ok , { [ ] , data } , context }
85+ { :ok , :ignore , context }
8786 end
8887 end
8988
@@ -94,23 +93,11 @@ defmodule Membrane.MP4.Container.ParseHelper do
9493 { :ok , result , context }
9594 end
9695
97- defp parse_field ( data , { name , { type , when: { key , [ mask: mask ] } } } , context ) do
98- context_object = Map . get ( context , key , 0 )
99-
100- if ( mask &&& context_object ) == mask do
101- parse_field ( data , { name , type } , context )
102- else
103- { :ok , { [ ] , data } , context }
104- end
105- end
106-
107- defp parse_field ( data , { name , { type , when: { key , [ value: value ] } } } , context ) do
108- context_object = Map . get ( context , key , 0 )
109-
110- if context_object == value do
96+ defp parse_field ( data , { name , { type , when: when_clause } } , context ) do
97+ if handle_when ( when_clause , context ) do
11198 parse_field ( data , { name , type } , context )
11299 else
113- { :ok , { [ ] , data } , context }
100+ { :ok , :ignore , context }
114101 end
115102 end
116103
@@ -188,4 +175,16 @@ defmodule Membrane.MP4.Container.ParseHelper do
188175 defp parse_field_error ( _data , name , context ) do
189176 { :error , [ field: name ] ++ context }
190177 end
178+
179+ defp handle_when ( { key , condition } , context ) do
180+ with { :ok , value } <- Map . fetch ( context , key ) do
181+ case condition do
182+ [ value: cond_value ] -> value == cond_value
183+ [ mask: mask ] -> ( mask &&& value ) == mask
184+ end
185+ else
186+ :error ->
187+ raise "MP4 schema field #{ key } not found in context"
188+ end
189+ end
191190end
0 commit comments