1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #include <rtl/uri.hxx>
32 #include <rtl/ustring.hxx>
33 #include <rtl/ustrbuf.hxx>
35 #include "NeonUri.hxx"
36 #include "DAVException.hxx"
38 #include "../inc/urihelper.hxx"
40 using namespace webdav_ucp
;
42 # if defined __SUNPRO_CC
43 // FIXME: not sure whether initializing a ne_uri statically is supposed to work
44 // the string fields of ne_uri are char*, not const char*
49 #define GCC_VERSION (__GNUC__ * 10000 \
50 + __GNUC_MINOR__ * 100 \
51 + __GNUC_PATCHLEVEL__)
52 /* Diagnostics pragma was introduced with gcc-4.2.1 */
53 #if GCC_VERSION >= 40201
54 #pragma GCC diagnostic ignored "-Wwrite-strings"
60 const ne_uri g_sUriDefaultsHTTP
= { "http",
67 const ne_uri g_sUriDefaultsHTTPS
= { "https",
74 const ne_uri g_sUriDefaultsFTP
= { "ftp",
83 # if defined __SUNPRO_CC
87 // -------------------------------------------------------------------
89 // -------------------------------------------------------------------
93 //TODO! rtl::OString::matchIgnoreAsciiCaseAsciiL() missing
94 inline bool matchIgnoreAsciiCase(rtl::OString
const & rStr1
,
95 sal_Char
const * pStr2
,
96 sal_Int32 nStr2Len
) SAL_THROW(())
99 rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
100 rStr1
.getStr(), rStr1
.getLength(), pStr2
, nStr2Len
, nStr2Len
)
106 NeonUri::NeonUri( const ne_uri
* inUri
)
107 throw ( DAVException
)
110 throw DAVException( DAVException::DAV_INVALID_ARG
);
112 char * uri
= ne_uri_unparse( inUri
);
115 throw DAVException( DAVException::DAV_INVALID_ARG
);
117 init( rtl::OString( uri
), inUri
);
123 NeonUri::NeonUri( const rtl::OUString
& inUri
)
124 throw ( DAVException
)
126 if ( inUri
.isEmpty() )
127 throw DAVException( DAVException::DAV_INVALID_ARG
);
130 rtl::OUString
aEscapedUri( ucb_impl::urihelper::encodeURI( inUri
) );
132 rtl::OString
theInputUri(
133 aEscapedUri
.getStr(), aEscapedUri
.getLength(), RTL_TEXTENCODING_UTF8
);
136 if ( ne_uri_parse( theInputUri
.getStr(), &theUri
) != 0 )
138 ne_uri_free( &theUri
);
139 throw DAVException( DAVException::DAV_INVALID_ARG
);
142 init( theInputUri
, &theUri
);
143 ne_uri_free( &theUri
);
148 void NeonUri::init( const rtl::OString
& rUri
, const ne_uri
* pUri
)
151 const ne_uri
* pUriDefs
152 = matchIgnoreAsciiCase( rUri
,
153 RTL_CONSTASCII_STRINGPARAM( "ftp:" ) ) ?
155 matchIgnoreAsciiCase( rUri
,
156 RTL_CONSTASCII_STRINGPARAM( "https:" ) ) ?
157 &g_sUriDefaultsHTTPS
:
160 mScheme
= rtl::OStringToOUString(
161 pUri
->scheme
? pUri
->scheme
: pUriDefs
->scheme
,
162 RTL_TEXTENCODING_UTF8
);
163 mUserInfo
= rtl::OStringToOUString(
164 pUri
->userinfo
? pUri
->userinfo
: pUriDefs
->userinfo
,
165 RTL_TEXTENCODING_UTF8
);
166 mHostName
= rtl::OStringToOUString(
167 pUri
->host
? pUri
->host
: pUriDefs
->host
,
168 RTL_TEXTENCODING_UTF8
);
169 mPort
= pUri
->port
> 0 ? pUri
->port
: pUriDefs
->port
;
170 mPath
= rtl::OStringToOUString(
171 pUri
->path
? pUri
->path
: pUriDefs
->path
,
172 RTL_TEXTENCODING_UTF8
);
176 mPath
+= rtl::OUString("?");
177 mPath
+= rtl::OStringToOUString(
178 pUri
->query
, RTL_TEXTENCODING_UTF8
);
181 if ( pUri
->fragment
)
183 mPath
+= rtl::OUString("#");
184 mPath
+= rtl::OStringToOUString(
185 pUri
->fragment
, RTL_TEXTENCODING_UTF8
);
189 // -------------------------------------------------------------------
191 // -------------------------------------------------------------------
196 void NeonUri::calculateURI ()
198 rtl::OUStringBuffer
aBuf( mScheme
);
199 aBuf
.appendAscii( "://" );
200 if ( !mUserInfo
.isEmpty() )
202 //TODO! differentiate between empty and missing userinfo
203 aBuf
.append( mUserInfo
);
204 aBuf
.appendAscii( "@" );
206 // Is host a numeric IPv6 address?
207 if ( ( mHostName
.indexOf( ':' ) != -1 ) &&
208 ( mHostName
[ 0 ] != sal_Unicode( '[' ) ) )
210 aBuf
.appendAscii( "[" );
211 aBuf
.append( mHostName
);
212 aBuf
.appendAscii( "]" );
216 aBuf
.append( mHostName
);
219 // append port, but only, if not default port.
220 bool bAppendPort
= true;
223 case DEFAULT_HTTP_PORT
:
224 bAppendPort
= mScheme
!= "http";
227 case DEFAULT_HTTPS_PORT
:
228 bAppendPort
= mScheme
!= "https";
231 case DEFAULT_FTP_PORT
:
232 bAppendPort
= mScheme
!= "ftp";
237 aBuf
.appendAscii( ":" );
238 aBuf
.append( rtl::OUString::valueOf( mPort
) );
240 aBuf
.append( mPath
);
242 mURI
= aBuf
.makeStringAndClear();
245 ::rtl::OUString
NeonUri::GetPathBaseName () const
247 sal_Int32 nPos
= mPath
.lastIndexOf ('/');
248 sal_Int32 nTrail
= 0;
249 if (nPos
== mPath
.getLength () - 1)
251 // Trailing slash found. Skip.
253 nPos
= mPath
.lastIndexOf ('/', nPos
);
258 mPath
.copy (nPos
+ 1, mPath
.getLength () - nPos
- 1 - nTrail
) );
260 // query, fragment present?
261 nPos
= aTemp
.indexOf( '?' );
263 nPos
= aTemp
.indexOf( '#' );
266 aTemp
= aTemp
.copy( 0, nPos
);
271 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("/"));
274 bool NeonUri::operator== ( const NeonUri
& rOther
) const
276 return ( mURI
== rOther
.mURI
);
279 ::rtl::OUString
NeonUri::GetPathBaseNameUnescaped () const
281 return unescape( GetPathBaseName() );
284 void NeonUri::AppendPath (const rtl::OUString
& rPath
)
286 if (mPath
.lastIndexOf ('/') != mPath
.getLength () - 1)
287 mPath
+= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("/"));
294 rtl::OUString
NeonUri::escapeSegment( const rtl::OUString
& segment
)
296 return rtl::Uri::encode( segment
,
297 rtl_UriCharClassPchar
,
298 rtl_UriEncodeIgnoreEscapes
,
299 RTL_TEXTENCODING_UTF8
);
303 rtl::OUString
NeonUri::unescape( const rtl::OUString
& segment
)
305 return rtl::Uri::decode( segment
,
306 rtl_UriDecodeWithCharset
,
307 RTL_TEXTENCODING_UTF8
);
311 rtl::OUString
NeonUri::makeConnectionEndPointString(
312 const rtl::OUString
& rHostName
, int nPort
)
314 rtl::OUStringBuffer aBuf
;
316 // Is host a numeric IPv6 address?
317 if ( ( rHostName
.indexOf( ':' ) != -1 ) &&
318 ( rHostName
[ 0 ] != sal_Unicode( '[' ) ) )
320 aBuf
.appendAscii( "[" );
321 aBuf
.append( rHostName
);
322 aBuf
.appendAscii( "]" );
326 aBuf
.append( rHostName
);
329 if ( ( nPort
!= DEFAULT_HTTP_PORT
) && ( nPort
!= DEFAULT_HTTPS_PORT
) )
331 aBuf
.appendAscii( ":" );
332 aBuf
.append( rtl::OUString::valueOf( sal_Int32( nPort
) ) );
334 return aBuf
.makeStringAndClear();
337 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */