]> Creatis software - gdcm.git/blob - gdcmValEntry.cxx
671e6bd381f4d198301f51dfb4aae666beb25add
[gdcm.git] / gdcmValEntry.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmValEntry.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/07/05 14:55:24 $
7   Version:   $Revision: 1.63 $
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 "gdcmValEntry.h"
20 #include "gdcmVR.h"
21 #include "gdcmTS.h"
22 #include "gdcmGlobal.h"
23 #include "gdcmUtil.h"
24 #include "gdcmDebug.h"
25 #include "gdcmDocument.h"
26
27 #include <fstream>
28 #include <ctype.h>  // for isdigit
29 #include <stdlib.h> // for atoi
30
31 namespace gdcm 
32 {
33 //-----------------------------------------------------------------------------
34 #define MAX_SIZE_PRINT_ELEMENT_VALUE 0x7fffffff
35 uint32_t ValEntry::MaxSizePrintEntry = MAX_SIZE_PRINT_ELEMENT_VALUE;
36 //-----------------------------------------------------------------------------
37 // Constructor / Destructor
38 /**
39  * \brief   Constructor from a given DictEntry
40  * @param   e Pointer to existing dictionary entry
41  */
42 ValEntry::ValEntry(DictEntry *e) 
43         : ContentEntry(e)
44 {
45 }
46
47 /**
48  * \brief   Constructor from a given DocEntry
49  * @param   e Pointer to existing Doc entry
50  */
51 ValEntry::ValEntry(DocEntry *e)
52         : ContentEntry(e->GetDictEntry())
53 {
54    Copy(e);
55 }
56
57 /**
58  * \brief   Canonical destructor.
59  */
60 ValEntry::~ValEntry ()
61 {
62 }
63
64 //-----------------------------------------------------------------------------
65 // Public
66 /**
67  * \brief   Writes the std::string representable' value of a ValEntry
68  * @param fp already open ofstream pointer
69  * @param filetype type of the file (ACR, ImplicitVR, ExplicitVR, ...)
70  */
71 void ValEntry::WriteContent(std::ofstream *fp, FileType filetype)
72 {
73    DocEntry::WriteContent(fp, filetype);
74
75    if ( GetGroup() == 0xfffe )
76    {
77       return; //delimitors have NO value
78    }
79
80    const VRKey &vr = GetVR();
81    unsigned int lgth = GetLength();
82    if (vr == "US" || vr == "SS")
83    {
84       // some 'Short integer' fields may be multivaluated
85       // each single value is separated from the next one by '\'
86       // we split the string and write each value as a short int
87       std::vector<std::string> tokens;
88       tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
89       Util::Tokenize (GetValue(), tokens, "\\");
90       for (unsigned int i=0; i<tokens.size();i++)
91       {
92          uint16_t val_uint16 = atoi(tokens[i].c_str());
93          binary_write( *fp, val_uint16);
94       }
95       tokens.clear();
96       return;
97    }
98    if (vr == "UL" || vr == "SL")
99    {
100       // Some 'Integer' fields may be multivaluated (multiple instances 
101       // of integer). But each single integer value is separated from the
102       // next one by '\' (backslash character). Hence we split the string
103       // along the '\' and write each value as an int:
104       std::vector<std::string> tokens;
105       tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
106       Util::Tokenize (GetValue(), tokens, "\\");
107       for (unsigned int i=0; i<tokens.size();i++)
108       {
109          uint32_t val_uint32 = atoi(tokens[i].c_str());
110          binary_write( *fp, val_uint32);
111       }
112       tokens.clear();
113       return;
114    } 
115
116    gdcmAssertMacro( lgth == GetValue().length() );
117    binary_write(*fp, GetValue());
118
119
120
121 /**
122  * \brief Header Elements too long will not be printed
123  * @param newSize new size
124  */ 
125 void ValEntry::SetMaxSizePrintEntry(long newSize) 
126 {
127    if ( newSize < 0 )
128    {
129       return;
130    }
131    if ((uint32_t)newSize >= (uint32_t)0xffffffff )
132    {
133       ValEntry::MaxSizePrintEntry = 0xffffffff;
134       return;
135    }
136    ValEntry::MaxSizePrintEntry = newSize;
137 }
138
139
140 /**
141  * \brief   Sets the std::string representable' value of a ValEntry
142  * @param  val value to set 
143  */
144 void ValEntry::SetValue(std::string const &val)
145 {
146    // Integers have a special treatement for their length:
147    int l = val.length();
148    if ( l != 0) // To avoid to be cheated by 'zero length' integers
149    {   
150       const VRKey &vr = GetVR();
151       if ( vr == "US" || vr == "SS" )
152       {
153          // for multivaluated items
154          l = (Util::CountSubstring(val, "\\") + 1) * 2;
155          ContentEntry::SetValue(val);
156       }
157       else if ( vr == "UL" || vr == "SL" )
158       {
159          // for multivaluated items
160          l = (Util::CountSubstring(val, "\\") + 1) * 4;;
161          ContentEntry::SetValue(val);
162       }
163       else
164       {
165          std::string finalVal = Util::DicomString( val.c_str() );
166          gdcmAssertMacro( !(finalVal.size() % 2) );
167
168          l = finalVal.length();
169          ContentEntry::SetValue(finalVal);
170       }
171    }
172    else
173    {
174       std::string finalVal = Util::DicomString( val.c_str() );
175       gdcmAssertMacro( !(finalVal.size() % 2) );
176
177       l = finalVal.length();
178       ContentEntry::SetValue(finalVal);
179    }
180
181    SetLength(l);
182 }
183
184 //-----------------------------------------------------------------------------
185 // Protected
186
187 //-----------------------------------------------------------------------------
188 // Private
189
190 //-----------------------------------------------------------------------------
191 // Print
192 /**
193  * \brief   Prints the 'std::string representable' value of ValEntry
194  * @param   os ostream we want to print in
195  * @param indent Indentation string to be prepended during printing
196  */
197 void ValEntry::Print(std::ostream &os, std::string const &)
198 {
199    uint16_t g = GetGroup();
200    uint16_t e = GetElement();
201    VRKey vr   = GetVR();
202    std::ostringstream s; 
203    std::string st;
204    std::string d2;
205      
206    os << "V ";
207    DocEntry::Print(os); 
208
209    if (g == 0xfffe) // delimiters have NO value
210    {
211       // just to avoid identing all the remaining code     
212       return;
213    }
214    
215    TS *ts = Global::GetTS();
216     
217    TSAtr v  = GetValue();     
218    d2 = Util::CreateCleanString(v);  // replace non printable characters by '.'            
219    if ( (long)GetLength() <= ValEntry::GetMaxSizePrintEntry()
220     || PrintLevel >= 3
221     || d2.find(GDCM_NOTLOADED) < d2.length() )
222    {
223       s << " [" << d2 << "]";
224    }
225    else
226    {
227       s << " [gdcm::too long for print (" << GetLength() << ") ]";
228    }
229    
230    // Display the UID value (instead of displaying only the rough code)
231    // First 'clean' trailing character (space or zero) 
232    if (g == 0x0002)
233    {
234       // Any more to be displayed ?
235       if ( e == 0x0010 || e == 0x0002 )
236       {
237          if ( v.length() != 0 )  // for brain damaged headers
238          {
239             if ( ! isdigit((unsigned char)v[v.length()-1]) )
240             {
241                v.erase(v.length()-1, 1);
242             }
243          }
244          s << "  ==>\t[" << ts->GetValue(v) << "]";
245       }
246    }
247    else
248    {
249       if (g == 0x0008)
250       {
251          if ( e == 0x0016 || e == 0x1150 )
252          {
253             if ( v.length() != 0 )  // for brain damaged headers
254             {
255                if ( ! isdigit((unsigned char)v[v.length()-1]) )
256                {
257                   v.erase(v.length()-1, 1);
258                }
259             }
260             s << "  ==>\t[" << ts->GetValue(v) << "]";
261          }
262       }
263       else
264       {
265          if (g == 0x0004)
266          {
267             if ( e == 0x1510 || e == 0x1512  )
268             {
269                if ( v.length() != 0 )  // for brain damaged headers  
270                {
271                   if ( ! isdigit((unsigned char)v[v.length()-1]) )
272                   {
273                      v.erase(v.length()-1, 1);  
274                   }
275                }
276               s << "  ==>\t[" << ts->GetValue(v) << "]";
277             }
278          }     
279       }
280    }
281    //if (e == 0x0000) {        // elem 0x0000 --> group length 
282    if ( vr == "UL" || vr == "US" || vr == "SL" || vr == "SS" )
283    {
284       if (v == "4294967295") // to avoid troubles in convertion 
285       {
286          st = "ffffffff";
287       }
288       else
289       {
290          if ( GetLength() != 0 )
291          {
292             st = Util::Format(" x(%x)", atoi(v.c_str()));//FIXME
293          }
294          else
295          {
296             st = " ";
297          }
298       }
299       s << st;
300    }
301    os << s.str();
302 }
303
304 //-----------------------------------------------------------------------------
305 } // end namespace gdcm
306