1use std::io::Write;
2
3use super::parser::Event;
4use super::parser::SimpleContent;
5use super::database::Class;
6use super::database::id_to_class;
7use super::database::class_to_id;
8use super::generator::generate_ebml_number;
9use super::generator::EbmlNumberMode;
10use std::rc::Rc;
11use super::Element;
12use super::parser::EventsHandler;
13use super::builder::Builder;
14use super::generator::generate;
15use super::el_bin;
16
17#[derive(Debug)]
18pub enum MidlevelEvent<'a> {
19 EnterElement(Class),
20 LeaveElement(Class),
21
22 Element(Rc<Element>), Content(SimpleContent<'a>),
24
25 Resync,
26}
27
28pub enum WhatToDo {
29 Build, GoOn, }
32
33pub trait MidlevelEventHandler {
34 fn event(&mut self, e: MidlevelEvent) -> ();
35 fn how_to_handle(&mut self, c: Class) -> WhatToDo;
36}
37
38pub struct MidlevelParser<H:MidlevelEventHandler> {
41 h:H,
42 b:Option<Builder>
43}
44
45impl<H:MidlevelEventHandler> MidlevelParser<H> {
46 pub fn new(h_:H) -> MidlevelParser<H> {
47 MidlevelParser { h:h_ , b:None}
48 }
49
50 pub fn borrow_handler (&self) -> &H { &self.h }
51 pub fn borrow_handler_mut(&mut self) -> &mut H {&mut self.h }
52 pub fn into_handler (self) -> H { self.h }
53}
54
55impl<H:MidlevelEventHandler> EventsHandler for MidlevelParser<H> {
56 fn event(&mut self, e : super::parser::Event) {
57 use super::parser::Event::*;
58
59 match e {
60 Begin(x) => {
61 if let Some(ref mut b) = self.b {
62 b.event(e);
63 } else {
64 let klass = id_to_class(x.id);
65 match self.h.how_to_handle(klass) {
66 WhatToDo::GoOn => {
67 self.h.event(MidlevelEvent::EnterElement(klass));
68 }
69 WhatToDo::Build => {
70 let mut b = Builder::new();
71 b.event(e);
72 self.b = Some(b);
73 }
74 }
75 }
76 }
77 Data(_) if self.b.is_some() => {
78 if let Some(ref mut b) = self.b {
79 b.event(e);
80 }
81 }
82 Data(x) => {
83 self.h.event(MidlevelEvent::Content(x));
84 }
85 End(x) => {
86 if let Some(mut b) = self.b.take() {
87 b.event(e);
88 if ! b.captured_elements().is_empty() {
89 let element = b.into_captured_elements().into_iter().next().unwrap();
90 self.h.event(MidlevelEvent::Element(element));
91 } else {
92 self.b = Some(b);
93 }
94 } else {
95 self.h.event(MidlevelEvent::LeaveElement(id_to_class(x.id)));
96 }
97
98 }
99 Resync => {
100 self.b = None;
101 self.h.event(MidlevelEvent::Resync);
102 },
103 };
104 }
105}
106
107
108pub struct MidlevelEventsToFile<W:Write> {
112 w: W,
113}
114
115impl<W:Write> MidlevelEventsToFile<W> {
116 pub fn new(w_:W) -> Self {
117 MidlevelEventsToFile { w:w_ }
118 }
119
120 pub fn borrow_file (&self) -> &W { &self.w }
121 pub fn borrow_file_mut(&mut self) -> &mut W {&mut self.w }
122 pub fn into_file (self) -> W { self.w }
123}
124
125impl<W:Write> MidlevelEventHandler for MidlevelEventsToFile<W> {
126 fn how_to_handle(&mut self, klass: Class) -> WhatToDo {
127 if klass == Class::Segment {
128 WhatToDo::GoOn
129 } else {
130 WhatToDo::Build
131 }
132 }
133 fn event(&mut self, e: MidlevelEvent) -> () {
134 match e {
135 MidlevelEvent::EnterElement(klass) => {
136 if (klass == Class::Segment) {
137 self.w.write(&generate_ebml_number(class_to_id(klass), EbmlNumberMode::Identifier)).unwrap();
138 self.w.write(b"\xFF").unwrap(); self.w.write(&generate(&el_bin(Class::Void, vec![0;32]))).unwrap();
140 } else {
141 panic!("Should not happen")
142 }
143 }
144 MidlevelEvent::Element(x) => {
145 self.w.write(&generate(&x)).unwrap();
146 }
147 MidlevelEvent::LeaveElement(_) => {
148 }
149 MidlevelEvent::Content(_) => {
150 }
151 MidlevelEvent::Resync => {
152 self.w.write(&generate(&el_bin(Class::Void, b"\nHere was resync\n".to_vec()))).unwrap();
153 }
154 }
155 }
156}