07ecbcc4e1116c69159e1d26e0f98110e7537da0
[occt.git] / src / Standard / Standard_Failure.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <Standard_ErrorHandler.hxx>
17 #include <Standard_Failure.hxx>
18 #include <Standard_Macro.hxx>
19 #include <Standard_NoSuchObject.hxx>
20 #include <Standard_PCharacter.hxx>
21 #include <Standard_Type.hxx>
22 #include <Standard_TypeMismatch.hxx>
23
24 #include <string.h>
25 IMPLEMENT_STANDARD_RTTIEXT(Standard_Failure,Standard_Transient)
26
27 static Standard_CString allocate_message(const Standard_CString AString)
28 {
29   Standard_CString aStr = 0;
30   if(AString) {
31     const Standard_Size aLen = strlen(AString);
32     aStr = (Standard_CString) malloc(aLen+sizeof(Standard_Integer)+1);
33     if (aStr) {
34       Standard_PCharacter pStr=(Standard_PCharacter)aStr;
35       strcpy(pStr+sizeof(Standard_Integer),AString);
36       *((Standard_Integer*)aStr) = 1;
37     }
38   }
39   return aStr;
40 }
41
42 static Standard_CString copy_message(Standard_CString aMessage)
43 {
44   Standard_CString aStr = 0;
45   if(aMessage) {
46     aStr = aMessage;
47     (*((Standard_Integer*)aStr))++;
48   }
49   return aStr;
50 }
51
52 static void deallocate_message(Standard_CString aMessage)
53 {
54   if(aMessage) {
55     (*((Standard_Integer*)aMessage))--;
56     if(*((Standard_Integer*)aMessage)==0)
57       free((void*)aMessage);
58   }
59 }
60
61
62 // ******************************************************************
63 //                           Standard_Failure                       *
64 // ******************************************************************
65 #ifndef NO_CXX_EXCEPTION
66 static Handle(Standard_Failure) RaisedError;
67 #endif
68 // ------------------------------------------------------------------
69 //
70 // ------------------------------------------------------------------
71 Standard_Failure::Standard_Failure ()
72 : myMessage(NULL) 
73 {
74 }
75
76 // ------------------------------------------------------------------
77 // Create returns mutable Failure;
78 // ------------------------------------------------------------------
79 Standard_Failure::Standard_Failure (const Standard_CString AString) 
80 :  myMessage(NULL)
81 {
82   myMessage = allocate_message(AString);
83 }
84
85 Standard_Failure::Standard_Failure (const Standard_Failure& theFailure) 
86 : Standard_Transient(theFailure)
87 {
88   myMessage = copy_message(theFailure.myMessage);
89 }
90
91 Standard_Failure::~Standard_Failure()
92 {
93   deallocate_message(myMessage);
94 }
95
96 void Standard_Failure::SetMessageString(const Standard_CString AString)
97 {
98   if ( AString == GetMessageString() ) return;
99   deallocate_message(myMessage);
100   myMessage = allocate_message(AString);
101 }
102
103 // ------------------------------------------------------------------
104 // Caught (myclass) returns mutable Failure raises NoSuchObject ;
105 // ------------------------------------------------------------------
106 Handle(Standard_Failure) Standard_Failure::Caught() 
107 {
108 #ifdef NO_CXX_EXCEPTION
109   return Standard_ErrorHandler::LastCaughtError();
110 #else
111   return RaisedError ;
112 #endif
113 }
114
115 // ------------------------------------------------------------------
116 // Raise (myclass; aMessage: CString = "") ;
117 // ------------------------------------------------------------------
118 void Standard_Failure::Raise (const Standard_CString AString) 
119
120   Handle(Standard_Failure) E = new Standard_Failure()  ;
121   E->Reraise (AString) ;
122 }
123
124 // ------------------------------------------------------------------
125 // Raise(myclass; aReason: in out SStream) ;
126 // ------------------------------------------------------------------
127 void Standard_Failure::Raise (const Standard_SStream& AReason) 
128
129   Handle(Standard_Failure) E = new Standard_Failure();
130   E->Reraise (AReason);
131 }
132
133 // ------------------------------------------------------------------
134 // Reraise (me: mutable; aMessage: CString) ;
135 // ------------------------------------------------------------------
136 void Standard_Failure::Reraise (const Standard_CString AString) 
137 {
138   SetMessageString(AString);
139   Reraise();
140 }
141
142 void Standard_Failure::Reraise (const Standard_SStream& AReason) 
143 {
144   SetMessageString(AReason.str().c_str());
145   Reraise();
146 }
147
148 void Standard_Failure::Reraise () 
149 {
150 #ifdef NO_CXX_EXCEPTION
151   Standard_ErrorHandler::Error (this);
152   Standard_ErrorHandler::Abort (this);
153 #else
154   RaisedError = this;
155   Throw();
156 #endif
157 }
158
159 void Standard_Failure::Jump()
160 {
161 #if defined (NO_CXX_EXCEPTION) || defined (OCC_CONVERT_SIGNALS)
162   Standard_ErrorHandler::Error (this);
163   Standard_ErrorHandler::Abort (this);
164 #else
165   RaisedError = this;
166   Throw();
167 #endif
168 }
169
170
171 // ------------------------------------------------------------------
172 // Throw (me) is virtual ;
173 // ------------------------------------------------------------------
174 void Standard_Failure::Throw() const
175 {
176 #ifndef NO_CXX_EXCEPTION
177   throw *this;
178 #endif
179 }
180
181 // ------------------------------------------------------------------
182 // Print (me; s: in out OStream) returns OStream;
183 // ------------------------------------------------------------------
184 void Standard_Failure::Print (Standard_OStream& AStream) const
185 {
186 if(myMessage){ 
187     AStream << DynamicType() << ": " << GetMessageString(); 
188  } 
189  else { 
190     AStream << DynamicType();
191  }
192 }
193
194 Handle(Standard_Failure) Standard_Failure::NewInstance(const Standard_CString AString)
195 {
196   return new Standard_Failure(AString)  ;
197 }
198
199 //=======================================================================
200 //function : GetMessageString
201 //purpose  : Returns error message
202 //=======================================================================
203 Standard_CString Standard_Failure::GetMessageString () const
204 {
205   return (myMessage ? myMessage+sizeof(Standard_Integer) : "");
206 }
207