update dev300-m58
[ooovba.git] / sal / osl / unx / file_url.cxx
blob4e67fce517d9a838af7122f9cd6882a9de6f025f
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: file_url.cxx,v $
10 * $Revision: 1.13 $
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_sal.hxx"
34 #include "file_url.h"
36 #include "system.h"
38 #include <limits.h>
39 #include <errno.h>
40 #include <strings.h>
41 #include <unistd.h>
43 #include "osl/file.hxx"
44 #include <osl/security.h>
45 #include <osl/diagnose.h>
46 #include <osl/thread.h>
47 #include <osl/process.h>
49 #include <rtl/uri.h>
50 #include <rtl/ustring.hxx>
51 #include <rtl/ustrbuf.h>
52 #include "rtl/textcvt.h"
54 #include "file_error_transl.h"
55 #include "file_path_helper.hxx"
57 #include "uunxapi.hxx"
59 /***************************************************
61 General note
63 This file contains the part that handles File URLs.
65 File URLs as scheme specific notion of URIs
66 (RFC2396) may be handled platform independend, but
67 will not in osl which is considered wrong.
68 Future version of osl should handle File URLs this
69 way. In rtl/uri there is already an URI parser etc.
70 so this code should be consolidated.
72 **************************************************/
73 /************************************************************************
74 * ToDo
76 * Fix osl_getCanonicalName
78 ***********************************************************************/
81 /***************************************************
82 * namespace directives
83 **************************************************/
85 using namespace osl;
87 /***************************************************
88 * constants
89 **************************************************/
91 const sal_Unicode UNICHAR_SLASH = ((sal_Unicode)'/');
92 const sal_Unicode UNICHAR_COLON = ((sal_Unicode)':');
93 const sal_Unicode UNICHAR_DOT = ((sal_Unicode)'.');
95 /******************************************************************************
97 * Exported Module Functions
99 *****************************************************************************/
101 /* a slightly modified version of Pchar in rtl/source/uri.c */
102 const sal_Bool uriCharClass[128] =
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Pchar but without encoding slashes */
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* !"#$%&'()*+,-./ */
107 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, /* 0123456789:;<=>? */
108 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ABCDEFGHIJKLMNO */
109 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* PQRSTUVWXYZ[\]^_ */
110 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* `abcdefghijklmno */
111 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 /* pqrstuvwxyz{|}~ */
115 /* check for top wrong usage strings */
117 static sal_Bool findWrongUsage( const sal_Unicode *path, sal_Int32 len )
119 rtl_uString *pTmp = NULL;
120 sal_Bool bRet;
122 rtl_uString_newFromStr_WithLength( &pTmp, path, len );
124 rtl_ustr_toAsciiLowerCase_WithLength( pTmp->buffer, pTmp->length );
126 bRet = ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "ftp://", 6 ) ) ||
127 ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "http://", 7 ) ) ||
128 ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "vnd.sun.star", 12 ) ) ||
129 ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "private:", 8 ) ) ||
130 ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "slot:", 5) );
132 rtl_uString_release( pTmp );
133 return bRet;
137 /****************************************************************************/
138 /* osl_getCanonicalName */
139 /****************************************************************************/
141 oslFileError SAL_CALL osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uString** pustrValidURL )
143 OSL_ENSURE(0, "osl_getCanonicalName not implemented");
145 rtl_uString_newFromString(pustrValidURL, ustrFileURL);
146 return osl_File_E_None;
149 /****************************************************************************/
150 /* osl_getSystemPathFromFileURL */
151 /****************************************************************************/
153 oslFileError SAL_CALL osl_getSystemPathFromFileURL( rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath )
155 sal_Int32 nIndex;
156 rtl_uString * pTmp = NULL;
158 sal_Unicode encodedSlash[3] = { '%', '2', 'F' };
159 sal_Unicode protocolDelimiter[3] = { ':', '/', '/' };
161 /* temporary hack: if already system path, return ustrFileURL */
163 if( (sal_Unicode) '/' == ustrFileURL->buffer[0] )
165 OSL_ENSURE( 0, "osl_getSystemPathFromFileURL: input is already system path" );
166 rtl_uString_assign( pustrSystemPath, ustrFileURL );
167 return osl_File_E_None;
171 /* a valid file url may not start with '/' */
172 if( ( 0 == ustrFileURL->length ) || ( (sal_Unicode) '/' == ustrFileURL->buffer[0] ) )
174 return osl_File_E_INVAL;
177 /* Check for non file:// protocols */
179 nIndex = rtl_ustr_indexOfStr_WithLength( ustrFileURL->buffer, ustrFileURL->length, protocolDelimiter, 3 );
180 if ( -1 != nIndex && (4 != nIndex || 0 != rtl_ustr_ascii_shortenedCompare_WithLength( ustrFileURL->buffer, ustrFileURL->length,"file", 4 ) ) )
182 return osl_File_E_INVAL;
185 /* search for encoded slashes (%2F) and decode every single token if we find one */
187 nIndex = 0;
189 if( -1 != rtl_ustr_indexOfStr_WithLength( ustrFileURL->buffer, ustrFileURL->length, encodedSlash, 3 ) )
191 rtl_uString * ustrPathToken = NULL;
192 sal_Int32 nOffset = 7;
196 nOffset += nIndex;
198 /* break url down in '/' devided tokens tokens */
199 nIndex = rtl_ustr_indexOfChar_WithLength( ustrFileURL->buffer + nOffset, ustrFileURL->length - nOffset, (sal_Unicode) '/' );
201 /* copy token to new string */
202 rtl_uString_newFromStr_WithLength( &ustrPathToken, ustrFileURL->buffer + nOffset,
203 -1 == nIndex ? ustrFileURL->length - nOffset : nIndex++ );
205 /* decode token */
206 rtl_uriDecode( ustrPathToken, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8, &pTmp );
208 /* the result should not contain any '/' */
209 if( -1 != rtl_ustr_indexOfChar_WithLength( pTmp->buffer, pTmp->length, (sal_Unicode) '/' ) )
211 rtl_uString_release( pTmp );
212 rtl_uString_release( ustrPathToken );
214 return osl_File_E_INVAL;
217 } while( -1 != nIndex );
219 /* release temporary string and restore index variable */
220 rtl_uString_release( ustrPathToken );
221 nIndex = 0;
224 /* protocol and server should not be encoded, so decode the whole string */
225 rtl_uriDecode( ustrFileURL, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8, &pTmp );
227 /* check if file protocol specified */
228 /* FIXME: use rtl_ustr_ascii_shortenedCompareIgnoreCase_WithLength when available */
229 if( 7 <= pTmp->length )
231 rtl_uString * pProtocol = NULL;
232 rtl_uString_newFromStr_WithLength( &pProtocol, pTmp->buffer, 7 );
234 /* protocol is case insensitive */
235 rtl_ustr_toAsciiLowerCase_WithLength( pProtocol->buffer, pProtocol->length );
237 if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pProtocol->buffer, pProtocol->length,"file://", 7 ) )
238 nIndex = 7;
240 rtl_uString_release( pProtocol );
243 /* skip "localhost" or "127.0.0.1" if "file://" is specified */
244 /* FIXME: use rtl_ustr_ascii_shortenedCompareIgnoreCase_WithLength when available */
245 if( nIndex && ( 10 <= pTmp->length - nIndex ) )
247 rtl_uString * pServer = NULL;
248 rtl_uString_newFromStr_WithLength( &pServer, pTmp->buffer + nIndex, 10 );
250 /* server is case insensitive */
251 rtl_ustr_toAsciiLowerCase_WithLength( pServer->buffer, pServer->length );
253 if( ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pServer->buffer, pServer->length,"localhost/", 10 ) ) ||
254 ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pServer->buffer, pServer->length,"127.0.0.1/", 10 ) ) )
256 /* don't exclude the '/' */
257 nIndex += 9;
260 rtl_uString_release( pServer );
263 if( nIndex )
264 rtl_uString_newFromStr_WithLength( &pTmp, pTmp->buffer + nIndex, pTmp->length - nIndex );
266 /* check if system path starts with ~ or ~user and replace it with the appropriate home dir */
267 if( (sal_Unicode) '~' == pTmp->buffer[0] )
269 /* check if another user is specified */
270 if( ( 1 == pTmp->length ) || ( (sal_Unicode)'/' == pTmp->buffer[1] ) )
272 rtl_uString *pTmp2 = NULL;
274 /* osl_getHomeDir returns file URL */
275 osl_getHomeDir( osl_getCurrentSecurity(), &pTmp2 );
277 /* remove "file://" prefix */
278 rtl_uString_newFromStr_WithLength( &pTmp2, pTmp2->buffer + 7, pTmp2->length - 7 );
280 /* replace '~' in original string */
281 rtl_uString_newReplaceStrAt( &pTmp, pTmp, 0, 1, pTmp2 );
282 rtl_uString_release( pTmp2 );
285 else
287 /* FIXME: replace ~user with users home directory */
288 return osl_File_E_INVAL;
292 /* temporary check for top 5 wrong usage strings (which are valid but unlikly filenames) */
294 OSL_ASSERT( !findWrongUsage( pTmp->buffer, pTmp->length ) );
297 *pustrSystemPath = pTmp;
298 return osl_File_E_None;
301 /****************************************************************************/
302 /* osl_getFileURLFromSystemPath */
303 /****************************************************************************/
305 oslFileError SAL_CALL osl_getFileURLFromSystemPath( rtl_uString *ustrSystemPath, rtl_uString **pustrFileURL )
307 static const sal_Unicode pDoubleSlash[2] = { '/', '/' };
309 rtl_uString *pTmp = NULL;
310 sal_Int32 nIndex;
312 if( 0 == ustrSystemPath->length )
313 return osl_File_E_INVAL;
315 /* temporary hack: if already file url, return ustrSystemPath */
317 if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( ustrSystemPath->buffer, ustrSystemPath->length,"file:", 5 ) )
320 if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( ustrSystemPath->buffer, ustrSystemPath->length,"file://", 7 ) )
322 OSL_ENSURE( 0, "osl_getFileURLFromSystemPath: input is already file URL" );
323 rtl_uString_assign( pustrFileURL, ustrSystemPath );
325 else
327 rtl_uString *pTmp2 = NULL;
329 OSL_ENSURE( 0, "osl_getFileURLFromSystemPath: input is wrong file URL" );
330 rtl_uString_newFromStr_WithLength( pustrFileURL, ustrSystemPath->buffer + 5, ustrSystemPath->length - 5 );
331 rtl_uString_newFromAscii( &pTmp2, "file://" );
332 rtl_uString_newConcat( pustrFileURL, *pustrFileURL, pTmp2 );
333 rtl_uString_release( pTmp2 );
335 return osl_File_E_None;
337 return osl_File_E_INVAL;
341 /* check if system path starts with ~ or ~user and replace it with the appropriate home dir */
342 if( (sal_Unicode) '~' == ustrSystemPath->buffer[0] )
344 /* check if another user is specified */
345 if( ( 1 == ustrSystemPath->length ) || ( (sal_Unicode)'/' == ustrSystemPath->buffer[1] ) )
347 /* osl_getHomeDir returns file URL */
348 osl_getHomeDir( osl_getCurrentSecurity(), &pTmp );
350 /* remove "file://" prefix */
351 rtl_uString_newFromStr_WithLength( &pTmp, pTmp->buffer + 7, pTmp->length - 7 );
353 /* replace '~' in original string */
354 rtl_uString_newReplaceStrAt( &pTmp, ustrSystemPath, 0, 1, pTmp );
357 else
359 /* FIXME: replace ~user with users home directory */
360 return osl_File_E_INVAL;
364 /* check if initial string contains double instances of '/' */
365 nIndex = rtl_ustr_indexOfStr_WithLength( ustrSystemPath->buffer, ustrSystemPath->length, pDoubleSlash, 2 );
366 if( -1 != nIndex )
368 sal_Int32 nSrcIndex;
369 sal_Int32 nDeleted = 0;
371 /* if pTmp is not already allocated, copy ustrSystemPath for modification */
372 if( NULL == pTmp )
373 rtl_uString_newFromString( &pTmp, ustrSystemPath );
375 /* adapt index to pTmp */
376 nIndex += pTmp->length - ustrSystemPath->length;
378 /* remove all occurances of '//' */
379 for( nSrcIndex = nIndex + 1; nSrcIndex < pTmp->length; nSrcIndex++ )
381 if( ((sal_Unicode) '/' == pTmp->buffer[nSrcIndex]) && ((sal_Unicode) '/' == pTmp->buffer[nIndex]) )
382 nDeleted++;
383 else
384 pTmp->buffer[++nIndex] = pTmp->buffer[nSrcIndex];
387 /* adjust length member */
388 pTmp->length -= nDeleted;
391 if( NULL == pTmp )
392 rtl_uString_assign( &pTmp, ustrSystemPath );
394 /* temporary check for top 5 wrong usage strings (which are valid but unlikly filenames) */
396 OSL_ASSERT( !findWrongUsage( pTmp->buffer, pTmp->length ) );
399 /* file URLs must be URI encoded */
400 rtl_uriEncode( pTmp, uriCharClass, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8, pustrFileURL );
402 rtl_uString_release( pTmp );
404 /* absolute urls should start with 'file://' */
405 if( (sal_Unicode)'/' == (*pustrFileURL)->buffer[0] )
407 rtl_uString *pProtocol = NULL;
409 rtl_uString_newFromAscii( &pProtocol, "file://" );
410 rtl_uString_newConcat( pustrFileURL, pProtocol, *pustrFileURL );
411 rtl_uString_release( pProtocol );
414 return osl_File_E_None;
417 /****************************************************************************
418 * osl_getSystemPathFromFileURL_Ex - helper function
419 * clients may specify if they want to accept relative
420 * URLs or not
421 ****************************************************************************/
423 oslFileError osl_getSystemPathFromFileURL_Ex(
424 rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath, sal_Bool bAllowRelative)
426 rtl_uString* temp = 0;
427 oslFileError osl_error = osl_getSystemPathFromFileURL(ustrFileURL, &temp);
429 if (osl_File_E_None == osl_error)
431 if (bAllowRelative || (UNICHAR_SLASH == temp->buffer[0]))
433 *pustrSystemPath = temp;
435 else
437 rtl_uString_release(temp);
438 osl_error = osl_File_E_INVAL;
442 return osl_error;
445 /******************************************************
446 * Resolve the paths if they exist. The resulting
447 * path must not exceed PATH_MAX else
448 * osl_File_E_NAMETOOLONG is the result
449 ******************************************************/
451 static oslFileError osl_getAbsoluteFileURL_impl_(const rtl::OUString& unresolved, rtl::OUString& resolved)
453 char unresolved_path[PATH_MAX];
454 char resolved_path[PATH_MAX];
456 if (!UnicodeToText(unresolved_path, sizeof(unresolved_path), unresolved.getStr(), unresolved.getLength()))
457 return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
459 if (realpath(unresolved_path, resolved_path))
461 sal_Unicode path[PATH_MAX];
462 if (!TextToUnicode(resolved_path, strlen(resolved_path), path, PATH_MAX))
463 return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
464 resolved = rtl::OUString(path, rtl_ustr_getLength(path));
465 return osl_File_E_None;
467 else
469 if (EACCES != errno && ENOTDIR != errno && ENOENT != errno)
470 return oslTranslateFileError(OSL_FET_ERROR, errno);
473 // the 'unresolved' does not exist, let's just copy it to 'resolved'
474 resolved = unresolved;
475 return osl_File_E_None;
478 /******************************************************
479 * osl_getAbsoluteFileURL
480 ******************************************************/
482 oslFileError osl_getAbsoluteFileURL(rtl_uString* ustrBaseDirURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL)
484 FileBase::RC rc;
485 rtl::OUString unresolved_path;
486 static char *allow_symlinks = getenv( "SAL_ALLOW_LINKOO_SYMLINKS" );
488 rc = FileBase::getSystemPathFromFileURL(rtl::OUString(ustrRelativeURL), unresolved_path);
490 if(FileBase::E_None != rc)
491 return oslFileError(rc);
493 if (systemPathIsRelativePath(unresolved_path))
495 rtl::OUString base_path;
496 rc = (FileBase::RC) osl_getSystemPathFromFileURL_Ex(ustrBaseDirURL, &base_path.pData, sal_False);
498 if (FileBase::E_None != rc)
499 return oslFileError(rc);
501 rtl::OUString abs_path;
502 systemPathMakeAbsolutePath(base_path, unresolved_path, abs_path);
504 unresolved_path = abs_path;
507 rtl::OUString resolved_path;
509 if (!allow_symlinks)
511 rc = (FileBase::RC) osl_getAbsoluteFileURL_impl_(unresolved_path, resolved_path);
513 else
515 // SAL_ALLOW_LINKOO_SYMLINKS environment variable:
516 // for linkoo to work, we need to let the symlinks to the libraries untouched
517 rtl::OUString base;
518 sal_Int32 last_slash = unresolved_path.lastIndexOf( UNICHAR_SLASH );
520 if (last_slash >= 0 && last_slash + 1 < unresolved_path.getLength())
522 base = unresolved_path.copy(last_slash+1);
523 unresolved_path = unresolved_path.copy(0, last_slash);
526 rc = (FileBase::RC) osl_getAbsoluteFileURL_impl_(unresolved_path, resolved_path);
528 if (base.getLength() > 0)
530 resolved_path += rtl::OUString( UNICHAR_SLASH );
531 resolved_path += base;
535 if (FileBase::E_None == rc)
537 rc = (FileBase::RC) osl_getFileURLFromSystemPath(resolved_path.pData, pustrAbsoluteURL);
538 OSL_ASSERT(FileBase::E_None == rc);
541 return oslFileError(rc);
545 namespace /* private */
548 /*********************************************
549 No separate error code if unicode to text
550 conversion or getenv fails because for the
551 caller there is no difference why a file
552 could not be found in $PATH
553 ********************************************/
555 bool find_in_PATH(const rtl::OUString& file_path, rtl::OUString& result)
557 bool bfound = false;
558 rtl::OUString path = rtl::OUString::createFromAscii("PATH");
559 rtl::OUString env_path;
561 if (osl_Process_E_None == osl_getEnvironment(path.pData, &env_path.pData))
562 bfound = osl::searchPath(file_path, env_path, result);
564 return bfound;
567 /*********************************************
568 No separate error code if unicode to text
569 conversion or getcwd fails because for the
570 caller there is no difference why a file
571 could not be found in CDW
572 ********************************************/
574 bool find_in_CWD(const rtl::OUString& file_path, rtl::OUString& result)
576 bool bfound = false;
577 rtl::OUString cwd_url;
579 if (osl_Process_E_None == osl_getProcessWorkingDir(&cwd_url.pData))
581 rtl::OUString cwd;
582 FileBase::getSystemPathFromFileURL(cwd_url, cwd);
583 bfound = osl::searchPath(file_path, cwd, result);
585 return bfound;
588 /*********************************************
590 ********************************************/
592 bool find_in_searchPath(const rtl::OUString& file_path, rtl_uString* search_path, rtl::OUString& result)
594 return (search_path && osl::searchPath(file_path, rtl::OUString(search_path), result));
597 } // end namespace private
600 /****************************************************************************
601 * osl_searchFileURL
602 ***************************************************************************/
604 oslFileError osl_searchFileURL(rtl_uString* ustrFilePath, rtl_uString* ustrSearchPath, rtl_uString** pustrURL)
606 OSL_PRECOND(ustrFilePath && pustrURL, "osl_searchFileURL: invalid parameter");
608 FileBase::RC rc;
609 rtl::OUString file_path;
611 // try to interpret search path as file url else assume it's a system path list
612 rc = FileBase::getSystemPathFromFileURL(rtl::OUString(ustrFilePath), file_path);
613 if ((FileBase::E_None != rc) && (FileBase::E_INVAL == rc))
614 file_path = ustrFilePath;
615 else if (FileBase::E_None != rc)
616 return oslFileError(rc);
618 bool bfound = false;
619 rtl::OUString result;
621 if (find_in_searchPath(file_path, ustrSearchPath, result) ||
622 find_in_PATH(file_path, result) ||
623 find_in_CWD(file_path, result))
625 rtl::OUString resolved;
627 if (osl::realpath(result, resolved))
629 #if OSL_DEBUG_LEVEL > 0
630 oslFileError osl_error =
631 #endif
632 osl_getFileURLFromSystemPath(resolved.pData, pustrURL);
633 OSL_ASSERT(osl_File_E_None == osl_error);
634 bfound = true;
637 return bfound ? osl_File_E_None : osl_File_E_NOENT;
641 /****************************************************************************
642 * FileURLToPath
643 ***************************************************************************/
645 oslFileError FileURLToPath(char * buffer, size_t bufLen, rtl_uString* ustrFileURL)
647 rtl_uString* ustrSystemPath = NULL;
648 oslFileError osl_error = osl_getSystemPathFromFileURL(ustrFileURL, &ustrSystemPath);
650 if(osl_File_E_None != osl_error)
651 return osl_error;
653 osl_systemPathRemoveSeparator(ustrSystemPath);
655 /* convert unicode path to text */
656 if(!UnicodeToText( buffer, bufLen, ustrSystemPath->buffer, ustrSystemPath->length))
657 osl_error = oslTranslateFileError(OSL_FET_ERROR, errno);
659 rtl_uString_release(ustrSystemPath);
661 return osl_error;
664 /*****************************************************************************
665 * UnicodeToText
666 ****************************************************************************/
668 namespace /* private */
670 class UnicodeToTextConverter_Impl
672 rtl_UnicodeToTextConverter m_converter;
674 UnicodeToTextConverter_Impl()
675 : m_converter (rtl_createUnicodeToTextConverter (osl_getThreadTextEncoding()))
678 ~UnicodeToTextConverter_Impl()
680 rtl_destroyUnicodeToTextConverter (m_converter);
682 public:
683 static UnicodeToTextConverter_Impl & getInstance()
685 static UnicodeToTextConverter_Impl g_theConverter;
686 return g_theConverter;
689 sal_Size convert(
690 sal_Unicode const * pSrcBuf, sal_Size nSrcChars, sal_Char * pDstBuf, sal_Size nDstBytes,
691 sal_uInt32 nFlags, sal_uInt32 * pInfo, sal_Size * pSrcCvtChars)
693 OSL_ASSERT(m_converter != 0);
694 return rtl_convertUnicodeToText (
695 m_converter, 0, pSrcBuf, nSrcChars, pDstBuf, nDstBytes, nFlags, pInfo, pSrcCvtChars);
698 } // end namespace private
700 int UnicodeToText( char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen )
702 sal_uInt32 nInfo = 0;
703 sal_Size nSrcChars = 0;
705 sal_Size nDestBytes = UnicodeToTextConverter_Impl::getInstance().convert (
706 uniText, uniTextLen, buffer, bufLen,
707 OUSTRING_TO_OSTRING_CVTFLAGS | RTL_UNICODETOTEXT_FLAGS_FLUSH, &nInfo, &nSrcChars);
709 if( nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
711 errno = EOVERFLOW;
712 return 0;
715 /* ensure trailing '\0' */
716 buffer[nDestBytes] = '\0';
717 return nDestBytes;
720 /*****************************************************************************
721 * TextToUnicode
722 ****************************************************************************/
724 namespace /* private */
726 class TextToUnicodeConverter_Impl
728 rtl_TextToUnicodeConverter m_converter;
730 TextToUnicodeConverter_Impl()
731 : m_converter (rtl_createTextToUnicodeConverter (osl_getThreadTextEncoding()))
734 ~TextToUnicodeConverter_Impl()
736 rtl_destroyTextToUnicodeConverter (m_converter);
739 public:
740 static TextToUnicodeConverter_Impl & getInstance()
742 static TextToUnicodeConverter_Impl g_theConverter;
743 return g_theConverter;
746 sal_Size convert(
747 sal_Char const * pSrcBuf, sal_Size nSrcBytes, sal_Unicode * pDstBuf, sal_Size nDstChars,
748 sal_uInt32 nFlags, sal_uInt32 * pInfo, sal_Size * pSrcCvtBytes)
750 OSL_ASSERT(m_converter != 0);
751 return rtl_convertTextToUnicode (
752 m_converter, 0, pSrcBuf, nSrcBytes, pDstBuf, nDstChars, nFlags, pInfo, pSrcCvtBytes);
755 } // end namespace private
757 int TextToUnicode(
758 const char* text,
759 size_t text_buffer_size,
760 sal_Unicode* unic_text,
761 sal_Int32 unic_text_buffer_size)
763 sal_uInt32 nInfo = 0;
764 sal_Size nSrcChars = 0;
766 sal_Size nDestBytes = TextToUnicodeConverter_Impl::getInstance().convert(
767 text, text_buffer_size, unic_text, unic_text_buffer_size,
768 OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_FLUSH, &nInfo, &nSrcChars);
770 if (nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)
772 errno = EOVERFLOW;
773 return 0;
776 /* ensure trailing '\0' */
777 unic_text[nDestBytes] = '\0';
778 return nDestBytes;