xref: /trunk/main/l10ntools/source/directory.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_l10ntools.hxx"
31 #include <l10ntools/directory.hxx>
32 #include "tools/string.hxx"
33 #include <iostream>
34 #include <vector>
35 #include <algorithm>
36 
37 namespace transex
38 {
39 
40 Directory::Directory( const rtl::OUString sFullpath ) : bSkipLinks( false )
41 {
42     sFullName = sFullpath;
43 }
44 
45 Directory::Directory( const rtl::OUString sFullPath , const rtl::OUString sEntry ) : bSkipLinks( false )
46 {
47     sFullName       = sFullPath;
48     sDirectoryName  = sEntry;
49 }
50 
51 
52 Directory::Directory( const ByteString sFullPath ) : bSkipLinks( false )
53 {
54     sDirectoryName = rtl::OUString( sFullPath.GetBuffer() , RTL_TEXTENCODING_UTF8 , sFullPath.Len() );
55 }
56 
57 bool Directory::lessDir ( const Directory& rKey1, const Directory& rKey2 )
58 {
59     rtl::OUString sName1( ( static_cast< Directory >( rKey1 ) ).getDirectoryName() );
60     rtl::OUString sName2( ( static_cast< Directory >( rKey2 ) ).getDirectoryName() );
61 
62     return sName1.compareTo( sName2 ) < 0 ;
63 }
64 
65 
66 void Directory::dump()
67 {
68 
69     for( std::vector< transex::File >::iterator iter = aFileVec.begin() ; iter != aFileVec.end() ; ++iter )
70     {
71         std::cout << "FILE " << rtl::OUStringToOString( (*iter).getFullName().getStr() , RTL_TEXTENCODING_UTF8 , (*iter).getFullName().getLength() ).getStr() << "\n";
72     }
73 
74     for( std::vector< transex::Directory >::iterator iter = aDirVec.begin() ; iter != aDirVec.end() ; ++iter )
75     {
76         std::cout << "DIR " << rtl::OUStringToOString( (*iter).getFullName().getStr() , RTL_TEXTENCODING_UTF8 , (*iter).getFullName().getLength() ).getStr() << "\n";
77     }
78 
79 }
80 
81 void Directory::scanSubDir( int nLevels )
82 {
83     readDirectory( sFullName );
84     dump();
85     if( nLevels > 0 ) {
86         for( std::vector< transex::Directory >::iterator iter = aDirVec.begin() ; iter != aDirVec.end() || nLevels > 0 ; ++iter , nLevels-- )
87         {
88             ( *iter ).scanSubDir();
89         }
90     }
91 }
92 
93 void Directory::setSkipLinks( bool is_skipped )
94 {
95     bSkipLinks = is_skipped;
96 }
97 
98 void Directory::readDirectory()
99 {
100     readDirectory( sFullName );
101 }
102 
103 #ifdef WNT
104 #include <tools/prewin.h>
105 #include <windows.h>
106 #include <tools/postwin.h>
107 
108 void Directory::readDirectory ( const rtl::OUString& sFullpath )
109 {
110     sal_Bool            fFinished;
111     HANDLE          hList;
112     TCHAR           szDir[MAX_PATH+1];
113     TCHAR           szSubDir[MAX_PATH+1];
114     WIN32_FIND_DATA FileData;
115 
116     rtl::OString sFullpathext = rtl::OUStringToOString( sFullpath , RTL_TEXTENCODING_UTF8 , sFullpath.getLength() );
117     const char *dirname = sFullpathext.getStr();
118 
119     // Get the proper directory path
120 	sprintf(szDir, "%s\\*", dirname);
121 
122     // Get the first file
123     hList = FindFirstFile(szDir, &FileData);
124     if (hList == INVALID_HANDLE_VALUE)
125     {
126         //FindClose(hList);
127         //printf("No files found %s\n", szDir ); return;
128     }
129     else
130     {
131         fFinished = sal_False;
132         while (!fFinished)
133         {
134 
135 			sprintf(szSubDir, "%s\\%s", dirname, FileData.cFileName);
136 			rtl::OString myfile( FileData.cFileName );
137 			rtl::OString mydir( szSubDir );
138 
139             if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
140             {
141                 if ( (strcmp(FileData.cFileName, ".") != 0 ) &&
142 					 (strcmp(FileData.cFileName, "..") != 0 ) )
143                 {
144 	                //sprintf(szSubDir, "%s\\%s", dirname, FileData.cFileName);
145 					transex::Directory aDir(	rtl::OStringToOUString( mydir , RTL_TEXTENCODING_UTF8 , mydir.getLength() ),
146 												rtl::OStringToOUString( myfile , RTL_TEXTENCODING_UTF8 , myfile.getLength() ) );
147 					aDirVec.push_back( aDir );
148                 }
149             }
150 			else
151 			{
152 				transex::File aFile(	rtl::OStringToOUString( mydir , RTL_TEXTENCODING_UTF8 , mydir.getLength() ),
153 										rtl::OStringToOUString( myfile , RTL_TEXTENCODING_UTF8 , myfile.getLength() ) );
154                 aFileVec.push_back( aFile );
155 			}
156             if (!FindNextFile(hList, &FileData))
157             {
158                 if (GetLastError() == ERROR_NO_MORE_FILES)
159                 {
160                     fFinished = sal_True;
161                 }
162             }
163         }
164     }
165 
166     FindClose(hList);
167 
168     ::std::sort( aFileVec.begin() , aFileVec.end() , File::lessFile );
169     ::std::sort( aDirVec.begin()  , aDirVec.end()  , Directory::lessDir  );
170 }
171 
172 #else
173 
174 class dirholder
175 {
176 private:
177     DIR *mpDir;
178 public:
179     dirholder(DIR *pDir) : mpDir(pDir) {}
180     int close() { int nRet = mpDir ? closedir(mpDir) : 0; mpDir = NULL; return nRet; }
181     ~dirholder() { close(); }
182 };
183 
184 void Directory::readDirectory( const rtl::OUString& sFullpath )
185 {
186     struct stat     statbuf;
187     struct stat     statbuf2;
188     struct dirent   *dirp;
189     DIR             *dir;
190 
191     if( sFullpath.getLength() < 1 ) return;
192 
193     rtl::OString   sFullpathext = rtl::OUStringToOString( sFullpath , RTL_TEXTENCODING_UTF8 , sFullpath.getLength() ).getStr();
194 
195     // stat
196 	if( stat( sFullpathext.getStr()  , &statbuf ) < 0 ){   printf("warning: Can not stat %s" , sFullpathext.getStr() ); return; }// error }
197 
198     if( S_ISDIR(statbuf.st_mode ) == 0 ) {  return; }// error }   return; // not dir
199 
200     if( (dir = opendir( sFullpathext.getStr() ) ) == NULL  ) {printf("readerror 2 in %s \n",sFullpathext.getStr()); return; } // error } return; // error
201 
202     dirholder aHolder(dir);
203 
204     sFullpathext += rtl::OString( "/" );
205 
206     const rtl::OString sDot ( "." ) ;
207     const rtl::OString sDDot( ".." );
208 
209     if ( chdir( sFullpathext.getStr() ) == -1 ) { printf("chdir error in %s \n",sFullpathext.getStr()); return; } // error
210 
211     while(  ( dirp = readdir( dir ) ) != NULL )
212     {
213         rtl::OString sEntryName(  dirp->d_name );
214 
215         if( sEntryName.equals( sDot )  || sEntryName.equals( sDDot ) )
216             continue;
217 
218         // add dir entry
219         rtl::OString sEntity = sFullpathext;
220         sEntity += sEntryName;
221 
222         // stat new entry
223         if( lstat( sEntity.getStr() , &statbuf2 ) < 0 )
224         {
225             printf("error on entry %s\n" , sEntity.getStr() ) ; // error
226             continue;
227         }
228 
229         // add file / dir to vector
230         switch( statbuf2.st_mode & S_IFMT )
231         {
232             case S_IFREG:
233 						{
234                             rtl::OString sFile = sFullpathext;
235                             sFile += sEntryName ;
236                             transex::File aFile( rtl::OStringToOUString( sEntity , RTL_TEXTENCODING_UTF8 , sEntity.getLength() ) ,
237                                                  rtl::OStringToOUString( sEntryName , RTL_TEXTENCODING_UTF8 , sEntryName.getLength() )
238                                                );
239 
240 							aFileVec.push_back( aFile ) ;
241                             break;
242                          }
243             case S_IFLNK:
244                         {
245                             if( bSkipLinks )    break;
246                         }
247             case S_IFDIR:
248 						{
249                             rtl::OString sDir = sFullpathext;
250                             sDir += sEntryName ;
251 
252                             transex::Directory aDir(
253                                                      rtl::OStringToOUString( sEntity , RTL_TEXTENCODING_UTF8 , sEntity.getLength() ) ,
254                                                      rtl::OStringToOUString( sEntryName , RTL_TEXTENCODING_UTF8 , sEntryName.getLength() )
255                                                    ) ;
256                             aDirVec.push_back( aDir ) ;
257                             break;
258                          }
259         }
260     }
261     if ( chdir( ".." ) == -1 ) { printf("chdir error in .. \n"); return; } // error
262     if( aHolder.close() < 0 )   return ; // error
263 
264     std::sort( aFileVec.begin() , aFileVec.end() , File::lessFile );
265     std::sort( aDirVec.begin()  , aDirVec.end()  , Directory::lessDir  );
266 
267 }
268 
269 #endif
270 }
271