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
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
pub extern crate generic_array;
use std::fs::File;
use std::io::{self, ErrorKind, Read, Seek, SeekFrom};
use generic_array::typenum::{IsGreaterOrEqual, True, U1, U256};
use generic_array::{ArrayLength, GenericArray};
#[inline]
pub fn same_content_from_files(a: &mut File, b: &mut File) -> Result<bool, io::Error> {
    same_content_from_files2::<U256>(a, b)
}
#[inline]
pub fn same_content_from_files2<N: ArrayLength<u8> + IsGreaterOrEqual<U1, Output = True>>(
    a: &mut File,
    b: &mut File,
) -> Result<bool, io::Error> {
    let metadata_a = a.metadata()?;
    let metadata_b = b.metadata()?;
    if metadata_a.len() != metadata_b.len() {
        return Ok(false);
    }
    a.seek(SeekFrom::Start(0))?;
    b.seek(SeekFrom::Start(0))?;
    same_content_from_readers2::<N>(a, b)
}
#[inline]
pub fn same_content_from_readers(a: &mut dyn Read, b: &mut dyn Read) -> Result<bool, io::Error> {
    same_content_from_readers2::<U256>(a, b)
}
pub fn same_content_from_readers2<N: ArrayLength<u8> + IsGreaterOrEqual<U1, Output = True>>(
    a: &mut dyn Read,
    b: &mut dyn Read,
) -> Result<bool, io::Error> {
    let mut buffer1: GenericArray<u8, N> = GenericArray::default();
    let mut buffer2: GenericArray<u8, N> = GenericArray::default();
    loop {
        let ca = a.read(&mut buffer1)?;
        if ca == 0 {
            let cb = read_try_exact(b, &mut buffer2[..1])?;
            return Ok(cb == 0);
        } else {
            let cb = read_try_exact(b, &mut buffer2[..ca])?;
            if ca != cb {
                return Ok(false);
            }
            if buffer1[..ca] != buffer2[..ca] {
                return Ok(false);
            }
        }
    }
}
fn read_try_exact(a: &mut dyn Read, mut buffer: &mut [u8]) -> Result<usize, io::Error> {
    let mut sum = 0;
    while !buffer.is_empty() {
        match a.read(buffer) {
            Ok(0) => break,
            Ok(n) => {
                buffer = &mut buffer[n..];
                sum += n;
            }
            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
            Err(e) => return Err(e),
        }
    }
    Ok(sum)
}