1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_codemaker.hxx"
26 #include "osl/process.h"
27 #include "rtl/strbuf.hxx"
28 #include "rtl/ustring.hxx"
29 #include "osl/thread.h"
30 #include "osl/file.hxx"
31
32 #include <string.h>
33 #if defined(SAL_W32) || defined(SAL_OS2)
34 #include <io.h>
35
36 #include <direct.h>
37 #include <errno.h>
38 #endif
39
40 #ifdef UNX
41 #include <sys/stat.h>
42 #include <errno.h>
43 #include <unistd.h>
44 #endif
45
46 #include "codemaker/global.hxx"
47
48 #ifdef SAL_UNX
49 #define SEPARATOR '/'
50 #else
51 #define SEPARATOR '\\'
52 #endif
53
54 using namespace ::rtl;
55 using namespace ::osl;
56
57
getTempDir(const OString & sFileName)58 OString getTempDir(const OString& sFileName)
59 {
60 sal_Int32 index = 0;
61 #ifdef SAL_UNX
62 if ((index=sFileName.lastIndexOf('/')) > 0)
63 return sFileName.copy(0, index);
64 #else
65 if ((index=sFileName.lastIndexOf('\\')) > 0)
66 return sFileName.copy(0, index);
67 #endif
68 return ".";
69 }
70
createFileNameFromType(const OString & destination,const OString typeName,const OString postfix,sal_Bool bLowerCase,const OString prefix)71 OString createFileNameFromType( const OString& destination,
72 const OString typeName,
73 const OString postfix,
74 sal_Bool bLowerCase,
75 const OString prefix )
76 {
77 OString type(typeName);
78
79 if (bLowerCase)
80 {
81 type = typeName.toAsciiLowerCase();
82 }
83
84 sal_uInt32 length = destination.getLength();
85
86 sal_Bool withPoint = sal_False;
87 if (length == 0)
88 {
89 length++;
90 withPoint = sal_True;
91 }
92
93 length += prefix.getLength() + type.getLength() + postfix.getLength();
94
95 sal_Bool withSeperator = sal_False;
96 if (destination.getStr()[destination.getLength()] != '\\' &&
97 destination.getStr()[destination.getLength()] != '/' &&
98 type.getStr()[0] != '\\' &&
99 type.getStr()[0] != '/')
100 {
101 length++;
102 withSeperator = sal_True;
103 }
104
105 OStringBuffer nameBuffer(length);
106
107 if (withPoint)
108 nameBuffer.append('.');
109 else
110 nameBuffer.append(destination.getStr(), destination.getLength());
111
112 if (withSeperator)
113 nameBuffer.append("/", 1);
114
115 OString tmpStr(type);
116 if ( !prefix.isEmpty() )
117 {
118 tmpStr = type.replaceAt(type.lastIndexOf('/')+1, 0, prefix);
119 }
120
121 nameBuffer.append(tmpStr.getStr(), tmpStr.getLength());
122 nameBuffer.append(postfix.getStr(), postfix.getLength());
123
124 OString fileName(nameBuffer);
125
126 sal_Char token;
127 #ifdef SAL_UNX
128 fileName = fileName.replace('\\', '/');
129 token = '/';
130 #else
131 fileName = fileName.replace('/', '\\');
132 token = '\\';
133 #endif
134
135 nameBuffer = OStringBuffer(length);
136
137 sal_Int32 nIndex = 0;
138 do
139 {
140 nameBuffer.append(fileName.getToken(0, token, nIndex).getStr());
141 if( nIndex == -1 )
142 break;
143
144 if (nameBuffer.getLength() == 0 || OString(".") == nameBuffer.getStr())
145 {
146 nameBuffer.append(token);
147 continue;
148 }
149
150 #if defined(SAL_UNX) || defined(SAL_OS2)
151 if (mkdir((char*)nameBuffer.getStr(), 0777) == -1)
152 #else
153 if (mkdir((char*)nameBuffer.getStr()) == -1)
154 #endif
155 {
156 if ( errno == ENOENT )
157 return OString();
158 }
159
160 nameBuffer.append(token);
161 } while( nIndex != -1 );
162
163 OUString uSysFileName;
164 OSL_VERIFY( FileBase::getSystemPathFromFileURL(
165 convertToFileUrl(fileName), uSysFileName) == FileBase::E_None );
166 return OUStringToOString(uSysFileName, osl_getThreadTextEncoding());;
167 }
168
fileExists(const OString & fileName)169 sal_Bool fileExists(const OString& fileName)
170 {
171 FILE *f= fopen(fileName.getStr(), "r");
172
173 if (f != NULL)
174 {
175 fclose(f);
176 return sal_True;
177 }
178
179 return sal_False;
180 }
181
checkFileContent(const OString & targetFileName,const OString & tmpFileName)182 sal_Bool checkFileContent(const OString& targetFileName, const OString& tmpFileName)
183 {
184 FILE *target = fopen(targetFileName.getStr(), "r");
185 FILE *tmp = fopen(tmpFileName.getStr(), "r");
186 sal_Bool bFindChanges = sal_False;
187
188 if (target != NULL && tmp != NULL)
189 {
190 sal_Char buffer1[1024+1];
191 sal_Char buffer2[1024+1];
192 sal_Int32 n1 = 0;
193 sal_Int32 n2 = 0;
194
195 while ( !bFindChanges && !feof(target) && !feof(tmp))
196 {
197 n1 = fread(buffer1, sizeof(sal_Char), 1024, target);
198 n2 = fread(buffer2, sizeof(sal_Char), 1024, tmp);
199
200 if ( n1 != n2 )
201 bFindChanges = sal_True;
202 else
203 if ( rtl_compareMemory(buffer1, buffer2, n2) != 0 )
204 bFindChanges = sal_True;
205 }
206 }
207
208 if (target) fclose(target);
209 if (tmp) fclose(tmp);
210
211 return bFindChanges;
212 }
213
makeValidTypeFile(const OString & targetFileName,const OString & tmpFileName,sal_Bool bFileCheck)214 sal_Bool makeValidTypeFile(const OString& targetFileName, const OString& tmpFileName,
215 sal_Bool bFileCheck)
216 {
217 if (bFileCheck) {
218 if (checkFileContent(targetFileName, tmpFileName)) {
219 if ( !unlink(targetFileName.getStr()) )
220 if ( !rename(tmpFileName.getStr(), targetFileName.getStr()) )
221 return sal_True;
222 } else
223 return removeTypeFile(tmpFileName);
224 } else {
225 if (fileExists(targetFileName))
226 if (!removeTypeFile(targetFileName))
227 return sal_False;
228
229 if ( rename(tmpFileName.getStr(), targetFileName.getStr()) ) {
230 if (errno == EEXIST)
231 return sal_True;
232 } else
233 return sal_True;
234 }
235 return sal_False;
236 }
237
removeTypeFile(const OString & fileName)238 sal_Bool removeTypeFile(const OString& fileName)
239 {
240 if ( !unlink(fileName.getStr()) )
241 return sal_True;
242
243 return sal_False;
244 }
245
isFileUrl(const OString & fileName)246 static sal_Bool isFileUrl(const OString& fileName)
247 {
248 if (fileName.indexOf("file://") == 0 )
249 return sal_True;
250 return sal_False;
251 }
252
convertToFileUrl(const OString & fileName)253 OUString convertToFileUrl(const OString& fileName)
254 {
255 if ( isFileUrl(fileName) )
256 {
257 return OStringToOUString(fileName, osl_getThreadTextEncoding());
258 }
259
260 OUString uUrlFileName;
261 OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
262 if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
263 {
264 OUString uWorkingDir;
265 if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None)
266 {
267 OSL_ASSERT(false);
268 }
269 if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName)
270 != FileBase::E_None)
271 {
272 OSL_ASSERT(false);
273 }
274 } else
275 {
276 if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName)
277 != FileBase::E_None)
278 {
279 OSL_ASSERT(false);
280 }
281 }
282
283 return uUrlFileName;
284 }
285
286
287 //*************************************************************************
288 // FileStream
289 //*************************************************************************
FileStream()290 FileStream::FileStream()
291 : m_file(NULL)
292 {
293 }
294
FileStream(const OString & name,FileAccessMode mode)295 FileStream::FileStream(const OString& name, FileAccessMode mode)
296 : m_file(NULL)
297 {
298 if ( !name.isEmpty() )
299 {
300 OUString sUrl(convertToFileUrl(name));
301 #ifdef SAL_UNX
302 sal_uInt64 uAttr = osl_File_Attribute_OwnWrite |
303 osl_File_Attribute_OwnRead |
304 osl_File_Attribute_GrpWrite |
305 osl_File_Attribute_GrpRead |
306 osl_File_Attribute_OthRead;
307 if (osl_openFile(sUrl.pData, &m_file, checkAccessMode(mode)) == osl_File_E_None &&
308 osl_setFileAttributes(sUrl.pData, uAttr) == osl_File_E_None)
309 #else
310 if (osl_openFile(sUrl.pData, &m_file, checkAccessMode(mode)) == osl_File_E_None)
311 #endif
312 m_name = name;
313 else
314 m_file = NULL;
315 }
316 }
317
~FileStream()318 FileStream::~FileStream()
319 {
320 if ( isValid() )
321 osl_closeFile(m_file);
322 }
323
isValid()324 sal_Bool FileStream::isValid()
325 {
326 if ( m_file )
327 return sal_True;
328
329 return sal_False;
330 }
331
createTempFile(const OString & sPath)332 void FileStream::createTempFile(const OString& sPath)
333 {
334 OString sTmp(".");
335 OUString sTmpPath;
336 OUString sTmpName;
337
338 if ( !sPath.isEmpty() )
339 sTmp = sPath;
340
341 sTmpPath = convertToFileUrl(sTmp);
342
343 if (osl_createTempFile(sTmpPath.pData, &m_file, &sTmpName.pData) == osl_File_E_None) {
344 #ifdef SAL_UNX
345 sal_uInt64 uAttr = osl_File_Attribute_OwnWrite |
346 osl_File_Attribute_OwnRead |
347 osl_File_Attribute_GrpWrite |
348 osl_File_Attribute_GrpRead |
349 osl_File_Attribute_OthRead;
350 if (osl_setFileAttributes(sTmpName.pData, uAttr) != osl_File_E_None) {
351 m_file = NULL;
352 return;
353 }
354 #endif
355 OUString sSysTmpName;
356 FileBase::getSystemPathFromFileURL(sTmpName, sSysTmpName);
357 m_name = OUStringToOString(sSysTmpName, osl_getThreadTextEncoding());
358 } else
359 m_file = NULL;
360 }
361
open(const OString & name,FileAccessMode mode)362 void FileStream::open(const OString& name, FileAccessMode mode)
363 {
364 if ( !name.isEmpty() )
365 {
366 oslFileError ret = osl_File_E_None;
367 if ((ret = osl_openFile(convertToFileUrl(name).pData, &m_file, checkAccessMode(mode))) == osl_File_E_None)
368 m_name = name;
369 else
370 m_file = NULL;
371 }
372 }
373
close()374 void FileStream::close()
375 {
376 if ( isValid() )
377 {
378 osl_closeFile(m_file);
379 m_file = NULL;
380 m_name = OString();
381 }
382 }
383
checkAccessMode(FileAccessMode mode)384 sal_uInt32 FileStream::checkAccessMode(FileAccessMode mode)
385 {
386 switch( mode )
387 {
388 case FAM_READ:
389 return osl_File_OpenFlag_Read;
390 case FAM_WRITE:
391 return osl_File_OpenFlag_Write;
392 case FAM_READWRITE_EXIST:
393 return osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
394 case FAM_READWRITE:
395 return osl_File_OpenFlag_Read | osl_File_OpenFlag_Write | osl_File_OpenFlag_Create;
396 }
397 return osl_File_OpenFlag_Read | osl_File_OpenFlag_Write | osl_File_OpenFlag_Create;
398 }
399
write(void const * buffer,sal_uInt64 size)400 bool FileStream::write(void const * buffer, sal_uInt64 size) {
401 while (size > 0) {
402 sal_uInt64 written;
403 if (osl_writeFile(m_file, buffer, size, &written) != osl_File_E_None) {
404 return false;
405 }
406 OSL_ASSERT(written <= size);
407 size -= written;
408 buffer = static_cast< char const * >(buffer) + written;
409 }
410 return true;
411 }
412
operator <<(FileStream & o,sal_uInt32 i)413 FileStream &operator<<(FileStream& o, sal_uInt32 i) {
414 sal_uInt64 writtenBytes;
415 OString s = OString::valueOf((sal_Int32)i);
416 osl_writeFile(o.m_file, s.getStr(), s.getLength() * sizeof(sal_Char), &writtenBytes);
417 return o;
418 }
operator <<(FileStream & o,char const * s)419 FileStream &operator<<(FileStream& o, char const * s) {
420 sal_uInt64 writtenBytes;
421 osl_writeFile(o.m_file, s, strlen(s), &writtenBytes);
422 return o;
423 }
operator <<(FileStream & o,::rtl::OString * s)424 FileStream &operator<<(FileStream& o, ::rtl::OString* s) {
425 sal_uInt64 writtenBytes;
426 osl_writeFile(o.m_file, s->getStr(), s->getLength() * sizeof(sal_Char), &writtenBytes);
427 return o;
428 }
operator <<(FileStream & o,const::rtl::OString & s)429 FileStream &operator<<(FileStream& o, const ::rtl::OString& s) {
430 sal_uInt64 writtenBytes;
431 osl_writeFile(o.m_file, s.getStr(), s.getLength() * sizeof(sal_Char), &writtenBytes);
432 return o;
433
434 }
operator <<(FileStream & o,::rtl::OStringBuffer * s)435 FileStream &operator<<(FileStream& o, ::rtl::OStringBuffer* s) {
436 sal_uInt64 writtenBytes;
437 osl_writeFile(o.m_file, s->getStr(), s->getLength() * sizeof(sal_Char), &writtenBytes);
438 return o;
439 }
operator <<(FileStream & o,const::rtl::OStringBuffer & s)440 FileStream &operator<<(FileStream& o, const ::rtl::OStringBuffer& s) {
441 sal_uInt64 writtenBytes;
442 osl_writeFile(
443 o.m_file, s.getStr(), s.getLength() * sizeof(sal_Char), &writtenBytes);
444 return o;
445 }
446