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 #[snafu(display("Item too long ({} bytes) for a 16-bit length", length))]
92 WriteHeaderTooLong { length: u32, backtrace: Backtrace },
93}
94
95pub type Result<T, E = Error> = std::result::Result<T, E>;
96
97pub trait BasicEncode {
101 fn endianness(&self) -> Endianness;
103
104 fn encode_us<W>(&self, to: W, value: u16) -> io::Result<()>
106 where
107 W: Write;
108
109 fn encode_ul<W>(&self, to: W, value: u32) -> io::Result<()>
111 where
112 W: Write;
113
114 fn encode_uv<W>(&self, to: W, value: u64) -> io::Result<()>
116 where
117 W: Write;
118
119 fn encode_ss<W>(&self, to: W, value: i16) -> io::Result<()>
121 where
122 W: Write;
123
124 fn encode_sl<W>(&self, to: W, value: i32) -> io::Result<()>
126 where
127 W: Write;
128
129 fn encode_sv<W>(&self, to: W, value: i64) -> io::Result<()>
131 where
132 W: Write;
133
134 fn encode_fl<W>(&self, to: W, value: f32) -> io::Result<()>
136 where
137 W: Write;
138
139 fn encode_fd<W>(&self, to: W, value: f64) -> io::Result<()>
141 where
142 W: Write;
143
144 #[inline]
147 fn with_encoder<T, F1, F2>(&self, f_le: F1, f_be: F2) -> T
148 where
149 F1: FnOnce(basic::LittleEndianBasicEncoder) -> T,
150 F2: FnOnce(basic::BigEndianBasicEncoder) -> T,
151 {
152 match self.endianness() {
153 Endianness::Little => f_le(basic::LittleEndianBasicEncoder),
154 Endianness::Big => f_be(basic::BigEndianBasicEncoder),
155 }
156 }
157
158 fn encode_primitive<W>(&self, mut to: W, value: &PrimitiveValue) -> Result<usize>
161 where
162 W: Write,
163 {
164 use PrimitiveValue::*;
165 match value {
166 Empty => Ok(0), Date(date) => {
168 encode_collection_delimited(&mut to, date, |to, date| encode_date(to, *date))
169 .context(WriteDateSnafu)
170 }
171 Time(time) => {
172 encode_collection_delimited(&mut to, time, |to, time| encode_time(to, *time))
173 .context(WriteTimeSnafu)
174 }
175 DateTime(datetime) => encode_collection_delimited(&mut to, datetime, |to, datetime| {
176 encode_datetime(to, *datetime)
177 })
178 .context(WriteDateTimeSnafu),
179 Str(s) => {
180 write!(to, "{s}").context(WriteStringSnafu)?;
184 Ok(s.len())
185 }
186 Strs(s) => encode_collection_delimited(&mut to, s, |to, s| {
187 write!(to, "{s}")?;
191 Ok(s.len())
192 })
193 .context(WriteStringSnafu),
194 F32(values) => {
195 for v in values {
196 self.encode_fl(&mut to, *v)
197 .context(WriteBinarySnafu { typ: "F32" })?;
198 }
199 Ok(values.len() * 4)
200 }
201 F64(values) => {
202 for v in values {
203 self.encode_fd(&mut to, *v)
204 .context(WriteBinarySnafu { typ: "F64" })?;
205 }
206 Ok(values.len() * 8)
207 }
208 U64(values) => {
209 for v in values {
210 self.encode_uv(&mut to, *v)
211 .context(WriteBinarySnafu { typ: "U64" })?;
212 }
213 Ok(values.len() * 8)
214 }
215 I64(values) => {
216 for v in values {
217 self.encode_sv(&mut to, *v)
218 .context(WriteBinarySnafu { typ: "I64" })?;
219 }
220 Ok(values.len() * 8)
221 }
222 U32(values) => {
223 for v in values {
224 self.encode_ul(&mut to, *v)
225 .context(WriteBinarySnafu { typ: "U32" })?;
226 }
227 Ok(values.len() * 4)
228 }
229 I32(values) => {
230 for v in values {
231 self.encode_sl(&mut to, *v)
232 .context(WriteBinarySnafu { typ: "I32" })?;
233 }
234 Ok(values.len() * 4)
235 }
236 U16(values) => {
237 for v in values {
238 self.encode_us(&mut to, *v)
239 .context(WriteBinarySnafu { typ: "U16" })?;
240 }
241 Ok(values.len() * 2)
242 }
243 I16(values) => {
244 for v in values {
245 self.encode_ss(&mut to, *v)
246 .context(WriteBinarySnafu { typ: "I16" })?;
247 }
248 Ok(values.len() * 2)
249 }
250 U8(values) => {
251 to.write_all(values).context(WriteBytesSnafu)?;
252 Ok(values.len())
253 }
254 Tags(tags) => {
255 for tag in tags {
256 self.encode_us(&mut to, tag.0).context(WriteTagGroupSnafu)?;
257 self.encode_us(&mut to, tag.1)
258 .context(WriteTagElementSnafu)?;
259 }
260 Ok(tags.len() * 4)
261 }
262 }
263 }
264}
265
266fn encode_collection_delimited<W, T, F>(
267 to: &mut W,
268 col: &[T],
269 mut encode_element_fn: F,
270) -> io::Result<usize>
271where
272 W: ?Sized + Write,
273 F: FnMut(&mut W, &T) -> io::Result<usize>,
274{
275 let mut acc = 0;
276 for (i, v) in col.iter().enumerate() {
277 acc += encode_element_fn(to, v)?;
278 if i < col.len() - 1 {
279 to.write_all(b"\\")?;
280 acc += 1;
281 }
282 }
283 Ok(acc)
284}
285
286pub trait Encode {
288 fn encode_tag<W>(&self, to: W, tag: Tag) -> Result<()>
290 where
291 W: Write;
292
293 fn encode_element_header<W>(&self, to: W, de: DataElementHeader) -> Result<usize>
296 where
297 W: Write;
298
299 fn encode_item_header<W>(&self, to: W, len: u32) -> Result<()>
303 where
304 W: Write;
305
306 fn encode_item_delimiter<W>(&self, mut to: W) -> Result<()>
308 where
309 W: Write,
310 {
311 self.encode_tag(&mut to, Tag(0xFFFE, 0xE00D))?;
312 to.write_all(&[0u8; 4]).context(WriteItemDelimiterSnafu)?;
313 Ok(())
314 }
315
316 fn encode_sequence_delimiter<W>(&self, mut to: W) -> Result<()>
318 where
319 W: Write,
320 {
321 self.encode_tag(&mut to, Tag(0xFFFE, 0xE0DD))?;
322 to.write_all(&[0u8; 4])
323 .context(WriteSequenceDelimiterSnafu)?;
324 Ok(())
325 }
326
327 fn encode_primitive<W>(&self, to: W, value: &PrimitiveValue) -> Result<usize>
329 where
330 W: Write;
331
332 fn encode_offset_table<W>(&self, to: W, offset_table: &[u32]) -> Result<usize>
340 where
341 W: Write;
342}
343
344impl<T: ?Sized> Encode for &T
345where
346 T: Encode,
347{
348 fn encode_tag<W>(&self, to: W, tag: Tag) -> Result<()>
349 where
350 W: Write,
351 {
352 (**self).encode_tag(to, tag)
353 }
354
355 fn encode_element_header<W>(&self, to: W, de: DataElementHeader) -> Result<usize>
356 where
357 W: Write,
358 {
359 (**self).encode_element_header(to, de)
360 }
361
362 fn encode_item_header<W>(&self, to: W, len: u32) -> Result<()>
363 where
364 W: Write,
365 {
366 (**self).encode_item_header(to, len)
367 }
368
369 fn encode_item_delimiter<W>(&self, to: W) -> Result<()>
370 where
371 W: Write,
372 {
373 (**self).encode_item_delimiter(to)
374 }
375
376 fn encode_sequence_delimiter<W>(&self, to: W) -> Result<()>
377 where
378 W: Write,
379 {
380 (**self).encode_sequence_delimiter(to)
381 }
382
383 fn encode_primitive<W>(&self, to: W, value: &PrimitiveValue) -> Result<usize>
384 where
385 W: Write,
386 {
387 (**self).encode_primitive(to, value)
388 }
389
390 fn encode_offset_table<W>(&self, to: W, offset_table: &[u32]) -> Result<usize>
391 where
392 W: Write,
393 {
394 (**self).encode_offset_table(to, offset_table)
395 }
396}
397
398impl<T: ?Sized> Encode for Box<T>
399where
400 T: Encode,
401{
402 fn encode_tag<W>(&self, to: W, tag: Tag) -> Result<()>
403 where
404 W: Write,
405 {
406 (**self).encode_tag(to, tag)
407 }
408
409 fn encode_element_header<W>(&self, to: W, de: DataElementHeader) -> Result<usize>
410 where
411 W: Write,
412 {
413 (**self).encode_element_header(to, de)
414 }
415
416 fn encode_item_header<W>(&self, to: W, len: u32) -> Result<()>
417 where
418 W: Write,
419 {
420 (**self).encode_item_header(to, len)
421 }
422
423 fn encode_item_delimiter<W>(&self, to: W) -> Result<()>
424 where
425 W: Write,
426 {
427 (**self).encode_item_delimiter(to)
428 }
429
430 fn encode_sequence_delimiter<W>(&self, to: W) -> Result<()>
431 where
432 W: Write,
433 {
434 (**self).encode_sequence_delimiter(to)
435 }
436
437 fn encode_primitive<W>(&self, to: W, value: &PrimitiveValue) -> Result<usize>
438 where
439 W: Write,
440 {
441 (**self).encode_primitive(to, value)
442 }
443
444 fn encode_offset_table<W>(&self, to: W, offset_table: &[u32]) -> Result<usize>
445 where
446 W: Write,
447 {
448 (**self).encode_offset_table(to, offset_table)
449 }
450}
451
452pub trait EncodeTo<W: ?Sized> {
454 fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()>
456 where
457 W: Write;
458
459 fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize>
466 where
467 W: Write;
468
469 fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()>
473 where
474 W: Write;
475
476 fn encode_item_delimiter(&self, to: &mut W) -> Result<()>
478 where
479 W: Write;
480
481 fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()>
483 where
484 W: Write;
485
486 fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize>
488 where
489 W: Write;
490
491 fn encode_offset_table(&self, to: &mut W, offset_table: &[u32]) -> Result<usize>
499 where
500 W: Write;
501}
502
503impl<T, W: ?Sized> EncodeTo<W> for &T
504where
505 T: EncodeTo<W>,
506{
507 fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()>
508 where
509 W: Write,
510 {
511 (**self).encode_tag(to, tag)
512 }
513
514 fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize>
515 where
516 W: Write,
517 {
518 (**self).encode_element_header(to, de)
519 }
520
521 fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()>
522 where
523 W: Write,
524 {
525 (**self).encode_item_header(to, len)
526 }
527
528 fn encode_item_delimiter(&self, to: &mut W) -> Result<()>
529 where
530 W: Write,
531 {
532 (**self).encode_item_delimiter(to)
533 }
534
535 fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()>
536 where
537 W: Write,
538 {
539 (**self).encode_sequence_delimiter(to)
540 }
541
542 fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize>
544 where
545 W: Write,
546 {
547 (**self).encode_primitive(to, value)
548 }
549
550 fn encode_offset_table(&self, to: &mut W, offset_table: &[u32]) -> Result<usize>
551 where
552 W: Write,
553 {
554 (**self).encode_offset_table(to, offset_table)
555 }
556}
557
558impl<T: ?Sized, W: ?Sized> EncodeTo<W> for Box<T>
559where
560 T: EncodeTo<W>,
561{
562 fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()>
563 where
564 W: Write,
565 {
566 (**self).encode_tag(to, tag)
567 }
568
569 fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize>
570 where
571 W: Write,
572 {
573 (**self).encode_element_header(to, de)
574 }
575
576 fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()>
577 where
578 W: Write,
579 {
580 (**self).encode_item_header(to, len)
581 }
582
583 fn encode_item_delimiter(&self, to: &mut W) -> Result<()>
584 where
585 W: Write,
586 {
587 (**self).encode_item_delimiter(to)
588 }
589
590 fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()>
591 where
592 W: Write,
593 {
594 (**self).encode_sequence_delimiter(to)
595 }
596
597 fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize>
599 where
600 W: Write,
601 {
602 (**self).encode_primitive(to, value)
603 }
604
605 fn encode_offset_table(&self, to: &mut W, offset_table: &[u32]) -> Result<usize>
606 where
607 W: Write,
608 {
609 (**self).encode_offset_table(to, offset_table)
610 }
611}
612
613pub struct EncoderFor<T, W: ?Sized> {
615 inner: T,
616 phantom: PhantomData<W>,
617}
618
619impl<T, W: ?Sized> EncoderFor<T, W> {
620 pub fn new(encoder: T) -> Self {
624 EncoderFor {
625 inner: encoder,
626 phantom: PhantomData,
627 }
628 }
629}
630
631impl<T: fmt::Debug, W: ?Sized> fmt::Debug for EncoderFor<T, W> {
632 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
633 f.debug_struct("ImplicitVRLittleEndianEncoder")
634 .field("inner", &self.inner)
635 .field("phantom", &self.phantom)
636 .finish()
637 }
638}
639
640impl<T, W: ?Sized> Default for EncoderFor<T, W>
641where
642 T: Default,
643{
644 fn default() -> Self {
645 EncoderFor {
646 inner: T::default(),
647 phantom: PhantomData,
648 }
649 }
650}
651
652impl<T, W: ?Sized> BasicEncode for EncoderFor<T, W>
653where
654 T: BasicEncode,
655 W: Write,
656{
657 fn endianness(&self) -> Endianness {
658 self.inner.endianness()
659 }
660
661 fn encode_us<S>(&self, to: S, value: u16) -> io::Result<()>
662 where
663 S: Write,
664 {
665 self.inner.encode_us(to, value)
666 }
667
668 fn encode_ul<S>(&self, to: S, value: u32) -> io::Result<()>
669 where
670 S: Write,
671 {
672 self.inner.encode_ul(to, value)
673 }
674
675 fn encode_uv<S>(&self, to: S, value: u64) -> io::Result<()>
676 where
677 S: Write,
678 {
679 self.inner.encode_uv(to, value)
680 }
681
682 fn encode_ss<S>(&self, to: S, value: i16) -> io::Result<()>
683 where
684 S: Write,
685 {
686 self.inner.encode_ss(to, value)
687 }
688
689 fn encode_sl<S>(&self, to: S, value: i32) -> io::Result<()>
690 where
691 S: Write,
692 {
693 self.inner.encode_sl(to, value)
694 }
695
696 fn encode_sv<S>(&self, to: S, value: i64) -> io::Result<()>
697 where
698 S: Write,
699 {
700 self.inner.encode_sv(to, value)
701 }
702
703 fn encode_fl<S>(&self, to: S, value: f32) -> io::Result<()>
704 where
705 S: Write,
706 {
707 self.inner.encode_fl(to, value)
708 }
709
710 fn encode_fd<S>(&self, to: S, value: f64) -> io::Result<()>
711 where
712 S: Write,
713 {
714 self.inner.encode_fd(to, value)
715 }
716}
717
718impl<T, W: ?Sized> EncodeTo<W> for EncoderFor<T, W>
719where
720 T: Encode,
721 W: Write,
722{
723 fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()> {
724 self.inner.encode_tag(to, tag)
725 }
726
727 fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize> {
728 self.inner.encode_element_header(to, de)
729 }
730
731 fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()> {
732 self.inner.encode_item_header(to, len)
733 }
734
735 fn encode_item_delimiter(&self, to: &mut W) -> Result<()> {
736 self.inner.encode_item_delimiter(to)
737 }
738
739 fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()> {
740 self.inner.encode_sequence_delimiter(to)
741 }
742
743 fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize> {
744 self.inner.encode_primitive(to, value)
745 }
746
747 fn encode_offset_table(&self, to: &mut W, offset_table: &[u32]) -> Result<usize> {
748 self.inner.encode_offset_table(to, offset_table)
749 }
750}
751
752#[cfg(test)]
753mod tests {
754 use super::*;
755
756 fn is_encode<T: Encode>(_encoder: &T) {}
757 fn is_encode_to<W: ?Sized, T: EncodeTo<W>>(_encoder: &T) {}
758
759 #[allow(unused)]
760 fn boxed_encode_is_encode<T>(encoder: T)
761 where
762 T: Encode,
763 T: Copy,
764 {
765 is_encode(&encoder);
766 is_encode_to::<dyn Write, _>(&EncoderFor::new(encoder));
767 let boxed = Box::new(encoder);
768 is_encode(&boxed);
769 is_encode_to::<dyn Write, _>(&EncoderFor::new(boxed));
770 }
771}