This file is indexed.

/usr/include/dcmtk/dcmdata/dcitem.h is in libdcmtk-dev 3.6.2-3build3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
/*
 *
 *  Copyright (C) 1994-2017, OFFIS e.V.
 *  All rights reserved.  See COPYRIGHT file for details.
 *
 *  This software and supporting documentation were developed by
 *
 *    OFFIS e.V.
 *    R&D Division Health
 *    Escherweg 2
 *    D-26121 Oldenburg, Germany
 *
 *
 *  Module:  dcmdata
 *
 *  Author:  Gerd Ehlers
 *
 *  Purpose: Interface of class DcmItem
 *
 */


#ifndef DCITEM_H
#define DCITEM_H

#include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */

#include "dcmtk/ofstd/offile.h"       /* for offile_off_t */
#include "dcmtk/dcmdata/dctypes.h"
#include "dcmtk/dcmdata/dcobject.h"
#include "dcmtk/dcmdata/dclist.h"
#include "dcmtk/dcmdata/dcpcache.h"


// forward declarations
class DcmElement;
class DcmJsonFormat;
class DcmSequenceOfItems;
class DcmSpecificCharacterSet;


/** a class representing a list of DICOM elements in which each
 *  element has a different tag and elements are maintained in
 *  increasing order of tags. In particular, a sequence item.
 */
class DCMTK_DCMDATA_EXPORT DcmItem
  : public DcmObject
{
  public:

    // be friend with "greater than" and "less than" operators that are defined
    // outside of this class
    friend OFBool operator< (const DcmItem& lhs, const DcmItem& rhs);
    friend OFBool operator> (const DcmItem& lhs, const DcmItem& rhs);
    friend OFBool operator<=(const DcmItem& lhs, const DcmItem& rhs);
    friend OFBool operator>=(const DcmItem& lhs, const DcmItem& rhs);

    /** default constructor
     */
    DcmItem();

    /** constructor.
     *  Create new item from given tag and length.
     *  @param tag DICOM tag for the new element
     *  @param len value length for the new element
     */
    DcmItem(const DcmTag &tag,
            const Uint32 len = 0);

    /** copy constructor
     *  @param old item to be copied
     */
    DcmItem(const DcmItem &old);

    /** assignment operator. Private creator cache is not copied
     *  as it is also the case for clone().
     *  @param obj the item to be copied
     *  @return Reference to this object after assignment
     */
    DcmItem &operator=(const DcmItem &obj);

    /** comparison operator that compares the value of this object
     *  with a given object of the same type. The tag of the element is also
     *  considered as the first component that is compared, followed by the
     *  object types (VR, i.e. DCMTK'S EVR) and the comparison of all value
     *  components of the object, preferably in the order declared in the
     *  object (if applicable). For item values that means that all elements
     *  within the items are compared to each other in ascending tag order.
     *  This may be an expensive operation.
     *  @param  rhs the right hand side of the comparison
     *  @return 0 if the object values are equal.
     *          -1 if this element has fewer components than the rhs element.
     *          Also -1 if the value of the first component that does not match
     *          is lower in this object than in rhs. Also returned if rhs
     *          cannot be casted to this object type or both objects are of
     *          different VR (i.e. the DcmEVR returned by the element's ident()
     *          call are different).
     *          1 if either this element has more components than the rhs element, or
     *          if the first component that does not match is greater in this object than
     *          in rhs object.
     */
    virtual int compare(const DcmItem& rhs) const;

    /** destructor
     */
    virtual ~DcmItem();

    /** clone method
     *  @return deep copy of this object
     */
    virtual DcmObject *clone() const
    {
      return new DcmItem(*this);
    }

    /** Virtual object copying. This method can be used for DcmObject
     *  and derived classes to get a deep copy of an object. Internally
     *  the assignment operator is called if the given DcmObject parameter
     *  is of the same type as "this" object instance. If not, an error
     *  is returned. This function permits copying an object by value
     *  in a virtual way which therefore is different to just calling the
     *  assignment operator of DcmElement which could result in slicing
     *  the object.
     *  @param rhs - [in] The instance to copy from. Has to be of the same
     *                class type as "this" object
     *  @return EC_Normal if copying was successful, error otherwise
     */
    virtual OFCondition copyFrom(const DcmObject& rhs);

    /** get type identifier
     *  @return type identifier of this class (EVR_item)
     */
    virtual DcmEVR ident() const;

    /** get value multiplicity
     *  @return always returns 1 (according to the DICOM standard)
     */
    virtual unsigned long getVM();

    /** get cardinality of this item
     *  @return number of elements in this item
     */
    virtual unsigned long card() const;

    /** check if this element is a leaf node in a dataset tree.
     *  All subclasses of DcmElement except for DcmSequenceOfItems
     *  are leaf nodes, while DcmSequenceOfItems, DcmItem, DcmDataset etc.
     *  are not.
     *  @return true if leaf node, false otherwise.
     */
    virtual OFBool isLeaf() const { return OFFalse; }

    /** check if this item is nested in a sequence of items, i.e.\ not a
     *  top-level or stand-alone item/dataset
     *  @return true if this item is nested, false otherwise
     */
    virtual OFBool isNested() const;

    /** print all elements of the item to a stream
     *  @param out output stream
     *  @param flags optional flag used to customize the output (see DCMTypes::PF_xxx)
     *  @param level current level of nested items. Used for indentation.
     *  @param pixelFileName not used
     *  @param pixelCounter not used
     */
    virtual void print(STD_NAMESPACE ostream&out,
                       const size_t flags = 0,
                       const int level = 0,
                       const char *pixelFileName = NULL,
                       size_t *pixelCounter = NULL);

    /** calculate the length of this DICOM element when encoded with the
     *  given transfer syntax and the given encoding type for sequences.
     *  For elements, the length includes the length of the tag, length field,
     *  VR field and the value itself, for items and sequences it returns
     *  the length of the complete item or sequence including delimitation tags
     *  if applicable.
     *  If length encoding is set to be explicit and the total item size is
     *  larger than the available 32-bit length field, then undefined length
     *  is returned. If "dcmWriteOversizedSeqsAndItemsImplicit" is disabled,
     *  also the internal DcmObject errorFlag is set to EC_SeqOrItemContentOverflow
     *  in case the item content (excluding tag header etc.) is already too
     *  large.
     *  @param xfer transfer syntax for length calculation
     *  @param enctype sequence encoding type for length calculation
     *  @return length of DICOM element
     */
    virtual Uint32 calcElementLength(const E_TransferSyntax xfer,
                                     const E_EncodingType enctype);

    /** calculate the value length (without attribute tag, VR and length field)
     *  of this DICOM element when encoded with the given transfer syntax and
     *  the given encoding type for sequences.
     *  If length encoding is set to be explicit and the item content is larger
     *  than the available 32-bit length field, then undefined length is
     *  returned. If "dcmWriteOversizedSeqsAndItemsUndefined" is disabled,
     *  also the internal DcmObject errorFlag is set to
     *  EC_SeqOrItemContentOverflow.
     *  @param xfer transfer syntax for length calculation
     *  @param enctype sequence encoding type for length calculation
     *  @return value length of DICOM element
     */
    virtual Uint32 getLength(const E_TransferSyntax xfer = EXS_LittleEndianImplicit,
                             const E_EncodingType enctype = EET_UndefinedLength);

    /** initialize the transfer state of this object. This method must be called
     *  before this object is written to a stream or read (parsed) from a stream.
     */
    virtual void transferInit();

    /** finalize the transfer state of this object. This method must be called
     *  when reading/writing this object from/to a stream has been completed.
     */
    virtual void transferEnd();

    /** get parent item of this object, i.e.\ the item/dataset in which the
     *  surrounding sequence element is stored.
     *  @return pointer to the parent item of this object (might be NULL)
     */
    virtual DcmItem *getParentItem();

    /** check if this DICOM object can be encoded in the given transfer syntax.
     *  @param newXfer transfer syntax in which the DICOM object is to be encoded
     *  @param oldXfer transfer syntax in which the DICOM object was read or created.
     *  @return true if object can be encoded in desired transfer syntax, false otherwise.
     */
    virtual OFBool canWriteXfer(const E_TransferSyntax newXfer,
                                const E_TransferSyntax oldXfer);

    /** This function reads the information of all attributes which
     *  are captured in the input stream and captures this information
     *  in elementList. Each attribute is represented as an element
     *  in this list. If not all information for an attribute could be
     *  read from the stream, the function returns EC_StreamNotifyClient.
     *  @param inStream      The stream which contains the information.
     *  @param ixfer         The transfer syntax which was used to encode
     *                       the information in inStream.
     *  @param glenc         Encoding type for group length; specifies
     *                       what will be done with group length tags.
     *  @param maxReadLength Maximum read length for reading an attribute value.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition read(DcmInputStream &inStream,
                             const E_TransferSyntax ixfer,
                             const E_GrpLenEncoding glenc = EGL_noChange,
                             const Uint32 maxReadLength = DCM_MaxReadLength);

    /** This function reads the information of all attributes which
     *  are captured in the input stream and captures this information
     *  in elementList, up to the attribute tag stopParsingAtElement.
     *  Each attribute is represented as an element
     *  in this list. If not all information for an attribute could be
     *  read from the stream, the function returns EC_StreamNotifyClient.
     *  @param inStream      The stream which contains the information.
     *  @param ixfer         The transfer syntax which was used to encode
     *                       the information in inStream.
     *  @param glenc         Encoding type for group length; specifies
     *                       what will be done with group length tags.
     *  @param maxReadLength Maximum read length for reading an attribute value.
     *  @param stopParsingAtElement parsing of the input stream is stopped when
     *                       this tag key or any higher tag is encountered.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition readUntilTag(DcmInputStream &inStream,
                                     const E_TransferSyntax ixfer,
                                     const E_GrpLenEncoding glenc = EGL_noChange,
                                     const Uint32 maxReadLength = DCM_MaxReadLength,
                                     const DcmTagKey &stopParsingAtElement = DCM_UndefinedTagKey);

    /** write object to a stream
     *  @param outStream DICOM output stream
     *  @param oxfer output transfer syntax
     *  @param enctype encoding types (undefined or explicit length)
     *  @param wcache pointer to write cache object, may be NULL
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition write(DcmOutputStream &outStream,
                              const E_TransferSyntax oxfer,
                              const E_EncodingType enctype,
                              DcmWriteCache *wcache);

    /** write object in XML format
     *  @param out output stream to which the XML document is written
     *  @param flags optional flag used to customize the output (see DCMTypes::XF_xxx)
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition writeXML(STD_NAMESPACE ostream&out,
                                 const size_t flags = 0);

    /** write object in JSON format
     *  @param out output stream to which the JSON document is written
     *  @param format used to format and customize the output
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition writeJson(STD_NAMESPACE ostream&out,
                                  DcmJsonFormat &format);

    /** special write method for creation of digital signatures
     *  @param outStream DICOM output stream
     *  @param oxfer output transfer syntax
     *  @param enctype encoding types (undefined or explicit length)
     *  @param wcache pointer to write cache object, may be NULL
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition writeSignatureFormat(DcmOutputStream &outStream,
                                             const E_TransferSyntax oxfer,
                                             const E_EncodingType enctype,
                                             DcmWriteCache *wcache);

    /** returns true if the object contains an element with Unknown VR at any nesting level
     *  @return true if the object contains an element with Unknown VR, false otherwise
     */
    virtual OFBool containsUnknownVR() const;

    /** check if this object contains non-ASCII characters at any nesting level. Please note
     *  that this check is pretty simple and only works for single-byte character sets that
     *  do include the 7-bit ASCII codes, e.g. for the ISO 8859 family. In other words: All
     *  character codes below 128 are considered to be ASCII codes and all others are
     *  considered to be non-ASCII.
     *  @param checkAllStrings if true, also check elements with string values not affected
     *    by SpecificCharacterSet (0008,0005). By default, only check PN, LO, LT, SH, ST,
     *    UC and UT.
     *  @return true if object contains non-ASCII characters, false otherwise
     */
    virtual OFBool containsExtendedCharacters(const OFBool checkAllStrings = OFFalse);

    /** check if this object is affected by SpecificCharacterSet at any nesting level.
     *  In detail, it is checked whether this object contains any data elements that
     *  according to their VR are affected by the SpecificCharacterSet (0008,0005)
     *  element. This is true for the following VRs: PN, LO, LT, SH, ST, UC and UT
     *  @return true if object is affected by SpecificCharacterSet, false otherwise
     */
    virtual OFBool isAffectedBySpecificCharacterSet() const;

    /** mode specifying whether the SpecificCharacterSet (0008,0005) element should be
     *  checked by convertCharacterSet() or not, i.e.\ whether this element might be
     *  present on this dataset-level. This method is reimplemented in derived classes.
     *  @return always returns OFFalse, i.e.\ SpecificCharacterSet should not be checked
     */
    virtual OFBool checkForSpecificCharacterSet() const { return OFFalse; }

    /** convert all element values that are contained in this item and that are affected
     *  by SpecificCharacterSet from the given source character set to the given
     *  destination character set. The defined terms for a particular character set can
     *  be found in the DICOM standard, e.g. "ISO_IR 100" for ISO 8859-1 (Latin 1) or
     *  "ISO_IR 192" for Unicode in UTF-8. An empty string denotes the default character
     *  repertoire, which is ASCII (7-bit). If multiple values are given for 'fromCharset'
     *  (separated by a backslash) code extension techniques are used and escape sequences
     *  may be encountered in the source string to switch between the specified character
     *  sets.
     *  @param fromCharset name of the source character set(s) used for the conversion
     *  @param toCharset name of the destination character set used for the conversion.
     *    Only a single value is permitted (i.e. no code extensions).
     *  @param flags optional flag used to customize the conversion (see DCMTypes::CF_xxx)
     *  @param updateCharset if OFTrue, the SpecificCharacterSet (0008,0005) element is
     *    updated, i.e.\ the current value is either replaced or a new element is inserted
     *    or the existing element is deleted. If OFFalse the SpecificCharacterSet element
     *    remains unchanged.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition convertCharacterSet(const OFString &fromCharset,
                                            const OFString &toCharset,
                                            const size_t flags = 0,
                                            const OFBool updateCharset = OFFalse);

    /** convert all element values that are contained in this item and that are affected
     *  by SpecificCharacterSet to the given destination character set. If not disabled,
     *  the source character set is determined automatically from the value of the
     *  SpecificCharacterSet (0008,0005) element. The defined terms for the destination
     *  character set can be found in the DICOM standard, e.g. "ISO_IR 100" for ISO 8859-1
     *  (Latin 1) or "ISO_IR 192" for Unicode in UTF-8. An empty string denotes the
     *  default character repertoire, which is ASCII (7-bit).
     *  @param toCharset name of the destination character set used for the conversion.
     *    Only a single value is permitted (i.e. no code extensions).
     *  @param flags optional flag used to customize the conversion (see DCMTypes::CF_xxx)
     *  @param ignoreCharset if OFTrue, the value of SpecificCharacterSet is ignored.
     *    Also see checkForSpecificCharacterSet().
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition convertCharacterSet(const OFString &toCharset,
                                            const size_t flags = 0,
                                            const OFBool ignoreCharset = OFFalse);

    /** convert all element values that are contained in this item and that are affected
     *  by SpecificCharacterSet from the currently selected source character set to the
     *  currently selected destination character set
     *  @param converter character set converter to be used to convert the element values
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition convertCharacterSet(DcmSpecificCharacterSet &converter);

    /** convert all element values that are contained in this item and that are affected
     *  by SpecificCharacterSet to UTF-8 (Unicode). The value of the SpecificCharacterSet
     *  (0008,0005) element is updated, set or deleted automatically if needed. The
     *  transliteration mode is disabled, i.e. the conversion flags are explicitly set to
     *  0 - see convertCharacterSet().
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition convertToUTF8();

    /** insert a new element into the list of elements maintained by this item.
     *  The list of elements is always kept in ascending tag order.
     *  @param elem element to be inserted, must not be contained in this or
     *    any other item.  Will be deleted upon destruction of this item object.
     *  @param replaceOld if true, this element replaces any other element with
     *    the same tag which may already be contained in the item.  If false,
     *    insert fails if another element with the same tag is already present.
     *  @param checkInsertOrder if true, a warning message is sent to the console
     *    if the element is not inserted at the end of the list.  This is used
     *    in the read() method to detect datasets with out-of-order elements.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition insert(DcmElement *elem,
                               OFBool replaceOld = OFFalse,
                               OFBool checkInsertOrder = OFFalse);

    /** access an element from the item. This method returns a pointer to one
     *  of the elements in the item, and not a copy.
     *  @param num index number of element, must be < card()
     *  @return pointer to element if found, NULL if num >= card()
     */
    virtual DcmElement *getElement(const unsigned long num);

    /** this method enables a stack based, depth-first traversal of a complete
     *  hierarchical DICOM dataset (that is, classes derived from DcmItem or
     *  DcmSequenceOfItems). With each call of this method, the next object
     *  in the tree is located and marked on the stack.
     *  @param stack "cursor" for current position in the dataset. The stack
     *    will contain a pointer to each dataset, sequence, item and element
     *    from the main dataset down to the current element, and is updated
     *    upon each call to this method. An empty stack is equivalent to a stack
     *    containing a pointer to this object only.
     *  @param intoSub if true, the nextObject method will perform a hierarchical
     *    search through the dataset (depth-first), if false, only the current
     *    container object will be traversed (e.g., all elements of an item
     *    or all items of a sequence).
     *  @return EC_Normal if value length is correct, an error code otherwise
     */
    virtual OFCondition nextObject(DcmStack &stack,
                                   const OFBool intoSub);

    /** this method is only used in container classes,
     *  that is, DcmItem and DcmSequenceOfItems. It returns a pointer to the
     *  next object in the list AFTER the given object. If the caller passes NULL,
     *  a pointer to the first object in the list is returned. If the given object
     *  is not found, the given object is the last one in the list or the list is empty,
     *  NULL is returned.
     *  @param obj pointer to one object in the container; we are looking for the
     *    next entry after this one. NULL if looking for the first entry.
     *  @return pointer to next object in container or NULL if not found
     */
    virtual DcmObject *nextInContainer(const DcmObject *obj);

    /** remove element from list. If found, the element is not deleted but
     *  returned to the caller who is responsible for further management of the
     *  DcmElement object.
     *  @param num index number of element, must be < card()
     *  @return pointer to DcmElement if found, NULL otherwise
     */
    virtual DcmElement *remove(const unsigned long num);

    /** remove element from list. If found, the element is not deleted but
     *  returned to the caller who is responsible for further management of the
     *  DcmElement object.
     *  @param elem pointer to element (as type DcmObject *) to be removed from list
     *  @return pointer to element (as type DcmElement *) if found, NULL otherwise
     */
    virtual DcmElement *remove(DcmObject *elem);

    /** remove element from list. If found, the element is not deleted but
     *  returned to the caller who is responsible for further management of the
     *  DcmElement object.
     *  @param tag attribute tag of element to be removed
     *  @return pointer to DcmElement if found, NULL otherwise
     */
    virtual DcmElement *remove(const DcmTagKey &tag);

    /** check if this item is empty
     *  @param normalize not used for this class
     *  @return true if item is empty, i.e.\ has no elements, false otherwise
     */
    virtual OFBool isEmpty(const OFBool normalize = OFTrue);

    /** clear (remove) all attributes from item and delete them from memory.
     *  @return EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition clear();

    /** check the currently stored element value
     *  @param autocorrect correct value length if OFTrue
     *  @return status, EC_Normal if value length is correct, an error code otherwise
     */
    virtual OFCondition verify(const OFBool autocorrect = OFFalse );

    /** a complex, stack-based, hierarchical search method. It allows for a search
     *  for a DICOM object with a given attribute within a given container,
     *  hierarchically, from a starting position identified through a cursor stack.
     *  @param xtag the DICOM attribute tag we are searching for
     *  @param resultStack Depending on the search mode (see below), this parameter
     *     either serves as an input and output parameter, or as an output parameter
     *     only (the latter being the default). When used as an input parameter,
     *     the cursor stack defines the start position for the search within a
     *     hierarchical DICOM dataset. Upon successful return, the stack contains
     *     the position of the element found, in the form of a pointer to each dataset,
     *     sequence, item and element from the main dataset down to the found element.
     *  @param mode search mode, controls how the search stack is handled.
     *     In the default mode, ESM_fromHere, the stack is ignored on input, and
     *     the search starts in the object for which this method is called.
     *     In the other modes, the stack is used both as an input and an output
     *     parameter and defines the starting point for the search.
     *  @param searchIntoSub if true, the search will be performed hierarchically descending
     *    into the sequences and items of the dataset. If false, only the current container
     *    (sequence or item) will be traversed.
     *  @return EC_Normal if found, EC_TagNotFound if not found, an error code is something
     *    went wrong.
     */
    virtual OFCondition search(const DcmTagKey &xtag,              // in
                               DcmStack &resultStack,              // inout
                               E_SearchMode mode = ESM_fromHere,   // in
                               OFBool searchIntoSub = OFTrue );    // in

    /** this method loads all attribute values maintained by this object and
     *  all sub-objects (in case of a container such as DcmDataset) into memory.
     *  After a call to this method, the file from which a dataset was read may safely
     *  be deleted or replaced. For large files, this method may obviously allocate large
     *  amounts of memory.
     *  @return EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition loadAllDataIntoMemory();

    /** iterate over all elements and remove those element values from memory which exceed
     *  a given length and which can be loaded from file when needed again. For all other
     *  elements, nothing is done.
     *  @param maxLength maximum length (number of bytes) allowed without removing the value
     */
    virtual void compactElements(const Uint32 maxLength);

    /** This function takes care of group length and padding elements
     *  in the current element list according to what is specified in
     *  glenc and padenc. If required, this function does the following
     *  two things:
     *    a) it calculates the group length of all groups which are
     *       contained in this item and sets the calculated values
     *       in the corresponding group length elements and
     *    b) it inserts a corresponding padding element (or, in case
     *       of sequences: padding elements) with a corresponding correct
     *       size into the element list.
     *  @param glenc          Encoding type for group length; specifies what shall
     *                        be done with group length tags.
     *  @param padenc         Encoding type for padding; specifies what shall be
     *                        done with padding tags.
     *  @param xfer           The transfer syntax that shall be used.
     *  @param enctype        Encoding type for sequences; specifies how sequences
     *                        will be handled.
     *  @param padlen         The length up to which the dataset shall be padded,
     *                        if padding is desired.
     *  @param subPadlen      For sequences (ie sub elements), the length up to
     *                        which item shall be padded, if padding is desired.
     *  @param instanceLength Number of extra bytes added to the item/dataset
     *                        length used when computing the padding; this
     *                        parameter is for instance used to pass the length
     *                        of the file meta header from the DcmFileFormat to
     *                        the DcmDataset object.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    virtual OFCondition computeGroupLengthAndPadding(const E_GrpLenEncoding glenc,
                                                     const E_PaddingEncoding padenc = EPD_noChange,
                                                     const E_TransferSyntax xfer = EXS_Unknown,
                                                     const E_EncodingType enctype = EET_ExplicitLength,
                                                     const Uint32 padlen = 0,
                                                     const Uint32 subPadlen = 0,
                                                     Uint32 instanceLength = 0);


    /** check if an element with the given attribute tag exists in the dataset
     *  @param key tag key to be searched
     *  @param searchIntoSub if true, do hierarchical search within sequences,
     *    if false only search through this dataset
     *  @return true if tag found, false otherwise
     */
    OFBool tagExists(const DcmTagKey &key,
                     OFBool searchIntoSub = OFFalse);

    /** check if an element with the given attribute tag exists in the dataset
     *  and has a non-empty value
     *  @param key tag key to be searched
     *  @param searchIntoSub if true, do hierarchical search within sequences,
     *    if false only search through this dataset
     *  @return true if tag found and element non-empty, false otherwise
     */
    OFBool tagExistsWithValue(const DcmTagKey &key,
                              OFBool searchIntoSub = OFFalse);

    /* --- findAndGet functions: find an element and get it or the value, respectively --- */

    /** find element and get a pointer to it (or copy it).
     *  Applicable to all DICOM value representations (VR).
     *  The result variable 'element' is automatically set to NULL if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param element variable in which the reference to (or copy of) the element is stored
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @param createCopy create a copy of the element if true, return a reference otherwise
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetElement(const DcmTagKey &tagKey,
                                  DcmElement *&element,
                                  const OFBool searchIntoSub = OFFalse,
                                  const OFBool createCopy = OFFalse);

    /** find all elements matching a particular tag and return references to them on a stack.
     *  This functions always performs a deep search (i.e. searches into sequence of items).
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param resultStack stack where references to the elements are stored (added to).
     *    If no element is found, the stack is not modified (e.g. cleared).
     *  @return EC_Normal if at least one matching tag is found, an error code otherwise.
     */
    OFCondition findAndGetElements(const DcmTagKey &tagKey,
                                   DcmStack &resultStack);

    /** find element and get value as a reference to a C string. NB: The string is not copied!
     *  Applicable to the following VRs: AE, AS, CS, DA, DS, DT, IS, LO, LT, PN, SH, ST, TM, UC, UI,
     *  UR, UT
     *  Since the getString() routine is called internally the resulting string reference represents
     *  the (possibly multi-valued) value as stored in the dataset, i.e. no normalization is performed.
     *  The result variable 'value' is automatically set to NULL if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the reference to the element value is stored (might be NULL)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetString(const DcmTagKey &tagKey,
                                 const char *&value,
                                 const OFBool searchIntoSub = OFFalse);

    /** find element and get value as a reference to a C string. NB: The string is not copied!
     *  Applicable to the following VRs: AE, AS, CS, DA, DS, DT, IS, LO, LT, PN, SH, ST, TM, UC, UI,
     *  UR, UT
     *  Since the getString() routine is called internally the resulting string reference represents
     *  the (possibly multi-valued) value as stored in the dataset, i.e. no normalization is performed.
     *  The result variable 'value' is automatically set to NULL and 'length' is set to 0 if an error
     *  occurs.
     *  Please note that since the length is returned separately, the string value can contain more
     *  than one NULL byte.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the reference to the element value is stored (might be NULL)
     *  @param length length of the string (number of characters without the trailing NULL byte)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetString(const DcmTagKey &tagKey,
                                 const char *&value,
                                 Uint32 &length,
                                 const OFBool searchIntoSub = OFFalse);

    /** find element and get value as a C++ string (only one component).
     *  Applicable to the following VRs: AE, AS, AT, CS, DA, DS, DT, FL, FD, IS, LO, LT, OB, OD, OF,
     *  OL, OW, PN, SH, SL, SS, ST, TM, UC, UI, UL, UR, US, UT
     *  Since the getOFString() routine is called internally the resulting string is normalized, i.e.
     *  leading and/or trailing spaces are removed according to the associated value representation,
     *  or the element value is converted to a character string (for non-string VRs) - see documentation
     *  in the corresponding header file.
     *  In contrast to the above and below function only the specified component (see parameter 'pos')
     *  is returned. The result variable 'value' is automatically set to an empty string if an error
     *  occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the element value is stored
     *  @param pos index of the value in case of multi-valued elements (0..vm-1)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetOFString(const DcmTagKey &tagKey,
                                   OFString &value,
                                   const unsigned long pos = 0,
                                   const OFBool searchIntoSub = OFFalse);

    /** find element and get value as a C++ string (all components).
     *  Applicable to the following VRs: AE, AS, AT, CS, DA, DS, DT, FL, FD, IS, LO, LT, OB, OD, OF,
     *  OL, OW, PN, SH, SL, SS, ST, TM, UC, UI, UL, UR, US, UT
     *  Since the getOFStringArray() routine is called internally the resulting string is normalized,
     *  i.e. leading and/or trailing spaces are removed according to the associated value representation
     *  or the element values are converted to character strings (for non-string VRs) - see documentation
     *  in the corresponding header file.
     *  The result variable 'value' is automatically set to an empty string if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the element value is stored
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetOFStringArray(const DcmTagKey &tagKey,
                                        OFString &value,
                                        const OFBool searchIntoSub = OFFalse);

    /** find element and get value as an unsigned 8-bit integer.
     *  Applicable to the following VRs: OB
     *  The result variable 'value' is automatically set to zero if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the element value is stored
     *  @param pos index of the value in case of multi-valued elements (0..vm-1)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetUint8(const DcmTagKey &tagKey,
                                Uint8 &value,
                                const unsigned long pos = 0,
                                const OFBool searchIntoSub = OFFalse);

    /** find element and get value as an array of unsigned 8-bit integers.
     *  Applicable to the following VRs: OB
     *  The result variable 'value' is automatically set to NULL if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the reference to the element value is stored
     *  @param count stores number of items in the result array (if not NULL)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetUint8Array(const DcmTagKey &tagKey,
                                     const Uint8 *&value,
                                     unsigned long *count = NULL,
                                     const OFBool searchIntoSub = OFFalse);

    /** find element and get value as an unsigned 16-bit integer.
     *  Applicable to the following VRs: OW, US
     *  The result variable 'value' is automatically set to zero if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the element value is stored
     *  @param pos index of the value in case of multi-valued elements (0..vm-1)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetUint16(const DcmTagKey &tagKey,
                                 Uint16 &value,
                                 const unsigned long pos = 0,
                                 const OFBool searchIntoSub = OFFalse);

    /** find element and get value as an array of unsigned 16-bit integers.
     *  Applicable to the following VRs: AT, OW, US
     *  The result variable 'value' is automatically set to NULL if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the reference to the element value is stored
     *  @param count stores number of items in the result array (if not NULL)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetUint16Array(const DcmTagKey &tagKey,
                                      const Uint16 *&value,
                                      unsigned long *count = NULL,
                                      const OFBool searchIntoSub = OFFalse);

    /** find element and get value as a signed 16-bit integer.
     *  Applicable to the following VRs: SS
     *  The result variable 'value' is automatically set to zero if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the element value is stored
     *  @param pos index of the value in case of multi-valued elements (0..vm-1)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetSint16(const DcmTagKey &tagKey,
                                 Sint16 &value,
                                 const unsigned long pos = 0,
                                 const OFBool searchIntoSub = OFFalse);

    /** find element and get value as an array of signed 16-bit integers.
     *  Applicable to the following VRs: SS
     *  The result variable 'value' is automatically set to NULL if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the reference to the element value is stored
     *  @param count stores number of items in the result array (if not NULL)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetSint16Array(const DcmTagKey &tagKey,
                                      const Sint16 *&value,
                                      unsigned long *count = NULL,
                                      const OFBool searchIntoSub = OFFalse);

    /** find element and get value as an unsigned 32-bit integer.
     *  Applicable to the following VRs: OL, UL
     *  The result variable 'value' is automatically set to zero if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the element value is stored
     *  @param pos index of the value in case of multi-valued elements (0..vm-1)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetUint32(const DcmTagKey &tagKey,
                                 Uint32 &value,
                                 const unsigned long pos = 0,
                                 const OFBool searchIntoSub = OFFalse);

    /** find element and get value as an array of unsigned 32-bit integers.
     *  Applicable to the following VRs: OL, UL
     *  The result variable 'value' is automatically set to NULL if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the reference to the element value is stored
     *  @param count stores number of items in the result array (if not NULL)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetUint32Array(const DcmTagKey &tagKey,
                                      const Uint32 *&value,
                                      unsigned long *count = NULL,
                                      const OFBool searchIntoSub = OFFalse);

    /** find element and get value as a signed 32-bit integer.
     *  Applicable to the following VRs: IS, SL
     *  The result variable 'value' is automatically set to zero if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the element value is stored
     *  @param pos index of the value in case of multi-valued elements (0..vm-1)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetSint32(const DcmTagKey &tagKey,
                                 Sint32 &value,
                                 const unsigned long pos = 0,
                                 const OFBool searchIntoSub = OFFalse);

    /** find element and get value as an array of signed 32-bit integers.
     *  Applicable to the following VRs: SL
     *  The result variable 'value' is automatically set to NULL if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the reference to the element value is stored
     *  @param count stores number of items in the result array (if not NULL)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetSint32Array(const DcmTagKey &tagKey,
                                      const Sint32 *&value,
                                      unsigned long *count = NULL,
                                      const OFBool searchIntoSub = OFFalse);

    /** find element and get value as a (signed) long integer.
     *  Applicable to the following VRs: IS, OL, SL, SS, UL, US
     *  The result variable 'value' is automatically set to zero if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the element value is stored
     *  @param pos index of the value in case of multi-valued elements (0..vm-1)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetLongInt(const DcmTagKey &tagKey,
                                  long int &value,
                                  const unsigned long pos = 0,
                                  const OFBool searchIntoSub = OFFalse);

    /** find element and get value as a 32-bit floating point.
     *  Applicable to the following VRs: FL, OF
     *  The result variable 'value' is automatically set to zero if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the element value is stored
     *  @param pos index of the value in case of multi-valued elements (0..vm-1)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetFloat32(const DcmTagKey &tagKey,
                                  Float32 &value,
                                  const unsigned long pos = 0,
                                  const OFBool searchIntoSub = OFFalse);

    /** find element and get value as an array of 32-bit floating point values.
     *  Applicable to the following VRs: FL, OF
     *  The result variable 'value' is automatically set to NULL if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the reference to the element value is stored
     *  @param count stores number of items in the result array (if not NULL)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetFloat32Array(const DcmTagKey &tagKey,
                                       const Float32 *&value,
                                       unsigned long *count = NULL,
                                       const OFBool searchIntoSub = OFFalse);

    /** find element and get value as a 64-bit floating point.
     *  Applicable to the following VRs: DS, FD, OD
     *  The result variable 'value' is automatically set to zero if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the element value is stored
     *  @param pos index of the value in case of multi-valued elements (0..vm-1)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetFloat64(const DcmTagKey &tagKey,
                                  Float64 &value,
                                  const unsigned long pos = 0,
                                  const OFBool searchIntoSub = OFFalse);

    /** find element and get value as an array of 64-bit floating point values.
     *  Applicable to the following VRs: FD, OD
     *  The result variable 'value' is automatically set to NULL if an error occurs.
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param value variable in which the reference to the element value is stored
     *  @param count stores number of items in the result array (if not NULL)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndGetFloat64Array(const DcmTagKey &tagKey,
                                       const Float64 *&value,
                                       unsigned long *count = NULL,
                                       const OFBool searchIntoSub = OFFalse);

    /** looks up and returns a given sequence.
     *  Applicable to the following VRs: SQ, (pixelSQ)
     *  The result variable 'sequence' is automatically set to NULL if an error occurs
     *  (e.g. if 'seqTagKey' does not refer to a sequence attribute).
     *  @param seqTagKey DICOM tag specifying the sequence attribute to be searched for
     *  @param sequence variable in which the reference to (or copy of) the sequence is stored
     *  @param searchIntoSub flag indicating whether to search into sub-sequences or not
     *  @param createCopy create a copy of the sequence if true, return a reference otherwise
     *  @return EC_Normal upon success, an error otherwise.
     */
    OFCondition findAndGetSequence(const DcmTagKey &seqTagKey,
                                   DcmSequenceOfItems *&sequence,
                                   const OFBool searchIntoSub = OFFalse,
                                   const OFBool createCopy = OFFalse);

    /** looks up and returns a given sequence item, if it exists. Otherwise sets 'item'
     *  to NULL and returns EC_TagNotFound (specified sequence does not exist) or
     *  EC_IllegalParameter (specified item does not exist). Only the top-most level of
     *  the dataset/item is examined (i.e. no deep-search is performed).
     *  Applicable to the following VRs: SQ, (pixelSQ)
     *  @param seqTagKey DICOM tag specifying the sequence attribute to be searched for
     *  @param item variable in which the reference to (or copy of) the item is stored
     *  @param itemNum number of the item to be searched for (0..n-1, -1 for last)
     *  @param createCopy create a copy of the item if true, return a reference otherwise
     *  @return EC_Normal upon success, an error otherwise.
     */
    OFCondition findAndGetSequenceItem(const DcmTagKey &seqTagKey,
                                       DcmItem *&item,
                                       const signed long itemNum = 0,
                                       const OFBool createCopy = OFFalse);


    /* --- findOrCreate functions: find an element or create a new one --- */

    /** looks up the given sequence in the current dataset and returns the given item.
     *  If either the sequence or the item do not exist, they are created. If necessary,
     *  multiple empty items are inserted. Only the top-most level of the dataset/item
     *  is examined (i.e. no deep-search is performed).
     *  Applicable to the following VRs: SQ, (pixelSQ)
     *  @param seqTag DICOM tag specifying the sequence attribute to be searched for
     *    (or to be created)
     *  @param item variable in which the reference to the sequence item is stored
     *  @param itemNum number of the item to be searched for (0..n-1, -1 for last,
     *    -2 for append new)
     *  @return EC_Normal upon success, an error otherwise.
     */
    OFCondition findOrCreateSequenceItem(const DcmTag &seqTag,
                                         DcmItem *&item,
                                         const signed long itemNum = 0);

    /* --- findAndXXX functions: find an element and do something with it --- */

    /** find element, create a copy and insert it into the given destination dataset.
     *  This functions never performs a deep search (i.e. does not search into sequence
     *  of items). Empty elements are also copied. However, if the given tag is not
     *  found in the current dataset, EC_TagNotFound is returned and the destination
     *  dataset remains unchanged.
     *  Applicable to all DICOM value representations (VR).
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param destItem destination dataset to which the copied element is inserted
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise
     */
    OFCondition findAndInsertCopyOfElement(const DcmTagKey &tagKey,
                                           DcmItem *destItem,
                                           const OFBool replaceOld = OFTrue);

    /** find element, remove it from the dataset and free the associated memory.
     *  Applicable to all DICOM value representations (VR).
     *  @param tagKey DICOM tag specifying the attribute to be searched for
     *  @param allOccurrences flag indicating whether to delete all occurrences of the
     *    attribute tag or the first one only (implies 'searchIntoSub' to be true)
     *  @param searchIntoSub flag indicating whether to search into sequences or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition findAndDeleteElement(const DcmTagKey &tagKey,
                                     const OFBool allOccurrences = OFFalse,
                                     const OFBool searchIntoSub = OFFalse);

    /** looks up the given sequence in the current dataset and deletes the given item.
     *  Applicable to the following VRs: SQ, (pixelSQ)
     *  @param seqTagKey DICOM tag specifying the sequence attribute to be searched for
     *  @param itemNum number of the item to be deleted (0..n-1, -1 for last)
     *  @return EC_Normal upon success, an error otherwise.
     */
    OFCondition findAndDeleteSequenceItem(const DcmTagKey &seqTagKey,
                                          const signed long itemNum);


    /* --- putAndInsert functions: put value and insert new element --- */

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: AE, AS, AT, CS, DA, DS, DT, FL, FD, IS, LO, LT, OB, OD, OF,
     *  OL, OW, PN, SH, SL, SS, ST, TM, UC, UI, UL, UR, US, UT
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value string value to be set for the new element (might be empty or NULL)
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertString(const DcmTag &tag,
                                   const char *value,
                                   const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: AE, AS, AT, CS, DA, DS, DT, FL, FD, IS, LO, LT, OB, OD, OF,
     *  OL, OW, PN, SH, SL, SS, ST, TM, UC, UI, UL, UR, US, UT
     *  Please note that since the length of the string has to be specified explicitly, the string
     *  can contain more than one NULL byte.
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value string value to be set for the new element (might be empty or NULL)
     *  @param length length of the string (number of characters without the trailing NULL byte)
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertString(const DcmTag &tag,
                                   const char *value,
                                   const Uint32 length,
                                   const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: AE, AS, CS, DA, DS, DT, IS, LO, LT, PN, SH, ST, TM, UC, UI,
     *  UR, UT
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element (might be empty)
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertOFStringArray(const DcmTag &tag,
                                          const OFString &value,
                                          const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: OB, ox (polymorph OB/OW or pixel data)
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element (might be NULL)
     *  @param count number of values (= bytes in this case) to be copied from 'value'
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertUint8Array(const DcmTag &tag,
                                       const Uint8 *value,
                                       const unsigned long count,
                                       const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: US, xs (US or SS)
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param pos index of the value to be set (0..vm). A value can be appended to
     *    the end of or inserted within the existing value field.
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertUint16(const DcmTag &tag,
                                   const Uint16 value,
                                   const unsigned long pos = 0,
                                   const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: AT, OW, US, ox (polymorph OB/OW or pixel data), xs (US or SS)
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element (might be NULL)
     *  @param count number of values (not bytes!) to be copied from 'value'
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertUint16Array(const DcmTag &tag,
                                        const Uint16 *value,
                                        const unsigned long count,
                                        const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: SS, xs (US or SS)
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param pos index of the value to be set (0..vm). A value can be appended to
     *    the end of or inserted within the existing value field.
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertSint16(const DcmTag &tag,
                                   const Sint16 value,
                                   const unsigned long pos = 0,
                                   const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: SS, xs (US or SS)
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param count number of values (not bytes!) to be copied from 'value'
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertSint16Array(const DcmTag &tag,
                                        const Sint16 *value,
                                        const unsigned long count,
                                        const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: OL, UL
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param pos index of the value to be set (0..vm). A value can be appended to
     *    the end of or inserted within the existing value field.
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertUint32(const DcmTag &tag,
                                   const Uint32 value,
                                   const unsigned long pos = 0,
                                   const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: OL, UL
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param count number of values (not bytes!) to be copied from 'value'
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertUint32Array(const DcmTag &tag,
                                       const Uint32 *value,
                                       const unsigned long count,
                                       const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: SL
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param pos index of the value to be set (0..vm). A value can be appended to
     *    the end of or inserted within the existing value field.
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertSint32(const DcmTag &tag,
                                   const Sint32 value,
                                   const unsigned long pos = 0,
                                   const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: FL, OF
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param pos index of the value to be set (0..vm). A value can be appended to
     *    the end of or inserted within the existing value field.
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertFloat32(const DcmTag &tag,
                                    const Float32 value,
                                    const unsigned long pos = 0,
                                    const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: FL, OF
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param count number of values (not bytes!) to be copied from 'value'
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertFloat32Array(const DcmTag &tag,
                                         const Float32 *value,
                                         const unsigned long count,
                                         const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: FD, OD
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param pos index of the value to be set (0..vm). A value can be appended to
     *    the end of or inserted within the existing value field.
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertFloat64(const DcmTag &tag,
                                    const Float64 value,
                                    const unsigned long pos = 0,
                                    const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: FD, OD
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param count number of values (not bytes!) to be copied from 'value'
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertFloat64Array(const DcmTag &tag,
                                         const Float64 *value,
                                         const unsigned long count,
                                         const OFBool replaceOld = OFTrue);

    /** create a new element, put specified value to it and insert the element into the dataset/item.
     *  Applicable to the following VRs: AT
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param value value to be set for the new element
     *  @param pos index of the value to be set (0..vm). A value can be appended to
     *    the end of or inserted within the existing value field.
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition putAndInsertTagKey(const DcmTag &tag,
                                   const DcmTagKey &value,
                                   const unsigned long pos = 0,
                                   const OFBool replaceOld = OFTrue);

    /* --- insertXXX functions: insert new element --- */

    /** create a new element (with no value) and insert it into the dataset/item.
     *  Applicable to the following VRs: AE, AS, AT, CS, DA, DS, DT, FL, FD, IS, LO, LT, OB, OD, OF,
     *  OL, OW, PN, SH, SL, SQ, SS, ST, TM, UC, UI, UL, UR, US, UT
     *  @param tag DICOM tag specifying the attribute to be created
     *  @param replaceOld flag indicating whether to replace an existing element or not
     *  @return EC_Normal upon success, an error code otherwise.
     */
    OFCondition insertEmptyElement(const DcmTag &tag,
                                   const OFBool replaceOld = OFTrue);

    /** looks up the given sequence in the current dataset and inserts the given item.
     *  If the sequence does not exist, it is created. If necessary, multiple empty items
     *  are inserted before the specified item position. Only the top-most level of the
     *  dataset/item is examined (i.e. no deep-search is performed).
     *  Applicable to the following VRs: SQ, (pixelSQ)
     *  @param seqTag DICOM tag specifying the sequence attribute to be searched for
     *    (or to be created)
     *  @param item item to be inserted into the sequence, must not be contained in this
     *    or any other sequence. Will be deleted upon destruction of the sequence object.
     *  @param itemNum position of the item (0..n-1, -1 = before last, -2 = after last)
     *  @return EC_Normal upon success, an error otherwise (delete 'item' manually!).
     */
    OFCondition insertSequenceItem(const DcmTag &seqTag,
                                   DcmItem *item,
                                   const signed long itemNum = -2);

    /** creates new DICOM element from given attribute tag.
     *  Creation of unknown attributes (e.g. private tag not being registered
     *  in the dictionary) will result in a DcmElement instance of derived type
     *  DcmOtherByteOtherWord.
     *  @param tag attribute tag of the element to be created
     *  @param privateCreator private creator of the element, if element tag
     *    is private (default: NULL, i.e. non-private DICOM standard tag)
     *  @return pointer to newly created element upon success, NULL pointer otherwise
     *
     */
     static DcmElement *newDicomElement(const DcmTagKey &tag,
                                        const char *privateCreator = NULL);

    /** creates new DICOM element from given attribute tag.
     *  Creation of unknown attributes (e.g. private tag not being registered
     *  in the dictionary) will result in a DcmElement instance of derived type
     *  DcmOtherByteOtherWord.
     *  @param newElement pointer to newly created element returned in this parameter
     *    upon success, NULL pointer otherwise
     *  @param tag attribute tag of the element to be created
     *  @param privateCreator private creator of the element, if element tag
     *    is private (default: NULL, i.e. non-private DICOM standard tag)
     *  @return EC_Normal upon success, an error code otherwise
     */
    static OFCondition newDicomElement(DcmElement *&newElement,
                                       const DcmTagKey &tag,
                                       const char *privateCreator = NULL);

    /** creates new DICOM element from given attribute tag and VR.
     *  Creation of unknown attributes (e.g. private tag not being registered
     *  in the dictionary) will result in a DcmElement instance of derived type
     *  DcmOtherByteOtherWord.
     *  @param newElement pointer to newly created element returned in this parameter
     *    upon success, NULL pointer otherwise
     *  @param tag attribute tag and VR of the element to be created
     *  @return EC_Normal upon success, an error code otherwise
     */
     static OFCondition newDicomElementWithVR(DcmElement *&newElement,
                                              const DcmTag &tag);

  protected:

    /// the list of elements maintained by this object
    DcmList *elementList;

    /** flag used during suspended I/O. Indicates whether the last element
     *  was completely or only partially read/written during the last call
     *  to read/write.
     */
    OFBool lastElementComplete;

    /** used during reading. Contains the position in the stream where
     *  the item started (needed for calculating the remaining number of
     *  bytes available for a fixed-length item).
     */
    offile_off_t fStartPosition;

    /** This function reads tag and length information from inStream and
     *  returns this information to the caller. When reading information,
     *  the transfer syntax which was passed is accounted for. If the
     *  transfer syntax shows an explicit value representation, the data
     *  type of this object is also read from the stream. In general, this
     *  function follows the rules which are specified in the DICOM standard
     *  (see DICOM standard (year 2000) part 5, section 7) (or the corresponding
     *  section in a later version of the standard) concerning the encoding
     *  of a dataset.
     *  @param inStream  The stream which contains the information.
     *  @param xfer      The transfer syntax which was used to encode the
     *                   information in inStream.
     *  @param tag       Contains in the end the tag that was read.
     *  @param length    Contains in the end the length value that was read.
     *  @param bytesRead Contains in the end the amount of bytes which were
     *                   read from inStream.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    OFCondition readTagAndLength(DcmInputStream &inStream,       // inout
                                 const E_TransferSyntax xfer,    // in
                                 DcmTag &tag,                    // out
                                 Uint32 &length,                 // out
                                 Uint32 &bytesRead);             // out

    /** This function creates a new DcmElement object on the basis of the newTag
     *  and newLength information which was passed, inserts this new element into
     *  elementList, reads the actual data value which belongs to this element
     *  (attribute) from the inStream and also assigns this information to the
     *  object which was created at the beginning.
     *  @param inStream      The stream which contains the information.
     *  @param newTag        The tag of the element of which the information is
     *                       being read.
     *  @param newLength     The length of the information which is being read.
     *  @param xfer          The transfer syntax which was used to encode the
     *                       information in inStream.
     *  @param glenc         Encoding type for group length. Specifies what will
     *                       be done with group length tags.
     *  @param maxReadLength Maximum read length for reading the attribute value.
     *  @return status, EC_Normal if successful, an error code otherwise
     */
    OFCondition readSubElement(DcmInputStream &inStream,         // inout
                               DcmTag &newTag,                   // inout
                               const Uint32 newLength,           // in
                               const E_TransferSyntax xfer,      // in
                               const E_GrpLenEncoding glenc,     // in
                               const Uint32 maxReadLength = DCM_MaxReadLength);

    /** This function reads the first 6 bytes from the input stream and determines
     *  the transfer syntax which was used to code the information in the stream.
     *  The decision is based on two questions: a) Did we encounter a valid tag?
     *  and b) Do the last 2 bytes which were read from the stream represent a valid
     *  VR? In certain special cases, where the transfer syntax cannot be determined
     *  without doubt, we want to guess the most likely transfer syntax (see code).
     *  @param inStream The stream which contains the coded information.
     *  @return The transfer syntax which was determined.
     */
    E_TransferSyntax checkTransferSyntax(DcmInputStream &inStream);

    /** check whether the given tag requires some special handling regarding the VR
     *  (i.e.\ in case it is undefined and multiple values are possible). If required,
     *  the VR of the given element tag is then updated according to the DICOM
     *  standard, e.g. the VR of PixelPaddingValue (if undefined) is set to 'SS' or
     *  'US' depending on the value of PixelRepresentation.
     *  @param item dataset or item that can be used to lookup other element values
     *  @param tag tag of the element to be checked and updated (if required)
     */
    void checkAndUpdateVR(DcmItem &item,
                          DcmTag &tag);

    /** update the SpecificCharacterSet (0008,0005) element depending on the given
     *  parameters. The current value of this element is either replaced or a new
     *  element is inserted or the existing element is deleted.
     *  @param status error status of previous operations (might also be updated)
     *  @param converter character set converter used to convert element values
     */
    void updateSpecificCharacterSet(OFCondition &status,
                                    const DcmSpecificCharacterSet &converter);

    /** creates new DICOM element from given attribute tag.
     *  Helper function used by DICOM parser (friend of this class) and thus
     *  hidden from the public interface. DcmItem's readSubElement() uses
     *  this function when reading new elements from input data. This method
     *  internally sets the length of the new element, but does not allocate
     *  any memory for the element's value. Thus subsequent access to an element
     *  created by this method can lead to crashes. DcmItem instead initializes
     *  the value itself a bit later during the read process.
     *  @param newElement pointer to newly created element returned in this
     *    parameter upon success, NULL pointer otherwise
     *  @param tag attribute tag of the element to be created. VR of tag may be
     *    updated within the method.
     *  @param length attribute value length of the element to be created
     *  @param privateCreatorCache cache object for private creator strings in
     *    the current dataset
     *  @param readAsUN flag indicating whether parser is currently handling
     *    UN element that must be read in implicit VR little endian; updated
     *    upon return
     *  @return EC_Normal upon success, an error code otherwise
     */
    static OFCondition newDicomElement(DcmElement *&newElement,
                                       DcmTag &tag,
                                       const Uint32 length,
                                       DcmPrivateTagCache *privateCreatorCache,
                                       OFBool& readAsUN);

  private:

    /** helper function for search(). May only be called if elementList is non-empty.
     *  Performs hierarchical search for given tag and pushes pointer of sub-element
     *  on result stack if found
     *  @param tag tag key to be searched
     *  @param resultStack upon successful return, pointer to element pushed onto this stack
     *  @param searchIntoSub flag indicating whether recursive search is desired
     *  @return EC_Normal if tag found and stack modified, EC_TagNotFound if tag not found
     *    and stack unmodified
     */
    OFCondition searchSubFromHere(const DcmTagKey &tag,          // in
                                  DcmStack &resultStack,         // inout
                                  OFBool searchIntoSub );        // in

    /** helper function that interprets the given pointer as a pointer to an
     *  array of two characters and checks whether these two characters form
     *  a valid standard DICOM VR.
     *  @param atposition pointer to array of (at least) two bytes interpreted as VR
     *  @return true if standard VR, false otherwise
     */
    static OFBool foundVR(const Uint8* atposition);

    /// cache for private creator tags and names
    DcmPrivateTagCache privateCreatorCache;
};

/** Checks whether left hand side item is smaller than right hand side
 *  item. Uses DcmItem's compare() method in order to perform the
 *  comparison. See DcmItem::compare() for details.
 *  @param lhs left hand side of the comparison
 *  @param rhs right hand side of the comparison
 *  @return OFTrue if lhs is smaller than rhs, OFFalse otherwise
 */
inline OFBool operator< (const DcmItem& lhs, const DcmItem& rhs)
{
  return ( lhs.compare(rhs) < 0 );
}

/** Checks whether left hand side item is greater than right hand side
 *  item. Uses DcmItem's compare() method in order to perform the
 *  comparison. See DcmItem::compare() for details.
 *  @param lhs left hand side of the comparison
 *  @param rhs right hand side of the comparison
 *  @return OFTrue if lhs is greater than rhs, OFFalse otherwise
 */
inline OFBool operator> (const DcmItem& lhs, const DcmItem& rhs)
{
  return rhs < lhs;
}

/** Checks whether left hand side item is smaller than or equal to right hand
 *  side item. Uses DcmItem's compare() method in order to perform the
 *  comparison. See DcmItem::compare() for details.
 *  @param lhs left hand side of the comparison
 *  @param rhs right hand side of the comparison
 *  @return OFTrue if lhs is smaller than rhs or both are equal, OFFalse
 *          otherwise
 */
inline OFBool operator<=(const DcmItem& lhs, const DcmItem& rhs)
{
  return !(lhs > rhs);
}

/** Checks whether left hand side element is greater than or equal to right hand
 *  side element. Uses DcmElement's compare() method in order to perform the
 *  comparison. See DcmElement::compare() for details.
 *  @param lhs left hand side of the comparison
 *  @param rhs right hand side of the comparison
 *  @return OFTrue if lhs is greater than rhs or both are equal, OFFalse
 *          otherwise
 */
inline OFBool operator>=(const DcmItem& lhs, const DcmItem& rhs)
{
  return !(lhs < rhs);
}

//
// SUPPORT FUNCTIONS
//


/** helper function for DcmElement::nextObject.
 *  hierarchically traverses all datasets/items after the position indicated by the call stack
 *  @param st stack
 *  @return EC_Normal upon success, an error code otherwise
 */
DCMTK_DCMDATA_EXPORT OFCondition nextUp(DcmStack &st);


#endif // DCITEM_H