Line data Source code
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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <tools/tempfile.hxx>
21 :
22 : #include <rtl/ustrbuf.hxx>
23 : #include <osl/file.hxx>
24 : #include <rtl/instance.hxx>
25 : #include <tools/time.hxx>
26 : #include <tools/debug.hxx>
27 :
28 : #include <stdio.h>
29 :
30 : using namespace osl;
31 :
32 : namespace { struct TempNameBase_Impl : public rtl::Static< OUString, TempNameBase_Impl > {}; }
33 :
34 0 : struct TempFile_Impl
35 : {
36 : OUString aName;
37 : };
38 :
39 10 : OUString ConstructTempDir_Impl()
40 : {
41 : // use system directory
42 10 : OUString& rTempNameBase_Impl = TempNameBase_Impl::get();
43 10 : if ( rTempNameBase_Impl.isEmpty() )
44 2 : osl::FileBase::getTempDirURL( rTempNameBase_Impl );
45 10 : OUString aName = rTempNameBase_Impl;
46 :
47 : // Make sure that directory ends with a separator
48 10 : if( !aName.endsWith( "/" ) )
49 10 : aName += "/";
50 :
51 10 : return aName;
52 : }
53 :
54 10 : void CreateTempName_Impl( OUString& rName, bool bKeep, bool bDir = true )
55 : {
56 : // add a suitable tempname
57 : // Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576
58 : // ER 13.07.00 why not radix 36 [0-9A-Z] ?!?
59 10 : const unsigned nRadix = 26;
60 10 : OUString aName( rName );
61 10 : aName += "sv";
62 :
63 10 : rName = "";
64 10 : static unsigned long u = Time::GetSystemTicks();
65 20 : for ( unsigned long nOld = u; ++u != nOld; )
66 : {
67 10 : u %= (nRadix*nRadix*nRadix);
68 : OUString aTmp = OUStringBuffer(aName).
69 20 : append((sal_Int32)(unsigned)u, nRadix).
70 10 : append(".tmp").
71 10 : makeStringAndClear();
72 :
73 10 : if ( bDir )
74 : {
75 10 : FileBase::RC err = Directory::create( aTmp );
76 10 : if ( err == FileBase::E_None )
77 : {
78 : // !bKeep: only for creating a name, not a file or directory
79 10 : if ( bKeep || Directory::remove( aTmp ) == FileBase::E_None )
80 10 : rName = aTmp;
81 10 : break;
82 : }
83 0 : else if ( err != FileBase::E_EXIST )
84 : {
85 : // if f.e. name contains invalid chars stop trying to create dirs
86 0 : break;
87 : }
88 : }
89 : else
90 : {
91 : DBG_ASSERT( bKeep, "Too expensive, use directory for creating name!" );
92 0 : File aFile( aTmp );
93 0 : FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
94 0 : if ( err == FileBase::E_None )
95 : {
96 0 : rName = aTmp;
97 0 : aFile.close();
98 0 : break;
99 : }
100 0 : else if ( err != FileBase::E_EXIST )
101 : {
102 : // if f.e. name contains invalid chars stop trying to create files
103 0 : break;
104 0 : }
105 : }
106 10 : }
107 10 : }
108 :
109 10 : OUString TempFile::CreateTempName()
110 : {
111 : // get correct directory
112 10 : OUString aName = ConstructTempDir_Impl();
113 :
114 : // get TempFile name with default naming scheme
115 10 : CreateTempName_Impl( aName, false );
116 :
117 10 : return aName;
118 : }
119 :
120 0 : TempFile::TempFile()
121 0 : : pImp( new TempFile_Impl )
122 0 : , bKillingFileEnabled( false )
123 : {
124 : // get correct directory
125 0 : pImp->aName = ConstructTempDir_Impl();
126 :
127 : // get TempFile with default naming scheme
128 0 : CreateTempName_Impl( pImp->aName, true, false );
129 0 : }
130 :
131 0 : TempFile::TempFile( const OUString& rLeadingChars, const OUString* pExtension )
132 0 : : pImp( new TempFile_Impl )
133 0 : , bKillingFileEnabled( false )
134 : {
135 : // get correct directory
136 0 : OUString aName = ConstructTempDir_Impl();
137 :
138 : // now use special naming scheme ( name takes leading chars and an index counting up from zero
139 0 : aName += rLeadingChars;
140 0 : for ( sal_Int32 i=0; ; i++ )
141 : {
142 0 : OUStringBuffer aTmpBuffer(aName);
143 0 : aTmpBuffer.append(i);
144 0 : if ( pExtension )
145 0 : aTmpBuffer.append(*pExtension);
146 : else
147 0 : aTmpBuffer.append(".tmp");
148 0 : OUString aTmp = aTmpBuffer.makeStringAndClear();
149 :
150 0 : File aFile( aTmp );
151 0 : FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
152 0 : if ( err == FileBase::E_None )
153 : {
154 0 : pImp->aName = aTmp;
155 0 : aFile.close();
156 0 : break;
157 : }
158 0 : else if ( err != FileBase::E_EXIST )
159 : // if f.e. name contains invalid chars stop trying to create dirs
160 0 : break;
161 0 : }
162 0 : }
163 :
164 0 : TempFile::~TempFile()
165 : {
166 0 : if ( bKillingFileEnabled )
167 : {
168 0 : File::remove( pImp->aName );
169 : }
170 :
171 0 : delete pImp;
172 0 : }
173 :
174 0 : OUString TempFile::GetName() const
175 : {
176 0 : OUString aTmp;
177 0 : aTmp = pImp->aName;
178 0 : return aTmp;
179 : }
180 :
181 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|