Update ooo320-m1
[ooovba.git] / tools / source / fsys / tempfile.cxx
blobbcfc0fd01a2c029b93f09cb10a1ad6ab4792f56e
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: tempfile.cxx,v $
10 * $Revision: 1.12 $
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_tools.hxx"
34 #include <tools/tempfile.hxx>
35 #include "comdep.hxx"
37 #include <rtl/ustring.hxx>
38 #include <osl/file.hxx>
39 #include <rtl/instance.hxx>
40 #include <tools/time.hxx>
41 #include <tools/debug.hxx>
42 #include <stdio.h>
44 #ifdef UNX
45 #define _MAX_PATH 260
46 #endif
48 using namespace osl;
50 namespace { struct TempNameBase_Impl : public rtl::Static< ::rtl::OUString, TempNameBase_Impl > {}; }
52 struct TempFile_Impl
54 String aName;
55 sal_Bool bIsDirectory;
58 String GetSystemTempDir_Impl()
60 char sBuf[_MAX_PATH];
61 const char *pDir = TempDirImpl(sBuf);
63 ::rtl::OString aTmpA( pDir );
64 ::rtl::OUString aTmp = ::rtl::OStringToOUString( aTmpA, osl_getThreadTextEncoding() );
65 rtl::OUString aRet;
66 FileBase::getFileURLFromSystemPath( aTmp, aRet );
67 String aName = aRet;
68 if( aName.GetChar(aName.Len()-1) != '/' )
69 aName += '/';
70 return aName;
73 #define TMPNAME_SIZE ( 1 + 5 + 5 + 4 + 1 )
74 String ConstructTempDir_Impl( const String* pParent )
76 String aName;
77 if ( pParent && pParent->Len() )
79 // if parent given try to use it
80 rtl::OUString aTmp( *pParent );
81 rtl::OUString aRet;
83 // test for valid filename
85 ::osl::DirectoryItem aItem;
86 sal_Int32 i = aRet.getLength();
87 if ( aRet[i-1] == '/' )
88 i--;
90 if ( DirectoryItem::get( ::rtl::OUString( aRet, i ), aItem ) == FileBase::E_None )
91 aName = aRet;
95 if ( !aName.Len() )
97 // if no parent or invalid parent : use system directory
98 ::rtl::OUString& rTempNameBase_Impl = TempNameBase_Impl::get();
99 if ( !rTempNameBase_Impl.getLength() )
100 rTempNameBase_Impl = GetSystemTempDir_Impl();
101 aName = rTempNameBase_Impl;
104 // Make sure that directory ends with a separator
105 xub_StrLen i = aName.Len();
106 if( i>0 && aName.GetChar(i-1) != '/' )
107 aName += '/';
109 return aName;
112 void CreateTempName_Impl( String& rName, sal_Bool bKeep, sal_Bool bDir = sal_True )
114 // add a suitable tempname
115 // Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576
116 // ER 13.07.00 why not radix 36 [0-9A-Z] ?!?
117 const unsigned nRadix = 26;
118 String aName( rName );
119 aName += String::CreateFromAscii( "sv" );
121 rName.Erase();
122 static unsigned long u = Time::GetSystemTicks();
123 for ( unsigned long nOld = u; ++u != nOld; )
125 u %= (nRadix*nRadix*nRadix);
126 String aTmp( aName );
127 aTmp += String::CreateFromInt32( (sal_Int32) (unsigned) u, nRadix );
128 aTmp += String::CreateFromAscii( ".tmp" );
130 if ( bDir )
132 FileBase::RC err = Directory::create( aTmp );
133 if ( err == FileBase::E_None )
135 // !bKeep: only for creating a name, not a file or directory
136 if ( bKeep || Directory::remove( aTmp ) == FileBase::E_None )
137 rName = aTmp;
138 break;
140 else if ( err != FileBase::E_EXIST )
142 // if f.e. name contains invalid chars stop trying to create dirs
143 break;
146 else
148 DBG_ASSERT( bKeep, "Too expensive, use directory for creating name!" );
149 File aFile( aTmp );
150 FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
151 if ( err == FileBase::E_None )
153 rName = aTmp;
154 aFile.close();
155 break;
157 else if ( err != FileBase::E_EXIST )
159 // if f.e. name contains invalid chars stop trying to create files
160 break;
166 String TempFile::CreateTempName( const String* pParent )
168 // get correct directory
169 String aName = ConstructTempDir_Impl( pParent );
171 // get TempFile name with default naming scheme
172 CreateTempName_Impl( aName, sal_False );
174 // convert to file URL
175 rtl::OUString aTmp;
176 if ( aName.Len() )
177 aTmp = aName;
178 return aTmp;
181 TempFile::TempFile( const String* pParent, sal_Bool bDirectory )
182 : pImp( new TempFile_Impl )
183 , bKillingFileEnabled( sal_False )
185 pImp->bIsDirectory = bDirectory;
187 // get correct directory
188 pImp->aName = ConstructTempDir_Impl( pParent );
190 // get TempFile with default naming scheme
191 CreateTempName_Impl( pImp->aName, sal_True, bDirectory );
194 TempFile::TempFile( const String& rLeadingChars, const String* pExtension, const String* pParent, sal_Bool bDirectory )
195 : pImp( new TempFile_Impl )
196 , bKillingFileEnabled( sal_False )
198 pImp->bIsDirectory = bDirectory;
200 // get correct directory
201 String aName = ConstructTempDir_Impl( pParent );
203 // now use special naming scheme ( name takes leading chars and an index counting up from zero
204 aName += rLeadingChars;
205 for ( sal_Int32 i=0;; i++ )
207 String aTmp( aName );
208 aTmp += String::CreateFromInt32( i );
209 if ( pExtension )
210 aTmp += *pExtension;
211 else
212 aTmp += String::CreateFromAscii( ".tmp" );
213 if ( bDirectory )
215 FileBase::RC err = Directory::create( aTmp );
216 if ( err == FileBase::E_None )
218 pImp->aName = aTmp;
219 break;
221 else if ( err != FileBase::E_EXIST )
222 // if f.e. name contains invalid chars stop trying to create dirs
223 break;
225 else
227 File aFile( aTmp );
228 FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
229 if ( err == FileBase::E_None )
231 pImp->aName = aTmp;
232 aFile.close();
233 break;
235 else if ( err != FileBase::E_EXIST )
236 // if f.e. name contains invalid chars stop trying to create dirs
237 break;
242 TempFile::~TempFile()
244 if ( bKillingFileEnabled )
246 if ( pImp->bIsDirectory )
248 // at the moment no recursiv algorithm present
249 Directory::remove( pImp->aName );
251 else
253 File::remove( pImp->aName );
257 delete pImp;
260 sal_Bool TempFile::IsValid() const
262 return pImp->aName.Len() != 0;
265 String TempFile::GetName() const
267 rtl::OUString aTmp;
268 aTmp = pImp->aName;
269 return aTmp;
272 String TempFile::SetTempNameBaseDirectory( const String &rBaseName )
274 String aName( rBaseName );
276 ::rtl::OUString& rTempNameBase_Impl = TempNameBase_Impl::get();
278 FileBase::RC err= Directory::create( aName );
279 if ( err == FileBase::E_None || err == FileBase::E_EXIST )
281 rTempNameBase_Impl = aName;
282 rTempNameBase_Impl += String( '/' );
284 TempFile aBase( NULL, sal_True );
285 if ( aBase.IsValid() )
286 rTempNameBase_Impl = aBase.pImp->aName;
289 rtl::OUString aTmp;
290 aTmp = rTempNameBase_Impl;
291 return aTmp;
294 String TempFile::GetTempNameBaseDirectory()
296 ::rtl::OUString& rTempNameBase_Impl = TempNameBase_Impl::get();
297 if ( !rTempNameBase_Impl.getLength() )
298 rTempNameBase_Impl = GetSystemTempDir_Impl();
300 rtl::OUString aTmp;
301 aTmp = rTempNameBase_Impl;
302 return aTmp;