1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::io::SeekFrom;
use std::io::{Error, ErrorKind};

pub trait Writer {
    fn write(&mut self, buf: &[u8]) -> io::Result<()>;
    fn get_position(&self) -> u64;
    fn set_position(&mut self, position: u64) -> io::Result<u64>;
    fn seekable(&self) -> bool;
    fn element_start_notify(&self, _element_id: u64, _position: u64) {}
}

pub struct MkvWriter {
    file: Box<File>,
    position: u64,
}

impl MkvWriter {
    fn new(file: File) -> MkvWriter {
        MkvWriter {
            file: Box::new(file),
            position: 0,
        }
    }
}

impl Writer for MkvWriter {
    fn write(&mut self, buffer: &[u8]) -> io::Result<()> {
        let size = self.file.write(buffer)?;
        self.position += size as u64;
        if size == buffer.len() {
            Ok(())
        } else {
            Err(Error::new(
                ErrorKind::Other,
                "Write size is not equal to buffer size",
            ))
        }
    }

    fn get_position(&self) -> u64 {
        self.position
    }

    fn set_position(&mut self, position: u64) -> io::Result<u64> {
        let size = self.file.seek(SeekFrom::Start(position))?;
        self.position = size;
        if size == position {
            Ok(size)
        } else {
            Err(Error::new(
                ErrorKind::Other,
                "Seek position is not equal to input position",
            ))
        }
    }

    fn seekable(&self) -> bool {
        true
    }
}