1use byteordered::Endianness;
3use dicom_core::value::serialize::{encode_date, encode_datetime, encode_time};
4use dicom_core::{DataElementHeader, PrimitiveValue, Tag};
5use snafu::{Backtrace, ResultExt, Snafu};
6use std::fmt;
7use std::io::{self, Write};
8use std::marker::PhantomData;
9
10pub mod basic;
11pub mod explicit_be;
12pub mod explicit_le;
13pub mod implicit_le;
14
15#[derive(Debug, Snafu)]
18#[non_exhaustive]
19pub enum Error {
20 #[snafu(display("Failed to write Date value"))]
21 WriteDate {
22 backtrace: Backtrace,
23 source: io::Error,
24 },
25 #[snafu(display("Failed to write Time value"))]
26 WriteTime {
27 backtrace: Backtrace,
28 source: io::Error,
29 },
30 #[snafu(display("Failed to write DateTime value"))]
31 WriteDateTime {
32 backtrace: Backtrace,
33 source: io::Error,
34 },
35 #[snafu(display("Failed to write tag"))]
36 WriteTag {
37 backtrace: Backtrace,
38 source: io::Error,
39 },
40 #[snafu(display("Failed to write tag group"))]
41 WriteTagGroup {
42 backtrace: Backtrace,
43 source: io::Error,
44 },
45 #[snafu(display("Failed to write tag element"))]
46 WriteTagElement {
47 backtrace: Backtrace,
48 source: io::Error,
49 },
50 #[snafu(display("Failed to write item header"))]
51 WriteItemHeader {
52 backtrace: Backtrace,
53 source: io::Error,
54 },
55 #[snafu(display("Failed to write element header"))]
56 WriteHeader {
57 backtrace: Backtrace,
58 source: io::Error,
59 },
60 #[snafu(display("Failed to write item delimiter"))]
61 WriteItemDelimiter {
62 backtrace: Backtrace,
63 source: io::Error,
64 },
65 #[snafu(display("Failed to write sequence delimiter"))]
66 WriteSequenceDelimiter {
67 backtrace: Backtrace,
68 source: io::Error,
69 },
70 #[snafu(display("Failed to write {} value", typ))]
71 WriteBinary {
72 typ: &'static str,
73 backtrace: Backtrace,
74 source: io::Error,
75 },
76 #[snafu(display("Failed to write string value"))]
77 WriteString {
78 backtrace: Backtrace,
79 source: io::Error,
80 },
81 #[snafu(display("Failed to write bytes"))]
82 WriteBytes {
83 backtrace: Backtrace,
84 source: io::Error,
85 },
86 #[snafu(display("Failed to write pixel data offset table"))]
87 WriteOffsetTable {
88 backtrace: Backtrace,
89 source: io::Error,
90 },
91}
92
93pub type Result<T, E = Error> = std::result::Result<T, E>;
94
95pub trait BasicEncode {
99 fn endianness(&self) -> Endianness;
101
102 fn encode_us<W>(&self, to: W, value: u16) -> io::Result<()>
104 where
105 W: Write;
106
107 fn encode_ul<W>(&self, to: W, value: u32) -> io::Result<()>
109 where
110 W: Write;
111
112 fn encode_uv<W>(&self, to: W, value: u64) -> io::Result<()>
114 where
115 W: Write;
116
117 fn encode_ss<W>(&self, to: W, value: i16) -> io::Result<()>
119 where
120 W: Write;
121
122 fn encode_sl<W>(&self, to: W, value: i32) -> io::Result<()>
124 where
125 W: Write;
126
127 fn encode_sv<W>(&self, to: W, value: i64) -> io::Result<()>
129 where
130 W: Write;
131
132 fn encode_fl<W>(&self, to: W, value: f32) -> io::Result<()>
134 where
135 W: Write;
136
137 fn encode_fd<W>(&self, to: W, value: f64) -> io::Result<()>
139 where
140 W: Write;
141
142 #[inline]
145 fn with_encoder<T, F1, F2>(&self, f_le: F1, f_be: F2) -> T
146 where
147 F1: FnOnce(basic::LittleEndianBasicEncoder) -> T,
148 F2: FnOnce(basic::BigEndianBasicEncoder) -> T,
149 {
150 match self.endianness() {
151 Endianness::Little => f_le(basic::LittleEndianBasicEncoder),
152 Endianness::Big => f_be(basic::BigEndianBasicEncoder),
153 }
154 }
155
156 fn encode_primitive<W>(&self, mut to: W, value: &PrimitiveValue) -> Result<usize>
159 where
160 W: Write,
161 {
162 use PrimitiveValue::*;
163 match value {
164 Empty => Ok(0), Date(date) => {
166 encode_collection_delimited(&mut to, date, |to, date| encode_date(to, *date))
167 .context(WriteDateSnafu)
168 }
169 Time(time) => {
170 encode_collection_delimited(&mut to, time, |to, time| encode_time(to, *time))
171 .context(WriteTimeSnafu)
172 }
173 DateTime(datetime) => encode_collection_delimited(&mut to, datetime, |to, datetime| {
174 encode_datetime(to, *datetime)
175 })
176 .context(WriteDateTimeSnafu),
177 Str(s) => {
178 write!(to, "{}", s).context(WriteStringSnafu)?;
182 Ok(s.len())
183 }
184 Strs(s) => encode_collection_delimited(&mut to, s, |to, s| {
185 write!(to, "{}", s)?;
189 Ok(s.len())
190 })
191 .context(WriteStringSnafu),
192 F32(values) => {
193 for v in values {
194 self.encode_fl(&mut to, *v)
195 .context(WriteBinarySnafu { typ: "F32" })?;
196 }
197 Ok(values.len() * 4)
198 }
199 F64(values) => {
200 for v in values {
201 self.encode_fd(&mut to, *v)
202 .context(WriteBinarySnafu { typ: "F64" })?;
203 }
204 Ok(values.len() * 8)
205 }
206 U64(values) => {
207 for v in values {
208 self.encode_uv(&mut to, *v)
209 .context(WriteBinarySnafu { typ: "U64" })?;
210 }
211 Ok(values.len() * 8)
212 }
213 I64(values) => {
214 for v in values {
215 self.encode_sv(&mut to, *v)
216 .context(WriteBinarySnafu { typ: "I64" })?;
217 }
218 Ok(values.len() * 8)
219 }
220 U32(values) => {
221 for v in values {
222 self.encode_ul(&mut to, *v)
223 .context(WriteBinarySnafu { typ: "U32" })?;
224 }
225 Ok(values.len() * 4)
226 }
227 I32(values) => {
228 for v in values {
229 self.encode_sl(&mut to, *v)
230 .context(WriteBinarySnafu { typ: "I32" })?;
231 }
232 Ok(values.len() * 4)
233 }
234 U16(values) => {
235 for v in values {
236 self.encode_us(&mut to, *v)
237 .context(WriteBinarySnafu { typ: "U16" })?;
238 }
239 Ok(values.len() * 2)
240 }
241 I16(values) => {
242 for v in values {
243 self.encode_ss(&mut to, *v)
244 .context(WriteBinarySnafu { typ: "I16" })?;
245 }
246 Ok(values.len() * 2)
247 }
248 U8(values) => {
249 to.write_all(values).context(WriteBytesSnafu)?;
250 Ok(values.len())
251 }
252 Tags(tags) => {
253 for tag in tags {
254 self.encode_us(&mut to, tag.0).context(WriteTagGroupSnafu)?;
255 self.encode_us(&mut to, tag.1)
256 .context(WriteTagElementSnafu)?;
257 }
258 Ok(tags.len() * 4)
259 }
260 }
261 }
262}
263
264fn encode_collection_delimited<W, T, F>(
265 to: &mut W,
266 col: &[T],
267 mut encode_element_fn: F,
268) -> io::Result<usize>
269where
270 W: ?Sized + Write,
271 F: FnMut(&mut W, &T) -> io::Result<usize>,
272{
273 let mut acc = 0;
274 for (i, v) in col.iter().enumerate() {
275 acc += encode_element_fn(to, v)?;
276 if i < col.len() - 1 {
277 to.write_all(b"\\")?;
278 acc += 1;
279 }
280 }
281 Ok(acc)
282}
283
284pub trait Encode {
286 fn encode_tag<W>(&self, to: W, tag: Tag) -> Result<()>
288 where
289 W: Write;
290
291 fn encode_element_header<W>(&self, to: W, de: DataElementHeader) -> Result<usize>
294 where
295 W: Write;
296
297 fn encode_item_header<W>(&self, to: W, len: u32) -> Result<()>
301 where
302 W: Write;
303
304 fn encode_item_delimiter<W>(&self, mut to: W) -> Result<()>
306 where
307 W: Write,
308 {
309 self.encode_tag(&mut to, Tag(0xFFFE, 0xE00D))?;
310 to.write_all(&[0u8; 4]).context(WriteItemDelimiterSnafu)?;
311 Ok(())
312 }
313
314 fn encode_sequence_delimiter<W>(&self, mut to: W) -> Result<()>
316 where
317 W: Write,
318 {
319 self.encode_tag(&mut to, Tag(0xFFFE, 0xE0DD))?;
320 to.write_all(&[0u8; 4])
321 .context(WriteSequenceDelimiterSnafu)?;
322 Ok(())
323 }
324
325 fn encode_primitive<W>(&self, to: W, value: &PrimitiveValue) -> Result<usize>
327 where
328 W: Write;
329
330 fn encode_offset_table<W>(&self, to: W, offset_table: &[u32]) -> Result<usize>
338 where
339 W: Write;
340}
341
342impl<T: ?Sized> Encode for &T
343where
344 T: Encode,
345{
346 fn encode_tag<W>(&self, to: W, tag: Tag) -> Result<()>
347 where
348 W: Write,
349 {
350 (**self).encode_tag(to, tag)
351 }
352
353 fn encode_element_header<W>(&self, to: W, de: DataElementHeader) -> Result<usize>
354 where
355 W: Write,
356 {
357 (**self).encode_element_header(to, de)
358 }
359
360 fn encode_item_header<W>(&self, to: W, len: u32) -> Result<()>
361 where
362 W: Write,
363 {
364 (**self).encode_item_header(to, len)
365 }
366
367 fn encode_item_delimiter<W>(&self, to: W) -> Result<()>
368 where
369 W: Write,
370 {
371 (**self).encode_item_delimiter(to)
372 }
373
374 fn encode_sequence_delimiter<W>(&self, to: W) -> Result<()>
375 where
376 W: Write,
377 {
378 (**self).encode_sequence_delimiter(to)
379 }
380
381 fn encode_primitive<W>(&self, to: W, value: &PrimitiveValue) -> Result<usize>
382 where
383 W: Write,
384 {
385 (**self).encode_primitive(to, value)
386 }
387
388 fn encode_offset_table<W>(&self, to: W, offset_table: &[u32]) -> Result<usize>
389 where
390 W: Write,
391 {
392 (**self).encode_offset_table(to, offset_table)
393 }
394}
395
396impl<T: ?Sized> Encode for Box<T>
397where
398 T: Encode,
399{
400 fn encode_tag<W>(&self, to: W, tag: Tag) -> Result<()>
401 where
402 W: Write,
403 {
404 (**self).encode_tag(to, tag)
405 }
406
407 fn encode_element_header<W>(&self, to: W, de: DataElementHeader) -> Result<usize>
408 where
409 W: Write,
410 {
411 (**self).encode_element_header(to, de)
412 }
413
414 fn encode_item_header<W>(&self, to: W, len: u32) -> Result<()>
415 where
416 W: Write,
417 {
418 (**self).encode_item_header(to, len)
419 }
420
421 fn encode_item_delimiter<W>(&self, to: W) -> Result<()>
422 where
423 W: Write,
424 {
425 (**self).encode_item_delimiter(to)
426 }
427
428 fn encode_sequence_delimiter<W>(&self, to: W) -> Result<()>
429 where
430 W: Write,
431 {
432 (**self).encode_sequence_delimiter(to)
433 }
434
435 fn encode_primitive<W>(&self, to: W, value: &PrimitiveValue) -> Result<usize>
436 where
437 W: Write,
438 {
439 (**self).encode_primitive(to, value)
440 }
441
442 fn encode_offset_table<W>(&self, to: W, offset_table: &[u32]) -> Result<usize>
443 where
444 W: Write,
445 {
446 (**self).encode_offset_table(to, offset_table)
447 }
448}
449
450pub trait EncodeTo<W: ?Sized> {
452 fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()>
454 where
455 W: Write;
456
457 fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize>
464 where
465 W: Write;
466
467 fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()>
471 where
472 W: Write;
473
474 fn encode_item_delimiter(&self, to: &mut W) -> Result<()>
476 where
477 W: Write;
478
479 fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()>
481 where
482 W: Write;
483
484 fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize>
486 where
487 W: Write;
488
489 fn encode_offset_table(&self, to: &mut W, offset_table: &[u32]) -> Result<usize>
497 where
498 W: Write;
499}
500
501impl<T, W: ?Sized> EncodeTo<W> for &T
502where
503 T: EncodeTo<W>,
504{
505 fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()>
506 where
507 W: Write,
508 {
509 (**self).encode_tag(to, tag)
510 }
511
512 fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize>
513 where
514 W: Write,
515 {
516 (**self).encode_element_header(to, de)
517 }
518
519 fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()>
520 where
521 W: Write,
522 {
523 (**self).encode_item_header(to, len)
524 }
525
526 fn encode_item_delimiter(&self, to: &mut W) -> Result<()>
527 where
528 W: Write,
529 {
530 (**self).encode_item_delimiter(to)
531 }
532
533 fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()>
534 where
535 W: Write,
536 {
537 (**self).encode_sequence_delimiter(to)
538 }
539
540 fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize>
542 where
543 W: Write,
544 {
545 (**self).encode_primitive(to, value)
546 }
547
548 fn encode_offset_table(&self, to: &mut W, offset_table: &[u32]) -> Result<usize>
549 where
550 W: Write,
551 {
552 (**self).encode_offset_table(to, offset_table)
553 }
554}
555
556impl<T: ?Sized, W: ?Sized> EncodeTo<W> for Box<T>
557where
558 T: EncodeTo<W>,
559{
560 fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()>
561 where
562 W: Write,
563 {
564 (**self).encode_tag(to, tag)
565 }
566
567 fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize>
568 where
569 W: Write,
570 {
571 (**self).encode_element_header(to, de)
572 }
573
574 fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()>
575 where
576 W: Write,
577 {
578 (**self).encode_item_header(to, len)
579 }
580
581 fn encode_item_delimiter(&self, to: &mut W) -> Result<()>
582 where
583 W: Write,
584 {
585 (**self).encode_item_delimiter(to)
586 }
587
588 fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()>
589 where
590 W: Write,
591 {
592 (**self).encode_sequence_delimiter(to)
593 }
594
595 fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize>
597 where
598 W: Write,
599 {
600 (**self).encode_primitive(to, value)
601 }
602
603 fn encode_offset_table(&self, to: &mut W, offset_table: &[u32]) -> Result<usize>
604 where
605 W: Write,
606 {
607 (**self).encode_offset_table(to, offset_table)
608 }
609}
610
611pub struct EncoderFor<T, W: ?Sized> {
613 inner: T,
614 phantom: PhantomData<W>,
615}
616
617impl<T, W: ?Sized> EncoderFor<T, W> {
618 pub fn new(encoder: T) -> Self {
622 EncoderFor {
623 inner: encoder,
624 phantom: PhantomData,
625 }
626 }
627}
628
629impl<T: fmt::Debug, W: ?Sized> fmt::Debug for EncoderFor<T, W> {
630 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
631 f.debug_struct("ImplicitVRLittleEndianEncoder")
632 .field("inner", &self.inner)
633 .field("phantom", &self.phantom)
634 .finish()
635 }
636}
637
638impl<T, W: ?Sized> Default for EncoderFor<T, W>
639where
640 T: Default,
641{
642 fn default() -> Self {
643 EncoderFor {
644 inner: T::default(),
645 phantom: PhantomData,
646 }
647 }
648}
649
650impl<T, W: ?Sized> BasicEncode for EncoderFor<T, W>
651where
652 T: BasicEncode,
653 W: Write,
654{
655 fn endianness(&self) -> Endianness {
656 self.inner.endianness()
657 }
658
659 fn encode_us<S>(&self, to: S, value: u16) -> io::Result<()>
660 where
661 S: Write,
662 {
663 self.inner.encode_us(to, value)
664 }
665
666 fn encode_ul<S>(&self, to: S, value: u32) -> io::Result<()>
667 where
668 S: Write,
669 {
670 self.inner.encode_ul(to, value)
671 }
672
673 fn encode_uv<S>(&self, to: S, value: u64) -> io::Result<()>
674 where
675 S: Write,
676 {
677 self.inner.encode_uv(to, value)
678 }
679
680 fn encode_ss<S>(&self, to: S, value: i16) -> io::Result<()>
681 where
682 S: Write,
683 {
684 self.inner.encode_ss(to, value)
685 }
686
687 fn encode_sl<S>(&self, to: S, value: i32) -> io::Result<()>
688 where
689 S: Write,
690 {
691 self.inner.encode_sl(to, value)
692 }
693
694 fn encode_sv<S>(&self, to: S, value: i64) -> io::Result<()>
695 where
696 S: Write,
697 {
698 self.inner.encode_sv(to, value)
699 }
700
701 fn encode_fl<S>(&self, to: S, value: f32) -> io::Result<()>
702 where
703 S: Write,
704 {
705 self.inner.encode_fl(to, value)
706 }
707
708 fn encode_fd<S>(&self, to: S, value: f64) -> io::Result<()>
709 where
710 S: Write,
711 {
712 self.inner.encode_fd(to, value)
713 }
714}
715
716impl<T, W: ?Sized> EncodeTo<W> for EncoderFor<T, W>
717where
718 T: Encode,
719 W: Write,
720{
721 fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()> {
722 self.inner.encode_tag(to, tag)
723 }
724
725 fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize> {
726 self.inner.encode_element_header(to, de)
727 }
728
729 fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()> {
730 self.inner.encode_item_header(to, len)
731 }
732
733 fn encode_item_delimiter(&self, to: &mut W) -> Result<()> {
734 self.inner.encode_item_delimiter(to)
735 }
736
737 fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()> {
738 self.inner.encode_sequence_delimiter(to)
739 }
740
741 fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize> {
742 self.inner.encode_primitive(to, value)
743 }
744
745 fn encode_offset_table(&self, to: &mut W, offset_table: &[u32]) -> Result<usize> {
746 self.inner.encode_offset_table(to, offset_table)
747 }
748}
749
750#[cfg(test)]
751mod tests {
752 use super::*;
753
754 fn is_encode<T: Encode>(_encoder: &T) {}
755 fn is_encode_to<W: ?Sized, T: EncodeTo<W>>(_encoder: &T) {}
756
757 #[allow(unused)]
758 fn boxed_encode_is_encode<T>(encoder: T)
759 where
760 T: Encode,
761 T: Copy,
762 {
763 is_encode(&encoder);
764 is_encode_to::<dyn Write, _>(&EncoderFor::new(encoder));
765 let boxed = Box::new(encoder);
766 is_encode(&boxed);
767 is_encode_to::<dyn Write, _>(&EncoderFor::new(boxed));
768 }
769}