Skip to content

Commit 930c25b

Browse files
authored
Merge pull request Enet4#32 from Enet4/imp/token_write
Data set writing
2 parents 1173a6f + 0174589 commit 930c25b

File tree

24 files changed

+2285
-925
lines changed

24 files changed

+2285
-925
lines changed

core/src/header.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ impl std::ops::SubAssign<i32> for Length {
753753
}
754754

755755
impl Length {
756-
/// Check whether this length is undefined.
756+
/// Check whether this length is undefined (unknown).
757757
#[inline]
758758
pub fn is_undefined(self) -> bool {
759759
self.0 == UNDEFINED_LEN
@@ -774,6 +774,13 @@ impl Length {
774774
v => Some(v),
775775
}
776776
}
777+
778+
/// Check whether the length is equally specified as another length.
779+
/// Unlike the implemented `PartialEq`, two undefined lengths are
780+
/// considered equivalent by this method.
781+
pub fn inner_eq(self, other: Length) -> bool {
782+
self.0 == other.0
783+
}
777784
}
778785

779786
impl fmt::Debug for Length {

core/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@ pub use error::{Error, Result};
2222
pub use header::{DataElement, DataElementHeader, Length, Tag, VR};
2323
pub use value::{PrimitiveValue, Value as DicomValue};
2424

25+
// re-export the chrono crate, as used in the public API
26+
pub use chrono;
27+
2528
mod util;

core/src/value.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
33
use crate::error::CastValueError;
44
use crate::header::{Length, Tag};
5-
use chrono::{DateTime, Datelike, FixedOffset, NaiveDate, NaiveTime, Timelike};
5+
use chrono::{Datelike, FixedOffset, Timelike};
66
use itertools::Itertools;
77
use smallvec::SmallVec;
88
use std::borrow::Cow;
99

10+
/// re-exported from chrono
11+
pub use chrono::{DateTime, NaiveDate, NaiveTime};
12+
1013
/// An aggregation of one or more elements in a value.
1114
pub type C<T> = SmallVec<[T; 2]>;
1215

encoding/src/decode/erased.rs

Lines changed: 0 additions & 141 deletions
This file was deleted.

encoding/src/decode/mod.rs

Lines changed: 119 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,21 @@ use dicom_core::Tag;
1111
use std::io::Read;
1212

1313
pub mod basic;
14-
pub mod erased;
14+
pub mod primitive_value;
1515

1616
/** Obtain the default data element decoder.
1717
* According to the standard, data elements are encoded in Implicit
1818
* VR Little Endian by default.
1919
*/
20-
pub fn get_default_reader<S>() -> StandardImplicitVRLittleEndianDecoder<S>
21-
where
22-
S: Read,
23-
{
20+
pub fn default_reader() -> StandardImplicitVRLittleEndianDecoder {
2421
ImplicitVRLittleEndianDecoder::default()
2522
}
2623

2724
/** Obtain a data element decoder for reading the data elements in a DICOM
2825
* file's Meta information. According to the standard, these are always
2926
* encoded in Explicit VR Little Endian.
3027
*/
31-
pub fn get_file_header_decoder<S>() -> ExplicitVRLittleEndianDecoder<S>
32-
where
33-
S: Read,
34-
{
28+
pub fn file_header_decoder() -> ExplicitVRLittleEndianDecoder {
3529
ExplicitVRLittleEndianDecoder::default()
3630
}
3731

@@ -248,9 +242,6 @@ where
248242
* may depend on the transfer syntax.
249243
*/
250244
pub trait Decode {
251-
/// The data source's type.
252-
type Source: ?Sized + Read;
253-
254245
/** Fetch and decode the next data element header from the given source.
255246
* This method returns only the header of the element. At the end of this operation, the source
256247
* will be pointing at the element's value data, which should be read or skipped as necessary.
@@ -260,34 +251,47 @@ pub trait Decode {
260251
*
261252
* Returns the expected header and the exact number of bytes read from the source.
262253
*/
263-
fn decode_header(&self, source: &mut Self::Source) -> Result<(DataElementHeader, usize)>;
254+
fn decode_header<S>(&self, source: &mut S) -> Result<(DataElementHeader, usize)>
255+
where
256+
S: ?Sized + Read;
264257

265258
/** Fetch and decode the next sequence item head from the given source. It is a separate method
266259
* because value representation is always implicit when reading item headers and delimiters.
267260
* This method returns only the header of the item. At the end of this operation, the source
268261
* will be pointing at the beginning of the item's data, which should be traversed if necessary.
269262
*/
270-
fn decode_item_header(&self, source: &mut Self::Source) -> Result<SequenceItemHeader>;
263+
fn decode_item_header<S>(&self, source: &mut S) -> Result<SequenceItemHeader>
264+
where
265+
S: ?Sized + Read;
271266

272267
/// Decode a DICOM attribute tag from the given source.
273-
fn decode_tag(&self, source: &mut Self::Source) -> Result<Tag>;
268+
fn decode_tag<S>(&self, source: &mut S) -> Result<Tag>
269+
where
270+
S: ?Sized + Read;
274271
}
275272

276273
impl<T: ?Sized> Decode for Box<T>
277274
where
278275
T: Decode,
279276
{
280-
type Source = <T as Decode>::Source;
281-
282-
fn decode_header(&self, source: &mut Self::Source) -> Result<(DataElementHeader, usize)> {
277+
fn decode_header<S>(&self, source: &mut S) -> Result<(DataElementHeader, usize)>
278+
where
279+
S: ?Sized + Read,
280+
{
283281
(**self).decode_header(source)
284282
}
285283

286-
fn decode_item_header(&self, source: &mut Self::Source) -> Result<SequenceItemHeader> {
284+
fn decode_item_header<S>(&self, source: &mut S) -> Result<SequenceItemHeader>
285+
where
286+
S: ?Sized + Read,
287+
{
287288
(**self).decode_item_header(source)
288289
}
289290

290-
fn decode_tag(&self, source: &mut Self::Source) -> Result<Tag> {
291+
fn decode_tag<S>(&self, source: &mut S) -> Result<Tag>
292+
where
293+
S: ?Sized + Read,
294+
{
291295
(**self).decode_tag(source)
292296
}
293297
}
@@ -296,17 +300,108 @@ impl<'a, T: ?Sized> Decode for &'a T
296300
where
297301
T: Decode,
298302
{
299-
type Source = <T as Decode>::Source;
303+
fn decode_header<S>(&self, source: &mut S) -> Result<(DataElementHeader, usize)>
304+
where
305+
S: ?Sized + Read,
306+
{
307+
(**self).decode_header(source)
308+
}
309+
310+
fn decode_item_header<S>(&self, source: &mut S) -> Result<SequenceItemHeader>
311+
where
312+
S: ?Sized + Read,
313+
{
314+
(**self).decode_item_header(source)
315+
}
316+
317+
fn decode_tag<S>(&self, source: &mut S) -> Result<Tag>
318+
where
319+
S: ?Sized + Read,
320+
{
321+
(**self).decode_tag(source)
322+
}
323+
}
324+
325+
/** Type trait for reading and decoding DICOM data elements from a specific source
326+
* reader type.
327+
*
328+
* The specific behaviour of decoding, even when abstracted from the original source,
329+
* may depend on the transfer syntax.
330+
*/
331+
pub trait DecodeFrom<S: ?Sized + Read> {
332+
/** Fetch and decode the next data element header from the given source.
333+
* This method returns only the header of the element. At the end of this operation, the source
334+
* will be pointing at the element's value data, which should be read or skipped as necessary.
335+
*
336+
* Decoding an item or sequence delimiter is considered valid, and so should be properly handled
337+
* by the decoder. The value representation in this case should be `UN`.
338+
*
339+
* Returns the expected header and the exact number of bytes read from the source.
340+
*/
341+
fn decode_header(&self, source: &mut S) -> Result<(DataElementHeader, usize)>;
342+
343+
/** Fetch and decode the next sequence item head from the given source. It is a separate method
344+
* because value representation is always implicit when reading item headers and delimiters.
345+
* This method returns only the header of the item. At the end of this operation, the source
346+
* will be pointing at the beginning of the item's data, which should be traversed if necessary.
347+
*/
348+
fn decode_item_header(&self, source: &mut S) -> Result<SequenceItemHeader>;
349+
350+
/// Decode a DICOM attribute tag from the given source.
351+
fn decode_tag(&self, source: &mut S) -> Result<Tag>;
352+
}
353+
354+
impl<S: ?Sized, T: ?Sized> DecodeFrom<S> for &T
355+
where
356+
S: Read,
357+
T: DecodeFrom<S>,
358+
{
359+
fn decode_header(&self, source: &mut S) -> Result<(DataElementHeader, usize)> {
360+
(**self).decode_header(source)
361+
}
362+
363+
fn decode_item_header(&self, source: &mut S) -> Result<SequenceItemHeader> {
364+
(**self).decode_item_header(source)
365+
}
300366

301-
fn decode_header(&self, source: &mut Self::Source) -> Result<(DataElementHeader, usize)> {
367+
fn decode_tag(&self, source: &mut S) -> Result<Tag> {
368+
(**self).decode_tag(source)
369+
}
370+
}
371+
372+
impl<S: ?Sized, T: ?Sized> DecodeFrom<S> for Box<T>
373+
where
374+
S: Read,
375+
T: DecodeFrom<S>,
376+
{
377+
fn decode_header(&self, source: &mut S) -> Result<(DataElementHeader, usize)> {
302378
(**self).decode_header(source)
303379
}
304380

305-
fn decode_item_header(&self, source: &mut Self::Source) -> Result<SequenceItemHeader> {
381+
fn decode_item_header(&self, source: &mut S) -> Result<SequenceItemHeader> {
306382
(**self).decode_item_header(source)
307383
}
308384

309-
fn decode_tag(&self, source: &mut Self::Source) -> Result<Tag> {
385+
fn decode_tag(&self, source: &mut S) -> Result<Tag> {
310386
(**self).decode_tag(source)
311387
}
312388
}
389+
390+
#[cfg(test)]
391+
mod tests {
392+
use super::*;
393+
394+
fn is_decode_from<T: DecodeFrom<dyn Read>>(_decoder: &T) {}
395+
396+
#[allow(unused)]
397+
fn boxed_decoder_from_is_decoder_from<T>(decoder: T)
398+
where
399+
T: DecodeFrom<dyn Read>,
400+
{
401+
is_decode_from(&decoder);
402+
let boxed = Box::new(decoder);
403+
is_decode_from(&boxed);
404+
let erased = boxed as Box<dyn DecodeFrom<dyn Read>>;
405+
is_decode_from(&erased);
406+
}
407+
}

0 commit comments

Comments
 (0)