1#![allow(bad_style)]
4
5use super::mem;
6
7#[repr(C)]
8#[derive(Clone, Debug, PartialEq)]
9pub enum ipserror {
10 ips_ok,
12 ips_notthis,
14 ips_thisout,
16 ips_scrambled,
18 ips_invalid,
20 ips_16MB,
25 ips_identical,
27 ips_shut_up_gcc,
29}
30
31#[repr(C)]
32#[derive(Clone, Debug, PartialEq)]
33pub struct ipsstudy {
34 error: ipserror,
35 outlen_min: libc::c_uint,
36 outlen_max: libc::c_uint,
37 outlen_min_mem: libc::c_uint,
38}
39
40impl Default for ipsstudy {
41 fn default() -> Self {
42 Self {
43 error: ipserror::ips_ok,
44 outlen_min: 0,
45 outlen_max: 0,
46 outlen_min_mem: 0,
47 }
48 }
49}
50
51#[link(name="ips")]
52extern "C" {
53 pub fn ips_apply(patch: mem, in_: mem, out: *mut mem) -> ipserror;
57
58 pub fn ips_create(source: mem, target: mem, patch: *mut mem) -> ipserror;
60
61 pub fn ips_free(mem: mem);
67
68 pub fn ips_study(patch: mem, study: *mut ipsstudy) -> ipserror;
70
71 pub fn ips_apply_study(patch: mem, study: *mut ipsstudy, in_: mem, out: *mut mem) -> ipserror;
77}
78
79#[cfg(test)]
80mod tests {
81
82 use core::ops::Deref;
83
84 use super::mem;
85 use super::ipserror;
86 use crate::test_utils::ArbitraryBuffer;
87
88 #[quickcheck_macros::quickcheck]
89 fn check_create_and_apply(mut source: ArbitraryBuffer, mut target: ArbitraryBuffer) -> bool {
90 if source == target {
91 return true;
92 }
93
94 unsafe {
95 let mut mem_patch = mem::default();
97 let result = super::ips_create(source.to_mem(), target.to_mem(), &mut mem_patch as *mut mem);
98 assert_eq!(result, ipserror::ips_ok, "could not create patch");
99
100 let mut mem_out = mem::default();
102 let result = super::ips_apply(mem_patch, source.to_mem(), &mut mem_out as *mut mem);
103 assert_eq!(result, ipserror::ips_ok, "could not apply patch");
104
105 mem_out.as_ref() == target.deref()
107 }
108 }
109
110 #[quickcheck_macros::quickcheck]
111 fn check_create_identical(mut source: ArbitraryBuffer) -> bool {
112 unsafe {
113 let mut mem_patch = core::mem::MaybeUninit::uninit().assume_init();
114 let result = super::ips_create(source.to_mem(), source.to_mem(), &mut mem_patch as *mut _);
115 result == ipserror::ips_identical
116 }
117 }
118
119 #[quickcheck_macros::quickcheck]
120 fn check_create_equal(mut source: ArbitraryBuffer) -> bool {
121 let mut target = source.clone();
122 unsafe {
123 let mut mem_patch = core::mem::MaybeUninit::uninit().assume_init();
124 let result = super::ips_create(source.to_mem(), target.to_mem(), &mut mem_patch as *mut _);
125 result == ipserror::ips_identical
126 }
127 }
128}