Update ooo320-m1
[ooovba.git] / ucb / source / ucp / webdav / NeonUri.cxx
blobed8315b1cd146c2170d7a86b65f43cd02249f840
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: NeonUri.cxx,v $
10 * $Revision: 1.25.16.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
34 #include <string.h>
35 #include <rtl/uri.hxx>
36 #include <rtl/ustring.hxx>
37 #include <rtl/ustrbuf.hxx>
38 #include "NeonUri.hxx"
39 #include "DAVException.hxx"
41 #include "../inc/urihelper.hxx"
43 using namespace webdav_ucp;
45 char *scheme;
46 char *host, *userinfo;
47 unsigned int port;
48 char *path, *query, *fragment;
50 # if defined __SUNPRO_CC
51 // FIXME: not sure whether initializing a ne_uri statically is supposed to work
52 // the string fields of ne_uri are char*, not const char*
53 # pragma disable_warn
54 # endif
56 #if defined __GNUC__
57 #define GCC_VERSION (__GNUC__ * 10000 \
58 + __GNUC_MINOR__ * 100 \
59 + __GNUC_PATCHLEVEL__)
60 /* Diagnostics pragma was introduced with gcc-4.2.1 */
61 #if GCC_VERSION > 40201
62 #pragma GCC diagnostic ignored "-Wwrite-strings"
63 #endif
64 #endif
66 namespace {
68 const ne_uri g_sUriDefaultsHTTP = { "http",
69 #if NEON_VERSION >= 0x0260
70 NULL,
71 #endif
72 NULL,
73 DEFAULT_HTTP_PORT,
74 #if NEON_VERSION >= 0x0260
75 NULL,
76 #endif
77 NULL,
78 NULL };
79 const ne_uri g_sUriDefaultsHTTPS = { "https",
80 #if NEON_VERSION >= 0x0260
81 NULL,
82 #endif
83 NULL,
84 DEFAULT_HTTPS_PORT,
85 #if NEON_VERSION >= 0x0260
86 NULL,
87 #endif
88 NULL,
89 NULL };
90 const ne_uri g_sUriDefaultsFTP = { "ftp",
91 #if NEON_VERSION >= 0x0260
92 NULL,
93 #endif
94 NULL,
95 DEFAULT_FTP_PORT,
96 #if NEON_VERSION >= 0x0260
97 NULL,
98 #endif
99 NULL,
100 NULL };
101 } // namespace
103 # if defined __SUNPRO_CC
104 # pragma enable_warn
105 #endif
107 // -------------------------------------------------------------------
108 // Constructor
109 // -------------------------------------------------------------------
111 namespace {
113 //TODO! rtl::OString::matchIgnoreAsciiCaseAsciiL() missing
114 inline bool matchIgnoreAsciiCase(rtl::OString const & rStr1,
115 sal_Char const * pStr2,
116 sal_Int32 nStr2Len) SAL_THROW(())
118 return
119 rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
120 rStr1.getStr(), rStr1.getLength(), pStr2, nStr2Len, nStr2Len)
121 == 0;
126 NeonUri::NeonUri( const ne_uri * inUri )
127 throw ( DAVException )
129 if ( inUri == 0 )
130 throw DAVException( DAVException::DAV_INVALID_ARG );
132 char * uri = ne_uri_unparse( inUri );
134 if ( uri == 0 )
135 throw DAVException( DAVException::DAV_INVALID_ARG );
137 init( rtl::OString( uri ), inUri );
138 free( uri );
140 calculateURI();
143 NeonUri::NeonUri( const rtl::OUString & inUri )
144 throw ( DAVException )
146 if ( inUri.getLength() <= 0 )
147 throw DAVException( DAVException::DAV_INVALID_ARG );
149 // #i77023#
150 rtl::OUString aEscapedUri( ucb_impl::urihelper::encodeURI( inUri ) );
152 rtl::OString theInputUri(
153 aEscapedUri.getStr(), aEscapedUri.getLength(), RTL_TEXTENCODING_UTF8 );
155 ne_uri theUri;
156 if ( ne_uri_parse( theInputUri.getStr(), &theUri ) != 0 )
158 ne_uri_free( &theUri );
159 throw DAVException( DAVException::DAV_INVALID_ARG );
162 init( theInputUri, &theUri );
163 ne_uri_free( &theUri );
165 calculateURI();
168 void NeonUri::init( const rtl::OString & rUri, const ne_uri * pUri )
170 // Complete URI.
171 const ne_uri * pUriDefs
172 = matchIgnoreAsciiCase( rUri,
173 RTL_CONSTASCII_STRINGPARAM( "ftp:" ) ) ?
174 &g_sUriDefaultsFTP :
175 matchIgnoreAsciiCase( rUri,
176 RTL_CONSTASCII_STRINGPARAM( "https:" ) ) ?
177 &g_sUriDefaultsHTTPS :
178 &g_sUriDefaultsHTTP;
180 mScheme = rtl::OStringToOUString(
181 pUri->scheme ? pUri->scheme : pUriDefs->scheme,
182 RTL_TEXTENCODING_UTF8 );
183 mUserInfo = rtl::OStringToOUString(
184 #if NEON_VERSION >= 0x0260
185 pUri->userinfo ? pUri->userinfo : pUriDefs->userinfo,
186 #else
187 pUri->authinfo ? pUri->authinfo : pUriDefs->authinfo,
188 #endif
189 RTL_TEXTENCODING_UTF8 );
190 mHostName = rtl::OStringToOUString(
191 pUri->host ? pUri->host : pUriDefs->host,
192 RTL_TEXTENCODING_UTF8 );
193 mPort = pUri->port > 0 ? pUri->port : pUriDefs->port;
194 mPath = rtl::OStringToOUString(
195 pUri->path ? pUri->path : pUriDefs->path,
196 RTL_TEXTENCODING_UTF8 );
198 #if NEON_VERSION >= 0x0260
199 if ( pUri->query )
201 mPath += rtl::OUString::createFromAscii( "?" );
202 mPath += rtl::OStringToOUString(
203 pUri->query, RTL_TEXTENCODING_UTF8 );
206 if ( pUri->fragment )
208 mPath += rtl::OUString::createFromAscii( "#" );
209 mPath += rtl::OStringToOUString(
210 pUri->fragment, RTL_TEXTENCODING_UTF8 );
212 #endif
215 // -------------------------------------------------------------------
216 // Destructor
217 // -------------------------------------------------------------------
218 NeonUri::~NeonUri( )
222 void NeonUri::calculateURI ()
224 rtl::OUStringBuffer aBuf( mScheme );
225 aBuf.appendAscii( "://" );
226 if ( mUserInfo.getLength() > 0 )
228 //TODO! differentiate between empty and missing userinfo
229 aBuf.append( mUserInfo );
230 aBuf.appendAscii( "@" );
232 // Is host a numeric IPv6 address?
233 if ( ( mHostName.indexOf( ':' ) != -1 ) &&
234 ( mHostName[ 0 ] != sal_Unicode( '[' ) ) )
236 aBuf.appendAscii( "[" );
237 aBuf.append( mHostName );
238 aBuf.appendAscii( "]" );
240 else
242 aBuf.append( mHostName );
245 // append port, but only, if not default port.
246 bool bAppendPort = true;
247 switch ( mPort )
249 case DEFAULT_HTTP_PORT:
250 bAppendPort
251 = !mScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) );
252 break;
254 case DEFAULT_HTTPS_PORT:
255 bAppendPort
256 = !mScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) );
257 break;
259 case DEFAULT_FTP_PORT:
260 bAppendPort
261 = !mScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ftp" ) );
262 break;
264 if ( bAppendPort )
266 aBuf.appendAscii( ":" );
267 aBuf.append( rtl::OUString::valueOf( mPort ) );
269 aBuf.append( mPath );
271 mURI = aBuf.makeStringAndClear();
274 ::rtl::OUString NeonUri::GetPathBaseName () const
276 sal_Int32 nPos = mPath.lastIndexOf ('/');
277 sal_Int32 nTrail = 0;
278 if (nPos == mPath.getLength () - 1)
280 // Trailing slash found. Skip.
281 nTrail = 1;
282 nPos = mPath.lastIndexOf ('/', nPos);
284 if (nPos != -1)
286 rtl::OUString aTemp(
287 mPath.copy (nPos + 1, mPath.getLength () - nPos - 1 - nTrail) );
289 // query, fragment present?
290 nPos = aTemp.indexOf( '?' );
291 if ( nPos == -1 )
292 nPos = aTemp.indexOf( '#' );
294 if ( nPos != -1 )
295 aTemp = aTemp.copy( 0, nPos );
297 return aTemp;
299 else
300 return rtl::OUString::createFromAscii ("/");
303 bool NeonUri::operator== ( const NeonUri & rOther ) const
305 return ( mURI == rOther.mURI );
308 ::rtl::OUString NeonUri::GetPathBaseNameUnescaped () const
310 return unescape( GetPathBaseName() );
313 void NeonUri::AppendPath (const rtl::OUString& rPath)
315 if (mPath.lastIndexOf ('/') != mPath.getLength () - 1)
316 mPath += rtl::OUString::createFromAscii ("/");
318 mPath += rPath;
319 calculateURI ();
322 // static
323 rtl::OUString NeonUri::escapeSegment( const rtl::OUString& segment )
325 return rtl::Uri::encode( segment,
326 rtl_UriCharClassPchar,
327 rtl_UriEncodeIgnoreEscapes,
328 RTL_TEXTENCODING_UTF8 );
331 // static
332 rtl::OUString NeonUri::unescape( const rtl::OUString& segment )
334 return rtl::Uri::decode( segment,
335 rtl_UriDecodeWithCharset,
336 RTL_TEXTENCODING_UTF8 );
339 // static
340 rtl::OUString NeonUri::makeConnectionEndPointString(
341 const rtl::OUString & rHostName, int nPort )
343 rtl::OUStringBuffer aBuf;
345 // Is host a numeric IPv6 address?
346 if ( ( rHostName.indexOf( ':' ) != -1 ) &&
347 ( rHostName[ 0 ] != sal_Unicode( '[' ) ) )
349 aBuf.appendAscii( "[" );
350 aBuf.append( rHostName );
351 aBuf.appendAscii( "]" );
353 else
355 aBuf.append( rHostName );
358 if ( ( nPort != DEFAULT_HTTP_PORT ) && ( nPort != DEFAULT_HTTPS_PORT ) )
360 aBuf.appendAscii( ":" );
361 aBuf.append( rtl::OUString::valueOf( sal_Int32( nPort ) ) );
363 return aBuf.makeStringAndClear();