1use super::BasicEncode;
5use byteordered::{ByteOrdered, Endianness};
6use std::io::Write;
7
8type Result<T> = std::io::Result<T>;
9
10#[derive(Debug, Default, Clone, PartialEq)]
12pub struct LittleEndianBasicEncoder;
13
14impl BasicEncode for LittleEndianBasicEncoder {
15 fn endianness(&self) -> Endianness {
16 Endianness::Little
17 }
18
19 fn encode_us<S>(&self, to: S, value: u16) -> Result<()>
20 where
21 S: Write,
22 {
23 ByteOrdered::le(to).write_u16(value)?;
24 Ok(())
25 }
26
27 fn encode_ul<S>(&self, to: S, value: u32) -> Result<()>
28 where
29 S: Write,
30 {
31 ByteOrdered::le(to).write_u32(value)?;
32 Ok(())
33 }
34
35 fn encode_uv<S>(&self, to: S, value: u64) -> Result<()>
36 where
37 S: Write,
38 {
39 ByteOrdered::le(to).write_u64(value)?;
40 Ok(())
41 }
42
43 fn encode_ss<S>(&self, to: S, value: i16) -> Result<()>
44 where
45 S: Write,
46 {
47 ByteOrdered::le(to).write_i16(value)?;
48 Ok(())
49 }
50
51 fn encode_sl<S>(&self, to: S, value: i32) -> Result<()>
52 where
53 S: Write,
54 {
55 ByteOrdered::le(to).write_i32(value)?;
56 Ok(())
57 }
58
59 fn encode_sv<S>(&self, to: S, value: i64) -> Result<()>
60 where
61 S: Write,
62 {
63 ByteOrdered::le(to).write_i64(value)?;
64 Ok(())
65 }
66
67 fn encode_fl<S>(&self, to: S, value: f32) -> Result<()>
68 where
69 S: Write,
70 {
71 ByteOrdered::le(to).write_f32(value)?;
72 Ok(())
73 }
74
75 fn encode_fd<S>(&self, to: S, value: f64) -> Result<()>
76 where
77 S: Write,
78 {
79 ByteOrdered::le(to).write_f64(value)?;
80 Ok(())
81 }
82}
83
84#[derive(Debug, Default, Clone, PartialEq)]
86pub struct BigEndianBasicEncoder;
87
88impl BasicEncode for BigEndianBasicEncoder {
89 fn endianness(&self) -> Endianness {
90 Endianness::Big
91 }
92
93 fn encode_us<S>(&self, to: S, value: u16) -> Result<()>
94 where
95 S: Write,
96 {
97 ByteOrdered::be(to).write_u16(value)?;
98 Ok(())
99 }
100
101 fn encode_ul<S>(&self, to: S, value: u32) -> Result<()>
102 where
103 S: Write,
104 {
105 ByteOrdered::be(to).write_u32(value)?;
106 Ok(())
107 }
108
109 fn encode_uv<S>(&self, to: S, value: u64) -> Result<()>
110 where
111 S: Write,
112 {
113 ByteOrdered::be(to).write_u64(value)?;
114 Ok(())
115 }
116
117 fn encode_ss<S>(&self, to: S, value: i16) -> Result<()>
118 where
119 S: Write,
120 {
121 ByteOrdered::be(to).write_i16(value)?;
122 Ok(())
123 }
124
125 fn encode_sl<S>(&self, to: S, value: i32) -> Result<()>
126 where
127 S: Write,
128 {
129 ByteOrdered::be(to).write_i32(value)?;
130 Ok(())
131 }
132
133 fn encode_sv<S>(&self, to: S, value: i64) -> Result<()>
134 where
135 S: Write,
136 {
137 ByteOrdered::be(to).write_i64(value)?;
138 Ok(())
139 }
140
141 fn encode_fl<S>(&self, to: S, value: f32) -> Result<()>
142 where
143 S: Write,
144 {
145 ByteOrdered::be(to).write_f32(value)?;
146 Ok(())
147 }
148
149 fn encode_fd<S>(&self, to: S, value: f64) -> Result<()>
150 where
151 S: Write,
152 {
153 ByteOrdered::be(to).write_f64(value)?;
154 Ok(())
155 }
156}
157
158#[derive(Debug, Clone, PartialEq)]
162pub enum BasicEncoder {
163 LE(LittleEndianBasicEncoder),
165 BE(BigEndianBasicEncoder),
167}
168
169use self::BasicEncoder::{BE, LE};
170
171macro_rules! for_both {
176 ($endianness: expr, |$e: ident| $f: expr) => {
177 match *$endianness {
178 LE(ref $e) => $f,
179 BE(ref $e) => $f,
180 }
181 };
182}
183
184impl BasicEncode for BasicEncoder {
185 fn endianness(&self) -> Endianness {
186 match *self {
187 LE(_) => Endianness::Little,
188 BE(_) => Endianness::Big,
189 }
190 }
191
192 fn encode_us<S>(&self, to: S, value: u16) -> Result<()>
193 where
194 S: Write,
195 {
196 for_both!(self, |e| e.encode_us(to, value))
197 }
198
199 fn encode_ul<S>(&self, to: S, value: u32) -> Result<()>
200 where
201 S: Write,
202 {
203 for_both!(self, |e| e.encode_ul(to, value))
204 }
205
206 fn encode_uv<S>(&self, to: S, value: u64) -> Result<()>
207 where
208 S: Write,
209 {
210 for_both!(self, |e| e.encode_uv(to, value))
211 }
212
213 fn encode_ss<S>(&self, to: S, value: i16) -> Result<()>
214 where
215 S: Write,
216 {
217 for_both!(self, |e| e.encode_ss(to, value))
218 }
219
220 fn encode_sl<S>(&self, to: S, value: i32) -> Result<()>
221 where
222 S: Write,
223 {
224 for_both!(self, |e| e.encode_sl(to, value))
225 }
226
227 fn encode_sv<S>(&self, to: S, value: i64) -> Result<()>
228 where
229 S: Write,
230 {
231 for_both!(self, |e| e.encode_sv(to, value))
232 }
233
234 fn encode_fl<S>(&self, to: S, value: f32) -> Result<()>
235 where
236 S: Write,
237 {
238 for_both!(self, |e| e.encode_fl(to, value))
239 }
240
241 fn encode_fd<S>(&self, to: S, value: f64) -> Result<()>
242 where
243 S: Write,
244 {
245 for_both!(self, |e| e.encode_fd(to, value))
246 }
247}
248
249#[cfg(test)]
250mod tests {
251 use super::*;
252 use dicom_core::value::DicomDate;
253 use dicom_core::{PrimitiveValue, Tag};
254
255 fn test_one_primitive_be(value: PrimitiveValue, raw: &[u8]) {
256 let mut out = vec![];
257 BigEndianBasicEncoder
258 .encode_primitive(&mut out, &value)
259 .unwrap();
260 assert_eq!(&*out, raw);
261 }
262
263 fn test_one_primitive_le(value: PrimitiveValue, raw: &[u8]) {
264 let mut out = vec![];
265 LittleEndianBasicEncoder
266 .encode_primitive(&mut out, &value)
267 .unwrap();
268 assert_eq!(&*out, raw);
269 }
270
271 #[test]
272 fn test_basic_encode_le() {
273 test_one_primitive_le(PrimitiveValue::Empty, &[]);
274 test_one_primitive_le(
275 PrimitiveValue::I32(vec![0x01, 0x0200, 0x0300_FFCC].into()),
276 &[
277 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xCC, 0xFF, 0x00, 0x03,
278 ],
279 );
280
281 test_one_primitive_le(
282 PrimitiveValue::Strs(
283 ["one", "more", "time"]
284 .iter()
285 .map(|s| s.to_string())
286 .collect(),
287 ),
288 &*b"one\\more\\time",
289 );
290
291 test_one_primitive_le(
292 PrimitiveValue::Date(
293 vec![
294 DicomDate::from_ymd(2016, 12, 01).unwrap(),
295 DicomDate::from_ymd(2123, 9, 13).unwrap(),
296 ]
297 .into(),
298 ),
299 &*b"20161201\\21230913",
300 );
301
302 test_one_primitive_le(
303 PrimitiveValue::Tags(vec![Tag(0x0002, 0x0001), Tag(0xFA80, 0xBC12)].into()),
304 &[0x02, 0x00, 0x01, 0x00, 0x80, 0xFA, 0x12, 0xBC],
305 );
306 }
307
308 #[test]
309 fn test_basic_encode_be() {
310 test_one_primitive_be(PrimitiveValue::Empty, &[]);
311 test_one_primitive_be(
312 PrimitiveValue::I32(vec![0x01, 0x0200, 0x0300_FFCC].into()),
313 &[
314 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0xFF, 0xCC,
315 ],
316 );
317
318 test_one_primitive_be(
319 PrimitiveValue::Strs(
320 ["one", "more", "time"]
321 .iter()
322 .map(|s| s.to_string())
323 .collect(),
324 ),
325 &*b"one\\more\\time",
326 );
327
328 test_one_primitive_be(
329 PrimitiveValue::Date(
330 vec![
331 DicomDate::from_ymd(2016, 12, 01).unwrap(),
332 DicomDate::from_ym(2123, 9).unwrap(),
333 ]
334 .into(),
335 ),
336 &*b"20161201\\212309",
337 );
338
339 test_one_primitive_be(
340 PrimitiveValue::Tags(vec![Tag(0x0002, 0x0001), Tag(0xFA80, 0xBC12)].into()),
341 &[0x00, 0x02, 0x00, 0x01, 0xFA, 0x80, 0xBC, 0x12],
342 );
343 }
344}