mkv 0.0.8

[incomplete yet] Matroska (mkv,webm) files parser and generator implemented in Rust
Documentation
#![allow(non_camel_case_types)]
#![allow(unused_imports)]

use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use std::io::Read;
use std::io::Write;
use std::env::args;

use mkv::elements::parser::Parser;
use mkv::elements::parser::EventsHandler;
use mkv::elements::Element;
use mkv::elements::database::Class;
use mkv::elements::database::class_to_id;
use mkv::elements::generator;
use mkv::elements::el_bin;
use mkv::elements::generator::generate;
use mkv::elements::generator::EbmlNumberMode;
use mkv::elements::generator::generate_ebml_number;

extern crate mkv;
extern crate env_logger;

use std::rc::Rc;

struct MyHandler {
    counter : usize,
    w : Option<Box<dyn Write>>,
}

use mkv::elements::midlevel::MidlevelEventHandler;
use mkv::elements::midlevel::MidlevelEvent;
use mkv::elements::midlevel::WhatToDo;
use mkv::elements::typical_matroska_header;

impl MidlevelEventHandler for MyHandler {

    fn how_to_handle(&mut self, klass: Class) -> WhatToDo {
        if klass == Class::Segment {
            WhatToDo::GoOn
        } else {
            WhatToDo::Build
        }
    }
    fn event(&mut self, e: MidlevelEvent) -> () {
        match e {
            MidlevelEvent::EnterElement(klass) => {
                if klass == Class::Segment {
                    let mut w;
                    {
                        let filen = format!("{}.mkv",self.counter);
                        w = File::create(Path::new(&filen)).expect("Can't open output file");
                    }
                    
                    w.write(&generate(&typical_matroska_header(false))).unwrap();
                    w.write(&generate_ebml_number(class_to_id(klass), EbmlNumberMode::Identifier)).unwrap();
                    w.write(b"\xFF").unwrap(); // unknown length
                    w.write(&generate(&el_bin(Class::Void, vec![0;32]))).unwrap();
                    
                    self.w = Some(Box::new(w));
                    self.counter += 1;
                } else {
                }
            }
            MidlevelEvent::Element(x) => {
                if let Some(ref mut w) = self.w {
                    w.write(&generate(&x)).unwrap();
                }
            }
            MidlevelEvent::LeaveElement(_) => { 
            }
            MidlevelEvent::Content(_) => {
            }
            MidlevelEvent::Resync => {
                if let Some(ref mut w) = self.w {
                    w.write(&generate(&el_bin(Class::Void, b"\nHere was resync\n".to_vec()))).unwrap();
                }
            }
        }
    }
}

const BSIZE : usize = 65536;
fn main() {
    env_logger::init().unwrap();

    let reader : Box<dyn Read> = match args().len() {
        1 => Box::new(std::io::stdin()),
        2 => Box::new(File::open(Path::new(args().nth(1).unwrap().as_str())).expect("Failed to open the file")),
        _ => panic!("Usage: mkvsplit2 [filename.mkv]\nExtracts segments to 1.mkv, 2.mkv and so on\n")
    };
    let mut f = BufReader::new(reader);
   
    
    //let mut stdout = std::io::stdout();
    let myhandler = MyHandler { counter: 1, w: None, };
    let mut midlevel = mkv::elements::midlevel::MidlevelParser::new(myhandler);
    
    {
        let mut m = mkv::elements::parser::new();
        
        loop {
            let mut b = [0; BSIZE];
            match f.read(&mut b) {
                Ok(x) => match x {
                        0 => break,
                        x => m.feed_bytes(b.split_at(x).0, &mut midlevel),
                    },
                Err(e) => { println!("error reading: {}", e); break; },
            }
        }
    }    
}