]> Creatis software - gdcm.git/blob - src/gdcmDictSet.cxx
ENH: Adding 'gdcm' namespace. Be nice with me this was a ~13000 lines patch. Also...
[gdcm.git] / src / gdcmDictSet.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDictSet.cxx,v $
5   Language:  C++
6   Date:      $Date: 2004/10/12 04:35:45 $
7   Version:   $Revision: 1.38 $
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 namespace gdcm 
24 {
25
26 //-----------------------------------------------------------------------------
27 // Constructor / Destructor
28 /** 
29  * \ingroup DictSet
30  * \brief   The Dictionnary Set obtained with this constructor simply
31  *          contains the Default Public dictionnary.
32  */
33 DictSet::DictSet() 
34 {
35    DictPath = BuildDictPath();
36    std::string pubDictFile(DictPath);
37    pubDictFile += PUB_DICT_FILENAME;
38    Dicts[PUB_DICT_NAME] = new Dict(pubDictFile);
39 }
40
41 /**
42  * \ingroup DictSet
43  * \brief  Destructor 
44  */
45 DictSet::~DictSet() 
46 {
47    // Remove dictionnaries
48    for (DictSetHT::iterator tag = Dicts.begin(); tag != Dicts.end(); ++tag) 
49    {
50       Dict *entryToDelete = tag->second;
51       if ( entryToDelete )
52       {
53          delete entryToDelete;
54       }
55       tag->second = NULL;
56    }
57    Dicts.clear();
58
59    // Remove virtual dictionnary entries
60    std::map<std::string,DictEntry *>::iterator it;
61    for(it = VirtualEntry.begin(); it != VirtualEntry.end(); ++it)
62    {
63       DictEntry *entry = it->second;
64       if ( entry )
65       {
66          delete entry;
67       }
68       it->second = NULL;
69    }
70 }
71
72 //-----------------------------------------------------------------------------
73 // Print
74 /**
75  * \ingroup DictSet
76  * \brief   Print, in an informal fashion, the list of all the dictionaries
77  *          contained is this DictSet, along with their respective content.
78  * @param   os Output stream used for printing.
79  */
80 void DictSet::Print(std::ostream& os) 
81 {
82    for (DictSetHT::iterator dict = Dicts.begin(); dict != Dicts.end(); ++dict)
83    {
84       os << "Printing dictionary " << dict->first << std::endl;
85       dict->second->Print(os);
86    }
87 }
88
89 //-----------------------------------------------------------------------------
90 // Public
91 /** 
92  * \ingroup DictSet
93  * \brief   Consider all the entries of the public dicom dictionnary. 
94  *          Build all list of all the tag names of all those entries.
95  * \sa DictSet::GetPubDictTagNamesByCategory
96  * @return  A list of all entries of the public dicom dictionnary.
97  */
98 std::list<std::string> *DictSet::GetPubDictEntryNames() 
99 {
100    return GetDefaultPubDict()->GetDictEntryNames();
101 }
102
103 /** 
104  * \ingroup DictSet
105  * \brief   
106  *          - Consider all the entries of the public dicom dictionnary.
107  *          - Build an hashtable whose keys are the names of the groups
108  *           (fourth field in each line of dictionary) and whose corresponding
109  *           values are lists of all the dictionnary entries among that
110  *           group. Note that apparently the Dicom standard doesn't explicitely
111  *           define a name (as a string) for each group.
112  *          - A typical usage of this method would be to enable a dynamic
113  *           configuration of a Dicom file browser: the admin/user can
114  *           select in the interface which Dicom tags should be displayed.
115  * \warning 
116  *          - Dicom *doesn't* define any name for any 'categorie'
117  *          (the dictionnary fourth field was formerly NIH defined
118  *           -and no longer he is-
119  *           and will be removed when Dicom provides us a text file
120  *           with the 'official' Dictionnary, that would be more friendly
121  *           than asking us to perform a line by line check of the dictionnary
122  *           at the beginning of each year to -try to- guess the changes)
123  *          - Therefore : please NEVER use that fourth field :-(
124  * *
125  * @return  An hashtable: whose keys are the names of the groups and whose
126  *          corresponding values are lists of all the dictionnary entries
127  *          among that group.
128  */
129 std::map<std::string, std::list<std::string> > *
130    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                                                 std::string vr,
178                                                 std::string fourth,
179                                                 std::string 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