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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! This module contains the type-erased version of a decoder.

use crate::error::Result;
use byteordered::Endianness;
use dicom_core::header::{DataElementHeader, Length, SequenceItemHeader};
use dicom_core::Tag;
use std::io::Read;

/** Type trait for reading and decoding basic data values from a data source.
 *
 * This trait aims to provide methods for reading binary numbers based on the
 * source's endianness.
 * This is the type-erased version of `super::BasicDecode`, where the data source type is not
 * known in compile time.
 */
pub trait BasicDecode {
    /// Retrieve the source's endianness, as expected by this decoder.
    fn endianness(&self) -> Endianness;

    /// Decode an unsigned short value from the given source.
    fn erased_decode_us(&self, source: &mut dyn Read) -> Result<u16>;

    /// Decode an unsigned long value from the given source.
    fn erased_decode_ul(&self, source: &mut dyn Read) -> Result<u32>;

    /// Decode an unsigned very long value from the given source.
    fn erased_decode_uv(&self, source: &mut dyn Read) -> Result<u64>;

    /// Decode a signed short value from the given source.
    fn erased_decode_ss(&self, source: &mut dyn Read) -> Result<i16>;

    /// Decode a signed long value from the given source.
    fn erased_decode_sl(&self, source: &mut dyn Read) -> Result<i32>;

    /// Decode a signed very long value from the given source.
    fn erased_decode_sv(&self, source: &mut dyn Read) -> Result<i64>;

    /// Decode a single precision float value from the given source.
    fn erased_decode_fl(&self, source: &mut dyn Read) -> Result<f32>;

    /// Decode a double precision float value from the given source.
    fn erased_decode_fd(&self, source: &mut dyn Read) -> Result<f64>;
}

/** Type trait for reading and decoding DICOM data elements.
 *
 * The specific behaviour of decoding, even when abstracted from the original source,
 * may depend on the given transfer syntax.
 *
 * This is the type-erased version of `super::Decode`, where the data source type is not
 * known in compile time. Users of this library should not need to rely on this level
 * directly, as the given implementations provide support for converting a generic decoder
 * to a type-erased decoder.
 */
pub trait Decode: BasicDecode {
    /** Fetch and decode the next data element header from the given source.
     * This method returns only the header of the element. At the end of this operation, the source
     * will be pointing at the element's value data, which should be read or skipped as necessary.
     */
    fn erased_decode(&self, source: &mut dyn Read) -> Result<DataElementHeader>;

    /** Fetch and decode the next sequence item head from the given source.
     * This method returns only the header of the item. At the end of this operation, the source
     * will be pointing at the beginning of the item's data, which should be traversed if necessary.
     */
    fn erased_decode_item(&self, mut source: &mut dyn Read) -> Result<SequenceItemHeader> {
        let tag = self.erased_decode_tag(&mut source)?;
        let len = self.erased_decode_ul(&mut source)?;
        let header = SequenceItemHeader::new(tag, Length(len))?;
        Ok(header)
    }

    /// Decode a DICOM attribute tag from the given source.
    fn erased_decode_tag(&self, source: &mut dyn Read) -> Result<Tag> {
        let group = self.erased_decode_us(source)?;
        let elem = self.erased_decode_us(source)?;
        Ok(Tag(group, elem))
    }
}

impl<'s> super::BasicDecode for &'s dyn BasicDecode {
    fn endianness(&self) -> Endianness {
        (**self).endianness()
    }

    fn decode_us<S>(&self, mut source: S) -> Result<u16>
    where
        S: Read,
    {
        (**self).erased_decode_us(&mut source)
    }

    fn decode_ul<S>(&self, mut source: S) -> Result<u32>
    where
        S: Read,
    {
        (**self).erased_decode_ul(&mut source)
    }

    fn decode_uv<S>(&self, mut source: S) -> Result<u64>
    where
        S: Read,
    {
        (**self).erased_decode_uv(&mut source)
    }

    fn decode_ss<S>(&self, mut source: S) -> Result<i16>
    where
        S: Read,
    {
        (**self).erased_decode_ss(&mut source)
    }

    fn decode_sl<S>(&self, mut source: S) -> Result<i32>
    where
        S: Read,
    {
        (**self).erased_decode_sl(&mut source)
    }

    fn decode_sv<S>(&self, mut source: S) -> Result<i64>
    where
        S: Read,
    {
        (**self).erased_decode_sv(&mut source)
    }

    fn decode_fl<S>(&self, mut source: S) -> Result<f32>
    where
        S: Read,
    {
        (**self).erased_decode_fl(&mut source)
    }

    fn decode_fd<S>(&self, mut source: S) -> Result<f64>
    where
        S: Read,
    {
        (**self).erased_decode_fd(&mut source)
    }
}