0022753: Fix mismatch new/delete in Standard_Failure.cxx
[occt.git] / src / Standard / Standard_Failure.cxx
1 // File:      Standard_Failure.cxx
2 // Copyright: Open Cascade 2006
3
4 #include <Standard_ErrorHandler.hxx>
5 #include <Standard_Failure.ixx>
6 #include <Standard_TypeMismatch.hxx>
7 #include <Standard_Type.hxx>
8 #include <Standard_Macro.hxx>
9 #include <string.h>
10 #include <Standard_PCharacter.hxx>
11
12 static Standard_CString allocate_message(const Standard_CString AString)
13 {
14   Standard_CString aStr = 0;
15   if(AString) {
16     const Standard_Size aLen = strlen(AString);
17     aStr = new Standard_Character[aLen+sizeof(Standard_Integer)+1];
18     Standard_PCharacter pStr=(Standard_PCharacter)aStr;
19     strcpy(pStr+sizeof(Standard_Integer),AString);
20     *((Standard_Integer*)aStr) = 1;
21   }
22   return aStr;
23
24 }
25
26 static Standard_CString copy_message(Standard_CString aMessage)
27 {
28   Standard_CString aStr = 0;
29   if(aMessage) {
30     aStr = aMessage;
31     (*((Standard_Integer*)aStr))++;
32   }
33   return aStr;
34 }
35
36 static void deallocate_message(Standard_CString aMessage)
37 {
38   if(aMessage) {
39     (*((Standard_Integer*)aMessage))--;
40     if(*((Standard_Integer*)aMessage)==0)
41       delete [](Standard_PCharacter)aMessage;
42   }
43 }
44
45
46 // ******************************************************************
47 //                           Standard_Failure                       *
48 // ******************************************************************
49 #ifndef NO_CXX_EXCEPTION
50 static Handle(Standard_Failure) RaisedError;
51 #endif
52 // ------------------------------------------------------------------
53 //
54 // ------------------------------------------------------------------
55 Standard_Failure::Standard_Failure ()
56 : myMessage(NULL) 
57 {
58 }
59
60 // ------------------------------------------------------------------
61 // Create returns mutable Failure;
62 // ------------------------------------------------------------------
63 Standard_Failure::Standard_Failure (const Standard_CString AString) 
64 :  myMessage(NULL)
65 {
66   myMessage = allocate_message(AString);
67 }
68
69 Standard_Failure::Standard_Failure (const Standard_Failure& aFailure) 
70 {
71   myMessage = copy_message(aFailure.myMessage);
72 }
73
74 void Standard_Failure::Destroy()
75 {
76   deallocate_message(myMessage);
77 }
78
79 void Standard_Failure::SetMessageString(const Standard_CString AString)
80 {
81   if ( AString == GetMessageString() ) return;
82   deallocate_message(myMessage);
83   myMessage = allocate_message(AString);
84 }
85
86 // ------------------------------------------------------------------
87 // Caught (myclass) returns mutable Failure raises NoSuchObject ;
88 // ------------------------------------------------------------------
89 Handle(Standard_Failure) Standard_Failure::Caught() 
90 {
91 #ifdef NO_CXX_EXCEPTION
92   return Standard_ErrorHandler::LastCaughtError();
93 #else
94   return RaisedError ;
95 #endif
96 }
97
98 // ------------------------------------------------------------------
99 // Raise (myclass; aMessage: CString = "") ;
100 // ------------------------------------------------------------------
101 void Standard_Failure::Raise (const Standard_CString AString) 
102
103   Handle(Standard_Failure) E = new Standard_Failure()  ;
104   E->Reraise (AString) ;
105 }
106
107 // ------------------------------------------------------------------
108 // Raise(myclass; aReason: in out SStream) ;
109 // ------------------------------------------------------------------
110 void Standard_Failure::Raise (const Standard_SStream& AReason) 
111
112   Handle(Standard_Failure) E = new Standard_Failure();
113   E->Reraise (AReason);
114 }
115
116 // ------------------------------------------------------------------
117 // Reraise (me: mutable; aMessage: CString) ;
118 // ------------------------------------------------------------------
119 void Standard_Failure::Reraise (const Standard_CString AString) 
120 {
121   SetMessageString(AString);
122   Reraise();
123 }
124
125 void Standard_Failure::Reraise (const Standard_SStream& AReason) 
126 {
127 #ifdef USE_STL_STREAM
128   SetMessageString(AReason.str().c_str());
129 #else
130   // Note: use dirty tricks -- unavoidable with old streams 
131   ((Standard_SStream&)AReason) << ends;
132   SetMessageString(((Standard_SStream&)AReason).str());
133   ((Standard_SStream&)AReason).freeze (false);
134 #endif
135   Reraise();
136 }
137
138 void Standard_Failure::Reraise () 
139 {
140 #ifdef NO_CXX_EXCEPTION
141   Standard_ErrorHandler::Error(this) ;
142   Standard_ErrorHandler::Abort();
143 #else
144   RaisedError = this;
145   Throw();
146 #endif
147 }
148
149 void Standard_Failure::Jump() const 
150 {
151 #if defined (NO_CXX_EXCEPTION) || defined (OCC_CONVERT_SIGNALS)
152   Standard_ErrorHandler::Error(this) ;
153   Standard_ErrorHandler::Abort();
154 #else
155   RaisedError = this;
156   Throw();
157 #endif
158 }
159
160
161 // ------------------------------------------------------------------
162 // Throw (me) is virtual ;
163 // ------------------------------------------------------------------
164 void Standard_Failure::Throw() const
165 {
166 #ifndef NO_CXX_EXCEPTION
167   throw *this;
168 #endif
169 }
170
171 // ------------------------------------------------------------------
172 // Print (me; s: in out OStream) returns OStream;
173 // ------------------------------------------------------------------
174 void Standard_Failure::Print (Standard_OStream& AStream) const
175 {
176 if(myMessage){ 
177     AStream << DynamicType() << ": " << GetMessageString(); 
178  } 
179  else { 
180     AStream << DynamicType();
181  }
182 }
183
184 Handle(Standard_Failure) Standard_Failure::NewInstance(const Standard_CString AString)
185 {
186   return new Standard_Failure(AString)  ;
187 }