]> Creatis software - gdcm.git/blob - src/gdcmDictSet.cxx
5993675bced31b532f20c4d800dffc684d1335f6
[gdcm.git] / src / gdcmDictSet.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDictSet.cxx,v $
5   Language:  C++
6   Date:      $Date: 2004/10/18 02:31:58 $
7   Version:   $Revision: 1.40 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18
19 #include "gdcmDictSet.h"
20 #include "gdcmDebug.h"
21 #include <fstream>
22 #include <stdlib.h>  // For getenv
23
24 namespace gdcm 
25 {
26
27 //-----------------------------------------------------------------------------
28 // Constructor / Destructor
29 /** 
30  * \ingroup DictSet
31  * \brief   The Dictionnary Set obtained with this constructor simply
32  *          contains the Default Public dictionnary.
33  */
34 DictSet::DictSet() 
35 {
36    DictPath = BuildDictPath();
37    std::string pubDictFile(DictPath);
38    pubDictFile += PUB_DICT_FILENAME;
39    Dicts[PUB_DICT_NAME] = new Dict(pubDictFile);
40 }
41
42 /**
43  * \ingroup DictSet
44  * \brief  Destructor 
45  */
46 DictSet::~DictSet() 
47 {
48    // Remove dictionnaries
49    for (DictSetHT::iterator tag = Dicts.begin(); tag != Dicts.end(); ++tag) 
50    {
51       Dict *entryToDelete = tag->second;
52       if ( entryToDelete )
53       {
54          delete entryToDelete;
55       }
56       tag->second = NULL;
57    }
58    Dicts.clear();
59
60    // Remove virtual dictionnary entries
61    std::map<std::string,DictEntry *>::iterator it;
62    for(it = VirtualEntry.begin(); it != VirtualEntry.end(); ++it)
63    {
64       DictEntry *entry = it->second;
65       if ( entry )
66       {
67          delete entry;
68       }
69       it->second = NULL;
70    }
71 }
72
73 //-----------------------------------------------------------------------------
74 // Print
75 /**
76  * \ingroup DictSet
77  * \brief   Print, in an informal fashion, the list of all the dictionaries
78  *          contained is this DictSet, along with their respective content.
79  * @param   os Output stream used for printing.
80  */
81 void DictSet::Print(std::ostream& os) 
82 {
83    for (DictSetHT::iterator dict = Dicts.begin(); dict != Dicts.end(); ++dict)
84    {
85       os << "Printing dictionary " << dict->first << std::endl;
86       dict->second->Print(os);
87    }
88 }
89
90 //-----------------------------------------------------------------------------
91 // Public
92 /** 
93  * \ingroup DictSet
94  * \brief   Consider all the entries of the public dicom dictionnary. 
95  *          Build all list of all the tag names of all those entries.
96  * \sa DictSet::GetPubDictTagNamesByCategory
97  * @return  A list of all entries of the public dicom dictionnary.
98  */
99 EntryNamesList * DictSet::GetPubDictEntryNames() 
100 {
101    return GetDefaultPubDict()->GetDictEntryNames();
102 }
103
104 /** 
105  * \ingroup DictSet
106  * \brief   
107  *          - Consider all the entries of the public dicom dictionnary.
108  *          - Build an hashtable whose keys are the names of the groups
109  *           (fourth field in each line of dictionary) and whose corresponding
110  *           values are lists of all the dictionnary entries among that
111  *           group. Note that apparently the Dicom standard doesn't explicitely
112  *           define a name (as a string) for each group.
113  *          - A typical usage of this method would be to enable a dynamic
114  *           configuration of a Dicom file browser: the admin/user can
115  *           select in the interface which Dicom tags should be displayed.
116  * \warning 
117  *          - Dicom *doesn't* define any name for any 'categorie'
118  *          (the dictionnary fourth field was formerly NIH defined
119  *           -and no longer he is-
120  *           and will be removed when Dicom provides us a text file
121  *           with the 'official' Dictionnary, that would be more friendly
122  *           than asking us to perform a line by line check of the dictionnary
123  *           at the beginning of each year to -try to- guess the changes)
124  *          - Therefore : please NEVER use that fourth field :-(
125  * *
126  * @return  An hashtable: whose keys are the names of the groups and whose
127  *          corresponding values are lists of all the dictionnary entries
128  *          among that group.
129  */
130 EntryNamesByCatMap * DictSet::GetPubDictEntryNamesByCategory() 
131 {
132    return GetDefaultPubDict()->GetDictEntryNamesByCategory();
133 }
134
135 /**
136  * \ingroup DictSet
137  * \brief   Loads a dictionary from a specified file, and add it
138  *          to already the existing ones contained in this DictSet.
139  * @param   fileName Absolute or relative filename containing the
140  *          dictionary to load.
141  * @param   name Symbolic name that be used as identifier of the newly 
142  *          created dictionary.
143  */
144 Dict *DictSet::LoadDictFromFile(std::string const & filename, 
145                                 DictKey const & name) 
146 {
147    Dict *newDict = new Dict(filename);
148    AppendDict(newDict, name);
149
150    return newDict;
151 }
152
153 /**
154  * \ingroup DictSet
155  * \brief   Retrieve the specified dictionary (when existing) from this
156  *          DictSet.
157  * @param   dictName The symbolic name of the searched dictionary.
158  * \result  The retrieved dictionary.
159  */
160 Dict *DictSet::GetDict(DictKey const & dictName) 
161 {
162    DictSetHT::iterator dict = Dicts.find(dictName);
163    if(dict != Dicts.end())
164    {
165       return dict->second;
166    }
167    return NULL;
168 }
169
170 /**
171  * \brief   Create a DictEntry which will be reference 
172  *          in no dictionnary
173  * @return  virtual entry
174  */
175 DictEntry *DictSet::NewVirtualDictEntry( uint16_t group,
176                                          uint16_t element,
177                                          TagName vr,
178                                          TagName fourth,
179                                          TagName name)
180 {
181    DictEntry* entry;
182    const std::string tag = DictEntry::TranslateToKey(group,element)
183                            + "#" + vr + "#" + fourth + "#" + name;
184    std::map<std::string,DictEntry *>::iterator it;
185    
186    it = VirtualEntry.find(tag);
187    if(it != VirtualEntry.end())
188    {
189       entry = it->second;
190    }
191    else
192    {
193       entry = new DictEntry(group, element, vr, fourth, name);
194       VirtualEntry[tag] = entry;
195    }
196
197    return entry;
198 }
199
200 /**
201  * \brief   Obtain from the GDCM_DICT_PATH environnement variable the
202  *          path to directory containing the dictionnaries. When
203  *          the environnement variable is absent the path is defaulted
204  *          to "../Dicts/".
205  * @return  path to directory containing the dictionnaries
206  */
207 std::string DictSet::BuildDictPath() 
208 {
209    std::string resultPath;
210    const char *envPath = 0;
211    envPath = getenv("GDCM_DICT_PATH");
212
213    if (envPath && (strlen(envPath) != 0)) 
214    {
215       resultPath = envPath;
216       if ( resultPath[resultPath.length()-1] != '/' )
217       {
218          resultPath += '/';
219       }
220       dbg.Verbose(1, "DictSet::BuildDictPath:",
221                      "Dictionary path set from environnement");
222    } 
223    else
224    {
225       resultPath = PUB_DICT_PATH;
226    }
227
228    return resultPath;
229 }
230
231 //-----------------------------------------------------------------------------
232 // Protected
233 bool DictSet::AppendDict(Dict *newDict, DictKey const & name)
234 {
235    Dicts[name] = newDict;
236
237    return true;   //FIXME
238 }
239
240 //-----------------------------------------------------------------------------
241 // Private
242
243 //-----------------------------------------------------------------------------
244
245 } // end namespace gdcm