Orfeo Toolbox  3.16
itkExceptionObject.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkExceptionObject.cxx,v $
5  Language: C++
6  Date: $Date: 2009-09-21 13:33:11 $
7  Version: $Revision: 1.18 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #include "itkExceptionObject.h"
18 #include "itkLightObject.h"
19 #include "itkIndent.h"
20 
21 #include <string>
22 
23 namespace itk
24 {
25 
33 {
34 protected:
35  // Constructor. Might throw an exception.
37  const std::string& file, unsigned int line,
38  const std::string& description,
39  const std::string& location)
40  :
41  m_Location(location),
42  m_Description(description),
43  m_File(file),
44  m_Line(line)
45  {
46  OStringStream loc;
47  loc << ":" << m_Line << ":\n";
48  m_What = m_File;
49  m_What += loc.str();
51  m_WhatPointer = m_What.c_str();
52  }
53 
54 private:
55  void operator=(const ExceptionData&); //purposely not implemented
56 
57  friend class ExceptionObject;
58 
59  // The data members should never change after construction of the ExceptionData object,
60  // to ensure the consistency of the exception data.
61  const std::string m_Location;
62  const std::string m_Description;
63  const std::string m_File;
64  const unsigned int m_Line;
65  std::string m_What;
66  const char * m_WhatPointer;
67 };
68 
69 
81 {
82 public:
86  const std::string& file, unsigned int line,
87  const std::string& description,
88  const std::string& location)
89  {
90  ConstPointer smartPtr;
91  const Self *const rawPtr = new Self(file, line, description, location);
92  smartPtr = rawPtr;
93  rawPtr->LightObject::UnRegister();
94  return smartPtr;
95  }
96 
99  virtual void Register() const
100  {
101  this->LightObject::Register();
102  }
103 
106  virtual void UnRegister() const
107  {
108  this->LightObject::UnRegister();
109  }
110 
111 private:
112  // Constructor. Might throw an exception.
114  const std::string& file, unsigned int line,
115  const std::string& description,
116  const std::string& location)
117  :
118  ExceptionData(file, line, description, location),
119  LightObject()
120  {
121  }
122 
123  // Destructor. Only invoked via LightObject::UnRegister(), when its reference count drops to zero.
125  {
126  }
127 
128  ReferenceCountedExceptionData(const Self&); //purposely not implemented
129  void operator=(const Self&); //purposely not implemented
130 };
131 
132 
134 {
135  // The default construction never throws an exception.
136 }
137 
139  const char *file,
140  unsigned int lineNumber,
141  const char *desc,
142  const char *loc)
143 :
144 m_ExceptionData( ReferenceCountedExceptionData::ConstNew(file == 0 ? "" : file, lineNumber, desc == 0 ? "" : desc, loc == 0 ? "" : loc) )
145 {
146 }
147 
149  const std::string& file,
150  unsigned int lineNumber,
151  const std::string& desc,
152  const std::string& loc)
153 :
154 m_ExceptionData( ReferenceCountedExceptionData::ConstNew(file, lineNumber, desc, loc) )
155 {
156 }
157 
159 :
160 Superclass(orig),
161 m_ExceptionData(orig.m_ExceptionData)
162 {
163  // This copy construction never throws, because it just copies the smart pointer.
164 }
165 
166 
168 {
169  // During destruction, the reference count of the ReferenceCountedExceptionData will be decreased
170  // automatically, by the destructor of the smart pointer.
171 }
172 
175 {
176  // Note: dynamic_cast does a runtime check if the m_ExceptionData pointer is indeed
177  // pointing to an ExceptionData object. In this case, a static_cast could have been
178  // used instead, which only does compile time checking. But we expect the
179  // runtime overhead of this particular dynamic_cast to be insignificant.
180  const ExceptionData * thisData =
181  dynamic_cast< const ExceptionData *>( this->m_ExceptionData.GetPointer() );
182  return thisData;
183 }
184 
187 {
188  // Note: there is no superclass assignment here, because std::exception::operator=
189  // appears have a bug on some platforms, including MSVC 2003. The MSVC 2003 bug is
190  // described at the Usenet newsgroup microsoft.public.vc.language, June 2, 2008,
191  // subject "VC7.1 std::exception assignment operator bug (crash) a known issue?"
192  // http://groups.google.com/group/microsoft.public.vc.language/msg/15b927c8c1130e88
193 
194  // Assigns its smart pointer:
196  return *this;
197 }
198 
199 bool
201 {
202  // operator== is reimplemented, but it still behaves like the previous version, from ITK 3.6.0.
203  const ExceptionData *const thisData = this->GetExceptionData();
204  const ExceptionData *const origData = orig.GetExceptionData();
205 
206  if ( thisData == origData )
207  {
208  return true;
209  }
210  else
211  {
212  return (thisData != 0) && (origData != 0) &&
213  thisData->m_Location == origData->m_Location &&
214  thisData->m_Description == origData->m_Description &&
215  thisData->m_File == origData->m_File &&
216  thisData->m_Line == origData->m_Line;
217  }
218 }
219 
220 void
221 ExceptionObject::SetLocation(const std::string& s)
222 {
223  const bool IsNull = m_ExceptionData.IsNull();
225  IsNull ? "" : this->GetExceptionData()->m_File.c_str(),
226  IsNull ? 0 : this->GetExceptionData()->m_Line,
227  IsNull ? "" : this->GetExceptionData()->m_Description.c_str(),
228  s);
229 }
230 
231 void
232 ExceptionObject::SetDescription(const std::string& s)
233 {
234  const bool IsNull = m_ExceptionData.IsNull();
236  IsNull ? "" : this->GetExceptionData()->m_File.c_str(),
237  IsNull ? 0 : this->GetExceptionData()->m_Line,
238  s,
239  IsNull ? "" : this->GetExceptionData()->m_Location.c_str());
240 }
241 
242 void
244 {
245  std::string location;
246  if( s )
247  {
248  location = s;
249  }
250  ExceptionObject::SetLocation( location );
251 }
252 
253 void
255 {
256  std::string description;
257  if( s )
258  {
259  description = s;
260  }
261  ExceptionObject::SetDescription( description );
262 }
263 
264 const char *
266 {
267  // Note: std::string::c_str() might throw an exception.
268  return m_ExceptionData.IsNull() ? "" : this->GetExceptionData()->m_Location.c_str();
269 }
270 
271 const char *
273 {
274  // Note: std::string::c_str() might throw an exception.
275  return m_ExceptionData.IsNull() ? "" : this->GetExceptionData()->m_Description.c_str();
276 }
277 
278 const char *
280 {
281  // Note: std::string::c_str() might throw an exception.
282  return m_ExceptionData.IsNull() ? "" : this->GetExceptionData()->m_File.c_str();
283 }
284 
285 unsigned int
287 {
288  return m_ExceptionData.IsNull() ? 0 : this->GetExceptionData()->m_Line;
289 }
290 
291 const char *
292 ExceptionObject::what() const throw()
293 {
294  const ExceptionData * const thisData = this->GetExceptionData();
295 
296  // Note: m_What.c_str() wouldn't be safe, because c_str() might throw an exception.
297  return thisData ? thisData->m_WhatPointer : "ExceptionObject";
298 }
299 
300 void
302 ::Print(std::ostream& os) const
303 {
304  Indent indent;
305 
306  // Print header
307  os << std::endl;
308  os << indent << "itk::" << this->GetNameOfClass() << " (" << this << ")\n";
309 
310  // Print self
311  indent.GetNextIndent();
312 
313  if (m_ExceptionData.IsNotNull())
314  {
315  const ExceptionData & data = *(this->GetExceptionData());
316 
317  if (! data.m_Location.empty())
318  {
319  os << indent << "Location: \"" << data.m_Location << "\" " << std::endl;
320  }
321 
322  if (! data.m_File.empty())
323  {
324  os << indent << "File: " << data.m_File << std::endl;
325  os << indent << "Line: " << data.m_Line << std::endl;
326  }
327 
328  if (! data.m_Description.empty())
329  {
330  os << indent << "Description: " << data.m_Description << std::endl;
331  }
332  }
333  // Print trailer
334  os << indent << std::endl;
335 }
336 
337 } // end namespace itk

Generated at Sat Feb 2 2013 23:36:04 for Orfeo Toolbox with doxygen 1.8.1.1