ndarray_npy/npy/elements/
num.rs

1//! Trait implementations for primitive numeric types.
2
3use super::{bytes_as_mut_slice, bytes_as_slice, check_for_extra_bytes};
4use crate::{ReadDataError, ReadableElement, ViewDataError, ViewElement, ViewMutElement};
5use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
6use py_literal::Value as PyValue;
7use std::io;
8
9macro_rules! impl_readable_primitive_one_byte {
10    ($elem:ty, [$($desc:expr),*], $zero:expr, $read_into:ident) => {
11        impl ReadableElement for $elem {
12            fn read_to_end_exact_vec<R: io::Read>(
13                mut reader: R,
14                type_desc: &PyValue,
15                len: usize,
16            ) -> Result<Vec<Self>, ReadDataError> {
17                match *type_desc {
18                    PyValue::String(ref s) if $(s == $desc)||* => {
19                        let mut out = vec![$zero; len];
20                        reader.$read_into(&mut out)?;
21                        check_for_extra_bytes(&mut reader)?;
22                        Ok(out)
23                    }
24                    ref other => Err(ReadDataError::WrongDescriptor(other.clone())),
25                }
26            }
27        }
28    };
29}
30
31macro_rules! impl_view_and_view_mut_primitive_one_byte {
32    ($elem:ty, [$($desc:expr),*]) => {
33        impl ViewElement for $elem {
34            fn bytes_as_slice<'a>(
35                bytes: &'a [u8],
36                type_desc: &PyValue,
37                len: usize,
38            ) -> Result<&'a [Self], ViewDataError> {
39                match *type_desc {
40                    PyValue::String(ref s) if $(s == $desc)||* => unsafe {
41                        bytes_as_slice(bytes, len)
42                    }
43                    ref other => Err(ViewDataError::WrongDescriptor(other.clone())),
44                }
45            }
46        }
47
48        impl ViewMutElement for $elem {
49            fn bytes_as_mut_slice<'a>(
50                bytes: &'a mut [u8],
51                type_desc: &PyValue,
52                len: usize,
53            ) -> Result<&'a mut [Self], ViewDataError> {
54                match *type_desc {
55                    PyValue::String(ref s) if $(s == $desc)||* => unsafe {
56                        bytes_as_mut_slice(bytes, len)
57                    }
58                    ref other => Err(ViewDataError::WrongDescriptor(other.clone())),
59                }
60            }
61        }
62    };
63}
64
65macro_rules! impl_primitive_one_byte {
66    ($elem:ty, $write_desc:expr, [$($read_desc:expr),*], $zero:expr, $read_into:ident) => {
67        impl_writable_element_always_valid_cast!($elem, $write_desc, $write_desc);
68        impl_readable_primitive_one_byte!($elem, [$($read_desc),*], $zero, $read_into);
69        impl_view_and_view_mut_primitive_one_byte!($elem, [$($read_desc),*]);
70    };
71}
72
73impl_primitive_one_byte!(i8, "|i1", ["|i1", "i1", "b"], 0, read_i8_into);
74impl_primitive_one_byte!(u8, "|u1", ["|u1", "u1", "B"], 0, read_exact);
75
76macro_rules! impl_readable_primitive_multi_byte {
77    ($elem:ty, $little_desc:expr, $big_desc:expr, $zero:expr, $read_into:ident) => {
78        impl ReadableElement for $elem {
79            fn read_to_end_exact_vec<R: io::Read>(
80                mut reader: R,
81                type_desc: &PyValue,
82                len: usize,
83            ) -> Result<Vec<Self>, ReadDataError> {
84                let mut out = vec![$zero; len];
85                match *type_desc {
86                    PyValue::String(ref s) if s == $little_desc => {
87                        reader.$read_into::<LittleEndian>(&mut out)?;
88                    }
89                    PyValue::String(ref s) if s == $big_desc => {
90                        reader.$read_into::<BigEndian>(&mut out)?;
91                    }
92                    ref other => {
93                        return Err(ReadDataError::WrongDescriptor(other.clone()));
94                    }
95                }
96                check_for_extra_bytes(&mut reader)?;
97                Ok(out)
98            }
99        }
100    };
101}
102
103macro_rules! impl_primitive_multi_byte {
104    ($elem:ty, $little_desc:expr, $big_desc:expr, $zero:expr, $read_into:ident) => {
105        impl_writable_element_always_valid_cast!($elem, $little_desc, $big_desc);
106        impl_readable_primitive_multi_byte!($elem, $little_desc, $big_desc, $zero, $read_into);
107        #[cfg(target_endian = "little")]
108        impl_view_and_view_mut_always_valid_cast_multi_byte!($elem, $little_desc, $big_desc);
109        #[cfg(target_endian = "big")]
110        impl_view_and_view_mut_always_valid_cast_multi_byte!($elem, $big_desc, $little_desc);
111    };
112}
113
114impl_primitive_multi_byte!(i16, "<i2", ">i2", 0, read_i16_into);
115impl_primitive_multi_byte!(i32, "<i4", ">i4", 0, read_i32_into);
116impl_primitive_multi_byte!(i64, "<i8", ">i8", 0, read_i64_into);
117
118impl_primitive_multi_byte!(u16, "<u2", ">u2", 0, read_u16_into);
119impl_primitive_multi_byte!(u32, "<u4", ">u4", 0, read_u32_into);
120impl_primitive_multi_byte!(u64, "<u8", ">u8", 0, read_u64_into);
121
122impl_primitive_multi_byte!(f32, "<f4", ">f4", 0., read_f32_into);
123impl_primitive_multi_byte!(f64, "<f8", ">f8", 0., read_f64_into);