@@ -439,6 +439,68 @@ where
439
439
Ok ( PrimitiveValue :: Strs ( parts?) )
440
440
}
441
441
442
+ fn read_value_pn (
443
+ & mut self ,
444
+ header : & DataElementHeader ,
445
+ specific_char_set : & SpecificCharacterSet ,
446
+ ) -> Result < PrimitiveValue > {
447
+ match self . read_value_pns ( header, specific_char_set) {
448
+ Ok ( PrimitiveValue :: Strs ( parts) ) => Ok ( PrimitiveValue :: Str ( parts. join ( "=" ) ) ) ,
449
+ Ok ( _) => {
450
+ panic ! ( "wron impl: read_value_pns should always return Strs" )
451
+ }
452
+ Err ( e) => Err ( e) ,
453
+ }
454
+ }
455
+
456
+ fn read_value_pns (
457
+ & mut self ,
458
+ header : & DataElementHeader ,
459
+ specific_char_set : & SpecificCharacterSet ,
460
+ ) -> Result < PrimitiveValue > {
461
+ let len = self . require_known_length ( header) ?;
462
+ self . buffer . resize_with ( len, Default :: default) ;
463
+ self . from
464
+ . read_exact ( & mut self . buffer )
465
+ . context ( ReadValueDataSnafu {
466
+ position : self . position ,
467
+ } ) ?;
468
+
469
+ let equal_positions: Vec < _ > = self
470
+ . buffer
471
+ . iter ( )
472
+ . enumerate ( )
473
+ . filter ( |& ( _, & b) | b == b'=' )
474
+ . map ( |( i, _) | i)
475
+ . collect ( ) ;
476
+
477
+ if equal_positions. len ( ) == 0 {
478
+ return self . read_value_str ( header) ;
479
+ }
480
+
481
+ let mut binary_data = Vec :: new ( ) ;
482
+ let mut equal_position = 0 ;
483
+ for & index in & equal_positions {
484
+ binary_data. push ( & self . buffer [ equal_position..index] ) ;
485
+ equal_position = index + 1 ;
486
+ }
487
+ binary_data. push ( & self . buffer [ equal_position..] ) ;
488
+
489
+ let mut decoded_parts = Vec :: new ( ) ;
490
+ for ( i, part) in binary_data. iter ( ) . enumerate ( ) {
491
+ let charset = match i {
492
+ 0 => specific_char_set,
493
+ _ => & SpecificCharacterSet :: IsoIr87 ,
494
+ } ;
495
+ let decoded = charset. decode ( part) . context ( DecodeTextSnafu {
496
+ position : self . position ,
497
+ } ) ?;
498
+ decoded_parts. push ( decoded) ;
499
+ }
500
+
501
+ Ok ( PrimitiveValue :: Strs ( decoded_parts. into ( ) ) )
502
+ }
503
+
442
504
fn read_value_str ( & mut self , header : & DataElementHeader ) -> Result < PrimitiveValue > {
443
505
let len = self . require_known_length ( header) ?;
444
506
@@ -920,9 +982,8 @@ where
920
982
. fail ( )
921
983
}
922
984
VR :: AT => self . read_value_tag ( header) ,
923
- VR :: AE | VR :: AS | VR :: PN | VR :: SH | VR :: LO | VR :: UC | VR :: UI => {
924
- self . read_value_strs ( header)
925
- }
985
+ VR :: AE | VR :: AS | VR :: SH | VR :: LO | VR :: UC | VR :: UI => self . read_value_strs ( header) ,
986
+ VR :: PN => self . read_value_pns ( header, & self . text . clone ( ) ) ,
926
987
VR :: CS => self . read_value_cs ( header) ,
927
988
VR :: UT | VR :: ST | VR :: UR | VR :: LT => self . read_value_str ( header) ,
928
989
VR :: UN | VR :: OB => self . read_value_ob ( header) ,
@@ -958,7 +1019,6 @@ where
958
1019
VR :: AT => self . read_value_tag ( header) ,
959
1020
VR :: AE
960
1021
| VR :: AS
961
- | VR :: PN
962
1022
| VR :: SH
963
1023
| VR :: LO
964
1024
| VR :: UC
@@ -968,6 +1028,7 @@ where
968
1028
| VR :: DA
969
1029
| VR :: TM
970
1030
| VR :: DT => self . read_value_strs ( header) ,
1031
+ VR :: PN => self . read_value_pn ( header, & self . text . clone ( ) ) ,
971
1032
VR :: CS => self . read_value_cs ( header) ,
972
1033
VR :: UT | VR :: ST | VR :: UR | VR :: LT => self . read_value_str ( header) ,
973
1034
VR :: UN | VR :: OB => self . read_value_ob ( header) ,
@@ -1065,13 +1126,16 @@ fn trim_trail_empty_bytes(mut x: &[u8]) -> &[u8] {
1065
1126
mod tests {
1066
1127
use super :: { StatefulDecode , StatefulDecoder } ;
1067
1128
use dicom_core:: header:: { DataElementHeader , HasLength , Header , Length , SequenceItemHeader } ;
1068
- use dicom_core:: { Tag , VR } ;
1129
+ use dicom_core:: { PrimitiveValue , Tag , VR } ;
1069
1130
use dicom_encoding:: decode:: basic:: LittleEndianBasicDecoder ;
1070
1131
use dicom_encoding:: decode:: {
1071
1132
explicit_le:: ExplicitVRLittleEndianDecoder , implicit_le:: ImplicitVRLittleEndianDecoder ,
1072
1133
} ;
1073
1134
use dicom_encoding:: text:: { SpecificCharacterSet , TextCodec } ;
1135
+ use encoding_rs:: { ISO_2022_JP , SHIFT_JIS } ;
1136
+ use smallvec:: SmallVec ;
1074
1137
use std:: io:: { Cursor , Seek , SeekFrom } ;
1138
+ use std:: str;
1075
1139
1076
1140
// manually crafting some DICOM data elements
1077
1141
// Tag: (0002,0002) Media Storage SOP Class UID
@@ -1479,4 +1543,85 @@ mod tests {
1479
1543
1480
1544
assert_eq ! ( decoder. position( ) , 138 ) ;
1481
1545
}
1546
+
1547
+ #[ test]
1548
+ fn test_read_value_pn ( ) {
1549
+ let yamada_taro_sjis = SHIFT_JIS . encode ( "ヤマダ^タロウ" ) . 0 ;
1550
+ let equal_ascii = b"=" ;
1551
+ let yamada_taro_iso2022jp = ISO_2022_JP . encode ( "山田^太郎" ) . 0 ;
1552
+ let equal_ascii_2 = b"=" ;
1553
+ let yamada_taro_kana_iso2022jp = ISO_2022_JP . encode ( "ヤマダ^タロウ" ) . 0 ;
1554
+
1555
+ let mut combined = Vec :: new ( ) ;
1556
+ combined. extend_from_slice ( & yamada_taro_sjis) ;
1557
+ combined. extend_from_slice ( equal_ascii) ;
1558
+ combined. extend_from_slice ( & yamada_taro_iso2022jp) ;
1559
+ combined. extend_from_slice ( equal_ascii_2) ;
1560
+ combined. extend_from_slice ( & yamada_taro_kana_iso2022jp) ;
1561
+
1562
+ let mut cursor = Cursor :: new ( & combined) ;
1563
+
1564
+ let mut decoder = StatefulDecoder :: new (
1565
+ & mut cursor,
1566
+ ImplicitVRLittleEndianDecoder :: default ( ) ,
1567
+ LittleEndianBasicDecoder ,
1568
+ SpecificCharacterSet :: IsoIr13 ,
1569
+ ) ;
1570
+
1571
+ let header =
1572
+ DataElementHeader :: new ( Tag ( 0x0010 , 0x0010 ) , VR :: PN , Length ( combined. len ( ) as u32 ) ) ;
1573
+
1574
+ let result = decoder. read_value ( & header) ;
1575
+ assert ! ( result. is_ok( ) ) ;
1576
+
1577
+ let value = result. unwrap ( ) ;
1578
+ let expected: SmallVec < [ & str ; 3 ] > =
1579
+ vec ! [ "ヤマタ\u{ff9e} ^タロウ" , "山田^太郎" , "ヤマダ^タロウ" ] . into ( ) ;
1580
+ match value {
1581
+ PrimitiveValue :: Strs ( s) => {
1582
+ assert_eq ! ( s, expected) ;
1583
+ }
1584
+ _ => panic ! ( "Unexpected value type" ) ,
1585
+ }
1586
+ }
1587
+
1588
+ #[ test]
1589
+ fn test_read_value_pns ( ) {
1590
+ let yamada_taro_sjis = SHIFT_JIS . encode ( "ヤマダ^タロウ" ) . 0 ;
1591
+ let equal_ascii = b"=" ;
1592
+ let yamada_taro_iso2022jp = ISO_2022_JP . encode ( "山田^太郎" ) . 0 ;
1593
+ let equal_ascii_2 = b"=" ;
1594
+ let yamada_taro_kana_iso2022jp = ISO_2022_JP . encode ( "ヤマダ^タロウ" ) . 0 ;
1595
+
1596
+ let mut combined = Vec :: new ( ) ;
1597
+ combined. extend_from_slice ( & yamada_taro_sjis) ;
1598
+ combined. extend_from_slice ( equal_ascii) ;
1599
+ combined. extend_from_slice ( & yamada_taro_iso2022jp) ;
1600
+ combined. extend_from_slice ( equal_ascii_2) ;
1601
+ combined. extend_from_slice ( & yamada_taro_kana_iso2022jp) ;
1602
+
1603
+ let mut cursor = Cursor :: new ( & combined) ;
1604
+
1605
+ let mut decoder = StatefulDecoder :: new (
1606
+ & mut cursor,
1607
+ ImplicitVRLittleEndianDecoder :: default ( ) ,
1608
+ LittleEndianBasicDecoder ,
1609
+ SpecificCharacterSet :: IsoIr13 ,
1610
+ ) ;
1611
+
1612
+ let header =
1613
+ DataElementHeader :: new ( Tag ( 0x0010 , 0x0010 ) , VR :: PN , Length ( combined. len ( ) as u32 ) ) ;
1614
+
1615
+ let result = decoder. read_value_preserved ( & header) ;
1616
+ assert ! ( result. is_ok( ) ) ;
1617
+
1618
+ let value = result. unwrap ( ) ;
1619
+ let expected = "ヤマタ\u{ff9e} ^タロウ=山田^太郎=ヤマダ^タロウ" ;
1620
+ match value {
1621
+ PrimitiveValue :: Str ( s) => {
1622
+ assert_eq ! ( s, expected) ;
1623
+ }
1624
+ _ => panic ! ( "Unexpected value type" ) ,
1625
+ }
1626
+ }
1482
1627
}
0 commit comments