00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #include "gdcmDicomDir.h"
00024 #include "gdcmDicomDirObject.h"
00025 #include "gdcmDicomDirStudy.h"
00026 #include "gdcmDicomDirSerie.h"
00027 #include "gdcmDicomDirVisit.h"
00028 #include "gdcmDicomDirImage.h"
00029 #include "gdcmDicomDirPatient.h"
00030 #include "gdcmDicomDirMeta.h"
00031 #include "gdcmDicomDirElement.h"
00032 #include "gdcmDirList.h"
00033 #include "gdcmUtil.h"
00034 #include "gdcmDebug.h"
00035 #include "gdcmGlobal.h"
00036 #include "gdcmFile.h"
00037 #include "gdcmSeqEntry.h"
00038 #include "gdcmSQItem.h"
00039 #include "gdcmDataEntry.h"
00040 #include "gdcmCommandManager.h"
00041 
00042 #include <fstream>
00043 #include <string>
00044 #include <algorithm>
00045 #include <sys/types.h>
00046 
00047 #ifdef _MSC_VER
00048 #   define getcwd _getcwd
00049 #endif
00050 
00051 #if defined(_MSC_VER) || defined(__BORLANDC__)
00052 #   include <direct.h>
00053 #else
00054 #   include <unistd.h>
00055 #endif
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112     
00113 namespace gdcm 
00114 {
00115 
00116 
00120 DicomDir::DicomDir()
00121 {
00122    Initialize();  
00123    ParseDir = false;
00124    NewMeta();
00125 }
00126 
00130 DicomDir::~DicomDir() 
00131 {
00132    ClearPatient();
00133    if ( MetaElems )
00134    {
00135       MetaElems->Delete();
00136    }
00137 }
00138 
00139 
00140 
00141 
00148 bool DicomDir::Load( ) 
00149 {
00150    if (!ParseDir)
00151    {
00152       if ( ! this->Document::Load( ) )
00153          return false;
00154    }
00155    return DoTheLoadingJob( );   
00156 }
00157 
00163 bool DicomDir::DoTheLoadingJob( ) 
00164 {
00165    Progress = 0.0f;
00166    Abort = false;
00167 
00168    if (!ParseDir)
00169    {
00170    
00171    
00172       Fp = 0;
00173       if (!Document::Load() )
00174       {
00175          return false;
00176       }
00177 
00178       if ( GetFirstEntry() == 0 ) 
00179       {
00180          gdcmWarningMacro( "Entry HT empty for file: "<< GetFileName());
00181          return false;
00182       }
00183       
00184       DocEntry *e = GetDocEntry(0x0004, 0x1220);
00185       if ( !e )
00186       {
00187          gdcmWarningMacro( "NO 'Directory record sequence' (0x0004,0x1220)"
00188                           << " in file " << GetFileName());
00189          return false;
00190       }
00191       else
00192          CreateDicomDir();
00193    }
00194    else
00195    {
00196    
00197    
00198       if ( GetFileName() == "." )
00199       {
00200          
00201          
00202          char buf[2048];
00203          const char *cwd = getcwd(buf, 2048);
00204          if( cwd )
00205          {
00206            SetFileName( buf ); 
00207          }
00208          else
00209          {
00210            gdcmErrorMacro( "Path was too long to fit on 2048 bytes" );
00211          }
00212       }
00213       NewMeta();
00214       gdcmDebugMacro( "Parse directory and create the DicomDir : " 
00215                          << GetFileName() );
00216       ParseDirectory();
00217    }
00218    return true;
00219 }
00220 
00229 bool DicomDir::IsReadable()
00230 {
00231    if ( Filetype == Unknown )
00232    {
00233       gdcmErrorMacro( "Wrong filetype for " << GetFileName());
00234       return false;
00235    }
00236    if ( !MetaElems )
00237    {
00238       gdcmWarningMacro( "Meta Elements missing in DicomDir");
00239       return false;
00240    }
00241    if ( Patients.size() <= 0 )
00242    {
00243       gdcmWarningMacro( "NO Patient in DicomDir");
00244       return false;
00245    }
00246 
00247    return true;
00248 }
00249 
00253 DicomDirMeta *DicomDir::NewMeta()
00254 {
00255    if ( MetaElems )
00256       MetaElems->Delete();
00257 
00258    DocEntry *entry = GetFirstEntry();
00259    if ( entry )
00260    { 
00261       MetaElems = DicomDirMeta::New(true); 
00262 
00263       entry = GetFirstEntry();
00264       while( entry )
00265       {
00266          if ( dynamic_cast<SeqEntry *>(entry) )
00267             break;
00268 
00269          MetaElems->AddEntry(entry);
00270          RemoveEntry(entry);
00271 
00272          entry = GetFirstEntry();
00273       }
00274    }
00275    else  
00276    {
00277       MetaElems = DicomDirMeta::New(false); 
00278    }
00279    MetaElems->SetSQItemNumber(0); 
00280    return MetaElems;  
00281 }
00282 
00287 DicomDirPatient *DicomDir::NewPatient()
00288 {
00289    DicomDirPatient *dd = DicomDirPatient::New();
00290    AddPatientToEnd( dd );
00291    return dd;
00292 }
00293 
00297 void DicomDir::ClearPatient()
00298 {
00299    for(ListDicomDirPatient::iterator cc = Patients.begin();
00300                                      cc!= Patients.end();
00301                                    ++cc)
00302    {
00303       (*cc)->Unregister();
00304    }
00305    Patients.clear();
00306 }
00307 
00312 DicomDirPatient *DicomDir::GetFirstPatient()
00313 {
00314    ItPatient = Patients.begin();
00315    if ( ItPatient != Patients.end() )
00316       return *ItPatient;
00317    return NULL;
00318 }
00319 
00325 DicomDirPatient *DicomDir::GetNextPatient()
00326 {
00327    gdcmAssertMacro (ItPatient != Patients.end());
00328 
00329    ++ItPatient;
00330    if ( ItPatient != Patients.end() )
00331       return *ItPatient;
00332    return NULL;
00333 }
00334 
00338 void DicomDir::ParseDirectory()
00339 {
00340    CreateDicomDirChainedList( GetFileName() );
00341    CreateDicomDir();
00342 }
00343 
00352 bool DicomDir::Write(std::string const &fileName) 
00353 {  
00354    int i;
00355    uint16_t sq[6] = { 0x0004, 0x1220, 0x5153, 0x0000, 0xffff, 0xffff };
00356    uint16_t sqt[4]= { 0xfffe, 0xe0dd, 0x0000, 0x0000 };
00357 
00358    std::ofstream *fp = new std::ofstream(fileName.c_str(),  
00359                                          std::ios::out | std::ios::binary);
00360    if ( !fp ) 
00361    {
00362       gdcmWarningMacro("Failed to open(write) File: " << fileName.c_str());
00363       return false;
00364    }
00365 
00366    char filePreamble[128];
00367    memset(filePreamble, 0, 128);
00368    fp->write(filePreamble, 128);
00369    binary_write( *fp, "DICM");
00370  
00371    DicomDirMeta *ptrMeta = GetMeta();
00372    ptrMeta->WriteContent(fp, ExplicitVR);
00373    
00374    
00375    for(i=0;i<6;++i)
00376    {
00377       binary_write(*fp, sq[i]);
00378    }
00379         
00380    for(ListDicomDirPatient::iterator cc  = Patients.begin();
00381                                      cc != Patients.end();
00382                                    ++cc )
00383    {
00384       (*cc)->WriteContent( fp, ExplicitVR );
00385    }
00386    
00387    
00388    for(i=0;i<4;++i)
00389    {
00390       binary_write(*fp, sqt[i]);  
00391    }
00392 
00393    fp->close();
00394    delete fp;
00395 
00396    return true;
00397 }
00398 
00404 bool DicomDir::Anonymize() 
00405 {
00406    DataEntry *v;
00407    
00408    std::ostringstream s;
00409    int i = 1;
00410    for(ListDicomDirPatient::iterator cc = Patients.begin();
00411                                      cc!= Patients.end();
00412                                    ++cc)
00413    {
00414       s << i;
00415       v = (*cc)->GetDataEntry(0x0010, 0x0010) ; 
00416       if (v)
00417       {
00418          v->SetString(s.str());
00419       }
00420 
00421       v = (*cc)->GetDataEntry(0x0010, 0x0020) ; 
00422       if (v)
00423       {
00424          v->SetString(" ");
00425       }
00426 
00427       v = (*cc)->GetDataEntry(0x0010, 0x0030) ; 
00428       if (v)
00429       {
00430          v->SetString(" ");
00431       }
00432       s << "";
00433       i++;
00434    }
00435    return true;
00436 }
00437 
00443 void DicomDir::Copy(DocEntrySet *set)
00444 {
00445    
00446    ClearPatient();
00447 
00448    Document::Copy(set);
00449 
00450    DicomDir *dd = dynamic_cast<DicomDir *>(set);
00451    if( dd )
00452    {
00453       if(MetaElems)
00454          MetaElems->Unregister();
00455       MetaElems = dd->MetaElems;
00456       if(MetaElems)
00457          MetaElems->Register();
00458 
00459       Patients = dd->Patients;
00460       for(ItPatient = Patients.begin();ItPatient != Patients.end();++ItPatient)
00461          (*ItPatient)->Register();
00462    }
00463 }
00464 
00465 
00466 
00471 void DicomDir::CreateDicomDirChainedList(std::string const &path)
00472 {
00473    CallStartMethod();
00474    DirList dirList(path,1); 
00475    unsigned int count = 0;
00476    VectDocument list;
00477    File *f;
00478 
00479    DirListType fileList = dirList.GetFilenames();
00480    unsigned int nbFile = fileList.size();
00481    for( DirListType::iterator it  = fileList.begin();
00482                               it != fileList.end();
00483                               ++it )
00484    {
00485       Progress = (float)(count+1)/(float)nbFile;
00486       CallProgressMethod();
00487       if ( Abort )
00488       {
00489          break;
00490       }
00491 
00492       f = File::New( );
00493       f->SetLoadMode(LoadMode); 
00494                                 
00495       f->SetFileName( it->c_str() );
00496       f->Load( );
00497 
00498       if ( f->IsReadable() )
00499       {
00500          
00501          list.push_back(f);
00502          gdcmDebugMacro( "Readable " << it->c_str() );
00503        }
00504        else
00505        {
00506           f->Delete();
00507        }
00508        count++;
00509    }
00510    
00511    std::sort(list.begin(), list.end(), DicomDir::HeaderLessThan );
00512    
00513    std::string tmp = dirList.GetDirName();      
00514    
00515    SetElements(tmp, list);
00516    CallEndMethod();
00517 
00518    for(VectDocument::iterator itDoc=list.begin();
00519        itDoc!=list.end();
00520        ++itDoc)
00521    {
00522       dynamic_cast<File *>(*itDoc)->Delete();
00523    }
00524 }
00525 
00526 
00527 
00528 
00532 void DicomDir::Initialize()
00533 {
00534    Progress = 0.0;
00535    Abort = false;
00536 
00537    MetaElems = NULL;   
00538 }
00539 
00543 void DicomDir::CreateDicomDir()
00544 {
00545    
00546    
00547    
00548    
00549    
00550    
00551    
00552    gdcmDebugMacro("Create DicomDir");
00553 
00554    
00555    DocEntry *e = GetDocEntry(0x0004, 0x1220);
00556    if ( !e )
00557    {
00558       gdcmWarningMacro( "No Directory Record Sequence (0004,1220) found");
00559       return;         
00560    }
00561    
00562    SeqEntry *s = dynamic_cast<SeqEntry *>(e);
00563    if ( !s )
00564    {
00565       gdcmWarningMacro( "Element (0004,1220) is not a Sequence ?!?");
00566       return;
00567    }
00568 
00569    NewMeta();
00570    
00571    DocEntry *d;
00572    std::string v;
00573    SQItem *si;
00574 
00575    SQItem *tmpSI=s->GetFirstSQItem();
00576    while(tmpSI)
00577    {
00578       d = tmpSI->GetDocEntry(0x0004, 0x1430); 
00579       if ( DataEntry *dataEntry = dynamic_cast<DataEntry *>(d) )
00580       {
00581          v = dataEntry->GetString();
00582       }
00583       else
00584       {
00585          gdcmWarningMacro( "(0004,1430) not a DataEntry ?!?");
00586          continue;
00587       }
00588 
00589       
00590       
00591       
00592 
00593       if ( v == "IMAGE " ) 
00594       {
00595          si = DicomDirImage::New(true);
00596          if ( !AddImageToEnd( static_cast<DicomDirImage *>(si)) )
00597          {
00598             si->Delete();
00599             si = NULL;
00600             gdcmErrorMacro( "Add AddImageToEnd failed");
00601          }
00602       }
00603       else if ( v == "SERIES" )
00604       {
00605          si = DicomDirSerie::New(true);
00606          if ( !AddSerieToEnd( static_cast<DicomDirSerie *>(si)) )
00607          {
00608             si->Delete();
00609             si = NULL;
00610             gdcmErrorMacro( "Add AddSerieToEnd failed");
00611          }
00612       }
00613       else if ( v == "VISIT " )
00614       {
00615          si = DicomDirVisit::New(true);
00616          if ( !AddVisitToEnd( static_cast<DicomDirVisit *>(si)) )
00617          {
00618             si->Delete();
00619             si = NULL;
00620             gdcmErrorMacro( "Add AddVisitToEnd failed");
00621          }
00622       }
00623       else if ( v == "STUDY " )
00624       {
00625          si = DicomDirStudy::New(true);
00626          if ( !AddStudyToEnd( static_cast<DicomDirStudy *>(si)) )
00627          {
00628             si->Delete();
00629             si = NULL;
00630             gdcmErrorMacro( "Add AddStudyToEnd failed");
00631          }
00632       }
00633       else if ( v == "PATIENT " )
00634       {
00635          si = DicomDirPatient::New(true);
00636          if ( !AddPatientToEnd( static_cast<DicomDirPatient *>(si)) )
00637          {
00638             si->Delete();
00639             si = NULL;
00640             gdcmErrorMacro( "Add PatientToEnd failed");
00641          }
00642       }
00643       else
00644       {
00645          
00646          
00647          gdcmDebugMacro( " -------------------------------------------"
00648          << "a non PATIENT/STUDY/SERIE/IMAGE SQItem was found : "
00649          << v);
00650 
00651         
00652         tmpSI=s->GetNextSQItem(); 
00653         continue;
00654       }
00655       if ( si )
00656          si->Copy(tmpSI);
00657 
00658       tmpSI=s->GetNextSQItem();
00659    }
00660    ClearEntry();
00661 }
00662 
00667 bool DicomDir::AddPatientToEnd(DicomDirPatient *dd)
00668 {
00669    Patients.push_back(dd);
00670    return true;
00671 }
00672 
00677 bool DicomDir::AddStudyToEnd(DicomDirStudy *dd)
00678 {
00679    if ( Patients.size() > 0 )
00680    {
00681       ListDicomDirPatient::iterator itp = Patients.end();
00682       itp--;
00683       (*itp)->AddStudy(dd);
00684       return true;
00685    }
00686    return false;
00687 }
00688 
00693 bool DicomDir::AddSerieToEnd(DicomDirSerie *dd)
00694 {
00695    if ( Patients.size() > 0 )
00696    {
00697       ListDicomDirPatient::iterator itp = Patients.end();
00698       itp--;
00699 
00700       DicomDirStudy *study = (*itp)->GetLastStudy();
00701       if ( study )
00702       {
00703          study->AddSerie(dd);
00704          return true;
00705       }
00706    }
00707    return false;
00708 }
00709 
00714 bool DicomDir::AddVisitToEnd(DicomDirVisit *dd)
00715 {
00716    if ( Patients.size() > 0 )
00717    {
00718       ListDicomDirPatient::iterator itp = Patients.end();
00719       itp--;
00720 
00721       DicomDirStudy *study = (*itp)->GetLastStudy();
00722       if ( study )
00723       {
00724          study->AddVisit(dd);
00725          return true;
00726       }
00727    }
00728    return false;
00729 }
00734 bool DicomDir::AddImageToEnd(DicomDirImage *dd)
00735 {
00736    if ( Patients.size() > 0 )
00737    {
00738       ListDicomDirPatient::iterator itp = Patients.end();
00739       itp--;
00740 
00741       DicomDirStudy *study = (*itp)->GetLastStudy();
00742       if ( study )
00743       {
00744          DicomDirSerie *serie = study->GetLastSerie();
00745          if ( serie )
00746          {
00747             serie->AddImage(dd);
00748             return true;
00749          }
00750       }
00751    }
00752    return false;
00753 }
00754 
00761 void DicomDir::SetElements(std::string const &path, VectDocument const &list)
00762 {
00763    ClearEntry();
00764    ClearPatient();
00765 
00766    std::string patPrevName         = "", patPrevID  = "";
00767    std::string studPrevInstanceUID = "", studPrevID = "";
00768    std::string serPrevInstanceUID  = "", serPrevID  = "";
00769 
00770    std::string patCurName,         patCurID;
00771    std::string studCurInstanceUID, studCurID;
00772    std::string serCurInstanceUID,  serCurID;
00773 
00774    bool first = true;
00775    for( VectDocument::const_iterator it = list.begin();
00776                                      it != list.end(); 
00777                                    ++it )
00778    {
00779       
00780       patCurName         = (*it)->GetEntryString(0x0010,0x0010);
00781       patCurID           = (*it)->GetEntryString(0x0010,0x0011);
00782       studCurInstanceUID = (*it)->GetEntryString(0x0020,0x000d);
00783       studCurID          = (*it)->GetEntryString(0x0020,0x0010);
00784       serCurInstanceUID  = (*it)->GetEntryString(0x0020,0x000e);
00785       serCurID           = (*it)->GetEntryString(0x0020,0x0011);
00786 
00787       if ( patCurName != patPrevName || patCurID != patPrevID || first )
00788       {
00789          SetElement(path, GDCM_DICOMDIR_PATIENT, *it);
00790          first = true;
00791       }
00792 
00793       
00794       if ( studCurInstanceUID != studPrevInstanceUID || studCurID != studPrevID 
00795          || first )
00796       {
00797          SetElement(path, GDCM_DICOMDIR_STUDY, *it);
00798          first = true;
00799       }
00800 
00801       
00802       if ( serCurInstanceUID != serPrevInstanceUID || serCurID != serPrevID
00803          || first )
00804       {
00805          SetElement(path, GDCM_DICOMDIR_SERIE, *it);
00806       }
00807       
00808       
00809       SetElement(path, GDCM_DICOMDIR_IMAGE, *it);
00810 
00811       patPrevName         = patCurName;
00812       patPrevID           = patCurID;
00813       studPrevInstanceUID = studCurInstanceUID;
00814       studPrevID          = studCurID;
00815       serPrevInstanceUID  = serCurInstanceUID;
00816       serPrevID           = serCurID;
00817       first = false;
00818    }
00819 }
00820 
00829 void DicomDir::SetElement(std::string const &path, DicomDirType type,
00830                           Document *header)
00831 {
00832    ListDicomDirElem elemList;
00833    ListDicomDirElem::const_iterator it;
00834    uint16_t tmpGr, tmpEl;
00835    DictEntry *dictEntry;
00836    DataEntry *entry;
00837    std::string val;
00838    SQItem *si;
00839 
00840    switch( type )
00841    {
00842       case GDCM_DICOMDIR_IMAGE:
00843          elemList = Global::GetDicomDirElements()->GetDicomDirImageElements();
00844          si = DicomDirImage::New(true);
00845          if ( !AddImageToEnd(static_cast<DicomDirImage *>(si)) )
00846          {
00847             si->Delete();
00848             gdcmErrorMacro( "Add ImageToEnd failed");
00849          }
00850          break;
00851       case GDCM_DICOMDIR_SERIE:
00852          elemList = Global::GetDicomDirElements()->GetDicomDirSerieElements();
00853          si = DicomDirSerie::New(true);
00854          if ( !AddSerieToEnd(static_cast<DicomDirSerie *>(si)) )
00855          {
00856             si->Delete();
00857             gdcmErrorMacro( "Add SerieToEnd failed");
00858          }
00859          break;
00860       case GDCM_DICOMDIR_STUDY:
00861          elemList = Global::GetDicomDirElements()->GetDicomDirStudyElements();
00862          si = DicomDirStudy::New(true);
00863          if ( !AddStudyToEnd(static_cast<DicomDirStudy *>(si)) )
00864          {
00865             si->Delete();
00866             gdcmErrorMacro( "Add StudyToEnd failed");
00867          }
00868          break;
00869       case GDCM_DICOMDIR_PATIENT:
00870          elemList = Global::GetDicomDirElements()->GetDicomDirPatientElements();
00871          si = DicomDirPatient::New(true);
00872          if ( !AddPatientToEnd(static_cast<DicomDirPatient *>(si)) )
00873          {
00874             si->Delete();
00875             gdcmErrorMacro( "Add PatientToEnd failed");
00876          }
00877          break;
00878       case GDCM_DICOMDIR_META:
00879          if ( MetaElems )
00880          {
00881             MetaElems->Delete();
00882             gdcmErrorMacro( "MetaElements already exist, they will be destroyed");
00883          }
00884          elemList = Global::GetDicomDirElements()->GetDicomDirMetaElements();
00885          MetaElems = DicomDirMeta::New(true);
00886          si = MetaElems;
00887          break;
00888       default:
00889          return;
00890    }
00891    
00892    
00893       
00894    
00895    
00896    
00897    
00898    
00899    
00900    
00901  
00902    std::string referencedVal;
00903    
00904    for( it = elemList.begin(); it != elemList.end(); ++it)
00905    {
00906       tmpGr     = it->Group;
00907       tmpEl     = it->Elem;
00908       dictEntry = GetPubDict()->GetEntry(tmpGr, tmpEl);
00909 
00910       entry     = DataEntry::New( dictEntry ); 
00911       entry->SetOffset(0); 
00912 
00913       if ( header )
00914       {
00915          
00916          
00917  
00918             val = header->GetEntryString(tmpGr, tmpEl); 
00919       }
00920       else
00921       {
00922          val = GDCM_UNFOUND;
00923       }
00924 
00925       if ( val == GDCM_UNFOUND) 
00926       {       
00927          if ( tmpGr == 0x0004 ) 
00928          {
00929             switch (tmpEl)
00930             {
00931             case 0x1130: 
00932                
00933                val = Util::GetName( path );
00934                break;
00935       
00936             case 0x1500: 
00937                if ( header->GetFileName().substr(0, path.length()) != path )
00938                { 
00939                  gdcmWarningMacro( "The base path of file name is incorrect");
00940                  val = header->GetFileName();
00941                }
00942                else
00943                { 
00944                  
00945                  if ( header->GetFileName().c_str()[path.length()] 
00946                                                       == GDCM_FILESEPARATOR )
00947                     val = &(header->GetFileName().c_str()[path.length()+1]);
00948                  else  
00949                     val = &(header->GetFileName().c_str()[path.length()]);   
00950                }
00951                break;
00952     
00953              case 0x1510:  
00954                referencedVal = header->GetEntryString(0x0008, 0x0016);
00955                
00956                val = referencedVal;
00957                break;
00958        
00959              case 0x1511: 
00960                referencedVal = header->GetEntryString(0x0008, 0x0018);
00961                
00962                val = referencedVal;
00963                break;
00964     
00965             case 0x1512: 
00966                referencedVal = header->GetEntryString(0x0002, 0x0010);
00967                
00968                val = referencedVal;
00969                break;
00970     
00971             default :
00972                val = it->Value;   
00973             } 
00974          }
00975          else
00976          {
00977             
00978             entry->Delete();
00979             continue;
00980           }
00981       }
00982       else
00983       {
00984          if ( header->GetEntryLength(tmpGr,tmpEl) == 0 )
00985          {
00986             val = it->Value;
00987             
00988             if (val == "")
00989             {
00990                entry->Delete();
00991                continue;
00992             }  
00993          }    
00994       }
00995 
00996 
00997 
00998 
00999 
01000 
01001 
01002 
01003 
01004 
01005 
01006 
01007  
01008 
01009       entry->SetString( val ); 
01010 
01011       if ( type == GDCM_DICOMDIR_META ) 
01012       {
01013          gdcmDebugMacro("GDCM_DICOMDIR_META ?!? should never print that");
01014       }
01015       
01016       si->AddEntry(entry);
01017       entry->Delete();
01018    }
01019 }
01020 
01027 void DicomDir::MoveSQItem(DocEntrySet *dst, DocEntrySet *src)
01028 { 
01029    DocEntry *entry;
01030 
01031 
01032    entry = src->GetFirstEntry();
01033    while(entry)
01034    {
01035       dst->AddEntry(entry);  
01036       src->RemoveEntry(entry);
01037       
01038       entry = src->GetFirstEntry();
01039    }
01040 }
01041 
01045 bool DicomDir::HeaderLessThan(Document *header1, Document *header2)
01046 {
01047    return *header1 < *header2;
01048 }
01049 
01050 
01051 
01057 void DicomDir::Print(std::ostream &os, std::string const & )
01058 {
01059    if ( MetaElems )
01060    {
01061       MetaElems->SetPrintLevel(PrintLevel);
01062       MetaElems->Print(os);   
01063    }   
01064    for(ListDicomDirPatient::iterator cc  = Patients.begin();
01065                                      cc != Patients.end();
01066                                    ++cc)
01067    {
01068      (*cc)->SetPrintLevel(PrintLevel);
01069      (*cc)->Print(os);
01070    }
01071 }
01072 
01073 
01074 }