00001 /* 00002 * 00003 * Copyright (C) 1998-2010, OFFIS e.V. 00004 * All rights reserved. See COPYRIGHT file for details. 00005 * 00006 * This software and supporting documentation were developed by 00007 * 00008 * OFFIS e.V. 00009 * R&D Division Health 00010 * Escherweg 2 00011 * D-26121 Oldenburg, Germany 00012 * 00013 * 00014 * Module: dcmpstat 00015 * 00016 * Author: Joerg Riesmeier 00017 * 00018 * Purpose: Classes for caching of the image database (Header/Source) 00019 * 00020 * Last Update: $Author: joergr $ 00021 * Update Date: $Date: 2010-10-14 13:16:35 $ 00022 * CVS/RCS Revision: $Revision: 1.20 $ 00023 * Status: $State: Exp $ 00024 * 00025 * CVS/RCS Log at end of file 00026 * 00027 */ 00028 00029 00030 #ifndef DVCACHE_H 00031 #define DVCACHE_H 00032 00033 #include "dcmtk/config/osconfig.h" 00034 00035 #include "dcmtk/ofstd/oflist.h" 00036 #include "dcmtk/ofstd/ofstring.h" 00037 #include "dcmtk/dcmqrdb/dcmqrdbi.h" /* for DVIFhierarchyStatus */ 00038 00039 00040 /*--------------------* 00041 * type definitions * 00042 *--------------------*/ 00043 00046 enum DVPSInstanceType 00047 { 00049 DVPSI_image, 00051 DVPSI_presentationState, 00053 DVPSI_structuredReport, 00055 DVPSI_storedPrint, 00057 DVPSI_hardcopyGrayscale 00058 }; 00059 00060 00061 /*---------------------* 00062 * class declaration * 00063 *---------------------*/ 00064 00070 class DVInstanceCache 00071 { 00072 00073 public: 00074 00077 struct ItemStruct 00078 { 00089 ItemStruct(const OFString &uid, 00090 const int pos, 00091 const DVIFhierarchyStatus status, 00092 const DVPSInstanceType type, 00093 const int size, 00094 const OFString &filename) 00095 : UID(uid), 00096 Pos(pos), 00097 Status(status), 00098 Type(type), 00099 ImageSize(size), 00100 Filename(filename), 00101 Checked(OFFalse), 00102 Description(), 00103 Label(), 00104 List() 00105 {} 00106 00108 OFString UID; 00110 int Pos; 00112 DVIFhierarchyStatus Status; 00114 DVPSInstanceType Type; 00116 int ImageSize; 00118 OFString Filename; 00120 OFBool Checked; 00122 OFString Description; 00124 OFString Label; 00126 OFList<ItemStruct *> List; 00127 }; 00128 00131 DVInstanceCache() 00132 : List(), 00133 Iterator(), 00134 OldIterator() 00135 { 00136 Iterator = OldIterator = List.end(); 00137 } 00138 00141 virtual ~DVInstanceCache() 00142 { 00143 clear(); 00144 } 00145 00149 inline void clear() 00150 { 00151 Iterator = List.begin(); 00152 OFListIterator(ItemStruct *) last = List.end(); 00153 while (Iterator != last) 00154 { 00155 delete (*Iterator); 00156 Iterator = List.erase(Iterator); 00157 } 00158 List.clear(); 00159 Iterator = OldIterator = List.end(); 00160 } 00161 00166 inline OFBool empty() const 00167 { 00168 return List.empty(); 00169 } 00170 00175 inline Uint32 getCount() const 00176 { 00177 return List.size(); 00178 } 00179 00186 inline OFBool gotoItem(Uint32 idx) 00187 { 00188 OFBool result = OFFalse; 00189 Iterator = List.begin(); 00190 OFListIterator(ItemStruct *) last = List.end(); 00191 while (Iterator != last) 00192 { 00193 if (idx == 0) 00194 { 00195 result = OFTrue; 00196 break; 00197 } 00198 idx--; 00199 ++Iterator; 00200 } 00201 return result; 00202 } 00203 00208 inline OFBool gotoFirst() 00209 { 00210 OldIterator = Iterator; 00211 Iterator = List.begin(); 00212 return (Iterator != List.end()); 00213 } 00214 00219 inline OFBool gotoNext() 00220 { 00221 OFListIterator(ItemStruct *) last = List.end(); 00222 if (Iterator != last) 00223 Iterator++; 00224 return (Iterator != last); 00225 } 00226 00232 inline OFBool reset() 00233 { 00234 OFBool result = OFFalse; 00235 OFListIterator(ItemStruct *) last = List.end(); 00236 if (OldIterator != last) 00237 { 00238 Iterator = OldIterator; 00239 OldIterator = last; 00240 result = OFTrue; 00241 } 00242 return result; 00243 } 00244 00251 inline OFBool isElem(const OFString &uid) 00252 { 00253 OFBool result = OFFalse; 00254 Iterator = List.begin(); 00255 OFListIterator(ItemStruct *) last = List.end(); 00256 while (Iterator != last) 00257 { 00258 const ItemStruct *item = (*Iterator); 00259 if (item != NULL) 00260 { 00261 if (item->UID == uid) 00262 { 00263 result = OFTrue; 00264 break; 00265 } 00266 } 00267 ++Iterator; 00268 } 00269 return result; 00270 } 00271 00276 inline int getPos() const 00277 { 00278 const ItemStruct *item = getItem(); 00279 return (item != NULL) ? item->Pos : 0; 00280 } 00281 00286 inline DVIFhierarchyStatus getStatus() const 00287 { 00288 const ItemStruct *item = getItem(); 00289 return (item != NULL) ? item->Status : DVIF_objectIsNew; 00290 } 00291 00296 inline DVPSInstanceType getType() const 00297 { 00298 const ItemStruct *item = getItem(); 00299 return (item != NULL) ? item->Type : DVPSI_image; 00300 } 00301 00306 inline int getImageSize() const 00307 { 00308 const ItemStruct *item = getItem(); 00309 return (item != NULL) ? item->ImageSize : 0; 00310 } 00311 00316 inline const char *getFilename() const 00317 { 00318 const ItemStruct *item = getItem(); 00319 return (item != NULL) ? item->Filename.c_str() : (const char *)NULL; 00320 } 00321 00326 inline ItemStruct *getItem() const 00327 { 00328 OFListConstIterator(ItemStruct *) it = Iterator; 00329 return (it != List.end()) ? (*Iterator) : (ItemStruct *)NULL; 00330 } 00331 00342 inline void addItem(const OFString &uid, 00343 const int pos, 00344 const DVIFhierarchyStatus status, 00345 const DVPSInstanceType type, 00346 const int size, 00347 const OFString &filename) 00348 { 00349 ItemStruct *item = new ItemStruct(uid, pos, status, type, size, filename); 00350 List.push_back(item); 00351 Iterator = --List.end(); // set to new position 00352 } 00353 00358 inline DVIFhierarchyStatus updateStatus() 00359 { 00360 OFListIterator(ItemStruct *) first = List.begin(); 00361 OFListIterator(ItemStruct *) last = List.end(); 00362 OFListIterator(ItemStruct *) iter = first; 00363 DVIFhierarchyStatus status = DVIF_objectIsNew; 00364 while (iter != last) 00365 { 00366 ItemStruct *item = (*iter); 00367 if (item != NULL) 00368 { 00369 switch (item->Status) 00370 { 00371 case DVIF_objectIsNew: 00372 if (status == DVIF_objectIsNotNew) 00373 status = DVIF_objectContainsNewSubobjects; 00374 break; 00375 case DVIF_objectIsNotNew: 00376 case DVIF_objectContainsNewSubobjects: 00377 if (iter == first) 00378 status = DVIF_objectIsNotNew; 00379 else if (status == DVIF_objectIsNew) 00380 status = DVIF_objectContainsNewSubobjects; 00381 break; 00382 } 00383 } 00384 ++iter; 00385 } 00386 return status; 00387 } 00388 00389 00390 protected: 00391 00393 OFList<ItemStruct *> List; 00395 OFListIterator(ItemStruct *) Iterator; 00397 OFListIterator(ItemStruct *) OldIterator; 00398 }; 00399 00400 00401 /* ------------------------------ */ 00402 00403 00409 class DVSeriesCache 00410 { 00411 00412 public: 00413 00416 struct ItemStruct 00417 { 00425 ItemStruct(const OFString &uid, 00426 const DVIFhierarchyStatus status = DVIF_objectIsNew, 00427 const DVPSInstanceType type = DVPSI_image) 00428 : UID(uid), 00429 Status(status), 00430 Type(type), 00431 List() 00432 {} 00433 00435 OFString UID; 00437 DVIFhierarchyStatus Status; 00439 DVPSInstanceType Type; 00441 DVInstanceCache List; 00442 }; 00443 00446 DVSeriesCache() 00447 : List(), 00448 Iterator(), 00449 OldIterator() 00450 { 00451 Iterator = OldIterator = List.end(); 00452 } 00453 00456 virtual ~DVSeriesCache() 00457 { 00458 clear(); 00459 } 00460 00464 inline void clear() 00465 { 00466 Iterator = List.begin(); 00467 OFListIterator(ItemStruct *) last = List.end(); 00468 while (Iterator != last) 00469 { 00470 delete (*Iterator); 00471 Iterator = List.erase(Iterator); 00472 } 00473 List.clear(); 00474 Iterator = OldIterator = List.end(); 00475 } 00476 00481 inline OFBool empty() const 00482 { 00483 return List.empty(); 00484 } 00485 00490 inline Uint32 getCount() const 00491 { 00492 return List.size(); 00493 } 00494 00501 inline OFBool gotoItem(Uint32 idx) 00502 { 00503 OFBool result = OFFalse; 00504 Iterator = List.begin(); 00505 OFListIterator(ItemStruct *) last = List.end(); 00506 while (Iterator != last) 00507 { 00508 if (idx == 0) 00509 { 00510 result = OFTrue; 00511 break; 00512 } 00513 idx--; 00514 ++Iterator; 00515 } 00516 return result; 00517 } 00518 00523 inline OFBool gotoFirst() 00524 { 00525 OldIterator = Iterator; 00526 Iterator = List.begin(); 00527 return (Iterator != List.end()); 00528 } 00529 00534 inline OFBool gotoNext() 00535 { 00536 OFListIterator(ItemStruct *) last = List.end(); 00537 if (Iterator != last) 00538 Iterator++; 00539 return (Iterator != last); 00540 } 00541 00547 inline OFBool reset() 00548 { 00549 OFBool result = OFFalse; 00550 OFListIterator(ItemStruct *) last = List.end(); 00551 if (OldIterator != last) 00552 { 00553 Iterator = OldIterator; 00554 OldIterator = last; 00555 result = OFTrue; 00556 } 00557 return result; 00558 } 00559 00566 inline OFBool isElem(const OFString &uid) 00567 { 00568 OFBool result = OFFalse; 00569 Iterator = List.begin(); 00570 OFListIterator(ItemStruct *) last = List.end(); 00571 while (Iterator != last) 00572 { 00573 const ItemStruct *item = (*Iterator); 00574 if (item != NULL) 00575 { 00576 if (item->UID == uid) 00577 { 00578 result = OFTrue; 00579 break; 00580 } 00581 } 00582 ++Iterator; 00583 } 00584 return result; 00585 } 00586 00591 inline DVIFhierarchyStatus getStatus() const 00592 { 00593 const ItemStruct *item = getItem(); 00594 return (item != NULL) ? item->Status : DVIF_objectIsNew; 00595 } 00596 00601 inline DVPSInstanceType getType() const 00602 { 00603 const ItemStruct *item = getItem(); 00604 return (item != NULL) ? item->Type : DVPSI_image; 00605 } 00606 00611 inline ItemStruct *getItem() const 00612 { 00613 OFListConstIterator(ItemStruct *) it = Iterator; 00614 return (it != List.end()) ? (*Iterator) : (ItemStruct *)NULL; 00615 } 00616 00623 inline void addItem(const OFString &uid, 00624 const DVIFhierarchyStatus status = DVIF_objectIsNew) 00625 { 00626 ItemStruct *item = new ItemStruct(uid, status); 00627 List.push_back(item); 00628 Iterator = --List.end(); // set to new position 00629 } 00630 00635 inline DVIFhierarchyStatus updateStatus() 00636 { 00637 OFListIterator(ItemStruct *) first = List.begin(); 00638 OFListIterator(ItemStruct *) last = List.end(); 00639 OFListIterator(ItemStruct *) iter = first; 00640 DVIFhierarchyStatus status = DVIF_objectIsNew; 00641 while (iter != last) 00642 { 00643 ItemStruct *item = (*iter); 00644 if (item != NULL) 00645 { 00646 item->Status = item->List.updateStatus(); 00647 switch (item->Status) 00648 { 00649 case DVIF_objectIsNew: 00650 if (status == DVIF_objectIsNotNew) 00651 status = DVIF_objectContainsNewSubobjects; 00652 break; 00653 case DVIF_objectIsNotNew: 00654 if (iter == first) 00655 status = DVIF_objectIsNotNew; 00656 else if (status == DVIF_objectIsNew) 00657 status = DVIF_objectContainsNewSubobjects; 00658 break; 00659 case DVIF_objectContainsNewSubobjects: 00660 status = DVIF_objectContainsNewSubobjects; 00661 break; 00662 } 00663 } 00664 ++iter; 00665 } 00666 return status; 00667 } 00668 00669 00670 protected: 00671 00673 OFList<ItemStruct *> List; 00675 OFListIterator(ItemStruct *) Iterator; 00677 OFListIterator(ItemStruct *) OldIterator; 00678 }; 00679 00680 00681 /* ------------------------------ */ 00682 00683 00689 class DVStudyCache 00690 { 00691 00692 public: 00693 00696 struct ItemStruct 00697 { 00704 ItemStruct(const OFString &uid, 00705 const DVIFhierarchyStatus status = DVIF_objectIsNew) 00706 : UID(uid), 00707 Status(status), 00708 List() 00709 {} 00710 00712 OFString UID; 00714 DVIFhierarchyStatus Status; 00716 DVSeriesCache List; 00717 }; 00718 00721 DVStudyCache() 00722 : List(), 00723 Iterator() 00724 { 00725 Iterator = List.end(); 00726 } 00727 00730 virtual ~DVStudyCache() 00731 { 00732 clear(); 00733 } 00734 00738 inline void clear() 00739 { 00740 Iterator = List.begin(); 00741 OFListIterator(ItemStruct *) last = List.end(); 00742 while (Iterator != last) 00743 { 00744 delete (*Iterator); 00745 Iterator = List.erase(Iterator); 00746 } 00747 List.clear(); 00748 Iterator = List.end(); 00749 } 00750 00755 inline OFBool empty() const 00756 { 00757 return List.empty(); 00758 } 00759 00764 inline Uint32 getCount() const 00765 { 00766 return List.size(); 00767 } 00768 00775 inline OFBool gotoItem(Uint32 idx) 00776 { 00777 OFBool result = OFFalse; 00778 Iterator = List.begin(); 00779 OFListIterator(ItemStruct *) last = List.end(); 00780 while (Iterator != last) 00781 { 00782 if (idx == 0) 00783 { 00784 result = OFTrue; 00785 break; 00786 } 00787 idx--; 00788 ++Iterator; 00789 } 00790 return result; 00791 } 00792 00797 inline OFBool gotoFirst() 00798 { 00799 //OldIterator = Iterator; 00800 Iterator = List.begin(); 00801 return (Iterator != List.end()); 00802 } 00803 00808 inline OFBool gotoNext() 00809 { 00810 OFListIterator(ItemStruct *) last = List.end(); 00811 if (Iterator != last) 00812 Iterator++; 00813 return (Iterator != last); 00814 } 00815 00822 inline OFBool isElem(const OFString &uid) 00823 { 00824 OFBool result = OFFalse; 00825 Iterator = List.begin(); 00826 OFListIterator(ItemStruct *) last = List.end(); 00827 while (Iterator != last) 00828 { 00829 const ItemStruct *item = (*Iterator); 00830 if (item != NULL) 00831 { 00832 if (item->UID == uid) 00833 { 00834 result= OFTrue; 00835 break; 00836 } 00837 } 00838 ++Iterator; 00839 } 00840 return result; 00841 } 00842 00847 inline DVIFhierarchyStatus getStatus() const 00848 { 00849 const ItemStruct *item = getItem(); 00850 return (item != NULL) ? item->Status : DVIF_objectIsNew; 00851 } 00852 00857 inline ItemStruct *getItem() const 00858 { 00859 OFListConstIterator(ItemStruct *) it = Iterator; 00860 return (it != List.end()) ? (*Iterator) : (ItemStruct *)NULL; 00861 } 00862 00869 inline void addItem(const OFString &uid, 00870 const DVIFhierarchyStatus status = DVIF_objectIsNew) 00871 { 00872 ItemStruct *item = new ItemStruct(uid, status); 00873 List.push_back(item); 00874 Iterator = --List.end(); // set to new position 00875 } 00876 00881 inline void updateStatus() 00882 { 00883 OFListIterator(ItemStruct *) iter = List.begin(); 00884 OFListIterator(ItemStruct *) last = List.end(); 00885 while (iter != last) 00886 { 00887 ItemStruct *item = (*iter); 00888 if (item != NULL) 00889 item->Status = item->List.updateStatus(); 00890 ++iter; 00891 } 00892 } 00893 00894 00895 protected: 00896 00898 OFList<ItemStruct *> List; 00900 OFListIterator(ItemStruct *) Iterator; 00901 }; 00902 00903 00904 #endif 00905 00906 00907 /* 00908 * 00909 * CVS/RCS Log: 00910 * $Log: dvcache.h,v $ 00911 * Revision 1.20 2010-10-14 13:16:35 joergr 00912 * Updated copyright header. Added reference to COPYRIGHT file. 00913 * 00914 * Revision 1.19 2010-10-07 14:31:35 joergr 00915 * Removed leading underscore characters from preprocessor symbols (reserved). 00916 * 00917 * Revision 1.18 2009-09-07 12:51:40 joergr 00918 * Converted Windows line breaks to Unix format. 00919 * 00920 * Revision 1.17 2009-09-04 13:53:09 meichel 00921 * Minor const iterator related changes needed to compile with VC6 with HAVE_STL 00922 * 00923 * Revision 1.16 2005-12-08 16:03:30 meichel 00924 * Changed include path schema for all DCMTK header files 00925 * 00926 * Revision 1.15 2005/04/04 10:11:57 meichel 00927 * Module dcmpstat now uses the dcmqrdb API instead of imagectn for maintaining 00928 * the index database 00929 * 00930 * Revision 1.14 2001/06/01 15:50:11 meichel 00931 * Updated copyright header 00932 * 00933 * Revision 1.13 2000/10/16 11:39:10 joergr 00934 * Added method allowing to select an instance by instance UID and SOP class 00935 * UID (without series and study UID). Required for composite references in 00936 * DICOM SR. 00937 * 00938 * Revision 1.12 2000/06/30 09:08:39 joergr 00939 * Fixed bug in database cache routines (re. study status). 00940 * 00941 * Revision 1.11 2000/05/30 13:37:15 joergr 00942 * Renamed GrayscaleHardcopy to HardcopyGrayscale (which is the correct term 00943 * according to the DICOM standard). 00944 * 00945 * Revision 1.10 2000/03/08 16:28:47 meichel 00946 * Updated copyright header. 00947 * 00948 * Revision 1.9 1999/09/08 17:03:00 joergr 00949 * Added support for new instance types in database (grayscale hardcopy and 00950 * stored print). 00951 * 00952 * Revision 1.8 1999/08/17 10:32:54 joergr 00953 * Added Doc++ styled comments. 00954 * Corrected wrong return type for method 'getImageSize()'. 00955 * 00956 * Revision 1.7 1999/05/03 11:01:08 joergr 00957 * Minor code purifications to keep Sun CC 2.0.1 quiet. 00958 * 00959 * Revision 1.6 1999/04/29 15:25:36 joergr 00960 * Added PresentationLabel to index file. 00961 * 00962 * Revision 1.5 1999/04/27 11:20:49 joergr 00963 * Add remaining member variables to member initialization list to avoid 00964 * compiler warnings. 00965 * 00966 * Revision 1.4 1999/02/24 20:14:39 joergr 00967 * Added support for presentation state caching (e.g. pstate description). 00968 * Removed unused methods. 00969 * 00970 * Revision 1.3 1999/02/19 18:56:08 joergr 00971 * Added new methods to interate through Caches (getFirst/getNext) - needed 00972 * for delete routines in Interface class. 00973 * 00974 * Revision 1.2 1999/02/19 09:45:19 joergr 00975 * Changed some comments, corrected typos and formatting. 00976 * 00977 * Revision 1.1 1999/02/18 18:50:18 joergr 00978 * Re-implemented methods to access index file (delete methods are still 00979 * missing). 00980 * 00981 * 00982 */