File: | home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx |
Warning: | line 1048, column 20 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * This file is part of the LibreOffice project. | |||
4 | * | |||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | |||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |||
8 | */ | |||
9 | ||||
10 | #include <cstdio> | |||
11 | #include <string_view> | |||
12 | ||||
13 | #include <com/sun/star/beans/IllegalTypeException.hpp> | |||
14 | #include <com/sun/star/beans/PropertyAttribute.hpp> | |||
15 | #include <com/sun/star/beans/PropertyValue.hpp> | |||
16 | #include <com/sun/star/beans/XPropertySetInfo.hpp> | |||
17 | #include <com/sun/star/document/CmisProperty.hpp> | |||
18 | #include <com/sun/star/io/XActiveDataSink.hpp> | |||
19 | #include <com/sun/star/io/XActiveDataStreamer.hpp> | |||
20 | #include <com/sun/star/lang/IllegalAccessException.hpp> | |||
21 | #include <com/sun/star/lang/IllegalArgumentException.hpp> | |||
22 | #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> | |||
23 | #include <com/sun/star/task/InteractionClassification.hpp> | |||
24 | #include <com/sun/star/ucb/ContentInfo.hpp> | |||
25 | #include <com/sun/star/ucb/ContentInfoAttribute.hpp> | |||
26 | #include <com/sun/star/ucb/InsertCommandArgument2.hpp> | |||
27 | #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> | |||
28 | #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> | |||
29 | #include <com/sun/star/ucb/MissingInputStreamException.hpp> | |||
30 | #include <com/sun/star/ucb/OpenMode.hpp> | |||
31 | #include <com/sun/star/ucb/UnsupportedCommandException.hpp> | |||
32 | #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> | |||
33 | #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp> | |||
34 | #include <com/sun/star/ucb/XCommandInfo.hpp> | |||
35 | #include <com/sun/star/ucb/XDynamicResultSet.hpp> | |||
36 | #ifndef SYSTEM_CURL | |||
37 | #include <com/sun/star/xml/crypto/XDigestContext.hpp> | |||
38 | #include <com/sun/star/xml/crypto/DigestID.hpp> | |||
39 | #include <com/sun/star/xml/crypto/NSSInitializer.hpp> | |||
40 | #endif | |||
41 | ||||
42 | #include <comphelper/processfactory.hxx> | |||
43 | #include <comphelper/sequence.hxx> | |||
44 | #include <cppuhelper/exc_hlp.hxx> | |||
45 | #include <cppuhelper/queryinterface.hxx> | |||
46 | #include <config_oauth2.h> | |||
47 | #include <o3tl/runtimetooustring.hxx> | |||
48 | #include <sal/log.hxx> | |||
49 | #include <tools/urlobj.hxx> | |||
50 | #include <ucbhelper/cancelcommandexecution.hxx> | |||
51 | #include <ucbhelper/content.hxx> | |||
52 | #include <ucbhelper/contentidentifier.hxx> | |||
53 | #include <ucbhelper/propertyvalueset.hxx> | |||
54 | #include <ucbhelper/proxydecider.hxx> | |||
55 | #include <ucbhelper/macros.hxx> | |||
56 | #include <sax/tools/converter.hxx> | |||
57 | ||||
58 | #include "auth_provider.hxx" | |||
59 | #include "certvalidation_handler.hxx" | |||
60 | #include "cmis_content.hxx" | |||
61 | #include "cmis_provider.hxx" | |||
62 | #include "cmis_resultset.hxx" | |||
63 | #include "cmis_strings.hxx" | |||
64 | #include "std_inputstream.hxx" | |||
65 | #include "std_outputstream.hxx" | |||
66 | ||||
67 | #define OUSTR_TO_STDSTR(s)string( OUStringToOString( s, (((rtl_TextEncoding) 76)) ).getStr () ) string( OUStringToOString( s, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)) ).getStr() ) | |||
68 | #define STD_TO_OUSTR( str )OUString( str.c_str(), str.length( ), (((rtl_TextEncoding) 76 )) ) OUString( str.c_str(), str.length( ), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)) ) | |||
69 | ||||
70 | using namespace com::sun::star; | |||
71 | using namespace std; | |||
72 | ||||
73 | namespace | |||
74 | { | |||
75 | util::DateTime lcl_boostToUnoTime(const boost::posix_time::ptime& boostTime) | |||
76 | { | |||
77 | util::DateTime unoTime; | |||
78 | unoTime.Year = boostTime.date().year(); | |||
79 | unoTime.Month = boostTime.date().month(); | |||
80 | unoTime.Day = boostTime.date().day(); | |||
81 | unoTime.Hours = boostTime.time_of_day().hours(); | |||
82 | unoTime.Minutes = boostTime.time_of_day().minutes(); | |||
83 | unoTime.Seconds = boostTime.time_of_day().seconds(); | |||
84 | ||||
85 | // TODO FIXME maybe we should compile with BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG | |||
86 | // to actually get nanosecond precision in boostTime? | |||
87 | // use this way rather than total_nanos to avoid overflows with 32-bit long | |||
88 | const long ticks = boostTime.time_of_day().fractional_seconds(); | |||
89 | long nanoSeconds = ticks * ( 1000000000 / boost::posix_time::time_duration::ticks_per_second()); | |||
90 | ||||
91 | unoTime.NanoSeconds = nanoSeconds; | |||
92 | ||||
93 | return unoTime; | |||
94 | } | |||
95 | ||||
96 | uno::Any lcl_cmisPropertyToUno( const libcmis::PropertyPtr& pProperty ) | |||
97 | { | |||
98 | uno::Any aValue; | |||
99 | switch ( pProperty->getPropertyType( )->getType( ) ) | |||
100 | { | |||
101 | default: | |||
102 | case libcmis::PropertyType::String: | |||
103 | { | |||
104 | vector< string > aCmisStrings = pProperty->getStrings( ); | |||
105 | uno::Sequence< OUString > aStrings( aCmisStrings.size( ) ); | |||
106 | OUString* aStringsArr = aStrings.getArray( ); | |||
107 | sal_Int32 i = 0; | |||
108 | for ( const auto& rCmisStr : aCmisStrings ) | |||
109 | { | |||
110 | aStringsArr[i++] = STD_TO_OUSTR( rCmisStr )OUString( rCmisStr.c_str(), rCmisStr.length( ), (((rtl_TextEncoding ) 76)) ); | |||
111 | } | |||
112 | aValue <<= aStrings; | |||
113 | } | |||
114 | break; | |||
115 | case libcmis::PropertyType::Integer: | |||
116 | { | |||
117 | vector< long > aCmisLongs = pProperty->getLongs( ); | |||
118 | uno::Sequence< sal_Int64 > aLongs( aCmisLongs.size( ) ); | |||
119 | sal_Int64* aLongsArr = aLongs.getArray( ); | |||
120 | sal_Int32 i = 0; | |||
121 | for ( const auto& rCmisLong : aCmisLongs ) | |||
122 | { | |||
123 | aLongsArr[i++] = rCmisLong; | |||
124 | } | |||
125 | aValue <<= aLongs; | |||
126 | } | |||
127 | break; | |||
128 | case libcmis::PropertyType::Decimal: | |||
129 | { | |||
130 | vector< double > aCmisDoubles = pProperty->getDoubles( ); | |||
131 | uno::Sequence< double > aDoubles = comphelper::containerToSequence(aCmisDoubles); | |||
132 | aValue <<= aDoubles; | |||
133 | } | |||
134 | break; | |||
135 | case libcmis::PropertyType::Bool: | |||
136 | { | |||
137 | vector< bool > aCmisBools = pProperty->getBools( ); | |||
138 | uno::Sequence< sal_Bool > aBools( aCmisBools.size( ) ); | |||
139 | sal_Bool* aBoolsArr = aBools.getArray( ); | |||
140 | sal_Int32 i = 0; | |||
141 | for ( bool bCmisBool : aCmisBools ) | |||
142 | { | |||
143 | aBoolsArr[i++] = bCmisBool; | |||
144 | } | |||
145 | aValue <<= aBools; | |||
146 | } | |||
147 | break; | |||
148 | case libcmis::PropertyType::DateTime: | |||
149 | { | |||
150 | vector< boost::posix_time::ptime > aCmisTimes = pProperty->getDateTimes( ); | |||
151 | uno::Sequence< util::DateTime > aTimes( aCmisTimes.size( ) ); | |||
152 | util::DateTime* aTimesArr = aTimes.getArray( ); | |||
153 | sal_Int32 i = 0; | |||
154 | for ( const auto& rCmisTime : aCmisTimes ) | |||
155 | { | |||
156 | aTimesArr[i++] = lcl_boostToUnoTime( rCmisTime ); | |||
157 | } | |||
158 | aValue <<= aTimes; | |||
159 | } | |||
160 | break; | |||
161 | } | |||
162 | return aValue; | |||
163 | } | |||
164 | ||||
165 | libcmis::PropertyPtr lcl_unoToCmisProperty(const document::CmisProperty& prop ) | |||
166 | { | |||
167 | libcmis::PropertyTypePtr propertyType( new libcmis::PropertyType( ) ); | |||
168 | ||||
169 | OUString id = prop.Id; | |||
170 | OUString name = prop.Name; | |||
171 | bool bUpdatable = prop.Updatable; | |||
172 | bool bRequired = prop.Required; | |||
173 | bool bMultiValued = prop.MultiValued; | |||
174 | bool bOpenChoice = prop.OpenChoice; | |||
175 | uno::Any value = prop.Value; | |||
176 | std::vector< std::string > values; | |||
177 | ||||
178 | libcmis::PropertyType::Type type = libcmis::PropertyType::String; | |||
179 | if ( prop.Type == CMIS_TYPE_STRING"String" ) | |||
180 | { | |||
181 | uno::Sequence< OUString > seqValue; | |||
182 | value >>= seqValue; | |||
183 | std::transform(seqValue.begin(), seqValue.end(), std::back_inserter(values), | |||
184 | [](const OUString& rValue) -> std::string { return OUSTR_TO_STDSTR( rValue )string( OUStringToOString( rValue, (((rtl_TextEncoding) 76)) ) .getStr() ); }); | |||
185 | type = libcmis::PropertyType::String; | |||
186 | } | |||
187 | else if ( prop.Type == CMIS_TYPE_BOOL"Bool" ) | |||
188 | { | |||
189 | uno::Sequence< sal_Bool > seqValue; | |||
190 | value >>= seqValue; | |||
191 | std::transform(seqValue.begin(), seqValue.end(), std::back_inserter(values), | |||
192 | [](const bool nValue) -> std::string { return OUSTR_TO_STDSTR( OUString::boolean( nValue ) )string( OUStringToOString( OUString::boolean( nValue ), (((rtl_TextEncoding ) 76)) ).getStr() ); }); | |||
193 | type = libcmis::PropertyType::Bool; | |||
194 | } | |||
195 | else if ( prop.Type == CMIS_TYPE_INTEGER"Integer" ) | |||
196 | { | |||
197 | uno::Sequence< sal_Int64 > seqValue; | |||
198 | value >>= seqValue; | |||
199 | std::transform(seqValue.begin(), seqValue.end(), std::back_inserter(values), | |||
200 | [](const sal_Int64 nValue) -> std::string { return OUSTR_TO_STDSTR( OUString::number( nValue ) )string( OUStringToOString( OUString::number( nValue ), (((rtl_TextEncoding ) 76)) ).getStr() ); }); | |||
201 | type = libcmis::PropertyType::Integer; | |||
202 | } | |||
203 | else if ( prop.Type == CMIS_TYPE_DECIMAL"Decimal" ) | |||
204 | { | |||
205 | uno::Sequence< double > seqValue; | |||
206 | value >>= seqValue; | |||
207 | std::transform(seqValue.begin(), seqValue.end(), std::back_inserter(values), | |||
208 | [](const double fValue) -> std::string { return OUSTR_TO_STDSTR( OUString::number( fValue ) )string( OUStringToOString( OUString::number( fValue ), (((rtl_TextEncoding ) 76)) ).getStr() ); }); | |||
209 | type = libcmis::PropertyType::Decimal; | |||
210 | } | |||
211 | else if ( prop.Type == CMIS_TYPE_DATETIME"Datetime" ) | |||
212 | { | |||
213 | uno::Sequence< util::DateTime > seqValue; | |||
214 | value >>= seqValue; | |||
215 | std::transform(seqValue.begin(), seqValue.end(), std::back_inserter(values), | |||
216 | [](const util::DateTime& rValue) -> std::string { | |||
217 | OUStringBuffer aBuffer; | |||
218 | ::sax::Converter::convertDateTime( aBuffer, rValue, nullptr ); | |||
219 | return OUSTR_TO_STDSTR( aBuffer.makeStringAndClear( ) )string( OUStringToOString( aBuffer.makeStringAndClear( ), ((( rtl_TextEncoding) 76)) ).getStr() ); | |||
220 | }); | |||
221 | type = libcmis::PropertyType::DateTime; | |||
222 | } | |||
223 | ||||
224 | propertyType->setId( OUSTR_TO_STDSTR( id )string( OUStringToOString( id, (((rtl_TextEncoding) 76)) ).getStr () )); | |||
225 | propertyType->setDisplayName( OUSTR_TO_STDSTR( name )string( OUStringToOString( name, (((rtl_TextEncoding) 76)) ). getStr() ) ); | |||
226 | propertyType->setUpdatable( bUpdatable ); | |||
227 | propertyType->setRequired( bRequired ); | |||
228 | propertyType->setMultiValued( bMultiValued ); | |||
229 | propertyType->setOpenChoice( bOpenChoice ); | |||
230 | propertyType->setType( type ); | |||
231 | ||||
232 | libcmis::PropertyPtr property( new libcmis::Property( propertyType, values ) ); | |||
233 | ||||
234 | return property; | |||
235 | } | |||
236 | ||||
237 | uno::Sequence< uno::Any > generateErrorArguments( const cmis::URL & rURL ) | |||
238 | { | |||
239 | uno::Sequence< uno::Any > aArguments(3); | |||
240 | ||||
241 | size_t i = 0; | |||
242 | aArguments[i++] <<= beans::PropertyValue( | |||
243 | "Binding URL", | |||
244 | - 1, | |||
245 | uno::makeAny( rURL.getBindingUrl() ), | |||
246 | beans::PropertyState_DIRECT_VALUE ); | |||
247 | ||||
248 | aArguments[i++] <<= beans::PropertyValue( | |||
249 | "Username", | |||
250 | -1, | |||
251 | uno::makeAny( rURL.getUsername() ), | |||
252 | beans::PropertyState_DIRECT_VALUE ); | |||
253 | ||||
254 | aArguments[i++] <<= beans::PropertyValue( | |||
255 | "Repository Id", | |||
256 | -1, | |||
257 | uno::makeAny( rURL.getRepositoryId() ), | |||
258 | beans::PropertyState_DIRECT_VALUE ); | |||
259 | ||||
260 | return aArguments; | |||
261 | } | |||
262 | } | |||
263 | ||||
264 | namespace cmis | |||
265 | { | |||
266 | Content::Content( const uno::Reference< uno::XComponentContext >& rxContext, | |||
267 | ContentProvider *pProvider, const uno::Reference< ucb::XContentIdentifier >& Identifier, | |||
268 | libcmis::ObjectPtr const & pObject ) | |||
269 | : ContentImplHelper( rxContext, pProvider, Identifier ), | |||
270 | m_pProvider( pProvider ), | |||
271 | m_pSession( nullptr ), | |||
272 | m_pObject( pObject ), | |||
273 | m_sURL( Identifier->getContentIdentifier( ) ), | |||
274 | m_aURL( Identifier->getContentIdentifier( ) ), | |||
275 | m_bTransient( false ), | |||
276 | m_bIsFolder( false ) | |||
277 | { | |||
278 | SAL_INFO( "ucb.ucp.cmis", "Content::Content() " << m_sURL )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Content::Content() " << m_sURL) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "278" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Content::Content() " << m_sURL) , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Content::Content() " << m_sURL; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "278" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Content::Content() " << m_sURL) == 1) { :: sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "278" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Content::Content() " << m_sURL) , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Content::Content() " << m_sURL; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "278" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
279 | ||||
280 | m_sObjectPath = m_aURL.getObjectPath( ); | |||
281 | m_sObjectId = m_aURL.getObjectId( ); | |||
282 | } | |||
283 | ||||
284 | Content::Content( const uno::Reference< uno::XComponentContext >& rxContext, ContentProvider *pProvider, | |||
285 | const uno::Reference< ucb::XContentIdentifier >& Identifier, | |||
286 | bool bIsFolder ) | |||
287 | : ContentImplHelper( rxContext, pProvider, Identifier ), | |||
288 | m_pProvider( pProvider ), | |||
289 | m_pSession( nullptr ), | |||
290 | m_sURL( Identifier->getContentIdentifier( ) ), | |||
291 | m_aURL( Identifier->getContentIdentifier( ) ), | |||
292 | m_bTransient( true ), | |||
293 | m_bIsFolder( bIsFolder ) | |||
294 | { | |||
295 | SAL_INFO( "ucb.ucp.cmis", "Content::Content() " << m_sURL )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Content::Content() " << m_sURL) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "295" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Content::Content() " << m_sURL) , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Content::Content() " << m_sURL; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "295" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Content::Content() " << m_sURL) == 1) { :: sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "295" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Content::Content() " << m_sURL) , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Content::Content() " << m_sURL; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "295" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
296 | ||||
297 | m_sObjectPath = m_aURL.getObjectPath( ); | |||
298 | m_sObjectId = m_aURL.getObjectId( ); | |||
299 | } | |||
300 | ||||
301 | Content::~Content() | |||
302 | { | |||
303 | } | |||
304 | ||||
305 | libcmis::Session* Content::getSession( const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
306 | { | |||
307 | // Set the proxy if needed. We are doing that all times as the proxy data shouldn't be cached. | |||
308 | ucbhelper::InternetProxyDecider aProxyDecider( m_xContext ); | |||
309 | INetURLObject aBindingUrl( m_aURL.getBindingUrl( ) ); | |||
310 | const ucbhelper::InternetProxyServer& rProxy = aProxyDecider.getProxy( | |||
311 | INetURLObject::GetScheme( aBindingUrl.GetProtocol( ) ), aBindingUrl.GetHost(), aBindingUrl.GetPort() ); | |||
312 | OUString sProxy = rProxy.aName; | |||
313 | if ( rProxy.nPort > 0 ) | |||
314 | sProxy += ":" + OUString::number( rProxy.nPort ); | |||
315 | libcmis::SessionFactory::setProxySettings( OUSTR_TO_STDSTR( sProxy )string( OUStringToOString( sProxy, (((rtl_TextEncoding) 76)) ) .getStr() ), string(), string(), string() ); | |||
316 | ||||
317 | // Look for a cached session, key is binding url + repo id | |||
318 | OUString sSessionId = m_aURL.getBindingUrl( ) + m_aURL.getRepositoryId( ); | |||
319 | if ( nullptr == m_pSession ) | |||
320 | m_pSession = m_pProvider->getSession( sSessionId, m_aURL.getUsername( ) ); | |||
321 | ||||
322 | if ( nullptr == m_pSession ) | |||
323 | { | |||
324 | #ifndef SYSTEM_CURL | |||
325 | // Initialize NSS library to make sure libcmis (and curl) can access CACERTs using NSS | |||
326 | // when using internal libcurl. | |||
327 | uno::Reference< css::xml::crypto::XNSSInitializer > | |||
328 | xNSSInitializer = css::xml::crypto::NSSInitializer::create( m_xContext ); | |||
329 | ||||
330 | uno::Reference< css::xml::crypto::XDigestContext > xDigestContext( | |||
331 | xNSSInitializer->getDigestContext( css::xml::crypto::DigestID::SHA256, | |||
332 | uno::Sequence< beans::NamedValue >() ), | |||
333 | uno::UNO_SET_THROW ); | |||
334 | #endif | |||
335 | ||||
336 | // Set the SSL Validation handler | |||
337 | libcmis::CertValidationHandlerPtr certHandler( | |||
338 | new CertValidationHandler( xEnv, m_xContext, aBindingUrl.GetHost( ) ) ); | |||
339 | libcmis::SessionFactory::setCertificateValidationHandler( certHandler ); | |||
340 | ||||
341 | // Get the auth credentials | |||
342 | AuthProvider aAuthProvider(xEnv, m_xIdentifier->getContentIdentifier(), m_aURL.getBindingUrl()); | |||
343 | AuthProvider::setXEnv( xEnv ); | |||
344 | ||||
345 | string rUsername = OUSTR_TO_STDSTR( m_aURL.getUsername( ) )string( OUStringToOString( m_aURL.getUsername( ), (((rtl_TextEncoding ) 76)) ).getStr() ); | |||
346 | string rPassword = OUSTR_TO_STDSTR( m_aURL.getPassword( ) )string( OUStringToOString( m_aURL.getPassword( ), (((rtl_TextEncoding ) 76)) ).getStr() ); | |||
347 | ||||
348 | bool bIsDone = false; | |||
349 | ||||
350 | while ( !bIsDone ) | |||
351 | { | |||
352 | if (aAuthProvider.authenticationQuery(rUsername, rPassword)) | |||
353 | { | |||
354 | // Initiate a CMIS session and register it as we found nothing | |||
355 | libcmis::OAuth2DataPtr oauth2Data; | |||
356 | if ( m_aURL.getBindingUrl( ) == GDRIVE_BASE_URL"https://www.googleapis.com/drive/v2" ) | |||
357 | { | |||
358 | libcmis::SessionFactory::setOAuth2AuthCodeProvider(AuthProvider::gdriveAuthCodeFallback); | |||
359 | oauth2Data.reset( new libcmis::OAuth2Data( | |||
360 | GDRIVE_AUTH_URL"https://accounts.google.com/o/oauth2/auth", GDRIVE_TOKEN_URL"https://accounts.google.com/o/oauth2/token", | |||
361 | GDRIVE_SCOPE"https://www.googleapis.com/auth/drive", GDRIVE_REDIRECT_URI"urn:ietf:wg:oauth:2.0:oob", | |||
362 | GDRIVE_CLIENT_ID"", GDRIVE_CLIENT_SECRET"" ) ); | |||
363 | } | |||
364 | if ( m_aURL.getBindingUrl().startsWith( ALFRESCO_CLOUD_BASE_URL"https://api.alfresco.com/" ) ) | |||
365 | oauth2Data.reset( new libcmis::OAuth2Data( | |||
366 | ALFRESCO_CLOUD_AUTH_URL"https://api.alfresco.com/auth/oauth/versions/2/authorize", ALFRESCO_CLOUD_TOKEN_URL"https://api.alfresco.com/auth/oauth/versions/2/token", | |||
367 | ALFRESCO_CLOUD_SCOPE"public_api", ALFRESCO_CLOUD_REDIRECT_URI"http://127.0.0.1/Callback", | |||
368 | ALFRESCO_CLOUD_CLIENT_ID"", ALFRESCO_CLOUD_CLIENT_SECRET"" ) ); | |||
369 | if ( m_aURL.getBindingUrl( ) == ONEDRIVE_BASE_URL"https://apis.live.net/v5.0" ) | |||
370 | { | |||
371 | libcmis::SessionFactory::setOAuth2AuthCodeProvider(AuthProvider::onedriveAuthCodeFallback); | |||
372 | oauth2Data.reset( new libcmis::OAuth2Data( | |||
373 | ONEDRIVE_AUTH_URL"https://login.live.com/oauth20_authorize.srf", ONEDRIVE_TOKEN_URL"https://login.live.com/oauth20_token.srf", | |||
374 | ONEDRIVE_SCOPE"wl.skydrive_update wl.offline_access", ONEDRIVE_REDIRECT_URI"https://login.live.com/oauth20_desktop.srf", | |||
375 | ONEDRIVE_CLIENT_ID"", ONEDRIVE_CLIENT_SECRET"" ) ); | |||
376 | } | |||
377 | try | |||
378 | { | |||
379 | m_pSession = libcmis::SessionFactory::createSession( | |||
380 | OUSTR_TO_STDSTR( m_aURL.getBindingUrl( ) )string( OUStringToOString( m_aURL.getBindingUrl( ), (((rtl_TextEncoding ) 76)) ).getStr() ), | |||
381 | rUsername, rPassword, OUSTR_TO_STDSTR( m_aURL.getRepositoryId( ) )string( OUStringToOString( m_aURL.getRepositoryId( ), (((rtl_TextEncoding ) 76)) ).getStr() ), false, oauth2Data ); | |||
382 | ||||
383 | if ( m_pSession == nullptr ) | |||
384 | { | |||
385 | // Fail: session was not created | |||
386 | ucbhelper::cancelCommandExecution( | |||
387 | ucb::IOErrorCode_INVALID_DEVICE, | |||
388 | generateErrorArguments(m_aURL), | |||
389 | xEnv); | |||
390 | } | |||
391 | else if ( m_pSession->getRepository() == nullptr ) | |||
392 | { | |||
393 | // Fail: no repository or repository is invalid | |||
394 | ucbhelper::cancelCommandExecution( | |||
395 | ucb::IOErrorCode_INVALID_DEVICE, | |||
396 | generateErrorArguments(m_aURL), | |||
397 | xEnv, | |||
398 | "error accessing a repository"); | |||
399 | } | |||
400 | else | |||
401 | { | |||
402 | m_pProvider->registerSession(sSessionId, m_aURL.getUsername( ), m_pSession); | |||
403 | } | |||
404 | ||||
405 | bIsDone = true; | |||
406 | } | |||
407 | catch( const libcmis::Exception & e ) | |||
408 | { | |||
409 | if ( e.getType() != "permissionDenied" ) | |||
410 | throw; | |||
411 | } | |||
412 | } | |||
413 | else | |||
414 | { | |||
415 | // Silently fail as the user cancelled the authentication | |||
416 | ucbhelper::cancelCommandExecution( | |||
417 | ucb::IOErrorCode_ABORT, | |||
418 | uno::Sequence< uno::Any >( 0 ), | |||
419 | xEnv ); | |||
420 | throw uno::RuntimeException( ); | |||
421 | } | |||
422 | } | |||
423 | } | |||
424 | return m_pSession; | |||
425 | } | |||
426 | ||||
427 | libcmis::ObjectTypePtr const & Content::getObjectType( const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
428 | { | |||
429 | if ( nullptr == m_pObjectType.get( ) && m_bTransient ) | |||
430 | { | |||
431 | string typeId = m_bIsFolder ? "cmis:folder" : "cmis:document"; | |||
432 | // The type to create needs to be fetched from the possible children types | |||
433 | // defined in the parent folder. Then, we'll pick up the first one we find matching | |||
434 | // cmis:folder or cmis:document (depending what we need to create). | |||
435 | // The easy case will work in most cases, but not on some servers (like Lotus Live) | |||
436 | libcmis::Folder* pParent = nullptr; | |||
437 | bool bTypeRestricted = false; | |||
438 | try | |||
439 | { | |||
440 | pParent = dynamic_cast< libcmis::Folder* >( getObject( xEnv ).get( ) ); | |||
441 | } | |||
442 | catch ( const libcmis::Exception& ) | |||
443 | { | |||
444 | } | |||
445 | ||||
446 | if ( pParent ) | |||
447 | { | |||
448 | map< string, libcmis::PropertyPtr >& aProperties = pParent->getProperties( ); | |||
449 | map< string, libcmis::PropertyPtr >::iterator it = aProperties.find( "cmis:allowedChildObjectTypeIds" ); | |||
450 | if ( it != aProperties.end( ) ) | |||
451 | { | |||
452 | libcmis::PropertyPtr pProperty = it->second; | |||
453 | if ( pProperty ) | |||
454 | { | |||
455 | vector< string > typesIds = pProperty->getStrings( ); | |||
456 | for ( const auto& rType : typesIds ) | |||
457 | { | |||
458 | bTypeRestricted = true; | |||
459 | libcmis::ObjectTypePtr type = getSession( xEnv )->getType( rType ); | |||
460 | ||||
461 | // FIXME Improve performances by adding getBaseTypeId( ) method to libcmis | |||
462 | if ( type->getBaseType( )->getId( ) == typeId ) | |||
463 | { | |||
464 | m_pObjectType = type; | |||
465 | break; | |||
466 | } | |||
467 | } | |||
468 | } | |||
469 | } | |||
470 | } | |||
471 | ||||
472 | if ( !bTypeRestricted ) | |||
473 | m_pObjectType = getSession( xEnv )->getType( typeId ); | |||
474 | } | |||
475 | return m_pObjectType; | |||
476 | } | |||
477 | ||||
478 | ||||
479 | libcmis::ObjectPtr const & Content::getObject( const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
480 | { | |||
481 | // can't get the session for some reason | |||
482 | // the recent file opening at start up is an example. | |||
483 | try | |||
484 | { | |||
485 | if ( !getSession( xEnv ) ) | |||
486 | return m_pObject; | |||
487 | } | |||
488 | catch ( uno::RuntimeException& ) | |||
489 | { | |||
490 | return m_pObject; | |||
491 | } | |||
492 | if ( !m_pObject.get() ) | |||
493 | { | |||
494 | if ( !m_sObjectId.isEmpty( ) ) | |||
495 | { | |||
496 | try | |||
497 | { | |||
498 | m_pObject = getSession( xEnv )->getObject( OUSTR_TO_STDSTR( m_sObjectId )string( OUStringToOString( m_sObjectId, (((rtl_TextEncoding) 76 )) ).getStr() ) ); | |||
499 | } | |||
500 | catch ( const libcmis::Exception& ) | |||
501 | { | |||
502 | throw libcmis::Exception( "Object not found" ); | |||
503 | } | |||
504 | } | |||
505 | else if (!(m_sObjectPath.isEmpty() || m_sObjectPath == "/")) | |||
506 | { | |||
507 | try | |||
508 | { | |||
509 | m_pObject = getSession( xEnv )->getObjectByPath( OUSTR_TO_STDSTR( m_sObjectPath )string( OUStringToOString( m_sObjectPath, (((rtl_TextEncoding ) 76)) ).getStr() ) ); | |||
510 | } | |||
511 | catch ( const libcmis::Exception& ) | |||
512 | { | |||
513 | // In some cases, getting the object from the path doesn't work, | |||
514 | // but getting the parent from its path and the get the child in the list is OK. | |||
515 | // It's weird, but needed to handle case where the path isn't the folders/files | |||
516 | // names separated by '/' (as in Lotus Live) | |||
517 | INetURLObject aParentUrl( m_sURL ); | |||
518 | string sName = OUSTR_TO_STDSTR( aParentUrl.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset ) )string( OUStringToOString( aParentUrl.getName( INetURLObject:: LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset ), (((rtl_TextEncoding) 76)) ).getStr() ); | |||
519 | aParentUrl.removeSegment( ); | |||
520 | OUString sParentUrl = aParentUrl.GetMainURL( INetURLObject::DecodeMechanism::NONE ); | |||
521 | // Avoid infinite recursion if sParentUrl == m_sURL | |||
522 | if (sParentUrl != m_sURL) | |||
523 | { | |||
524 | rtl::Reference<Content> xParent(new Content(m_xContext, m_pProvider, new ucbhelper::ContentIdentifier(sParentUrl))); | |||
525 | libcmis::FolderPtr pParentFolder = boost::dynamic_pointer_cast< libcmis::Folder >(xParent->getObject(xEnv)); | |||
526 | if (pParentFolder) | |||
527 | { | |||
528 | vector< libcmis::ObjectPtr > children = pParentFolder->getChildren(); | |||
529 | auto it = std::find_if(children.begin(), children.end(), | |||
530 | [&sName](const libcmis::ObjectPtr& rChild) { return rChild->getName() == sName; }); | |||
531 | if (it != children.end()) | |||
532 | m_pObject = *it; | |||
533 | } | |||
534 | } | |||
535 | ||||
536 | if ( !m_pObject ) | |||
537 | throw libcmis::Exception( "Object not found" ); | |||
538 | } | |||
539 | } | |||
540 | else | |||
541 | { | |||
542 | m_pObject = getSession( xEnv )->getRootFolder( ); | |||
543 | m_sObjectPath = "/"; | |||
544 | m_sObjectId = OUString( ); | |||
545 | } | |||
546 | } | |||
547 | ||||
548 | return m_pObject; | |||
549 | } | |||
550 | ||||
551 | bool Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
552 | { | |||
553 | bool bIsFolder = false; | |||
554 | try | |||
555 | { | |||
556 | libcmis::ObjectPtr obj = getObject( xEnv ); | |||
557 | if ( obj ) | |||
558 | bIsFolder = obj->getBaseType( ) == "cmis:folder"; | |||
559 | } | |||
560 | catch ( const libcmis::Exception& e ) | |||
561 | { | |||
562 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: " << e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "562" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "562" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "562" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "562" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
563 | ||||
564 | ucbhelper::cancelCommandExecution( | |||
565 | ucb::IOErrorCode_GENERAL, | |||
566 | uno::Sequence< uno::Any >( 0 ), | |||
567 | xEnv, | |||
568 | OUString::createFromAscii( e.what( ) ) ); | |||
569 | ||||
570 | } | |||
571 | return bIsFolder; | |||
572 | } | |||
573 | ||||
574 | uno::Any Content::getBadArgExcept() | |||
575 | { | |||
576 | return uno::makeAny( lang::IllegalArgumentException( | |||
577 | "Wrong argument type!", | |||
578 | static_cast< cppu::OWeakObject * >( this ), -1) ); | |||
579 | } | |||
580 | ||||
581 | libcmis::ObjectPtr Content::updateProperties( | |||
582 | const uno::Any& iCmisProps, | |||
583 | const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
584 | { | |||
585 | // Convert iCmisProps to Cmis Properties; | |||
586 | uno::Sequence< document::CmisProperty > aPropsSeq; | |||
587 | iCmisProps >>= aPropsSeq; | |||
588 | map< string, libcmis::PropertyPtr > aProperties; | |||
589 | ||||
590 | for ( const auto& rProp : std::as_const(aPropsSeq) ) | |||
591 | { | |||
592 | std::string id = OUSTR_TO_STDSTR( rProp.Id )string( OUStringToOString( rProp.Id, (((rtl_TextEncoding) 76) ) ).getStr() ); | |||
593 | libcmis::PropertyPtr prop = lcl_unoToCmisProperty( rProp ); | |||
594 | aProperties.insert( std::pair<string, libcmis::PropertyPtr>( id, prop ) ); | |||
595 | } | |||
596 | libcmis::ObjectPtr updateObj; | |||
597 | try | |||
598 | { | |||
599 | updateObj = getObject( xEnv )->updateProperties( aProperties ); | |||
600 | } | |||
601 | catch ( const libcmis::Exception& e ) | |||
602 | { | |||
603 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: "<< e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "603" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unexpected libcmis exception: "<< e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "603" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: "<< e.what( ) ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "603" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unexpected libcmis exception: "<< e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "603" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
604 | } | |||
605 | ||||
606 | return updateObj; | |||
607 | } | |||
608 | ||||
609 | uno::Reference< sdbc::XRow > Content::getPropertyValues( | |||
610 | const uno::Sequence< beans::Property >& rProperties, | |||
611 | const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
612 | { | |||
613 | rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( m_xContext ); | |||
614 | ||||
615 | for( const beans::Property& rProp : rProperties ) | |||
616 | { | |||
617 | try | |||
618 | { | |||
619 | if ( rProp.Name == "IsDocument" ) | |||
620 | { | |||
621 | try | |||
622 | { | |||
623 | libcmis::ObjectPtr obj = getObject( xEnv ); | |||
624 | if ( obj ) | |||
625 | xRow->appendBoolean( rProp, obj->getBaseType( ) == "cmis:document" ); | |||
626 | } | |||
627 | catch ( const libcmis::Exception& ) | |||
628 | { | |||
629 | if ( m_pObjectType.get( ) ) | |||
630 | xRow->appendBoolean( rProp, getObjectType( xEnv )->getBaseType()->getId( ) == "cmis:document" ); | |||
631 | else | |||
632 | xRow->appendVoid( rProp ); | |||
633 | } | |||
634 | } | |||
635 | else if ( rProp.Name == "IsFolder" ) | |||
636 | { | |||
637 | try | |||
638 | { | |||
639 | libcmis::ObjectPtr obj = getObject( xEnv ); | |||
640 | if ( obj ) | |||
641 | xRow->appendBoolean( rProp, obj->getBaseType( ) == "cmis:folder" ); | |||
642 | else | |||
643 | xRow->appendBoolean( rProp, false ); | |||
644 | } | |||
645 | catch ( const libcmis::Exception& ) | |||
646 | { | |||
647 | if ( m_pObjectType.get( ) ) | |||
648 | xRow->appendBoolean( rProp, getObjectType( xEnv )->getBaseType()->getId( ) == "cmis:folder" ); | |||
649 | else | |||
650 | xRow->appendVoid( rProp ); | |||
651 | } | |||
652 | } | |||
653 | else if ( rProp.Name == "Title" ) | |||
654 | { | |||
655 | OUString sTitle; | |||
656 | try | |||
657 | { | |||
658 | sTitle = STD_TO_OUSTR( getObject( xEnv )->getName() )OUString( getObject( xEnv )->getName().c_str(), getObject( xEnv )->getName().length( ), (((rtl_TextEncoding) 76)) ); | |||
659 | } | |||
660 | catch ( const libcmis::Exception& ) | |||
661 | { | |||
662 | if ( !m_pObjectProps.empty() ) | |||
663 | { | |||
664 | map< string, libcmis::PropertyPtr >::iterator it = m_pObjectProps.find( "cmis:name" ); | |||
665 | if ( it != m_pObjectProps.end( ) ) | |||
666 | { | |||
667 | vector< string > values = it->second->getStrings( ); | |||
668 | if ( !values.empty() ) | |||
669 | sTitle = STD_TO_OUSTR( values.front( ) )OUString( values.front( ).c_str(), values.front( ).length( ), (((rtl_TextEncoding) 76)) ); | |||
670 | } | |||
671 | } | |||
672 | } | |||
673 | ||||
674 | // Nothing worked... get it from the path | |||
675 | if ( sTitle.isEmpty( ) ) | |||
676 | { | |||
677 | OUString sPath = m_sObjectPath; | |||
678 | ||||
679 | // Get rid of the trailing slash problem | |||
680 | if ( sPath.endsWith("/") ) | |||
681 | sPath = sPath.copy( 0, sPath.getLength() - 1 ); | |||
682 | ||||
683 | // Get the last segment | |||
684 | sal_Int32 nPos = sPath.lastIndexOf( '/' ); | |||
685 | if ( nPos >= 0 ) | |||
686 | sTitle = sPath.copy( nPos + 1 ); | |||
687 | } | |||
688 | ||||
689 | if ( !sTitle.isEmpty( ) ) | |||
690 | xRow->appendString( rProp, sTitle ); | |||
691 | else | |||
692 | xRow->appendVoid( rProp ); | |||
693 | } | |||
694 | else if ( rProp.Name == "ObjectId" ) | |||
695 | { | |||
696 | OUString sId; | |||
697 | try | |||
698 | { | |||
699 | sId = STD_TO_OUSTR( getObject( xEnv )->getId() )OUString( getObject( xEnv )->getId().c_str(), getObject( xEnv )->getId().length( ), (((rtl_TextEncoding) 76)) ); | |||
700 | } | |||
701 | catch ( const libcmis::Exception& ) | |||
702 | { | |||
703 | if ( !m_pObjectProps.empty() ) | |||
704 | { | |||
705 | map< string, libcmis::PropertyPtr >::iterator it = m_pObjectProps.find( "cmis:objectId" ); | |||
706 | if ( it != m_pObjectProps.end( ) ) | |||
707 | { | |||
708 | vector< string > values = it->second->getStrings( ); | |||
709 | if ( !values.empty() ) | |||
710 | sId = STD_TO_OUSTR( values.front( ) )OUString( values.front( ).c_str(), values.front( ).length( ), (((rtl_TextEncoding) 76)) ); | |||
711 | } | |||
712 | } | |||
713 | } | |||
714 | ||||
715 | if ( !sId.isEmpty( ) ) | |||
716 | xRow->appendString( rProp, sId ); | |||
717 | else | |||
718 | xRow->appendVoid( rProp ); | |||
719 | } | |||
720 | else if ( rProp.Name == "TitleOnServer" ) | |||
721 | { | |||
722 | xRow->appendString( rProp, m_sObjectPath); | |||
723 | } | |||
724 | else if ( rProp.Name == "IsReadOnly" ) | |||
725 | { | |||
726 | boost::shared_ptr< libcmis::AllowableActions > allowableActions = getObject( xEnv )->getAllowableActions( ); | |||
727 | bool bReadOnly = false; | |||
728 | if ( !allowableActions->isAllowed( libcmis::ObjectAction::SetContentStream ) && | |||
729 | !allowableActions->isAllowed( libcmis::ObjectAction::CheckIn ) ) | |||
730 | bReadOnly = true; | |||
731 | ||||
732 | xRow->appendBoolean( rProp, bReadOnly ); | |||
733 | } | |||
734 | else if ( rProp.Name == "DateCreated" ) | |||
735 | { | |||
736 | util::DateTime aTime = lcl_boostToUnoTime( getObject( xEnv )->getCreationDate( ) ); | |||
737 | xRow->appendTimestamp( rProp, aTime ); | |||
738 | } | |||
739 | else if ( rProp.Name == "DateModified" ) | |||
740 | { | |||
741 | util::DateTime aTime = lcl_boostToUnoTime( getObject( xEnv )->getLastModificationDate( ) ); | |||
742 | xRow->appendTimestamp( rProp, aTime ); | |||
743 | } | |||
744 | else if ( rProp.Name == "Size" ) | |||
745 | { | |||
746 | try | |||
747 | { | |||
748 | libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject( xEnv ).get( ) ); | |||
749 | if ( nullptr != document ) | |||
750 | xRow->appendLong( rProp, document->getContentLength() ); | |||
751 | else | |||
752 | xRow->appendVoid( rProp ); | |||
753 | } | |||
754 | catch ( const libcmis::Exception& ) | |||
755 | { | |||
756 | xRow->appendVoid( rProp ); | |||
757 | } | |||
758 | } | |||
759 | else if ( rProp.Name == "CreatableContentsInfo" ) | |||
760 | { | |||
761 | xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) ); | |||
762 | } | |||
763 | else if ( rProp.Name == "MediaType" ) | |||
764 | { | |||
765 | try | |||
766 | { | |||
767 | libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject( xEnv ).get( ) ); | |||
768 | if ( nullptr != document ) | |||
769 | xRow->appendString( rProp, STD_TO_OUSTR( document->getContentType() )OUString( document->getContentType().c_str(), document-> getContentType().length( ), (((rtl_TextEncoding) 76)) ) ); | |||
770 | else | |||
771 | xRow->appendVoid( rProp ); | |||
772 | } | |||
773 | catch ( const libcmis::Exception& ) | |||
774 | { | |||
775 | xRow->appendVoid( rProp ); | |||
776 | } | |||
777 | } | |||
778 | else if ( rProp.Name == "IsVolume" ) | |||
779 | { | |||
780 | xRow->appendBoolean( rProp, false ); | |||
781 | } | |||
782 | else if ( rProp.Name == "IsRemote" ) | |||
783 | { | |||
784 | xRow->appendBoolean( rProp, false ); | |||
785 | } | |||
786 | else if ( rProp.Name == "IsRemoveable" ) | |||
787 | { | |||
788 | xRow->appendBoolean( rProp, false ); | |||
789 | } | |||
790 | else if ( rProp.Name == "IsFloppy" ) | |||
791 | { | |||
792 | xRow->appendBoolean( rProp, false ); | |||
793 | } | |||
794 | else if ( rProp.Name == "IsCompactDisc" ) | |||
795 | { | |||
796 | xRow->appendBoolean( rProp, false ); | |||
797 | } | |||
798 | else if ( rProp.Name == "IsHidden" ) | |||
799 | { | |||
800 | xRow->appendBoolean( rProp, false ); | |||
801 | } | |||
802 | else if ( rProp.Name == "TargetURL" ) | |||
803 | { | |||
804 | xRow->appendString( rProp, "" ); | |||
805 | } | |||
806 | else if ( rProp.Name == "BaseURI" ) | |||
807 | { | |||
808 | xRow->appendString( rProp, m_aURL.getBindingUrl( ) ); | |||
809 | } | |||
810 | else if ( rProp.Name == "CmisProperties" ) | |||
811 | { | |||
812 | try | |||
813 | { | |||
814 | libcmis::ObjectPtr object = getObject( xEnv ); | |||
815 | map< string, libcmis::PropertyPtr >& aProperties = object->getProperties( ); | |||
816 | uno::Sequence< document::CmisProperty > aCmisProperties( aProperties.size( ) ); | |||
817 | document::CmisProperty* pCmisProps = aCmisProperties.getArray( ); | |||
818 | sal_Int32 i = 0; | |||
819 | for ( const auto& [sId, rProperty] : aProperties ) | |||
820 | { | |||
821 | string sDisplayName = rProperty->getPropertyType()->getDisplayName( ); | |||
822 | bool bUpdatable = rProperty->getPropertyType()->isUpdatable( ); | |||
823 | bool bRequired = rProperty->getPropertyType()->isRequired( ); | |||
824 | bool bMultiValued = rProperty->getPropertyType()->isMultiValued(); | |||
825 | bool bOpenChoice = rProperty->getPropertyType()->isOpenChoice(); | |||
826 | ||||
827 | pCmisProps[i].Id = STD_TO_OUSTR( sId )OUString( sId.c_str(), sId.length( ), (((rtl_TextEncoding) 76 )) ); | |||
828 | pCmisProps[i].Name = STD_TO_OUSTR( sDisplayName )OUString( sDisplayName.c_str(), sDisplayName.length( ), (((rtl_TextEncoding ) 76)) ); | |||
829 | pCmisProps[i].Updatable = bUpdatable; | |||
830 | pCmisProps[i].Required = bRequired; | |||
831 | pCmisProps[i].MultiValued = bMultiValued; | |||
832 | pCmisProps[i].OpenChoice = bOpenChoice; | |||
833 | pCmisProps[i].Value = lcl_cmisPropertyToUno( rProperty ); | |||
834 | switch ( rProperty->getPropertyType( )->getType( ) ) | |||
835 | { | |||
836 | default: | |||
837 | case libcmis::PropertyType::String: | |||
838 | pCmisProps[i].Type = CMIS_TYPE_STRING"String"; | |||
839 | break; | |||
840 | case libcmis::PropertyType::Integer: | |||
841 | pCmisProps[i].Type = CMIS_TYPE_INTEGER"Integer"; | |||
842 | break; | |||
843 | case libcmis::PropertyType::Decimal: | |||
844 | pCmisProps[i].Type = CMIS_TYPE_DECIMAL"Decimal"; | |||
845 | break; | |||
846 | case libcmis::PropertyType::Bool: | |||
847 | pCmisProps[i].Type = CMIS_TYPE_BOOL"Bool"; | |||
848 | break; | |||
849 | case libcmis::PropertyType::DateTime: | |||
850 | pCmisProps[i].Type = CMIS_TYPE_DATETIME"Datetime"; | |||
851 | break; | |||
852 | } | |||
853 | ++i; | |||
854 | } | |||
855 | xRow->appendObject( rProp.Name, uno::makeAny( aCmisProperties ) ); | |||
856 | } | |||
857 | catch ( const libcmis::Exception& ) | |||
858 | { | |||
859 | xRow->appendVoid( rProp ); | |||
860 | } | |||
861 | } | |||
862 | else if ( rProp.Name == "IsVersionable" ) | |||
863 | { | |||
864 | try | |||
865 | { | |||
866 | libcmis::ObjectPtr object = getObject( xEnv ); | |||
867 | bool bIsVersionable = object->getTypeDescription( )->isVersionable( ); | |||
868 | xRow->appendBoolean( rProp, bIsVersionable ); | |||
869 | } | |||
870 | catch ( const libcmis::Exception& ) | |||
871 | { | |||
872 | xRow->appendVoid( rProp ); | |||
873 | } | |||
874 | } | |||
875 | else if ( rProp.Name == "CanCheckOut" ) | |||
876 | { | |||
877 | try | |||
878 | { | |||
879 | libcmis::ObjectPtr pObject = getObject( xEnv ); | |||
880 | libcmis::AllowableActionsPtr aAllowables = pObject->getAllowableActions( ); | |||
881 | bool bAllowed = false; | |||
882 | if ( aAllowables ) | |||
883 | { | |||
884 | bAllowed = aAllowables->isAllowed( libcmis::ObjectAction::CheckOut ); | |||
885 | } | |||
886 | xRow->appendBoolean( rProp, bAllowed ); | |||
887 | } | |||
888 | catch ( const libcmis::Exception& ) | |||
889 | { | |||
890 | xRow->appendVoid( rProp ); | |||
891 | } | |||
892 | } | |||
893 | else if ( rProp.Name == "CanCancelCheckOut" ) | |||
894 | { | |||
895 | try | |||
896 | { | |||
897 | libcmis::ObjectPtr pObject = getObject( xEnv ); | |||
898 | libcmis::AllowableActionsPtr aAllowables = pObject->getAllowableActions( ); | |||
899 | bool bAllowed = false; | |||
900 | if ( aAllowables ) | |||
901 | { | |||
902 | bAllowed = aAllowables->isAllowed( libcmis::ObjectAction::CancelCheckOut ); | |||
903 | } | |||
904 | xRow->appendBoolean( rProp, bAllowed ); | |||
905 | } | |||
906 | catch ( const libcmis::Exception& ) | |||
907 | { | |||
908 | xRow->appendVoid( rProp ); | |||
909 | } | |||
910 | } | |||
911 | else if ( rProp.Name == "CanCheckIn" ) | |||
912 | { | |||
913 | try | |||
914 | { | |||
915 | libcmis::ObjectPtr pObject = getObject( xEnv ); | |||
916 | libcmis::AllowableActionsPtr aAllowables = pObject->getAllowableActions( ); | |||
917 | bool bAllowed = false; | |||
918 | if ( aAllowables ) | |||
919 | { | |||
920 | bAllowed = aAllowables->isAllowed( libcmis::ObjectAction::CheckIn ); | |||
921 | } | |||
922 | xRow->appendBoolean( rProp, bAllowed ); | |||
923 | } | |||
924 | catch ( const libcmis::Exception& ) | |||
925 | { | |||
926 | xRow->appendVoid( rProp ); | |||
927 | } | |||
928 | } | |||
929 | else | |||
930 | SAL_INFO( "ucb.ucp.cmis", "Looking for unsupported property " << rProp.Name )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Looking for unsupported property " << rProp.Name) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "930" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Looking for unsupported property " << rProp.Name), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Looking for unsupported property " << rProp.Name; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "930" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Looking for unsupported property " << rProp .Name) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "930" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Looking for unsupported property " << rProp.Name), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Looking for unsupported property " << rProp.Name; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "930" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
931 | } | |||
932 | catch (const libcmis::Exception&) | |||
933 | { | |||
934 | xRow->appendVoid( rProp ); | |||
935 | } | |||
936 | } | |||
937 | ||||
938 | return uno::Reference< sdbc::XRow >( xRow.get() ); | |||
939 | } | |||
940 | ||||
941 | uno::Any Content::open(const ucb::OpenCommandArgument2 & rOpenCommand, | |||
942 | const uno::Reference< ucb::XCommandEnvironment > & xEnv ) | |||
943 | { | |||
944 | bool bIsFolder = isFolder( xEnv ); | |||
945 | ||||
946 | // Handle the case of the non-existing file | |||
947 | if ( !getObject( xEnv ) ) | |||
948 | { | |||
949 | uno::Sequence< uno::Any > aArgs( 1 ); | |||
950 | aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier(); | |||
951 | uno::Any aErr = uno::makeAny( | |||
952 | ucb::InteractiveAugmentedIOException(OUString(), static_cast< cppu::OWeakObject * >( this ), | |||
953 | task::InteractionClassification_ERROR, | |||
954 | bIsFolder ? ucb::IOErrorCode_NOT_EXISTING_PATH : ucb::IOErrorCode_NOT_EXISTING, aArgs) | |||
955 | ); | |||
956 | ||||
957 | ucbhelper::cancelCommandExecution(aErr, xEnv); | |||
958 | } | |||
959 | ||||
960 | uno::Any aRet; | |||
961 | ||||
962 | bool bOpenFolder = ( | |||
963 | ( rOpenCommand.Mode == ucb::OpenMode::ALL ) || | |||
964 | ( rOpenCommand.Mode == ucb::OpenMode::FOLDERS ) || | |||
965 | ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENTS ) | |||
966 | ); | |||
967 | ||||
968 | if ( bOpenFolder && bIsFolder ) | |||
969 | { | |||
970 | uno::Reference< ucb::XDynamicResultSet > xSet | |||
971 | = new DynamicResultSet(m_xContext, this, rOpenCommand, xEnv ); | |||
972 | aRet <<= xSet; | |||
973 | } | |||
974 | else if ( rOpenCommand.Sink.is() ) | |||
975 | { | |||
976 | if ( | |||
977 | ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) || | |||
978 | ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) | |||
979 | ) | |||
980 | { | |||
981 | ucbhelper::cancelCommandExecution( | |||
982 | uno::makeAny ( ucb::UnsupportedOpenModeException | |||
983 | ( OUString(), static_cast< cppu::OWeakObject * >( this ), | |||
984 | sal_Int16( rOpenCommand.Mode ) ) ), | |||
985 | xEnv ); | |||
986 | } | |||
987 | ||||
988 | if ( !feedSink( rOpenCommand.Sink, xEnv ) ) | |||
989 | { | |||
990 | // Note: rOpenCommand.Sink may contain an XStream | |||
991 | // implementation. Support for this type of | |||
992 | // sink is optional... | |||
993 | SAL_INFO( "ucb.ucp.cmis", "Failed to copy data to sink" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Failed to copy data to sink" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "993" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Failed to copy data to sink"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Failed to copy data to sink"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "993" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Failed to copy data to sink") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "993" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Failed to copy data to sink"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Failed to copy data to sink"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "993" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
994 | ||||
995 | ucbhelper::cancelCommandExecution( | |||
996 | uno::makeAny (ucb::UnsupportedDataSinkException | |||
997 | ( OUString(), static_cast< cppu::OWeakObject * >( this ), | |||
998 | rOpenCommand.Sink ) ), | |||
999 | xEnv ); | |||
1000 | } | |||
1001 | } | |||
1002 | else | |||
1003 | SAL_INFO( "ucb.ucp.cmis", "Open falling through ..." )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Open falling through ..." ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1003" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Open falling through ..."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Open falling through ..."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1003" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Open falling through ...") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1003" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Open falling through ..."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Open falling through ..."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1003" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1004 | ||||
1005 | return aRet; | |||
1006 | } | |||
1007 | ||||
1008 | OUString Content::checkIn( const ucb::CheckinArgument& rArg, | |||
1009 | const uno::Reference< ucb::XCommandEnvironment > & xEnv ) | |||
1010 | { | |||
1011 | ucbhelper::Content aSourceContent( rArg.SourceURL, xEnv, comphelper::getProcessComponentContext( ) ); | |||
1012 | uno::Reference< io::XInputStream > xIn = aSourceContent.openStream( ); | |||
1013 | ||||
1014 | libcmis::ObjectPtr object; | |||
1015 | try | |||
1016 | { | |||
1017 | object = getObject( xEnv ); | |||
| ||||
1018 | } | |||
1019 | catch ( const libcmis::Exception& e ) | |||
1020 | { | |||
1021 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: " << e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1021" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1021" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1021" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1021" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1022 | ucbhelper::cancelCommandExecution( | |||
1023 | ucb::IOErrorCode_GENERAL, | |||
1024 | uno::Sequence< uno::Any >( 0 ), | |||
1025 | xEnv, | |||
1026 | OUString::createFromAscii( e.what() ) ); | |||
1027 | } | |||
1028 | ||||
1029 | libcmis::Document* pPwc = dynamic_cast< libcmis::Document* >( object.get( ) ); | |||
1030 | if ( !pPwc ) | |||
1031 | { | |||
1032 | ucbhelper::cancelCommandExecution( | |||
1033 | ucb::IOErrorCode_GENERAL, | |||
1034 | uno::Sequence< uno::Any >( 0 ), | |||
1035 | xEnv, | |||
1036 | "Checkin only supported by documents" ); | |||
1037 | } | |||
1038 | ||||
1039 | boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) ); | |||
1040 | uno::Reference < io::XOutputStream > xOutput = new StdOutputStream( pOut ); | |||
1041 | copyData( xIn, xOutput ); | |||
1042 | ||||
1043 | map< string, libcmis::PropertyPtr > newProperties; | |||
1044 | libcmis::DocumentPtr pDoc; | |||
1045 | ||||
1046 | try | |||
1047 | { | |||
1048 | pDoc = pPwc->checkIn( rArg.MajorVersion, OUSTR_TO_STDSTR( rArg.VersionComment )string( OUStringToOString( rArg.VersionComment, (((rtl_TextEncoding ) 76)) ).getStr() ), newProperties, | |||
| ||||
1049 | pOut, OUSTR_TO_STDSTR( rArg.MimeType )string( OUStringToOString( rArg.MimeType, (((rtl_TextEncoding ) 76)) ).getStr() ), OUSTR_TO_STDSTR( rArg.NewTitle )string( OUStringToOString( rArg.NewTitle, (((rtl_TextEncoding ) 76)) ).getStr() ) ); | |||
1050 | } | |||
1051 | catch ( const libcmis::Exception& e ) | |||
1052 | { | |||
1053 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: " << e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1053" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1053" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1053" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1053" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1054 | ucbhelper::cancelCommandExecution( | |||
1055 | ucb::IOErrorCode_GENERAL, | |||
1056 | uno::Sequence< uno::Any >( 0 ), | |||
1057 | xEnv, | |||
1058 | OUString::createFromAscii( e.what() ) ); | |||
1059 | } | |||
1060 | ||||
1061 | // Get the URL and send it back as a result | |||
1062 | URL aCmisUrl( m_sURL ); | |||
1063 | vector< string > aPaths = pDoc->getPaths( ); | |||
1064 | if ( !aPaths.empty() ) | |||
1065 | { | |||
1066 | string sPath = aPaths.front( ); | |||
1067 | aCmisUrl.setObjectPath( STD_TO_OUSTR( sPath )OUString( sPath.c_str(), sPath.length( ), (((rtl_TextEncoding ) 76)) ) ); | |||
1068 | } | |||
1069 | else | |||
1070 | { | |||
1071 | // We may have unfiled document depending on the server, those | |||
1072 | // won't have any path, use their ID instead | |||
1073 | string sId = pDoc->getId( ); | |||
1074 | aCmisUrl.setObjectId( STD_TO_OUSTR( sId )OUString( sId.c_str(), sId.length( ), (((rtl_TextEncoding) 76 )) ) ); | |||
1075 | } | |||
1076 | return aCmisUrl.asString( ); | |||
1077 | } | |||
1078 | ||||
1079 | OUString Content::checkOut( const uno::Reference< ucb::XCommandEnvironment > & xEnv ) | |||
1080 | { | |||
1081 | OUString aRet; | |||
1082 | try | |||
1083 | { | |||
1084 | // Checkout the document if possible | |||
1085 | libcmis::DocumentPtr pDoc = boost::dynamic_pointer_cast< libcmis::Document >( getObject( xEnv ) ); | |||
1086 | if ( pDoc.get( ) == nullptr ) | |||
1087 | { | |||
1088 | ucbhelper::cancelCommandExecution( | |||
1089 | ucb::IOErrorCode_GENERAL, | |||
1090 | uno::Sequence< uno::Any >( 0 ), | |||
1091 | xEnv, | |||
1092 | "Checkout only supported by documents" ); | |||
1093 | } | |||
1094 | libcmis::DocumentPtr pPwc = pDoc->checkOut( ); | |||
1095 | ||||
1096 | // Compute the URL of the Private Working Copy (PWC) | |||
1097 | URL aCmisUrl( m_sURL ); | |||
1098 | vector< string > aPaths = pPwc->getPaths( ); | |||
1099 | if ( !aPaths.empty() ) | |||
1100 | { | |||
1101 | string sPath = aPaths.front( ); | |||
1102 | aCmisUrl.setObjectPath( STD_TO_OUSTR( sPath )OUString( sPath.c_str(), sPath.length( ), (((rtl_TextEncoding ) 76)) ) ); | |||
1103 | } | |||
1104 | else | |||
1105 | { | |||
1106 | // We may have unfiled PWC depending on the server, those | |||
1107 | // won't have any path, use their ID instead | |||
1108 | string sId = pPwc->getId( ); | |||
1109 | aCmisUrl.setObjectId( STD_TO_OUSTR( sId )OUString( sId.c_str(), sId.length( ), (((rtl_TextEncoding) 76 )) ) ); | |||
1110 | } | |||
1111 | aRet = aCmisUrl.asString( ); | |||
1112 | } | |||
1113 | catch ( const libcmis::Exception& e ) | |||
1114 | { | |||
1115 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: " << e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1115" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1115" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1115" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1115" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1116 | ucbhelper::cancelCommandExecution( | |||
1117 | ucb::IOErrorCode_GENERAL, | |||
1118 | uno::Sequence< uno::Any >( 0 ), | |||
1119 | xEnv, | |||
1120 | o3tl::runtimeToOUString(e.what())); | |||
1121 | } | |||
1122 | return aRet; | |||
1123 | } | |||
1124 | ||||
1125 | OUString Content::cancelCheckOut( const uno::Reference< ucb::XCommandEnvironment > & xEnv ) | |||
1126 | { | |||
1127 | OUString aRet; | |||
1128 | try | |||
1129 | { | |||
1130 | libcmis::DocumentPtr pPwc = boost::dynamic_pointer_cast< libcmis::Document >( getObject( xEnv ) ); | |||
1131 | if ( pPwc.get( ) == nullptr ) | |||
1132 | { | |||
1133 | ucbhelper::cancelCommandExecution( | |||
1134 | ucb::IOErrorCode_GENERAL, | |||
1135 | uno::Sequence< uno::Any >( 0 ), | |||
1136 | xEnv, | |||
1137 | "CancelCheckout only supported by documents" ); | |||
1138 | } | |||
1139 | pPwc->cancelCheckout( ); | |||
1140 | ||||
1141 | // Get the Original document (latest version) | |||
1142 | vector< libcmis::DocumentPtr > aVersions = pPwc->getAllVersions( ); | |||
1143 | for ( const auto& rVersion : aVersions ) | |||
1144 | { | |||
1145 | libcmis::DocumentPtr pVersion = rVersion; | |||
1146 | map< string, libcmis::PropertyPtr > aProps = pVersion->getProperties( ); | |||
1147 | bool bIsLatestVersion = false; | |||
1148 | map< string, libcmis::PropertyPtr >::iterator propIt = aProps.find( string( "cmis:isLatestVersion" ) ); | |||
1149 | if ( propIt != aProps.end( ) && !propIt->second->getBools( ).empty( ) ) | |||
1150 | { | |||
1151 | bIsLatestVersion = propIt->second->getBools( ).front( ); | |||
1152 | } | |||
1153 | ||||
1154 | if ( bIsLatestVersion ) | |||
1155 | { | |||
1156 | // Compute the URL of the Document | |||
1157 | URL aCmisUrl( m_sURL ); | |||
1158 | vector< string > aPaths = pVersion->getPaths( ); | |||
1159 | if ( !aPaths.empty() ) | |||
1160 | { | |||
1161 | string sPath = aPaths.front( ); | |||
1162 | aCmisUrl.setObjectPath( STD_TO_OUSTR( sPath )OUString( sPath.c_str(), sPath.length( ), (((rtl_TextEncoding ) 76)) ) ); | |||
1163 | } | |||
1164 | else | |||
1165 | { | |||
1166 | // We may have unfiled doc depending on the server, those | |||
1167 | // won't have any path, use their ID instead | |||
1168 | string sId = pVersion->getId( ); | |||
1169 | aCmisUrl.setObjectId( STD_TO_OUSTR( sId )OUString( sId.c_str(), sId.length( ), (((rtl_TextEncoding) 76 )) ) ); | |||
1170 | } | |||
1171 | aRet = aCmisUrl.asString( ); | |||
1172 | break; | |||
1173 | } | |||
1174 | } | |||
1175 | } | |||
1176 | catch ( const libcmis::Exception& e ) | |||
1177 | { | |||
1178 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: " << e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1178" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1178" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1178" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1178" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1179 | ucbhelper::cancelCommandExecution( | |||
1180 | ucb::IOErrorCode_GENERAL, | |||
1181 | uno::Sequence< uno::Any >( 0 ), | |||
1182 | xEnv, | |||
1183 | o3tl::runtimeToOUString(e.what())); | |||
1184 | } | |||
1185 | return aRet; | |||
1186 | } | |||
1187 | ||||
1188 | uno::Sequence< document::CmisVersion> Content::getAllVersions( const uno::Reference< ucb::XCommandEnvironment > & xEnv ) | |||
1189 | { | |||
1190 | try | |||
1191 | { | |||
1192 | // get the document | |||
1193 | libcmis::DocumentPtr pDoc = boost::dynamic_pointer_cast< libcmis::Document >( getObject( xEnv ) ); | |||
1194 | if ( pDoc.get( ) == nullptr ) | |||
1195 | { | |||
1196 | ucbhelper::cancelCommandExecution( | |||
1197 | ucb::IOErrorCode_GENERAL, | |||
1198 | uno::Sequence< uno::Any >( 0 ), | |||
1199 | xEnv, | |||
1200 | "Can not get the document" ); | |||
1201 | } | |||
1202 | vector< libcmis::DocumentPtr > aCmisVersions = pDoc->getAllVersions( ); | |||
1203 | uno::Sequence< document::CmisVersion > aVersions( aCmisVersions.size( ) ); | |||
1204 | int i = 0; | |||
1205 | for ( const auto& rVersion : aCmisVersions ) | |||
1206 | { | |||
1207 | libcmis::DocumentPtr pVersion = rVersion; | |||
1208 | aVersions[i].Id = STD_TO_OUSTR( pVersion->getId( ) )OUString( pVersion->getId( ).c_str(), pVersion->getId( ) .length( ), (((rtl_TextEncoding) 76)) ); | |||
1209 | aVersions[i].Author = STD_TO_OUSTR( pVersion->getCreatedBy( ) )OUString( pVersion->getCreatedBy( ).c_str(), pVersion-> getCreatedBy( ).length( ), (((rtl_TextEncoding) 76)) ); | |||
1210 | aVersions[i].TimeStamp = lcl_boostToUnoTime( pVersion->getLastModificationDate( ) ); | |||
1211 | aVersions[i].Comment = STD_TO_OUSTR( pVersion->getStringProperty("cmis:checkinComment") )OUString( pVersion->getStringProperty("cmis:checkinComment" ).c_str(), pVersion->getStringProperty("cmis:checkinComment" ).length( ), (((rtl_TextEncoding) 76)) ); | |||
1212 | ++i; | |||
1213 | } | |||
1214 | return aVersions; | |||
1215 | } | |||
1216 | catch ( const libcmis::Exception& e ) | |||
1217 | { | |||
1218 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: " << e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1218" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1218" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1218" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1218" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1219 | ucbhelper::cancelCommandExecution( | |||
1220 | ucb::IOErrorCode_GENERAL, | |||
1221 | uno::Sequence< uno::Any >( 0 ), | |||
1222 | xEnv, | |||
1223 | o3tl::runtimeToOUString(e.what())); | |||
1224 | } | |||
1225 | return uno::Sequence< document::CmisVersion > ( ); | |||
1226 | } | |||
1227 | ||||
1228 | void Content::transfer( const ucb::TransferInfo& rTransferInfo, | |||
1229 | const uno::Reference< ucb::XCommandEnvironment > & xEnv ) | |||
1230 | { | |||
1231 | // If the source isn't on the same CMIS repository, then simply copy | |||
1232 | INetURLObject aSourceUrl( rTransferInfo.SourceURL ); | |||
1233 | if ( aSourceUrl.GetProtocol() != INetProtocol::Cmis ) | |||
1234 | { | |||
1235 | OUString sSrcBindingUrl = URL( rTransferInfo.SourceURL ).getBindingUrl( ); | |||
1236 | if ( sSrcBindingUrl != m_aURL.getBindingUrl( ) ) | |||
1237 | { | |||
1238 | ucbhelper::cancelCommandExecution( | |||
1239 | uno::makeAny( | |||
1240 | ucb::InteractiveBadTransferURLException( | |||
1241 | "Unsupported URL scheme!", | |||
1242 | static_cast< cppu::OWeakObject * >( this ) ) ), | |||
1243 | xEnv ); | |||
1244 | } | |||
1245 | } | |||
1246 | ||||
1247 | SAL_INFO( "ucb.ucp.cmis", "TODO - Content::transfer()" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "TODO - Content::transfer()" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1247" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "TODO - Content::transfer()"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "TODO - Content::transfer()"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1247" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "TODO - Content::transfer()") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1247" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "TODO - Content::transfer()"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "TODO - Content::transfer()"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1247" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1248 | } | |||
1249 | ||||
1250 | void Content::insert( const uno::Reference< io::XInputStream > & xInputStream, | |||
1251 | bool bReplaceExisting, const OUString& rMimeType, | |||
1252 | const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
1253 | { | |||
1254 | if ( !xInputStream.is() ) | |||
1255 | { | |||
1256 | ucbhelper::cancelCommandExecution( uno::makeAny | |||
1257 | ( ucb::MissingInputStreamException | |||
1258 | ( OUString(), static_cast< cppu::OWeakObject * >( this ) ) ), | |||
1259 | xEnv ); | |||
1260 | } | |||
1261 | ||||
1262 | // For transient content, the URL is the one of the parent | |||
1263 | if ( !m_bTransient ) | |||
1264 | return; | |||
1265 | ||||
1266 | OUString sNewPath; | |||
1267 | ||||
1268 | // Try to get the object from the server if there is any | |||
1269 | libcmis::FolderPtr pFolder; | |||
1270 | try | |||
1271 | { | |||
1272 | pFolder = boost::dynamic_pointer_cast< libcmis::Folder >( getObject( xEnv ) ); | |||
1273 | } | |||
1274 | catch ( const libcmis::Exception& ) | |||
1275 | { | |||
1276 | } | |||
1277 | ||||
1278 | if ( pFolder == nullptr ) | |||
1279 | return; | |||
1280 | ||||
1281 | libcmis::ObjectPtr object; | |||
1282 | map< string, libcmis::PropertyPtr >::iterator it = m_pObjectProps.find( "cmis:name" ); | |||
1283 | if ( it == m_pObjectProps.end( ) ) | |||
1284 | { | |||
1285 | ucbhelper::cancelCommandExecution( uno::makeAny | |||
1286 | ( uno::RuntimeException( "Missing name property", | |||
1287 | static_cast< cppu::OWeakObject * >( this ) ) ), | |||
1288 | xEnv ); | |||
1289 | } | |||
1290 | string newName = it->second->getStrings( ).front( ); | |||
1291 | string newPath = OUSTR_TO_STDSTR( m_sObjectPath )string( OUStringToOString( m_sObjectPath, (((rtl_TextEncoding ) 76)) ).getStr() ); | |||
1292 | if ( !newPath.empty( ) && newPath[ newPath.size( ) - 1 ] != '/' ) | |||
1293 | newPath += "/"; | |||
1294 | newPath += newName; | |||
1295 | try | |||
1296 | { | |||
1297 | if ( !m_sObjectId.isEmpty( ) ) | |||
1298 | object = getSession( xEnv )->getObject( OUSTR_TO_STDSTR( m_sObjectId)string( OUStringToOString( m_sObjectId, (((rtl_TextEncoding) 76 )) ).getStr() ) ); | |||
1299 | else | |||
1300 | object = getSession( xEnv )->getObjectByPath( newPath ); | |||
1301 | sNewPath = STD_TO_OUSTR( newPath )OUString( newPath.c_str(), newPath.length( ), (((rtl_TextEncoding ) 76)) ); | |||
1302 | } | |||
1303 | catch ( const libcmis::Exception& ) | |||
1304 | { | |||
1305 | // Nothing matched the path | |||
1306 | } | |||
1307 | ||||
1308 | if ( nullptr != object.get( ) ) | |||
1309 | { | |||
1310 | // Are the base type matching? | |||
1311 | if ( object->getBaseType( ) != m_pObjectType->getBaseType( )->getId() ) | |||
1312 | { | |||
1313 | ucbhelper::cancelCommandExecution( uno::makeAny | |||
1314 | ( uno::RuntimeException( "Can't change a folder into a document and vice-versa.", | |||
1315 | static_cast< cppu::OWeakObject * >( this ) ) ), | |||
1316 | xEnv ); | |||
1317 | } | |||
1318 | ||||
1319 | // Update the existing object if it's a document | |||
1320 | libcmis::Document* document = dynamic_cast< libcmis::Document* >( object.get( ) ); | |||
1321 | if ( nullptr != document ) | |||
1322 | { | |||
1323 | boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) ); | |||
1324 | uno::Reference < io::XOutputStream > xOutput = new StdOutputStream( pOut ); | |||
1325 | copyData( xInputStream, xOutput ); | |||
1326 | try | |||
1327 | { | |||
1328 | document->setContentStream( pOut, OUSTR_TO_STDSTR( rMimeType )string( OUStringToOString( rMimeType, (((rtl_TextEncoding) 76 )) ).getStr() ), string( ), bReplaceExisting ); | |||
1329 | } | |||
1330 | catch ( const libcmis::Exception& ) | |||
1331 | { | |||
1332 | ucbhelper::cancelCommandExecution( uno::makeAny | |||
1333 | ( uno::RuntimeException( "Error when setting document content", | |||
1334 | static_cast< cppu::OWeakObject * >( this ) ) ), | |||
1335 | xEnv ); | |||
1336 | } | |||
1337 | } | |||
1338 | } | |||
1339 | else | |||
1340 | { | |||
1341 | // We need to create a brand new object... either folder or document | |||
1342 | bool bIsFolder = getObjectType( xEnv )->getBaseType( )->getId( ) == "cmis:folder"; | |||
1343 | setCmisProperty( "cmis:objectTypeId", getObjectType( xEnv )->getId( ), xEnv ); | |||
1344 | ||||
1345 | if ( bIsFolder ) | |||
1346 | { | |||
1347 | try | |||
1348 | { | |||
1349 | pFolder->createFolder( m_pObjectProps ); | |||
1350 | sNewPath = STD_TO_OUSTR( newPath )OUString( newPath.c_str(), newPath.length( ), (((rtl_TextEncoding ) 76)) ); | |||
1351 | } | |||
1352 | catch ( const libcmis::Exception& ) | |||
1353 | { | |||
1354 | ucbhelper::cancelCommandExecution( uno::makeAny | |||
1355 | ( uno::RuntimeException( "Error when creating folder", | |||
1356 | static_cast< cppu::OWeakObject * >( this ) ) ), | |||
1357 | xEnv ); | |||
1358 | } | |||
1359 | } | |||
1360 | else | |||
1361 | { | |||
1362 | boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) ); | |||
1363 | uno::Reference < io::XOutputStream > xOutput = new StdOutputStream( pOut ); | |||
1364 | copyData( xInputStream, xOutput ); | |||
1365 | try | |||
1366 | { | |||
1367 | pFolder->createDocument( m_pObjectProps, pOut, OUSTR_TO_STDSTR( rMimeType )string( OUStringToOString( rMimeType, (((rtl_TextEncoding) 76 )) ).getStr() ), string() ); | |||
1368 | sNewPath = STD_TO_OUSTR( newPath )OUString( newPath.c_str(), newPath.length( ), (((rtl_TextEncoding ) 76)) ); | |||
1369 | } | |||
1370 | catch ( const libcmis::Exception& ) | |||
1371 | { | |||
1372 | ucbhelper::cancelCommandExecution( uno::makeAny | |||
1373 | ( uno::RuntimeException( "Error when creating document", | |||
1374 | static_cast< cppu::OWeakObject * >( this ) ) ), | |||
1375 | xEnv ); | |||
1376 | } | |||
1377 | } | |||
1378 | } | |||
1379 | ||||
1380 | if ( sNewPath.isEmpty( ) && m_sObjectId.isEmpty( ) ) | |||
1381 | return; | |||
1382 | ||||
1383 | // Update the current content: it's no longer transient | |||
1384 | m_sObjectPath = sNewPath; | |||
1385 | URL aUrl( m_sURL ); | |||
1386 | aUrl.setObjectPath( m_sObjectPath ); | |||
1387 | aUrl.setObjectId( m_sObjectId ); | |||
1388 | m_sURL = aUrl.asString( ); | |||
1389 | m_pObject.reset( ); | |||
1390 | m_pObjectType.reset( ); | |||
1391 | m_pObjectProps.clear( ); | |||
1392 | m_bTransient = false; | |||
1393 | inserted(); | |||
1394 | } | |||
1395 | ||||
1396 | const int TRANSFER_BUFFER_SIZE = 65536; | |||
1397 | ||||
1398 | void Content::copyData( | |||
1399 | const uno::Reference< io::XInputStream >& xIn, | |||
1400 | const uno::Reference< io::XOutputStream >& xOut ) | |||
1401 | { | |||
1402 | uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE ); | |||
1403 | ||||
1404 | while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 ) | |||
1405 | xOut->writeBytes( theData ); | |||
1406 | ||||
1407 | xOut->closeOutput(); | |||
1408 | } | |||
1409 | ||||
1410 | uno::Sequence< uno::Any > Content::setPropertyValues( | |||
1411 | const uno::Sequence< beans::PropertyValue >& rValues, | |||
1412 | const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
1413 | { | |||
1414 | try | |||
1415 | { | |||
1416 | // Get the already set properties if possible | |||
1417 | if ( !m_bTransient && getObject( xEnv ).get( ) ) | |||
1418 | { | |||
1419 | m_pObjectProps.clear( ); | |||
1420 | m_pObjectType = getObject( xEnv )->getTypeDescription(); | |||
1421 | } | |||
1422 | } | |||
1423 | catch ( const libcmis::Exception& e ) | |||
1424 | { | |||
1425 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: " << e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1425" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1425" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1425" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1425" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1426 | ucbhelper::cancelCommandExecution( | |||
1427 | ucb::IOErrorCode_GENERAL, | |||
1428 | uno::Sequence< uno::Any >( 0 ), | |||
1429 | xEnv, | |||
1430 | o3tl::runtimeToOUString(e.what())); | |||
1431 | } | |||
1432 | ||||
1433 | sal_Int32 nCount = rValues.getLength(); | |||
1434 | uno::Sequence< uno::Any > aRet( nCount ); | |||
1435 | ||||
1436 | bool bChanged = false; | |||
1437 | const beans::PropertyValue* pValues = rValues.getConstArray(); | |||
1438 | for ( sal_Int32 n = 0; n < nCount; ++n ) | |||
1439 | { | |||
1440 | const beans::PropertyValue& rValue = pValues[ n ]; | |||
1441 | if ( rValue.Name == "ContentType" || | |||
1442 | rValue.Name == "MediaType" || | |||
1443 | rValue.Name == "IsDocument" || | |||
1444 | rValue.Name == "IsFolder" || | |||
1445 | rValue.Name == "Size" || | |||
1446 | rValue.Name == "CreatableContentsInfo" ) | |||
1447 | { | |||
1448 | lang::IllegalAccessException e ( "Property is read-only!", | |||
1449 | static_cast< cppu::OWeakObject* >( this ) ); | |||
1450 | aRet[ n ] <<= e; | |||
1451 | } | |||
1452 | else if ( rValue.Name == "Title" ) | |||
1453 | { | |||
1454 | OUString aNewTitle; | |||
1455 | if (!( rValue.Value >>= aNewTitle )) | |||
1456 | { | |||
1457 | aRet[ n ] <<= beans::IllegalTypeException | |||
1458 | ( "Property value has wrong type!", | |||
1459 | static_cast< cppu::OWeakObject * >( this ) ); | |||
1460 | continue; | |||
1461 | } | |||
1462 | ||||
1463 | if ( aNewTitle.getLength() <= 0 ) | |||
1464 | { | |||
1465 | aRet[ n ] <<= lang::IllegalArgumentException | |||
1466 | ( "Empty title not allowed!", | |||
1467 | static_cast< cppu::OWeakObject * >( this ), -1 ); | |||
1468 | continue; | |||
1469 | ||||
1470 | } | |||
1471 | ||||
1472 | setCmisProperty( "cmis:name", OUSTR_TO_STDSTR( aNewTitle )string( OUStringToOString( aNewTitle, (((rtl_TextEncoding) 76 )) ).getStr() ), xEnv ); | |||
1473 | bChanged = true; | |||
1474 | } | |||
1475 | else | |||
1476 | { | |||
1477 | SAL_INFO( "ucb.ucp.cmis", "Couldn't set property: " << rValue.Name )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Couldn't set property: " << rValue.Name) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1477" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Couldn't set property: " << rValue .Name), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Couldn't set property: " << rValue.Name; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1477" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Couldn't set property: " << rValue.Name) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1477" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Couldn't set property: " << rValue .Name), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Couldn't set property: " << rValue.Name; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1477" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1478 | lang::IllegalAccessException e ( "Property is read-only!", | |||
1479 | static_cast< cppu::OWeakObject* >( this ) ); | |||
1480 | aRet[ n ] <<= e; | |||
1481 | } | |||
1482 | } | |||
1483 | ||||
1484 | try | |||
1485 | { | |||
1486 | if ( !m_bTransient && bChanged ) | |||
1487 | { | |||
1488 | getObject( xEnv )->updateProperties( m_pObjectProps ); | |||
1489 | } | |||
1490 | } | |||
1491 | catch ( const libcmis::Exception& e ) | |||
1492 | { | |||
1493 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: " << e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1493" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1493" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1493" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1493" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1494 | ucbhelper::cancelCommandExecution( | |||
1495 | ucb::IOErrorCode_GENERAL, | |||
1496 | uno::Sequence< uno::Any >( 0 ), | |||
1497 | xEnv, | |||
1498 | o3tl::runtimeToOUString(e.what())); | |||
1499 | } | |||
1500 | ||||
1501 | return aRet; | |||
1502 | } | |||
1503 | ||||
1504 | bool Content::feedSink( const uno::Reference< uno::XInterface>& xSink, | |||
1505 | const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
1506 | { | |||
1507 | if ( !xSink.is() ) | |||
1508 | return false; | |||
1509 | ||||
1510 | uno::Reference< io::XOutputStream > xOut(xSink, uno::UNO_QUERY ); | |||
1511 | uno::Reference< io::XActiveDataSink > xDataSink(xSink, uno::UNO_QUERY ); | |||
1512 | uno::Reference< io::XActiveDataStreamer > xDataStreamer( xSink, uno::UNO_QUERY ); | |||
1513 | ||||
1514 | if ( !xOut.is() && !xDataSink.is() && ( !xDataStreamer.is() || !xDataStreamer->getStream().is() ) ) | |||
1515 | return false; | |||
1516 | ||||
1517 | if ( xDataStreamer.is() && !xOut.is() ) | |||
1518 | xOut = xDataStreamer->getStream()->getOutputStream(); | |||
1519 | ||||
1520 | try | |||
1521 | { | |||
1522 | libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject( xEnv ).get() ); | |||
1523 | ||||
1524 | if (!document) | |||
1525 | return false; | |||
1526 | ||||
1527 | boost::shared_ptr< istream > aIn = document->getContentStream( ); | |||
1528 | ||||
1529 | uno::Reference< io::XInputStream > xIn = new StdInputStream( aIn ); | |||
1530 | if( !xIn.is( ) ) | |||
1531 | return false; | |||
1532 | ||||
1533 | if ( xDataSink.is() ) | |||
1534 | xDataSink->setInputStream( xIn ); | |||
1535 | else if ( xOut.is() ) | |||
1536 | copyData( xIn, xOut ); | |||
1537 | } | |||
1538 | catch ( const libcmis::Exception& e ) | |||
1539 | { | |||
1540 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: " << e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1540" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1540" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1540" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1540" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1541 | ucbhelper::cancelCommandExecution( | |||
1542 | ucb::IOErrorCode_GENERAL, | |||
1543 | uno::Sequence< uno::Any >( 0 ), | |||
1544 | xEnv, | |||
1545 | o3tl::runtimeToOUString(e.what())); | |||
1546 | } | |||
1547 | ||||
1548 | return true; | |||
1549 | } | |||
1550 | ||||
1551 | uno::Sequence< beans::Property > Content::getProperties( | |||
1552 | const uno::Reference< ucb::XCommandEnvironment > & ) | |||
1553 | { | |||
1554 | static const beans::Property aGenericProperties[] = | |||
1555 | { | |||
1556 | beans::Property( "IsDocument", | |||
1557 | -1, cppu::UnoType<bool>::get(), | |||
1558 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1559 | beans::Property( "IsFolder", | |||
1560 | -1, cppu::UnoType<bool>::get(), | |||
1561 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1562 | beans::Property( "Title", | |||
1563 | -1, cppu::UnoType<OUString>::get(), | |||
1564 | beans::PropertyAttribute::BOUND ), | |||
1565 | beans::Property( "ObjectId", | |||
1566 | -1, cppu::UnoType<OUString>::get(), | |||
1567 | beans::PropertyAttribute::BOUND ), | |||
1568 | beans::Property( "TitleOnServer", | |||
1569 | -1, cppu::UnoType<OUString>::get(), | |||
1570 | beans::PropertyAttribute::BOUND ), | |||
1571 | beans::Property( "IsReadOnly", | |||
1572 | -1, cppu::UnoType<bool>::get(), | |||
1573 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1574 | beans::Property( "DateCreated", | |||
1575 | -1, cppu::UnoType<util::DateTime>::get(), | |||
1576 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1577 | beans::Property( "DateModified", | |||
1578 | -1, cppu::UnoType<util::DateTime>::get(), | |||
1579 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1580 | beans::Property( "Size", | |||
1581 | -1, cppu::UnoType<sal_Int64>::get(), | |||
1582 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1583 | beans::Property( "CreatableContentsInfo", | |||
1584 | -1, cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(), | |||
1585 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1586 | beans::Property( "MediaType", | |||
1587 | -1, cppu::UnoType<OUString>::get(), | |||
1588 | beans::PropertyAttribute::BOUND ), | |||
1589 | beans::Property( "CmisProperties", | |||
1590 | -1, cppu::UnoType<uno::Sequence< document::CmisProperty>>::get(), | |||
1591 | beans::PropertyAttribute::BOUND ), | |||
1592 | beans::Property( "IsVersionable", | |||
1593 | -1, cppu::UnoType<bool>::get(), | |||
1594 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1595 | beans::Property( "CanCheckOut", | |||
1596 | -1, cppu::UnoType<bool>::get(), | |||
1597 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1598 | beans::Property( "CanCancelCheckOut", | |||
1599 | -1, cppu::UnoType<bool>::get(), | |||
1600 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1601 | beans::Property( "CanCheckIn", | |||
1602 | -1, cppu::UnoType<bool>::get(), | |||
1603 | beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), | |||
1604 | }; | |||
1605 | ||||
1606 | const int nProps = SAL_N_ELEMENTS(aGenericProperties)(sizeof(sal_n_array_size(aGenericProperties))); | |||
1607 | return uno::Sequence< beans::Property > ( aGenericProperties, nProps ); | |||
1608 | } | |||
1609 | ||||
1610 | uno::Sequence< ucb::CommandInfo > Content::getCommands( | |||
1611 | const uno::Reference< ucb::XCommandEnvironment > & xEnv ) | |||
1612 | { | |||
1613 | static const ucb::CommandInfo aCommandInfoTable[] = | |||
1614 | { | |||
1615 | // Required commands | |||
1616 | ucb::CommandInfo | |||
1617 | ( "getCommandInfo", | |||
1618 | -1, cppu::UnoType<void>::get() ), | |||
1619 | ucb::CommandInfo | |||
1620 | ( "getPropertySetInfo", | |||
1621 | -1, cppu::UnoType<void>::get() ), | |||
1622 | ucb::CommandInfo | |||
1623 | ( "getPropertyValues", | |||
1624 | -1, cppu::UnoType<uno::Sequence< beans::Property >>::get() ), | |||
1625 | ucb::CommandInfo | |||
1626 | ( "setPropertyValues", | |||
1627 | -1, cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get() ), | |||
1628 | ||||
1629 | // Optional standard commands | |||
1630 | ucb::CommandInfo | |||
1631 | ( "delete", | |||
1632 | -1, cppu::UnoType<bool>::get() ), | |||
1633 | ucb::CommandInfo | |||
1634 | ( "insert", | |||
1635 | -1, cppu::UnoType<ucb::InsertCommandArgument2>::get() ), | |||
1636 | ucb::CommandInfo | |||
1637 | ( "open", | |||
1638 | -1, cppu::UnoType<ucb::OpenCommandArgument2>::get() ), | |||
1639 | ||||
1640 | // Mandatory CMIS-only commands | |||
1641 | ucb::CommandInfo ( "checkout", -1, cppu::UnoType<void>::get() ), | |||
1642 | ucb::CommandInfo ( "cancelCheckout", -1, cppu::UnoType<void>::get() ), | |||
1643 | ucb::CommandInfo ( "checkIn", -1, | |||
1644 | cppu::UnoType<ucb::TransferInfo>::get() ), | |||
1645 | ucb::CommandInfo ( "updateProperties", -1, cppu::UnoType<void>::get() ), | |||
1646 | ucb::CommandInfo | |||
1647 | ( "getAllVersions", | |||
1648 | -1, cppu::UnoType<uno::Sequence< document::CmisVersion >>::get() ), | |||
1649 | ||||
1650 | ||||
1651 | // Folder Only, omitted if not a folder | |||
1652 | ucb::CommandInfo | |||
1653 | ( "transfer", | |||
1654 | -1, cppu::UnoType<ucb::TransferInfo>::get() ), | |||
1655 | ucb::CommandInfo | |||
1656 | ( "createNewContent", | |||
1657 | -1, cppu::UnoType<ucb::ContentInfo>::get() ) | |||
1658 | }; | |||
1659 | ||||
1660 | const int nProps = SAL_N_ELEMENTS( aCommandInfoTable )(sizeof(sal_n_array_size(aCommandInfoTable))); | |||
1661 | return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, isFolder( xEnv ) ? nProps : nProps - 2); | |||
1662 | } | |||
1663 | ||||
1664 | OUString Content::getParentURL( ) | |||
1665 | { | |||
1666 | SAL_INFO( "ucb.ucp.cmis", "Content::getParentURL()" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Content::getParentURL()" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1666" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Content::getParentURL()"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Content::getParentURL()"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1666" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Content::getParentURL()") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1666" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Content::getParentURL()"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Content::getParentURL()"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1666" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1667 | OUString parentUrl = "/"; | |||
1668 | if ( m_sObjectPath == "/" ) | |||
1669 | return parentUrl; | |||
1670 | else | |||
1671 | { | |||
1672 | INetURLObject aUrl( m_sURL ); | |||
1673 | if ( aUrl.getSegmentCount( ) > 0 ) | |||
1674 | { | |||
1675 | URL aCmisUrl( m_sURL ); | |||
1676 | aUrl.removeSegment( ); | |||
1677 | aCmisUrl.setObjectPath( aUrl.GetURLPath( INetURLObject::DecodeMechanism::WithCharset ) ); | |||
1678 | parentUrl = aCmisUrl.asString( ); | |||
1679 | } | |||
1680 | } | |||
1681 | return parentUrl; | |||
1682 | } | |||
1683 | ||||
1684 | XTYPEPROVIDER_COMMON_IMPL( Content )css::uno::Sequence< sal_Int8 > Content::getImplementationId () { return css::uno::Sequence<sal_Int8>(); }; | |||
1685 | ||||
1686 | void SAL_CALL Content::acquire() throw() | |||
1687 | { | |||
1688 | ContentImplHelper::acquire(); | |||
1689 | } | |||
1690 | ||||
1691 | void SAL_CALL Content::release() throw() | |||
1692 | { | |||
1693 | ContentImplHelper::release(); | |||
1694 | } | |||
1695 | ||||
1696 | uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) | |||
1697 | { | |||
1698 | uno::Any aRet = cppu::queryInterface( rType, static_cast< ucb::XContentCreator * >( this ) ); | |||
1699 | return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface(rType); | |||
1700 | } | |||
1701 | ||||
1702 | OUString SAL_CALL Content::getImplementationName() | |||
1703 | { | |||
1704 | return "com.sun.star.comp.CmisContent"; | |||
1705 | } | |||
1706 | ||||
1707 | uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames() | |||
1708 | { | |||
1709 | uno::Sequence<OUString> aSNS { "com.sun.star.ucb.CmisContent" }; | |||
1710 | return aSNS; | |||
1711 | } | |||
1712 | ||||
1713 | OUString SAL_CALL Content::getContentType() | |||
1714 | { | |||
1715 | OUString sRet; | |||
1716 | try | |||
1717 | { | |||
1718 | sRet = isFolder( uno::Reference< ucb::XCommandEnvironment >() ) | |||
1719 | ? std::u16string_view(u"" CMIS_FOLDER_TYPE"application/vnd.libreoffice.cmis-folder") | |||
1720 | : std::u16string_view(u"" CMIS_FILE_TYPE"application/vnd.libreoffice.cmis-file"); | |||
1721 | } | |||
1722 | catch (const uno::RuntimeException&) | |||
1723 | { | |||
1724 | throw; | |||
1725 | } | |||
1726 | catch (const uno::Exception& e) | |||
1727 | { | |||
1728 | uno::Any a(cppu::getCaughtException()); | |||
1729 | throw lang::WrappedTargetRuntimeException( | |||
1730 | "wrapped Exception " + e.Message, | |||
1731 | uno::Reference<uno::XInterface>(), a); | |||
1732 | } | |||
1733 | return sRet; | |||
1734 | } | |||
1735 | ||||
1736 | uno::Any SAL_CALL Content::execute( | |||
1737 | const ucb::Command& aCommand, | |||
1738 | sal_Int32 /*CommandId*/, | |||
1739 | const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
1740 | { | |||
1741 | SAL_INFO( "ucb.ucp.cmis", "Content::execute( ) - " << aCommand.Name )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Content::execute( ) - " << aCommand.Name) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1741" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Content::execute( ) - " << aCommand .Name), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Content::execute( ) - " << aCommand.Name; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1741" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Content::execute( ) - " << aCommand.Name) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1741" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Content::execute( ) - " << aCommand .Name), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Content::execute( ) - " << aCommand.Name; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1741" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1742 | uno::Any aRet; | |||
1743 | ||||
1744 | if ( aCommand.Name == "getPropertyValues" ) | |||
1745 | { | |||
1746 | uno::Sequence< beans::Property > Properties; | |||
1747 | if ( !( aCommand.Argument >>= Properties ) ) | |||
1748 | ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv ); | |||
1749 | aRet <<= getPropertyValues( Properties, xEnv ); | |||
1750 | } | |||
1751 | else if ( aCommand.Name == "getPropertySetInfo" ) | |||
1752 | aRet <<= getPropertySetInfo( xEnv, false ); | |||
1753 | else if ( aCommand.Name == "getCommandInfo" ) | |||
1754 | aRet <<= getCommandInfo( xEnv, false ); | |||
1755 | else if ( aCommand.Name == "open" ) | |||
1756 | { | |||
1757 | ucb::OpenCommandArgument2 aOpenCommand; | |||
1758 | if ( !( aCommand.Argument >>= aOpenCommand ) ) | |||
1759 | ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv ); | |||
1760 | aRet = open( aOpenCommand, xEnv ); | |||
1761 | } | |||
1762 | else if ( aCommand.Name == "transfer" ) | |||
1763 | { | |||
1764 | ucb::TransferInfo transferArgs; | |||
1765 | if ( !( aCommand.Argument >>= transferArgs ) ) | |||
1766 | ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv ); | |||
1767 | transfer( transferArgs, xEnv ); | |||
1768 | } | |||
1769 | else if ( aCommand.Name == "setPropertyValues" ) | |||
1770 | { | |||
1771 | uno::Sequence< beans::PropertyValue > aProperties; | |||
1772 | if ( !( aCommand.Argument >>= aProperties ) || !aProperties.hasElements() ) | |||
1773 | ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv ); | |||
1774 | aRet <<= setPropertyValues( aProperties, xEnv ); | |||
1775 | } | |||
1776 | else if (aCommand.Name == "createNewContent" | |||
1777 | && isFolder( xEnv ) ) | |||
1778 | { | |||
1779 | ucb::ContentInfo arg; | |||
1780 | if ( !( aCommand.Argument >>= arg ) ) | |||
1781 | ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv ); | |||
1782 | aRet <<= createNewContent( arg ); | |||
1783 | } | |||
1784 | else if ( aCommand.Name == "insert" ) | |||
1785 | { | |||
1786 | ucb::InsertCommandArgument2 arg; | |||
1787 | if ( !( aCommand.Argument >>= arg ) ) | |||
1788 | { | |||
1789 | ucb::InsertCommandArgument insertArg; | |||
1790 | if ( !( aCommand.Argument >>= insertArg ) ) | |||
1791 | ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv ); | |||
1792 | ||||
1793 | arg.Data = insertArg.Data; | |||
1794 | arg.ReplaceExisting = insertArg.ReplaceExisting; | |||
1795 | } | |||
1796 | // store the document id | |||
1797 | m_sObjectId = arg.DocumentId; | |||
1798 | insert( arg.Data, arg.ReplaceExisting, arg.MimeType, xEnv ); | |||
1799 | } | |||
1800 | else if ( aCommand.Name == "delete" ) | |||
1801 | { | |||
1802 | try | |||
1803 | { | |||
1804 | if ( !isFolder( xEnv ) ) | |||
1805 | { | |||
1806 | getObject( xEnv )->remove( ); | |||
1807 | } | |||
1808 | else | |||
1809 | { | |||
1810 | libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( getObject( xEnv ).get() ); | |||
1811 | if (folder) | |||
1812 | folder->removeTree( ); | |||
1813 | } | |||
1814 | } | |||
1815 | catch ( const libcmis::Exception& e ) | |||
1816 | { | |||
1817 | SAL_INFO( "ucb.ucp.cmis", "Unexpected libcmis exception: " << e.what( ) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1817" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1817" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unexpected libcmis exception: " << e.what( )) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1817" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unexpected libcmis exception: " << e.what( )), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Unexpected libcmis exception: " << e.what( ); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1817" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1818 | ucbhelper::cancelCommandExecution( | |||
1819 | ucb::IOErrorCode_GENERAL, | |||
1820 | uno::Sequence< uno::Any >( 0 ), | |||
1821 | xEnv, | |||
1822 | o3tl::runtimeToOUString(e.what())); | |||
1823 | } | |||
1824 | } | |||
1825 | else if ( aCommand.Name == "checkout" ) | |||
1826 | { | |||
1827 | aRet <<= checkOut( xEnv ); | |||
1828 | } | |||
1829 | else if ( aCommand.Name == "cancelCheckout" ) | |||
1830 | { | |||
1831 | aRet <<= cancelCheckOut( xEnv ); | |||
1832 | } | |||
1833 | else if ( aCommand.Name == "checkin" ) | |||
1834 | { | |||
1835 | ucb::CheckinArgument aArg; | |||
1836 | if ( !( aCommand.Argument >>= aArg ) ) | |||
1837 | { | |||
1838 | ucbhelper::cancelCommandExecution ( getBadArgExcept(), xEnv ); | |||
1839 | } | |||
1840 | aRet <<= checkIn( aArg, xEnv ); | |||
1841 | } | |||
1842 | else if ( aCommand.Name == "getAllVersions" ) | |||
1843 | { | |||
1844 | aRet <<= getAllVersions( xEnv ); | |||
1845 | } | |||
1846 | else if ( aCommand.Name == "updateProperties" ) | |||
1847 | { | |||
1848 | updateProperties( aCommand.Argument, xEnv ); | |||
1849 | } | |||
1850 | else | |||
1851 | { | |||
1852 | SAL_INFO( "ucb.ucp.cmis", "Unknown command to execute" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unknown command to execute" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1852" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unknown command to execute"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unknown command to execute"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1852" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unknown command to execute") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1852" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unknown command to execute"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unknown command to execute"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1852" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1853 | ||||
1854 | ucbhelper::cancelCommandExecution | |||
1855 | ( uno::makeAny( ucb::UnsupportedCommandException | |||
1856 | ( OUString(), | |||
1857 | static_cast< cppu::OWeakObject * >( this ) ) ), | |||
1858 | xEnv ); | |||
1859 | } | |||
1860 | ||||
1861 | return aRet; | |||
1862 | } | |||
1863 | ||||
1864 | void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) | |||
1865 | { | |||
1866 | SAL_INFO( "ucb.ucp.cmis", "TODO - Content::abort()" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "TODO - Content::abort()" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1866" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "TODO - Content::abort()"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "TODO - Content::abort()"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1866" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "TODO - Content::abort()") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1866" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "TODO - Content::abort()"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "TODO - Content::abort()"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1866" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1867 | // TODO Implement me | |||
1868 | } | |||
1869 | ||||
1870 | uno::Sequence< ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo() | |||
1871 | { | |||
1872 | return queryCreatableContentsInfo( uno::Reference< ucb::XCommandEnvironment >() ); | |||
1873 | } | |||
1874 | ||||
1875 | uno::Reference< ucb::XContent > SAL_CALL Content::createNewContent( | |||
1876 | const ucb::ContentInfo& Info ) | |||
1877 | { | |||
1878 | bool create_document; | |||
1879 | ||||
1880 | if ( Info.Type == CMIS_FILE_TYPE"application/vnd.libreoffice.cmis-file" ) | |||
1881 | create_document = true; | |||
1882 | else if ( Info.Type == CMIS_FOLDER_TYPE"application/vnd.libreoffice.cmis-folder" ) | |||
1883 | create_document = false; | |||
1884 | else | |||
1885 | { | |||
1886 | SAL_INFO( "ucb.ucp.cmis", "Unknown type of content to create" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unknown type of content to create" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1886" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unknown type of content to create") , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unknown type of content to create"; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1886" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unknown type of content to create") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1886" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Unknown type of content to create") , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unknown type of content to create"; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "1886" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1887 | return uno::Reference< ucb::XContent >(); | |||
1888 | } | |||
1889 | ||||
1890 | OUString sParentURL = m_xIdentifier->getContentIdentifier(); | |||
1891 | ||||
1892 | // Set the parent URL for the transient objects | |||
1893 | uno::Reference< ucb::XContentIdentifier > xId(new ::ucbhelper::ContentIdentifier(sParentURL)); | |||
1894 | ||||
1895 | try | |||
1896 | { | |||
1897 | return new ::cmis::Content( m_xContext, m_pProvider, xId, !create_document ); | |||
1898 | } | |||
1899 | catch ( ucb::ContentCreationException & ) | |||
1900 | { | |||
1901 | return uno::Reference< ucb::XContent >(); | |||
1902 | } | |||
1903 | } | |||
1904 | ||||
1905 | uno::Sequence< uno::Type > SAL_CALL Content::getTypes() | |||
1906 | { | |||
1907 | try | |||
1908 | { | |||
1909 | if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) ) | |||
1910 | { | |||
1911 | static cppu::OTypeCollection s_aFolderCollection | |||
1912 | (CPPU_TYPE_REF( lang::XTypeProvider )cppu::UnoType<lang::XTypeProvider>::get(), | |||
1913 | CPPU_TYPE_REF( lang::XServiceInfo )cppu::UnoType<lang::XServiceInfo>::get(), | |||
1914 | CPPU_TYPE_REF( lang::XComponent )cppu::UnoType<lang::XComponent>::get(), | |||
1915 | CPPU_TYPE_REF( ucb::XContent )cppu::UnoType<ucb::XContent>::get(), | |||
1916 | CPPU_TYPE_REF( ucb::XCommandProcessor )cppu::UnoType<ucb::XCommandProcessor>::get(), | |||
1917 | CPPU_TYPE_REF( beans::XPropertiesChangeNotifier )cppu::UnoType<beans::XPropertiesChangeNotifier>::get(), | |||
1918 | CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier )cppu::UnoType<ucb::XCommandInfoChangeNotifier>::get(), | |||
1919 | CPPU_TYPE_REF( beans::XPropertyContainer )cppu::UnoType<beans::XPropertyContainer>::get(), | |||
1920 | CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier )cppu::UnoType<beans::XPropertySetInfoChangeNotifier>::get (), | |||
1921 | CPPU_TYPE_REF( container::XChild )cppu::UnoType<container::XChild>::get(), | |||
1922 | CPPU_TYPE_REF( ucb::XContentCreator )cppu::UnoType<ucb::XContentCreator>::get() ); | |||
1923 | return s_aFolderCollection.getTypes(); | |||
1924 | } | |||
1925 | } | |||
1926 | catch (const uno::RuntimeException&) | |||
1927 | { | |||
1928 | throw; | |||
1929 | } | |||
1930 | catch (const uno::Exception& e) | |||
1931 | { | |||
1932 | uno::Any a(cppu::getCaughtException()); | |||
1933 | throw lang::WrappedTargetRuntimeException( | |||
1934 | "wrapped Exception " + e.Message, | |||
1935 | uno::Reference<uno::XInterface>(), a); | |||
1936 | } | |||
1937 | ||||
1938 | static cppu::OTypeCollection s_aFileCollection | |||
1939 | (CPPU_TYPE_REF( lang::XTypeProvider )cppu::UnoType<lang::XTypeProvider>::get(), | |||
1940 | CPPU_TYPE_REF( lang::XServiceInfo )cppu::UnoType<lang::XServiceInfo>::get(), | |||
1941 | CPPU_TYPE_REF( lang::XComponent )cppu::UnoType<lang::XComponent>::get(), | |||
1942 | CPPU_TYPE_REF( ucb::XContent )cppu::UnoType<ucb::XContent>::get(), | |||
1943 | CPPU_TYPE_REF( ucb::XCommandProcessor )cppu::UnoType<ucb::XCommandProcessor>::get(), | |||
1944 | CPPU_TYPE_REF( beans::XPropertiesChangeNotifier )cppu::UnoType<beans::XPropertiesChangeNotifier>::get(), | |||
1945 | CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier )cppu::UnoType<ucb::XCommandInfoChangeNotifier>::get(), | |||
1946 | CPPU_TYPE_REF( beans::XPropertyContainer )cppu::UnoType<beans::XPropertyContainer>::get(), | |||
1947 | CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier )cppu::UnoType<beans::XPropertySetInfoChangeNotifier>::get (), | |||
1948 | CPPU_TYPE_REF( container::XChild )cppu::UnoType<container::XChild>::get() ); | |||
1949 | ||||
1950 | return s_aFileCollection.getTypes(); | |||
1951 | } | |||
1952 | ||||
1953 | uno::Sequence< ucb::ContentInfo > Content::queryCreatableContentsInfo( | |||
1954 | const uno::Reference< ucb::XCommandEnvironment >& xEnv) | |||
1955 | { | |||
1956 | try | |||
1957 | { | |||
1958 | if ( isFolder( xEnv ) ) | |||
1959 | { | |||
1960 | uno::Sequence< ucb::ContentInfo > seq(2); | |||
1961 | ||||
1962 | // Minimum set of props we really need | |||
1963 | uno::Sequence< beans::Property > props( 1 ); | |||
1964 | props[0] = beans::Property( | |||
1965 | "Title", | |||
1966 | -1, | |||
1967 | cppu::UnoType<OUString>::get(), | |||
1968 | beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND ); | |||
1969 | ||||
1970 | // file | |||
1971 | seq[0].Type = CMIS_FILE_TYPE"application/vnd.libreoffice.cmis-file"; | |||
1972 | seq[0].Attributes = ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM | | |||
1973 | ucb::ContentInfoAttribute::KIND_DOCUMENT ); | |||
1974 | seq[0].Properties = props; | |||
1975 | ||||
1976 | // folder | |||
1977 | seq[1].Type = CMIS_FOLDER_TYPE"application/vnd.libreoffice.cmis-folder"; | |||
1978 | seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER; | |||
1979 | seq[1].Properties = props; | |||
1980 | ||||
1981 | return seq; | |||
1982 | } | |||
1983 | } | |||
1984 | catch (const uno::RuntimeException&) | |||
1985 | { | |||
1986 | throw; | |||
1987 | } | |||
1988 | catch (const uno::Exception& e) | |||
1989 | { | |||
1990 | uno::Any a(cppu::getCaughtException()); | |||
1991 | throw lang::WrappedTargetRuntimeException( | |||
1992 | "wrapped Exception " + e.Message, | |||
1993 | uno::Reference<uno::XInterface>(), a); | |||
1994 | } | |||
1995 | return uno::Sequence< ucb::ContentInfo >(); | |||
1996 | } | |||
1997 | ||||
1998 | std::vector< uno::Reference< ucb::XContent > > Content::getChildren( ) | |||
1999 | { | |||
2000 | std::vector< uno::Reference< ucb::XContent > > results; | |||
2001 | SAL_INFO( "ucb.ucp.cmis", "Content::getChildren() " << m_sURL )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Content::getChildren() " << m_sURL) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "2001" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Content::getChildren() " << m_sURL ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Content::getChildren() " << m_sURL; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "2001" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Content::getChildren() " << m_sURL) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "2001" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Content::getChildren() " << m_sURL ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Content::getChildren() " << m_sURL; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "2001" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
2002 | ||||
2003 | libcmis::FolderPtr pFolder = boost::dynamic_pointer_cast< libcmis::Folder >( getObject( uno::Reference< ucb::XCommandEnvironment >() ) ); | |||
2004 | if ( nullptr != pFolder ) | |||
2005 | { | |||
2006 | // Get the children from pObject | |||
2007 | try | |||
2008 | { | |||
2009 | vector< libcmis::ObjectPtr > children = pFolder->getChildren( ); | |||
2010 | ||||
2011 | // Loop over the results | |||
2012 | for ( const auto& rChild : children ) | |||
2013 | { | |||
2014 | // TODO Cache the objects | |||
2015 | ||||
2016 | INetURLObject aURL( m_sURL ); | |||
2017 | OUString sUser = aURL.GetUser( INetURLObject::DecodeMechanism::WithCharset ); | |||
2018 | ||||
2019 | URL aUrl( m_sURL ); | |||
2020 | OUString sPath( m_sObjectPath ); | |||
2021 | if ( !sPath.endsWith("/") ) | |||
2022 | sPath += "/"; | |||
2023 | sPath += STD_TO_OUSTR( rChild->getName( ) )OUString( rChild->getName( ).c_str(), rChild->getName( ) .length( ), (((rtl_TextEncoding) 76)) ); | |||
2024 | OUString sId = STD_TO_OUSTR( rChild->getId( ) )OUString( rChild->getId( ).c_str(), rChild->getId( ).length ( ), (((rtl_TextEncoding) 76)) ); | |||
2025 | ||||
2026 | aUrl.setObjectId( sId ); | |||
2027 | aUrl.setObjectPath( sPath ); | |||
2028 | aUrl.setUsername( sUser ); | |||
2029 | ||||
2030 | uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aUrl.asString( ) ); | |||
2031 | uno::Reference< ucb::XContent > xContent = new Content( m_xContext, m_pProvider, xId, rChild ); | |||
2032 | ||||
2033 | results.push_back( xContent ); | |||
2034 | } | |||
2035 | } | |||
2036 | catch ( const libcmis::Exception& e ) | |||
2037 | { | |||
2038 | SAL_INFO( "ucb.ucp.cmis", "Exception thrown: " << e.what() )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "ucb.ucp.cmis")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Exception thrown: " << e.what()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "2038" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Exception thrown: " << e.what ()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Exception thrown: " << e.what(); ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "2038" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Exception thrown: " << e.what()) == 1) { :: sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis" ), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "2038" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Exception thrown: " << e.what ()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Exception thrown: " << e.what(); ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("ucb.ucp.cmis"), ("/home/maarten/src/libreoffice/core/ucb/source/ucp/cmis/cmis_content.cxx" ":" "2038" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
2039 | } | |||
2040 | } | |||
2041 | ||||
2042 | return results; | |||
2043 | } | |||
2044 | ||||
2045 | void Content::setCmisProperty(const std::string& rName, const std::string& rValue, const uno::Reference< ucb::XCommandEnvironment >& xEnv ) | |||
2046 | { | |||
2047 | if ( !getObjectType( xEnv ).get( ) ) | |||
2048 | return; | |||
2049 | ||||
2050 | map< string, libcmis::PropertyPtr >::iterator propIt = m_pObjectProps.find(rName); | |||
2051 | vector< string > values; | |||
2052 | values.push_back(rValue); | |||
2053 | ||||
2054 | if ( propIt == m_pObjectProps.end( ) && getObjectType( xEnv ).get( ) ) | |||
2055 | { | |||
2056 | map< string, libcmis::PropertyTypePtr > propsTypes = getObjectType( xEnv )->getPropertiesTypes( ); | |||
2057 | map< string, libcmis::PropertyTypePtr >::iterator typeIt = propsTypes.find(rName); | |||
2058 | ||||
2059 | if ( typeIt != propsTypes.end( ) ) | |||
2060 | { | |||
2061 | libcmis::PropertyTypePtr propType = typeIt->second; | |||
2062 | libcmis::PropertyPtr property( new libcmis::Property( propType, values ) ); | |||
2063 | m_pObjectProps.insert(pair< string, libcmis::PropertyPtr >(rName, property)); | |||
2064 | } | |||
2065 | } | |||
2066 | else if ( propIt != m_pObjectProps.end( ) ) | |||
2067 | { | |||
2068 | propIt->second->setValues( values ); | |||
2069 | } | |||
2070 | } | |||
2071 | } | |||
2072 | ||||
2073 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED |
2 | #define BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED |
3 | |
4 | // |
5 | // shared_ptr.hpp |
6 | // |
7 | // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. |
8 | // Copyright (c) 2001-2008 Peter Dimov |
9 | // |
10 | // Distributed under the Boost Software License, Version 1.0. (See |
11 | // accompanying file LICENSE_1_0.txt or copy at |
12 | // http://www.boost.org/LICENSE_1_0.txt) |
13 | // |
14 | // See http://www.boost.org/libs/smart_ptr/ for documentation. |
15 | // |
16 | |
17 | #include <boost/config.hpp> // for broken compiler workarounds |
18 | |
19 | // In order to avoid circular dependencies with Boost.TR1 |
20 | // we make sure that our include of <memory> doesn't try to |
21 | // pull in the TR1 headers: that's why we use this header |
22 | // rather than including <memory> directly: |
23 | #include <boost/config/no_tr1/memory.hpp> // std::auto_ptr |
24 | |
25 | #include <boost/assert.hpp> |
26 | #include <boost/checked_delete.hpp> |
27 | #include <boost/throw_exception.hpp> |
28 | #include <boost/smart_ptr/detail/shared_count.hpp> |
29 | #include <boost/detail/workaround.hpp> |
30 | #include <boost/smart_ptr/detail/sp_convertible.hpp> |
31 | #include <boost/smart_ptr/detail/sp_nullptr_t.hpp> |
32 | #include <boost/smart_ptr/detail/sp_disable_deprecated.hpp> |
33 | #include <boost/smart_ptr/detail/sp_noexcept.hpp> |
34 | |
35 | #if !defined(BOOST_SP_NO_ATOMIC_ACCESS) |
36 | #include <boost/smart_ptr/detail/spinlock_pool.hpp> |
37 | #endif |
38 | |
39 | #include <algorithm> // for std::swap |
40 | #include <functional> // for std::less |
41 | #include <typeinfo> // for std::bad_cast |
42 | #include <cstddef> // for std::size_t |
43 | |
44 | #if !defined(BOOST_NO_IOSTREAM) |
45 | #if !defined(BOOST_NO_IOSFWD) |
46 | #include <iosfwd> // for std::basic_ostream |
47 | #else |
48 | #include <ostream> |
49 | #endif |
50 | #endif |
51 | |
52 | #if defined( BOOST_SP_DISABLE_DEPRECATED ) |
53 | #pragma GCC diagnostic push |
54 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
55 | #endif |
56 | |
57 | namespace boost |
58 | { |
59 | |
60 | template<class T> class shared_ptr; |
61 | template<class T> class weak_ptr; |
62 | template<class T> class enable_shared_from_this; |
63 | class enable_shared_from_raw; |
64 | |
65 | namespace movelib |
66 | { |
67 | |
68 | template< class T, class D > class unique_ptr; |
69 | |
70 | } // namespace movelib |
71 | |
72 | namespace detail |
73 | { |
74 | |
75 | // sp_element, element_type |
76 | |
77 | template< class T > struct sp_element |
78 | { |
79 | typedef T type; |
80 | }; |
81 | |
82 | #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
83 | |
84 | template< class T > struct sp_element< T[] > |
85 | { |
86 | typedef T type; |
87 | }; |
88 | |
89 | #if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )((1 + 0 == 0) && (__BORLANDC__ != 0) && (1 % ( ( (__BORLANDC__ < 0x600) ) + 1))) |
90 | |
91 | template< class T, std::size_t N > struct sp_element< T[N] > |
92 | { |
93 | typedef T type; |
94 | }; |
95 | |
96 | #endif |
97 | |
98 | #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
99 | |
100 | // sp_dereference, return type of operator* |
101 | |
102 | template< class T > struct sp_dereference |
103 | { |
104 | typedef T & type; |
105 | }; |
106 | |
107 | template<> struct sp_dereference< void > |
108 | { |
109 | typedef void type; |
110 | }; |
111 | |
112 | #if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) |
113 | |
114 | template<> struct sp_dereference< void const > |
115 | { |
116 | typedef void type; |
117 | }; |
118 | |
119 | template<> struct sp_dereference< void volatile > |
120 | { |
121 | typedef void type; |
122 | }; |
123 | |
124 | template<> struct sp_dereference< void const volatile > |
125 | { |
126 | typedef void type; |
127 | }; |
128 | |
129 | #endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) |
130 | |
131 | #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
132 | |
133 | template< class T > struct sp_dereference< T[] > |
134 | { |
135 | typedef void type; |
136 | }; |
137 | |
138 | #if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )((1 + 0 == 0) && (__BORLANDC__ != 0) && (1 % ( ( (__BORLANDC__ < 0x600) ) + 1))) |
139 | |
140 | template< class T, std::size_t N > struct sp_dereference< T[N] > |
141 | { |
142 | typedef void type; |
143 | }; |
144 | |
145 | #endif |
146 | |
147 | #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
148 | |
149 | // sp_member_access, return type of operator-> |
150 | |
151 | template< class T > struct sp_member_access |
152 | { |
153 | typedef T * type; |
154 | }; |
155 | |
156 | #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
157 | |
158 | template< class T > struct sp_member_access< T[] > |
159 | { |
160 | typedef void type; |
161 | }; |
162 | |
163 | #if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )((1 + 0 == 0) && (__BORLANDC__ != 0) && (1 % ( ( (__BORLANDC__ < 0x600) ) + 1))) |
164 | |
165 | template< class T, std::size_t N > struct sp_member_access< T[N] > |
166 | { |
167 | typedef void type; |
168 | }; |
169 | |
170 | #endif |
171 | |
172 | #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
173 | |
174 | // sp_array_access, return type of operator[] |
175 | |
176 | template< class T > struct sp_array_access |
177 | { |
178 | typedef void type; |
179 | }; |
180 | |
181 | #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
182 | |
183 | template< class T > struct sp_array_access< T[] > |
184 | { |
185 | typedef T & type; |
186 | }; |
187 | |
188 | #if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )((1 + 0 == 0) && (__BORLANDC__ != 0) && (1 % ( ( (__BORLANDC__ < 0x600) ) + 1))) |
189 | |
190 | template< class T, std::size_t N > struct sp_array_access< T[N] > |
191 | { |
192 | typedef T & type; |
193 | }; |
194 | |
195 | #endif |
196 | |
197 | #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
198 | |
199 | // sp_extent, for operator[] index check |
200 | |
201 | template< class T > struct sp_extent |
202 | { |
203 | enum _vt { value = 0 }; |
204 | }; |
205 | |
206 | #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
207 | |
208 | template< class T, std::size_t N > struct sp_extent< T[N] > |
209 | { |
210 | enum _vt { value = N }; |
211 | }; |
212 | |
213 | #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
214 | |
215 | // enable_shared_from_this support |
216 | |
217 | template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe ) |
218 | { |
219 | if( pe != 0 ) |
220 | { |
221 | pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); |
222 | } |
223 | } |
224 | |
225 | template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); |
226 | |
227 | #ifdef _MANAGED |
228 | |
229 | // Avoid C4793, ... causes native code generation |
230 | |
231 | struct sp_any_pointer |
232 | { |
233 | template<class T> sp_any_pointer( T* ) {} |
234 | }; |
235 | |
236 | inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer ) |
237 | { |
238 | } |
239 | |
240 | #else // _MANAGED |
241 | |
242 | inline void sp_enable_shared_from_this( ... ) |
243 | { |
244 | } |
245 | |
246 | #endif // _MANAGED |
247 | |
248 | #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR ) |
249 | |
250 | // rvalue auto_ptr support based on a technique by Dave Abrahams |
251 | |
252 | template< class T, class R > struct sp_enable_if_auto_ptr |
253 | { |
254 | }; |
255 | |
256 | template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R > |
257 | { |
258 | typedef R type; |
259 | }; |
260 | |
261 | #endif |
262 | |
263 | // sp_assert_convertible |
264 | |
265 | template< class Y, class T > inline void sp_assert_convertible() BOOST_SP_NOEXCEPTnoexcept |
266 | { |
267 | #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) |
268 | |
269 | // static_assert( sp_convertible< Y, T >::value ); |
270 | typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ]; |
271 | (void)sizeof( tmp ); |
272 | |
273 | #else |
274 | |
275 | T* p = static_cast< Y* >( 0 ); |
276 | (void)p; |
277 | |
278 | #endif |
279 | } |
280 | |
281 | // pointer constructor helper |
282 | |
283 | template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn ) |
284 | { |
285 | boost::detail::shared_count( p ).swap( pn ); |
286 | boost::detail::sp_enable_shared_from_this( ppx, p, p ); |
287 | } |
288 | |
289 | #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
290 | |
291 | template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn ) |
292 | { |
293 | sp_assert_convertible< Y[], T[] >(); |
294 | boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); |
295 | } |
296 | |
297 | template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * p, boost::detail::shared_count & pn ) |
298 | { |
299 | sp_assert_convertible< Y[N], T[N] >(); |
300 | boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); |
301 | } |
302 | |
303 | #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
304 | |
305 | // deleter constructor helper |
306 | |
307 | template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p ) |
308 | { |
309 | boost::detail::sp_enable_shared_from_this( ppx, p, p ); |
310 | } |
311 | |
312 | #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
313 | |
314 | template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ ) |
315 | { |
316 | sp_assert_convertible< Y[], T[] >(); |
317 | } |
318 | |
319 | template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ ) |
320 | { |
321 | sp_assert_convertible< Y[N], T[N] >(); |
322 | } |
323 | |
324 | #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
325 | |
326 | struct sp_internal_constructor_tag |
327 | { |
328 | }; |
329 | |
330 | } // namespace detail |
331 | |
332 | |
333 | // |
334 | // shared_ptr |
335 | // |
336 | // An enhanced relative of scoped_ptr with reference counted copy semantics. |
337 | // The object pointed to is deleted when the last shared_ptr pointing to it |
338 | // is destroyed or reset. |
339 | // |
340 | |
341 | template<class T> class shared_ptr |
342 | { |
343 | private: |
344 | |
345 | // Borland 5.5.1 specific workaround |
346 | typedef shared_ptr<T> this_type; |
347 | |
348 | public: |
349 | |
350 | typedef typename boost::detail::sp_element< T >::type element_type; |
351 | |
352 | BOOST_CONSTEXPRconstexpr shared_ptr() BOOST_SP_NOEXCEPTnoexcept : px( 0 ), pn() |
353 | { |
354 | } |
355 | |
356 | #if !defined( BOOST_NO_CXX11_NULLPTR ) |
357 | |
358 | BOOST_CONSTEXPRconstexpr shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPTnoexcept : px( 0 ), pn() |
359 | { |
360 | } |
361 | |
362 | #endif |
363 | |
364 | BOOST_CONSTEXPRconstexpr shared_ptr( boost::detail::sp_internal_constructor_tag, element_type * px_, boost::detail::shared_count const & pn_ ) BOOST_SP_NOEXCEPTnoexcept : px( px_ ), pn( pn_ ) |
365 | { |
366 | } |
367 | |
368 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
369 | |
370 | BOOST_CONSTEXPRconstexpr shared_ptr( boost::detail::sp_internal_constructor_tag, element_type * px_, boost::detail::shared_count && pn_ ) BOOST_SP_NOEXCEPTnoexcept : px( px_ ), pn( std::move( pn_ ) ) |
371 | { |
372 | } |
373 | |
374 | #endif |
375 | |
376 | template<class Y> |
377 | explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete |
378 | { |
379 | boost::detail::sp_pointer_construct( this, p, pn ); |
380 | } |
381 | |
382 | // |
383 | // Requirements: D's copy constructor must not throw |
384 | // |
385 | // shared_ptr will release p by calling d(p) |
386 | // |
387 | |
388 | template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d ) |
389 | { |
390 | boost::detail::sp_deleter_construct( this, p ); |
391 | } |
392 | |
393 | #if !defined( BOOST_NO_CXX11_NULLPTR ) |
394 | |
395 | template<class D> shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d ) |
396 | { |
397 | } |
398 | |
399 | #endif |
400 | |
401 | // As above, but with allocator. A's copy constructor shall not throw. |
402 | |
403 | template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a ) |
404 | { |
405 | boost::detail::sp_deleter_construct( this, p ); |
406 | } |
407 | |
408 | #if !defined( BOOST_NO_CXX11_NULLPTR ) |
409 | |
410 | template<class D, class A> shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a ) |
411 | { |
412 | } |
413 | |
414 | #endif |
415 | |
416 | // generated copy constructor, destructor are fine... |
417 | |
418 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
419 | |
420 | // ... except in C++0x, move disables the implicit copy |
421 | |
422 | shared_ptr( shared_ptr const & r ) BOOST_SP_NOEXCEPTnoexcept : px( r.px ), pn( r.pn ) |
423 | { |
424 | } |
425 | |
426 | #endif |
427 | |
428 | template<class Y> |
429 | explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw |
430 | { |
431 | boost::detail::sp_assert_convertible< Y, T >(); |
432 | |
433 | // it is now safe to copy r.px, as pn(r.pn) did not throw |
434 | px = r.px; |
435 | } |
436 | |
437 | template<class Y> |
438 | shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ) |
439 | BOOST_SP_NOEXCEPTnoexcept : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) |
440 | { |
441 | if( !pn.empty() ) |
442 | { |
443 | px = r.px; |
444 | } |
445 | } |
446 | |
447 | template<class Y> |
448 | #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) |
449 | |
450 | shared_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) |
451 | |
452 | #else |
453 | |
454 | shared_ptr( shared_ptr<Y> const & r ) |
455 | |
456 | #endif |
457 | BOOST_SP_NOEXCEPTnoexcept : px( r.px ), pn( r.pn ) |
458 | { |
459 | boost::detail::sp_assert_convertible< Y, T >(); |
460 | } |
461 | |
462 | // aliasing |
463 | template< class Y > |
464 | shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPTnoexcept : px( p ), pn( r.pn ) |
465 | { |
466 | } |
467 | |
468 | #ifndef BOOST_NO_AUTO_PTR |
469 | |
470 | template<class Y> |
471 | explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn() |
472 | { |
473 | boost::detail::sp_assert_convertible< Y, T >(); |
474 | |
475 | Y * tmp = r.get(); |
476 | pn = boost::detail::shared_count( r ); |
477 | |
478 | boost::detail::sp_deleter_construct( this, tmp ); |
479 | } |
480 | |
481 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
482 | |
483 | template<class Y> |
484 | shared_ptr( std::auto_ptr<Y> && r ): px(r.get()), pn() |
485 | { |
486 | boost::detail::sp_assert_convertible< Y, T >(); |
487 | |
488 | Y * tmp = r.get(); |
489 | pn = boost::detail::shared_count( r ); |
490 | |
491 | boost::detail::sp_deleter_construct( this, tmp ); |
492 | } |
493 | |
494 | #elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
495 | |
496 | template<class Ap> |
497 | explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn() |
498 | { |
499 | typedef typename Ap::element_type Y; |
500 | |
501 | boost::detail::sp_assert_convertible< Y, T >(); |
502 | |
503 | Y * tmp = r.get(); |
504 | pn = boost::detail::shared_count( r ); |
505 | |
506 | boost::detail::sp_deleter_construct( this, tmp ); |
507 | } |
508 | |
509 | #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
510 | |
511 | #endif // BOOST_NO_AUTO_PTR |
512 | |
513 | #if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
514 | |
515 | template< class Y, class D > |
516 | shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn() |
517 | { |
518 | boost::detail::sp_assert_convertible< Y, T >(); |
519 | |
520 | typename std::unique_ptr< Y, D >::pointer tmp = r.get(); |
521 | |
522 | if( tmp != 0 ) |
523 | { |
524 | pn = boost::detail::shared_count( r ); |
525 | boost::detail::sp_deleter_construct( this, tmp ); |
526 | } |
527 | } |
528 | |
529 | #endif |
530 | |
531 | template< class Y, class D > |
532 | shared_ptr( boost::movelib::unique_ptr< Y, D > r ): px( r.get() ), pn() |
533 | { |
534 | boost::detail::sp_assert_convertible< Y, T >(); |
535 | |
536 | typename boost::movelib::unique_ptr< Y, D >::pointer tmp = r.get(); |
537 | |
538 | if( tmp != 0 ) |
539 | { |
540 | pn = boost::detail::shared_count( r ); |
541 | boost::detail::sp_deleter_construct( this, tmp ); |
542 | } |
543 | } |
544 | |
545 | // assignment |
546 | |
547 | shared_ptr & operator=( shared_ptr const & r ) BOOST_SP_NOEXCEPTnoexcept |
548 | { |
549 | this_type(r).swap(*this); |
550 | return *this; |
551 | } |
552 | |
553 | #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400) |
554 | |
555 | template<class Y> |
556 | shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_SP_NOEXCEPTnoexcept |
557 | { |
558 | this_type(r).swap(*this); |
559 | return *this; |
560 | } |
561 | |
562 | #endif |
563 | |
564 | #ifndef BOOST_NO_AUTO_PTR |
565 | |
566 | template<class Y> |
567 | shared_ptr & operator=( std::auto_ptr<Y> & r ) |
568 | { |
569 | this_type( r ).swap( *this ); |
570 | return *this; |
571 | } |
572 | |
573 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
574 | |
575 | template<class Y> |
576 | shared_ptr & operator=( std::auto_ptr<Y> && r ) |
577 | { |
578 | this_type( static_cast< std::auto_ptr<Y> && >( r ) ).swap( *this ); |
579 | return *this; |
580 | } |
581 | |
582 | #elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) |
583 | |
584 | template<class Ap> |
585 | typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r ) |
586 | { |
587 | this_type( r ).swap( *this ); |
588 | return *this; |
589 | } |
590 | |
591 | #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
592 | |
593 | #endif // BOOST_NO_AUTO_PTR |
594 | |
595 | #if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
596 | |
597 | template<class Y, class D> |
598 | shared_ptr & operator=( std::unique_ptr<Y, D> && r ) |
599 | { |
600 | this_type( static_cast< std::unique_ptr<Y, D> && >( r ) ).swap(*this); |
601 | return *this; |
602 | } |
603 | |
604 | #endif |
605 | |
606 | template<class Y, class D> |
607 | shared_ptr & operator=( boost::movelib::unique_ptr<Y, D> r ) |
608 | { |
609 | // this_type( static_cast< unique_ptr<Y, D> && >( r ) ).swap( *this ); |
610 | |
611 | boost::detail::sp_assert_convertible< Y, T >(); |
612 | |
613 | typename boost::movelib::unique_ptr< Y, D >::pointer p = r.get(); |
614 | |
615 | shared_ptr tmp; |
616 | |
617 | if( p != 0 ) |
618 | { |
619 | tmp.px = p; |
620 | tmp.pn = boost::detail::shared_count( r ); |
621 | |
622 | boost::detail::sp_deleter_construct( &tmp, p ); |
623 | } |
624 | |
625 | tmp.swap( *this ); |
626 | |
627 | return *this; |
628 | } |
629 | |
630 | // Move support |
631 | |
632 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
633 | |
634 | shared_ptr( shared_ptr && r ) BOOST_SP_NOEXCEPTnoexcept : px( r.px ), pn() |
635 | { |
636 | pn.swap( r.pn ); |
637 | r.px = 0; |
638 | } |
639 | |
640 | template<class Y> |
641 | #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) |
642 | |
643 | shared_ptr( shared_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) |
644 | |
645 | #else |
646 | |
647 | shared_ptr( shared_ptr<Y> && r ) |
648 | |
649 | #endif |
650 | BOOST_SP_NOEXCEPTnoexcept : px( r.px ), pn() |
651 | { |
652 | boost::detail::sp_assert_convertible< Y, T >(); |
653 | |
654 | pn.swap( r.pn ); |
655 | r.px = 0; |
656 | } |
657 | |
658 | shared_ptr & operator=( shared_ptr && r ) BOOST_SP_NOEXCEPTnoexcept |
659 | { |
660 | this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); |
661 | return *this; |
662 | } |
663 | |
664 | template<class Y> |
665 | shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_SP_NOEXCEPTnoexcept |
666 | { |
667 | this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this ); |
668 | return *this; |
669 | } |
670 | |
671 | // aliasing move |
672 | template<class Y> |
673 | shared_ptr( shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPTnoexcept : px( p ), pn() |
674 | { |
675 | pn.swap( r.pn ); |
676 | r.px = 0; |
677 | } |
678 | |
679 | #endif |
680 | |
681 | #if !defined( BOOST_NO_CXX11_NULLPTR ) |
682 | |
683 | shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPTnoexcept |
684 | { |
685 | this_type().swap(*this); |
686 | return *this; |
687 | } |
688 | |
689 | #endif |
690 | |
691 | void reset() BOOST_SP_NOEXCEPTnoexcept |
692 | { |
693 | this_type().swap(*this); |
694 | } |
695 | |
696 | template<class Y> void reset( Y * p ) // Y must be complete |
697 | { |
698 | BOOST_ASSERT( p == 0 || p != px )(static_cast <bool> (p == 0 || p != px) ? void (0) : __assert_fail ("p == 0 || p != px", "/home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost/boost/smart_ptr/shared_ptr.hpp" , 698, __extension__ __PRETTY_FUNCTION__)); // catch self-reset errors |
699 | this_type( p ).swap( *this ); |
700 | } |
701 | |
702 | template<class Y, class D> void reset( Y * p, D d ) |
703 | { |
704 | this_type( p, d ).swap( *this ); |
705 | } |
706 | |
707 | template<class Y, class D, class A> void reset( Y * p, D d, A a ) |
708 | { |
709 | this_type( p, d, a ).swap( *this ); |
710 | } |
711 | |
712 | template<class Y> void reset( shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPTnoexcept |
713 | { |
714 | this_type( r, p ).swap( *this ); |
715 | } |
716 | |
717 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
718 | |
719 | template<class Y> void reset( shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPTnoexcept |
720 | { |
721 | this_type( static_cast< shared_ptr<Y> && >( r ), p ).swap( *this ); |
722 | } |
723 | |
724 | #endif |
725 | |
726 | typename boost::detail::sp_dereference< T >::type operator* () const BOOST_SP_NOEXCEPT_WITH_ASSERTnoexcept |
727 | { |
728 | BOOST_ASSERT( px != 0 )(static_cast <bool> (px != 0) ? void (0) : __assert_fail ("px != 0", "/home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost/boost/smart_ptr/shared_ptr.hpp" , 728, __extension__ __PRETTY_FUNCTION__)); |
729 | return *px; |
730 | } |
731 | |
732 | typename boost::detail::sp_member_access< T >::type operator-> () const BOOST_SP_NOEXCEPT_WITH_ASSERTnoexcept |
733 | { |
734 | BOOST_ASSERT( px != 0 )(static_cast <bool> (px != 0) ? void (0) : __assert_fail ("px != 0", "/home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost/boost/smart_ptr/shared_ptr.hpp" , 734, __extension__ __PRETTY_FUNCTION__)); |
735 | return px; |
736 | } |
737 | |
738 | typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const BOOST_SP_NOEXCEPT_WITH_ASSERTnoexcept |
739 | { |
740 | BOOST_ASSERT( px != 0 )(static_cast <bool> (px != 0) ? void (0) : __assert_fail ("px != 0", "/home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost/boost/smart_ptr/shared_ptr.hpp" , 740, __extension__ __PRETTY_FUNCTION__)); |
741 | BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) )(static_cast <bool> (i >= 0 && ( i < boost ::detail::sp_extent< T >::value || boost::detail::sp_extent < T >::value == 0 )) ? void (0) : __assert_fail ("i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 )" , "/home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost/boost/smart_ptr/shared_ptr.hpp" , 741, __extension__ __PRETTY_FUNCTION__)); |
742 | |
743 | return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] ); |
744 | } |
745 | |
746 | element_type * get() const BOOST_SP_NOEXCEPTnoexcept |
747 | { |
748 | return px; |
749 | } |
750 | |
751 | // implicit conversion to "bool" |
752 | #include <boost/smart_ptr/detail/operator_bool.hpp> |
753 | |
754 | bool unique() const BOOST_SP_NOEXCEPTnoexcept |
755 | { |
756 | return pn.unique(); |
757 | } |
758 | |
759 | long use_count() const BOOST_SP_NOEXCEPTnoexcept |
760 | { |
761 | return pn.use_count(); |
762 | } |
763 | |
764 | void swap( shared_ptr & other ) BOOST_SP_NOEXCEPTnoexcept |
765 | { |
766 | std::swap(px, other.px); |
767 | pn.swap(other.pn); |
768 | } |
769 | |
770 | template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPTnoexcept |
771 | { |
772 | return pn < rhs.pn; |
773 | } |
774 | |
775 | template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPTnoexcept |
776 | { |
777 | return pn < rhs.pn; |
778 | } |
779 | |
780 | void * _internal_get_deleter( boost::detail::sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPTnoexcept |
781 | { |
782 | return pn.get_deleter( ti ); |
783 | } |
784 | |
785 | void * _internal_get_local_deleter( boost::detail::sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPTnoexcept |
786 | { |
787 | return pn.get_local_deleter( ti ); |
788 | } |
789 | |
790 | void * _internal_get_untyped_deleter() const BOOST_SP_NOEXCEPTnoexcept |
791 | { |
792 | return pn.get_untyped_deleter(); |
793 | } |
794 | |
795 | bool _internal_equiv( shared_ptr const & r ) const BOOST_SP_NOEXCEPTnoexcept |
796 | { |
797 | return px == r.px && pn == r.pn; |
798 | } |
799 | |
800 | boost::detail::shared_count _internal_count() const BOOST_SP_NOEXCEPTnoexcept |
801 | { |
802 | return pn; |
803 | } |
804 | |
805 | // Tasteless as this may seem, making all members public allows member templates |
806 | // to work in the absence of member template friends. (Matthew Langston) |
807 | |
808 | #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS |
809 | |
810 | private: |
811 | |
812 | template<class Y> friend class shared_ptr; |
813 | template<class Y> friend class weak_ptr; |
814 | |
815 | |
816 | #endif |
817 | |
818 | element_type * px; // contained pointer |
819 | boost::detail::shared_count pn; // reference counter |
820 | |
821 | }; // shared_ptr |
822 | |
823 | template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPTnoexcept |
824 | { |
825 | return a.get() == b.get(); |
826 | } |
827 | |
828 | template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPTnoexcept |
829 | { |
830 | return a.get() != b.get(); |
831 | } |
832 | |
833 | #if __GNUC__4 == 2 && __GNUC_MINOR__2 <= 96 |
834 | |
835 | // Resolve the ambiguity between our op!= and the one in rel_ops |
836 | |
837 | template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_SP_NOEXCEPTnoexcept |
838 | { |
839 | return a.get() != b.get(); |
840 | } |
841 | |
842 | #endif |
843 | |
844 | #if !defined( BOOST_NO_CXX11_NULLPTR ) |
845 | |
846 | template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPTnoexcept |
847 | { |
848 | return p.get() == 0; |
849 | } |
850 | |
851 | template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPTnoexcept |
852 | { |
853 | return p.get() == 0; |
854 | } |
855 | |
856 | template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPTnoexcept |
857 | { |
858 | return p.get() != 0; |
859 | } |
860 | |
861 | template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPTnoexcept |
862 | { |
863 | return p.get() != 0; |
864 | } |
865 | |
866 | #endif |
867 | |
868 | template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPTnoexcept |
869 | { |
870 | return a.owner_before( b ); |
871 | } |
872 | |
873 | template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_SP_NOEXCEPTnoexcept |
874 | { |
875 | a.swap(b); |
876 | } |
877 | |
878 | template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPTnoexcept |
879 | { |
880 | (void) static_cast< T* >( static_cast< U* >( 0 ) ); |
881 | |
882 | typedef typename shared_ptr<T>::element_type E; |
883 | |
884 | E * p = static_cast< E* >( r.get() ); |
885 | return shared_ptr<T>( r, p ); |
886 | } |
887 | |
888 | template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPTnoexcept |
889 | { |
890 | (void) const_cast< T* >( static_cast< U* >( 0 ) ); |
891 | |
892 | typedef typename shared_ptr<T>::element_type E; |
893 | |
894 | E * p = const_cast< E* >( r.get() ); |
895 | return shared_ptr<T>( r, p ); |
896 | } |
897 | |
898 | template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPTnoexcept |
899 | { |
900 | (void) dynamic_cast< T* >( static_cast< U* >( 0 ) ); |
901 | |
902 | typedef typename shared_ptr<T>::element_type E; |
903 | |
904 | E * p = dynamic_cast< E* >( r.get() ); |
905 | return p? shared_ptr<T>( r, p ): shared_ptr<T>(); |
906 | } |
907 | |
908 | template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPTnoexcept |
909 | { |
910 | (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); |
911 | |
912 | typedef typename shared_ptr<T>::element_type E; |
913 | |
914 | E * p = reinterpret_cast< E* >( r.get() ); |
915 | return shared_ptr<T>( r, p ); |
916 | } |
917 | |
918 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
919 | |
920 | template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPTnoexcept |
921 | { |
922 | (void) static_cast< T* >( static_cast< U* >( 0 ) ); |
923 | |
924 | typedef typename shared_ptr<T>::element_type E; |
925 | |
926 | E * p = static_cast< E* >( r.get() ); |
927 | return shared_ptr<T>( std::move(r), p ); |
928 | } |
929 | |
930 | template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPTnoexcept |
931 | { |
932 | (void) const_cast< T* >( static_cast< U* >( 0 ) ); |
933 | |
934 | typedef typename shared_ptr<T>::element_type E; |
935 | |
936 | E * p = const_cast< E* >( r.get() ); |
937 | return shared_ptr<T>( std::move(r), p ); |
938 | } |
939 | |
940 | template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPTnoexcept |
941 | { |
942 | (void) dynamic_cast< T* >( static_cast< U* >( 0 ) ); |
943 | |
944 | typedef typename shared_ptr<T>::element_type E; |
945 | |
946 | E * p = dynamic_cast< E* >( r.get() ); |
947 | return p? shared_ptr<T>( std::move(r), p ): shared_ptr<T>(); |
948 | } |
949 | |
950 | template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPTnoexcept |
951 | { |
952 | (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); |
953 | |
954 | typedef typename shared_ptr<T>::element_type E; |
955 | |
956 | E * p = reinterpret_cast< E* >( r.get() ); |
957 | return shared_ptr<T>( std::move(r), p ); |
958 | } |
959 | |
960 | #endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
961 | |
962 | // get_pointer() enables boost::mem_fn to recognize shared_ptr |
963 | |
964 | template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_SP_NOEXCEPTnoexcept |
965 | { |
966 | return p.get(); |
967 | } |
968 | |
969 | // operator<< |
970 | |
971 | #if !defined(BOOST_NO_IOSTREAM) |
972 | |
973 | #if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__4) && (__GNUC__4 < 3) ) |
974 | |
975 | template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p) |
976 | { |
977 | os << p.get(); |
978 | return os; |
979 | } |
980 | |
981 | #else |
982 | |
983 | // in STLport's no-iostreams mode no iostream symbols can be used |
984 | #ifndef _STLP_NO_IOSTREAMS |
985 | |
986 | # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)((1 + 0 == 0) && (BOOST_MSVC != 0) && (1 % (( (BOOST_MSVC < 1300 && __SGI_STL_PORT) ) + 1))) |
987 | // MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL |
988 | using std::basic_ostream; |
989 | template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p) |
990 | # else |
991 | template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p) |
992 | # endif |
993 | { |
994 | os << p.get(); |
995 | return os; |
996 | } |
997 | |
998 | #endif // _STLP_NO_IOSTREAMS |
999 | |
1000 | #endif // __GNUC__ < 3 |
1001 | |
1002 | #endif // !defined(BOOST_NO_IOSTREAM) |
1003 | |
1004 | // get_deleter |
1005 | |
1006 | namespace detail |
1007 | { |
1008 | |
1009 | template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_SP_NOEXCEPTnoexcept |
1010 | { |
1011 | return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID_(D)typeid(D)) ); |
1012 | } |
1013 | |
1014 | template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPTnoexcept; |
1015 | template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPTnoexcept; |
1016 | |
1017 | class esft2_deleter_wrapper |
1018 | { |
1019 | private: |
1020 | |
1021 | shared_ptr<void const volatile> deleter_; |
1022 | |
1023 | public: |
1024 | |
1025 | esft2_deleter_wrapper() BOOST_SP_NOEXCEPTnoexcept |
1026 | { |
1027 | } |
1028 | |
1029 | template< class T > void set_deleter( shared_ptr<T> const & deleter ) BOOST_SP_NOEXCEPTnoexcept |
1030 | { |
1031 | deleter_ = deleter; |
1032 | } |
1033 | |
1034 | template<typename D> D* get_deleter() const BOOST_SP_NOEXCEPTnoexcept |
1035 | { |
1036 | return boost::detail::basic_get_deleter<D>( deleter_ ); |
1037 | } |
1038 | |
1039 | template< class T> void operator()( T* ) BOOST_SP_NOEXCEPT_WITH_ASSERTnoexcept |
1040 | { |
1041 | BOOST_ASSERT( deleter_.use_count() <= 1 )(static_cast <bool> (deleter_.use_count() <= 1) ? void (0) : __assert_fail ("deleter_.use_count() <= 1", "/home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost/boost/smart_ptr/shared_ptr.hpp" , 1041, __extension__ __PRETTY_FUNCTION__)); |
1042 | deleter_.reset(); |
1043 | } |
1044 | }; |
1045 | |
1046 | } // namespace detail |
1047 | |
1048 | template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_SP_NOEXCEPTnoexcept |
1049 | { |
1050 | D * d = boost::detail::basic_get_deleter<D>( p ); |
1051 | |
1052 | if( d == 0 ) |
1053 | { |
1054 | d = boost::detail::basic_get_local_deleter( d, p ); |
1055 | } |
1056 | |
1057 | if( d == 0 ) |
1058 | { |
1059 | boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter<boost::detail::esft2_deleter_wrapper>(p); |
1060 | // The following get_deleter method call is fully qualified because |
1061 | // older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>() |
1062 | if(del_wrapper) d = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>(); |
1063 | } |
1064 | |
1065 | return d; |
1066 | } |
1067 | |
1068 | // atomic access |
1069 | |
1070 | #if !defined(BOOST_SP_NO_ATOMIC_ACCESS) |
1071 | |
1072 | template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_SP_NOEXCEPTnoexcept |
1073 | { |
1074 | return false; |
1075 | } |
1076 | |
1077 | template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ) BOOST_SP_NOEXCEPTnoexcept |
1078 | { |
1079 | boost::detail::spinlock_pool<2>::scoped_lock lock( p ); |
1080 | return *p; |
1081 | } |
1082 | |
1083 | template<class T, class M> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, /*memory_order mo*/ M ) BOOST_SP_NOEXCEPTnoexcept |
1084 | { |
1085 | return atomic_load( p ); |
1086 | } |
1087 | |
1088 | template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ) BOOST_SP_NOEXCEPTnoexcept |
1089 | { |
1090 | boost::detail::spinlock_pool<2>::scoped_lock lock( p ); |
1091 | p->swap( r ); |
1092 | } |
1093 | |
1094 | template<class T, class M> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ M ) BOOST_SP_NOEXCEPTnoexcept |
1095 | { |
1096 | atomic_store( p, r ); // std::move( r ) |
1097 | } |
1098 | |
1099 | template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ) BOOST_SP_NOEXCEPTnoexcept |
1100 | { |
1101 | boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p ); |
1102 | |
1103 | sp.lock(); |
1104 | p->swap( r ); |
1105 | sp.unlock(); |
1106 | |
1107 | return r; // return std::move( r ) |
1108 | } |
1109 | |
1110 | template<class T, class M> shared_ptr<T> inline atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ M ) BOOST_SP_NOEXCEPTnoexcept |
1111 | { |
1112 | return atomic_exchange( p, r ); // std::move( r ) |
1113 | } |
1114 | |
1115 | template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ) BOOST_SP_NOEXCEPTnoexcept |
1116 | { |
1117 | boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p ); |
1118 | |
1119 | sp.lock(); |
1120 | |
1121 | if( p->_internal_equiv( *v ) ) |
1122 | { |
1123 | p->swap( w ); |
1124 | |
1125 | sp.unlock(); |
1126 | |
1127 | return true; |
1128 | } |
1129 | else |
1130 | { |
1131 | shared_ptr<T> tmp( *p ); |
1132 | |
1133 | sp.unlock(); |
1134 | |
1135 | tmp.swap( *v ); |
1136 | return false; |
1137 | } |
1138 | } |
1139 | |
1140 | template<class T, class M> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, /*memory_order success*/ M, /*memory_order failure*/ M ) BOOST_SP_NOEXCEPTnoexcept |
1141 | { |
1142 | return atomic_compare_exchange( p, v, w ); // std::move( w ) |
1143 | } |
1144 | |
1145 | #endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS) |
1146 | |
1147 | // hash_value |
1148 | |
1149 | template< class T > struct hash; |
1150 | |
1151 | template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_SP_NOEXCEPTnoexcept |
1152 | { |
1153 | return boost::hash< typename boost::shared_ptr<T>::element_type* >()( p.get() ); |
1154 | } |
1155 | |
1156 | } // namespace boost |
1157 | |
1158 | #include <boost/smart_ptr/detail/local_sp_deleter.hpp> |
1159 | |
1160 | namespace boost |
1161 | { |
1162 | |
1163 | namespace detail |
1164 | { |
1165 | |
1166 | template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPTnoexcept |
1167 | { |
1168 | return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID_(local_sp_deleter<D>)typeid(local_sp_deleter<D>) ) ); |
1169 | } |
1170 | |
1171 | template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPTnoexcept |
1172 | { |
1173 | return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID_(local_sp_deleter<D>)typeid(local_sp_deleter<D>) ) ); |
1174 | } |
1175 | |
1176 | } // namespace detail |
1177 | |
1178 | } // namespace boost |
1179 | |
1180 | #if defined( BOOST_SP_DISABLE_DEPRECATED ) |
1181 | #pragma GCC diagnostic pop |
1182 | #endif |
1183 | |
1184 | #endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED |
1 | // Move, forward and identity for C++11 + swap -*- C++ -*- |
2 | |
3 | // Copyright (C) 2007-2020 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /** @file bits/move.h |
26 | * This is an internal header file, included by other library headers. |
27 | * Do not attempt to use it directly. @headername{utility} |
28 | */ |
29 | |
30 | #ifndef _MOVE_H1 |
31 | #define _MOVE_H1 1 |
32 | |
33 | #include <bits/c++config.h> |
34 | #if __cplusplus201703L < 201103L |
35 | # include <bits/concept_check.h> |
36 | #endif |
37 | |
38 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
39 | { |
40 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
41 | |
42 | // Used, in C++03 mode too, by allocators, etc. |
43 | /** |
44 | * @brief Same as C++11 std::addressof |
45 | * @ingroup utilities |
46 | */ |
47 | template<typename _Tp> |
48 | inline _GLIBCXX_CONSTEXPRconstexpr _Tp* |
49 | __addressof(_Tp& __r) _GLIBCXX_NOEXCEPTnoexcept |
50 | { return __builtin_addressof(__r); } |
51 | |
52 | #if __cplusplus201703L >= 201103L |
53 | |
54 | _GLIBCXX_END_NAMESPACE_VERSION |
55 | } // namespace |
56 | |
57 | #include <type_traits> // Brings in std::declval too. |
58 | |
59 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
60 | { |
61 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
62 | |
63 | /** |
64 | * @addtogroup utilities |
65 | * @{ |
66 | */ |
67 | |
68 | /** |
69 | * @brief Forward an lvalue. |
70 | * @return The parameter cast to the specified type. |
71 | * |
72 | * This function is used to implement "perfect forwarding". |
73 | */ |
74 | template<typename _Tp> |
75 | constexpr _Tp&& |
76 | forward(typename std::remove_reference<_Tp>::type& __t) noexcept |
77 | { return static_cast<_Tp&&>(__t); } |
78 | |
79 | /** |
80 | * @brief Forward an rvalue. |
81 | * @return The parameter cast to the specified type. |
82 | * |
83 | * This function is used to implement "perfect forwarding". |
84 | */ |
85 | template<typename _Tp> |
86 | constexpr _Tp&& |
87 | forward(typename std::remove_reference<_Tp>::type&& __t) noexcept |
88 | { |
89 | static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument" |
90 | " substituting _Tp is an lvalue reference type"); |
91 | return static_cast<_Tp&&>(__t); |
92 | } |
93 | |
94 | /** |
95 | * @brief Convert a value to an rvalue. |
96 | * @param __t A thing of arbitrary type. |
97 | * @return The parameter cast to an rvalue-reference to allow moving it. |
98 | */ |
99 | template<typename _Tp> |
100 | constexpr typename std::remove_reference<_Tp>::type&& |
101 | move(_Tp&& __t) noexcept |
102 | { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); } |
103 | |
104 | |
105 | template<typename _Tp> |
106 | struct __move_if_noexcept_cond |
107 | : public __and_<__not_<is_nothrow_move_constructible<_Tp>>, |
108 | is_copy_constructible<_Tp>>::type { }; |
109 | |
110 | /** |
111 | * @brief Conditionally convert a value to an rvalue. |
112 | * @param __x A thing of arbitrary type. |
113 | * @return The parameter, possibly cast to an rvalue-reference. |
114 | * |
115 | * Same as std::move unless the type's move constructor could throw and the |
116 | * type is copyable, in which case an lvalue-reference is returned instead. |
117 | */ |
118 | template<typename _Tp> |
119 | constexpr typename |
120 | conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type |
121 | move_if_noexcept(_Tp& __x) noexcept |
122 | { return std::move(__x); } |
123 | |
124 | // declval, from type_traits. |
125 | |
126 | #if __cplusplus201703L > 201402L |
127 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
128 | // 2296. std::addressof should be constexpr |
129 | # define __cpp_lib_addressof_constexpr201603 201603 |
130 | #endif |
131 | /** |
132 | * @brief Returns the actual address of the object or function |
133 | * referenced by r, even in the presence of an overloaded |
134 | * operator&. |
135 | * @param __r Reference to an object or function. |
136 | * @return The actual address. |
137 | */ |
138 | template<typename _Tp> |
139 | inline _GLIBCXX17_CONSTEXPRconstexpr _Tp* |
140 | addressof(_Tp& __r) noexcept |
141 | { return std::__addressof(__r); } |
142 | |
143 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
144 | // 2598. addressof works on temporaries |
145 | template<typename _Tp> |
146 | const _Tp* addressof(const _Tp&&) = delete; |
147 | |
148 | // C++11 version of std::exchange for internal use. |
149 | template <typename _Tp, typename _Up = _Tp> |
150 | _GLIBCXX20_CONSTEXPR |
151 | inline _Tp |
152 | __exchange(_Tp& __obj, _Up&& __new_val) |
153 | { |
154 | _Tp __old_val = std::move(__obj); |
155 | __obj = std::forward<_Up>(__new_val); |
156 | return __old_val; |
157 | } |
158 | |
159 | /// @} group utilities |
160 | |
161 | #define _GLIBCXX_MOVE(__val)std::move(__val) std::move(__val) |
162 | #define _GLIBCXX_FORWARD(_Tp, __val)std::forward<_Tp>(__val) std::forward<_Tp>(__val) |
163 | #else |
164 | #define _GLIBCXX_MOVE(__val)std::move(__val) (__val) |
165 | #define _GLIBCXX_FORWARD(_Tp, __val)std::forward<_Tp>(__val) (__val) |
166 | #endif |
167 | |
168 | /** |
169 | * @addtogroup utilities |
170 | * @{ |
171 | */ |
172 | |
173 | /** |
174 | * @brief Swaps two values. |
175 | * @param __a A thing of arbitrary type. |
176 | * @param __b Another thing of arbitrary type. |
177 | * @return Nothing. |
178 | */ |
179 | template<typename _Tp> |
180 | _GLIBCXX20_CONSTEXPR |
181 | inline |
182 | #if __cplusplus201703L >= 201103L |
183 | typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>, |
184 | is_move_constructible<_Tp>, |
185 | is_move_assignable<_Tp>>::value>::type |
186 | #else |
187 | void |
188 | #endif |
189 | swap(_Tp& __a, _Tp& __b) |
190 | _GLIBCXX_NOEXCEPT_IF(__and_<is_nothrow_move_constructible<_Tp>,noexcept(__and_<is_nothrow_move_constructible<_Tp>, is_nothrow_move_assignable <_Tp>>::value) |
191 | is_nothrow_move_assignable<_Tp>>::value)noexcept(__and_<is_nothrow_move_constructible<_Tp>, is_nothrow_move_assignable <_Tp>>::value) |
192 | { |
193 | #if __cplusplus201703L < 201103L |
194 | // concept requirements |
195 | __glibcxx_function_requires(_SGIAssignableConcept<_Tp>) |
196 | #endif |
197 | _Tp __tmp = _GLIBCXX_MOVE(__a)std::move(__a); |
198 | __a = _GLIBCXX_MOVE(__b)std::move(__b); |
199 | __b = _GLIBCXX_MOVE(__tmp)std::move(__tmp); |
200 | } |
201 | |
202 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
203 | // DR 809. std::swap should be overloaded for array types. |
204 | /// Swap the contents of two arrays. |
205 | template<typename _Tp, size_t _Nm> |
206 | _GLIBCXX20_CONSTEXPR |
207 | inline |
208 | #if __cplusplus201703L >= 201103L |
209 | typename enable_if<__is_swappable<_Tp>::value>::type |
210 | #else |
211 | void |
212 | #endif |
213 | swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) |
214 | _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Tp>::value)noexcept(__is_nothrow_swappable<_Tp>::value) |
215 | { |
216 | for (size_t __n = 0; __n < _Nm; ++__n) |
217 | swap(__a[__n], __b[__n]); |
218 | } |
219 | |
220 | /// @} group utilities |
221 | _GLIBCXX_END_NAMESPACE_VERSION |
222 | } // namespace |
223 | |
224 | #endif /* _MOVE_H */ |