sl@0
|
1 |
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
// Name : stdcpp_support.cpp
|
sl@0
|
15 |
// Part of : standard c++ library.
|
sl@0
|
16 |
//
|
sl@0
|
17 |
//
|
sl@0
|
18 |
|
sl@0
|
19 |
#include <new>
|
sl@0
|
20 |
#include <stdcpp_support.h>
|
sl@0
|
21 |
#include <typeinfo>
|
sl@0
|
22 |
#include <string>
|
sl@0
|
23 |
#include <stdexcept>
|
sl@0
|
24 |
|
sl@0
|
25 |
|
sl@0
|
26 |
EXPORT_C void TranslateSymErrorToCppException(TInt aError)
|
sl@0
|
27 |
{
|
sl@0
|
28 |
switch(aError)
|
sl@0
|
29 |
{
|
sl@0
|
30 |
case KErrNoMemory:
|
sl@0
|
31 |
// This is about to use the emergency buffer!
|
sl@0
|
32 |
__THROW(std::bad_alloc());
|
sl@0
|
33 |
case KErrArgument:
|
sl@0
|
34 |
__THROW(std::invalid_argument("Invalid argument"));
|
sl@0
|
35 |
case KErrOverflow :
|
sl@0
|
36 |
__THROW(std::overflow_error("Overflow error"));
|
sl@0
|
37 |
case KErrUnderflow:
|
sl@0
|
38 |
__THROW(std::underflow_error("Underflow error"));
|
sl@0
|
39 |
default:
|
sl@0
|
40 |
__THROW(Symbian_error(KErrGeneral));
|
sl@0
|
41 |
}
|
sl@0
|
42 |
}
|
sl@0
|
43 |
|
sl@0
|
44 |
EXPORT_C TInt TranslateCppExceptionToSymError(const std::exception& aThrow)
|
sl@0
|
45 |
{
|
sl@0
|
46 |
#ifndef __GCCXML__
|
sl@0
|
47 |
const std::type_info& atype = typeid(aThrow);
|
sl@0
|
48 |
|
sl@0
|
49 |
if(atype == typeid (std::bad_alloc))
|
sl@0
|
50 |
return KErrNoMemory;
|
sl@0
|
51 |
else if(atype == typeid(std::invalid_argument))
|
sl@0
|
52 |
return KErrArgument;
|
sl@0
|
53 |
else if(atype == typeid(std::out_of_range))
|
sl@0
|
54 |
// std::out_of_range is of type logic_error which by definition means that it is
|
sl@0
|
55 |
// "presumably detectable before the program executes".
|
sl@0
|
56 |
// std::out_of_range is used to report an argument is not within the expected range.
|
sl@0
|
57 |
// The description of KErrArgument says an argument is out of range. Hence the mapping.
|
sl@0
|
58 |
return KErrArgument;
|
sl@0
|
59 |
else if(atype == typeid(std::overflow_error))
|
sl@0
|
60 |
return KErrOverflow;
|
sl@0
|
61 |
else if(atype == typeid(std::underflow_error))
|
sl@0
|
62 |
return KErrUnderflow;
|
sl@0
|
63 |
else
|
sl@0
|
64 |
return KErrGeneral;
|
sl@0
|
65 |
#else
|
sl@0
|
66 |
return KErrGeneral;
|
sl@0
|
67 |
#endif
|
sl@0
|
68 |
}
|
sl@0
|
69 |
|
sl@0
|
70 |
#ifdef __WINSCW__
|
sl@0
|
71 |
/*
|
sl@0
|
72 |
* The StdC++ global new and delete operators defined here. They are done only for the emulator
|
sl@0
|
73 |
* as for EABI platforms, it is part of the runtime support(i.e., stdnew.dll).
|
sl@0
|
74 |
*/
|
sl@0
|
75 |
#include <e32std.h>
|
sl@0
|
76 |
|
sl@0
|
77 |
EXPORT_C const std::nothrow_t std::nothrow;
|
sl@0
|
78 |
|
sl@0
|
79 |
EXPORT_C void* operator new(std::size_t a_size) __THROW(std::bad_alloc)
|
sl@0
|
80 |
{
|
sl@0
|
81 |
for (;;)
|
sl@0
|
82 |
{
|
sl@0
|
83 |
void* p = User::Alloc(a_size);
|
sl@0
|
84 |
|
sl@0
|
85 |
if (p)
|
sl@0
|
86 |
{
|
sl@0
|
87 |
return p;
|
sl@0
|
88 |
}
|
sl@0
|
89 |
std::new_handler nh_func ;
|
sl@0
|
90 |
std::new_handler *ptr = reinterpret_cast<std::new_handler*>(Dll::Tls());
|
sl@0
|
91 |
nh_func = (ptr)?(*ptr):NULL;
|
sl@0
|
92 |
|
sl@0
|
93 |
if (nh_func)
|
sl@0
|
94 |
{
|
sl@0
|
95 |
nh_func();
|
sl@0
|
96 |
}
|
sl@0
|
97 |
else
|
sl@0
|
98 |
{
|
sl@0
|
99 |
__THROW(std::bad_alloc());
|
sl@0
|
100 |
}
|
sl@0
|
101 |
}
|
sl@0
|
102 |
}
|
sl@0
|
103 |
|
sl@0
|
104 |
EXPORT_C void* operator new[](std::size_t a_size) __THROW(std::bad_alloc)
|
sl@0
|
105 |
{
|
sl@0
|
106 |
return ::operator new(a_size);
|
sl@0
|
107 |
}
|
sl@0
|
108 |
|
sl@0
|
109 |
EXPORT_C void* operator new(std::size_t a_size, const std::nothrow_t&) __NO_THROW
|
sl@0
|
110 |
{
|
sl@0
|
111 |
for (;;)
|
sl@0
|
112 |
{
|
sl@0
|
113 |
void* p = User::Alloc(a_size);
|
sl@0
|
114 |
|
sl@0
|
115 |
if (p)
|
sl@0
|
116 |
{
|
sl@0
|
117 |
return p;
|
sl@0
|
118 |
}
|
sl@0
|
119 |
|
sl@0
|
120 |
std::new_handler nh_func ;
|
sl@0
|
121 |
std::new_handler *ptr = reinterpret_cast<std::new_handler*>(Dll::Tls());
|
sl@0
|
122 |
nh_func = (ptr)?(*ptr):NULL;
|
sl@0
|
123 |
|
sl@0
|
124 |
if (nh_func)
|
sl@0
|
125 |
{
|
sl@0
|
126 |
try
|
sl@0
|
127 |
{
|
sl@0
|
128 |
nh_func();
|
sl@0
|
129 |
}
|
sl@0
|
130 |
catch (...)
|
sl@0
|
131 |
{
|
sl@0
|
132 |
return 0;
|
sl@0
|
133 |
}
|
sl@0
|
134 |
}
|
sl@0
|
135 |
else
|
sl@0
|
136 |
{
|
sl@0
|
137 |
return 0;
|
sl@0
|
138 |
}
|
sl@0
|
139 |
}
|
sl@0
|
140 |
}
|
sl@0
|
141 |
|
sl@0
|
142 |
EXPORT_C void* operator new[](std::size_t a_size, const std::nothrow_t) __NO_THROW
|
sl@0
|
143 |
{
|
sl@0
|
144 |
return ::operator new(a_size, std::nothrow);
|
sl@0
|
145 |
}
|
sl@0
|
146 |
|
sl@0
|
147 |
// Symbian-specific addition.
|
sl@0
|
148 |
EXPORT_C void* operator new(std::size_t a_size, std::size_t a_extra_size) __NO_THROW
|
sl@0
|
149 |
{
|
sl@0
|
150 |
return ::operator new(a_size + a_extra_size, std::nothrow);
|
sl@0
|
151 |
}
|
sl@0
|
152 |
|
sl@0
|
153 |
EXPORT_C void operator delete(void* p) __NO_THROW
|
sl@0
|
154 |
{
|
sl@0
|
155 |
User::Free(p);
|
sl@0
|
156 |
}
|
sl@0
|
157 |
|
sl@0
|
158 |
EXPORT_C void operator delete(void* p, const std::nothrow_t&) __NO_THROW
|
sl@0
|
159 |
{
|
sl@0
|
160 |
User::Free(p);
|
sl@0
|
161 |
}
|
sl@0
|
162 |
|
sl@0
|
163 |
EXPORT_C void operator delete[](void* p) __NO_THROW
|
sl@0
|
164 |
{
|
sl@0
|
165 |
User::Free(p);
|
sl@0
|
166 |
}
|
sl@0
|
167 |
|
sl@0
|
168 |
EXPORT_C void operator delete[](void* p, const std::nothrow_t&) __NO_THROW
|
sl@0
|
169 |
{
|
sl@0
|
170 |
User::Free(p);
|
sl@0
|
171 |
}
|
sl@0
|
172 |
|
sl@0
|
173 |
// Symbian-specific addition.
|
sl@0
|
174 |
EXPORT_C void operator delete(void* p, std::size_t) __NO_THROW
|
sl@0
|
175 |
{
|
sl@0
|
176 |
User::Free(p);
|
sl@0
|
177 |
}
|
sl@0
|
178 |
_LIT(K,"set_new_handler");
|
sl@0
|
179 |
|
sl@0
|
180 |
|
sl@0
|
181 |
using std::new_handler;
|
sl@0
|
182 |
|
sl@0
|
183 |
EXPORT_C new_handler std::set_new_handler(new_handler a_new_nh) __NO_THROW
|
sl@0
|
184 |
{
|
sl@0
|
185 |
new_handler current_nh;
|
sl@0
|
186 |
TAny* tls_word_p = Dll::Tls();
|
sl@0
|
187 |
|
sl@0
|
188 |
if (!tls_word_p)
|
sl@0
|
189 |
{
|
sl@0
|
190 |
// This is the first time we're called, so we need to set up the TLS.
|
sl@0
|
191 |
|
sl@0
|
192 |
tls_word_p = User::Alloc( sizeof(new_handler) );
|
sl@0
|
193 |
if ( !tls_word_p )
|
sl@0
|
194 |
{
|
sl@0
|
195 |
User::Panic(K, KErrNoMemory);
|
sl@0
|
196 |
}
|
sl@0
|
197 |
|
sl@0
|
198 |
Dll::SetTls(tls_word_p);
|
sl@0
|
199 |
current_nh = 0;
|
sl@0
|
200 |
}
|
sl@0
|
201 |
else
|
sl@0
|
202 |
{
|
sl@0
|
203 |
// Get the currently installed new_handler function.
|
sl@0
|
204 |
current_nh = *reinterpret_cast<new_handler*>(tls_word_p);
|
sl@0
|
205 |
}
|
sl@0
|
206 |
|
sl@0
|
207 |
// Set the new new_handler.
|
sl@0
|
208 |
*reinterpret_cast<new_handler*>(tls_word_p) = a_new_nh;
|
sl@0
|
209 |
|
sl@0
|
210 |
return current_nh;
|
sl@0
|
211 |
}
|
sl@0
|
212 |
|
sl@0
|
213 |
#endif //__WINSCW__
|