0029935: Foundation Classes - introduce OSD_ThreadPool class defining a thread pool
[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 //                           Standard_Failure                       *
63 // ******************************************************************
64 static Standard_THREADLOCAL Handle(Standard_Failure) RaisedError;
65
66 // ------------------------------------------------------------------
67 //
68 // ------------------------------------------------------------------
69 Standard_Failure::Standard_Failure ()
70 : myMessage(NULL) 
71 {
72 }
73
74 // ------------------------------------------------------------------
75 // Create returns mutable Failure;
76 // ------------------------------------------------------------------
77 Standard_Failure::Standard_Failure (const Standard_CString AString) 
78 :  myMessage(NULL)
79 {
80   myMessage = allocate_message(AString);
81 }
82
83 Standard_Failure::Standard_Failure (const Standard_Failure& theFailure) 
84 : Standard_Transient(theFailure)
85 {
86   myMessage = copy_message(theFailure.myMessage);
87 }
88
89 Standard_Failure::~Standard_Failure()
90 {
91   deallocate_message(myMessage);
92 }
93
94 void Standard_Failure::SetMessageString(const Standard_CString AString)
95 {
96   if ( AString == GetMessageString() ) return;
97   deallocate_message(myMessage);
98   myMessage = allocate_message(AString);
99 }
100
101 // ------------------------------------------------------------------
102 // Caught (myclass) returns mutable Failure raises NoSuchObject ;
103 // ------------------------------------------------------------------
104 Handle(Standard_Failure) Standard_Failure::Caught() 
105 {
106   return RaisedError ;
107 }
108
109 // ------------------------------------------------------------------
110 // Raise (myclass; aMessage: CString = "") ;
111 // ------------------------------------------------------------------
112 void Standard_Failure::Raise (const Standard_CString AString) 
113
114   Handle(Standard_Failure) E = new Standard_Failure()  ;
115   E->Reraise (AString) ;
116 }
117
118 // ------------------------------------------------------------------
119 // Raise(myclass; aReason: in out SStream) ;
120 // ------------------------------------------------------------------
121 void Standard_Failure::Raise (const Standard_SStream& AReason) 
122
123   Handle(Standard_Failure) E = new Standard_Failure();
124   E->Reraise (AReason);
125 }
126
127 // ------------------------------------------------------------------
128 // Reraise (me: mutable; aMessage: CString) ;
129 // ------------------------------------------------------------------
130 void Standard_Failure::Reraise (const Standard_CString AString) 
131 {
132   SetMessageString(AString);
133   Reraise();
134 }
135
136 void Standard_Failure::Reraise (const Standard_SStream& AReason) 
137 {
138   SetMessageString(AReason.str().c_str());
139   Reraise();
140 }
141
142 void Standard_Failure::Reraise () 
143 {
144   RaisedError = this;
145   Throw();
146 }
147
148 void Standard_Failure::Jump()
149 {
150 #if defined (OCC_CONVERT_SIGNALS)
151   Standard_ErrorHandler::Error (this);
152   Standard_ErrorHandler::Abort (this);
153 #else
154   RaisedError = this;
155   Throw();
156 #endif
157 }
158
159
160 // ------------------------------------------------------------------
161 // Throw (me) is virtual ;
162 // ------------------------------------------------------------------
163 void Standard_Failure::Throw() const
164 {
165   throw *this;
166 }
167
168 // ------------------------------------------------------------------
169 // Print (me; s: in out OStream) returns OStream;
170 // ------------------------------------------------------------------
171 void Standard_Failure::Print (Standard_OStream& AStream) const
172 {
173 if(myMessage){ 
174     AStream << DynamicType() << ": " << GetMessageString(); 
175  } 
176  else { 
177     AStream << DynamicType();
178  }
179 }
180
181 Handle(Standard_Failure) Standard_Failure::NewInstance(const Standard_CString AString)
182 {
183   return new Standard_Failure(AString)  ;
184 }
185
186 //=======================================================================
187 //function : GetMessageString
188 //purpose  : Returns error message
189 //=======================================================================
190 Standard_CString Standard_Failure::GetMessageString () const
191 {
192   return (myMessage ? myMessage+sizeof(Standard_Integer) : "");
193 }
194