xref: /trunk/main/l10ntools/source/directory.cxx (revision 46d9d397)
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_l10ntools.hxx"
26 #include <l10ntools/directory.hxx>
27 #include "tools/string.hxx"
28 #include <iostream>
29 #include <vector>
30 #include <algorithm>
31 
32 namespace transex
33 {
34 
Directory(const rtl::OUString sFullpath)35 Directory::Directory( const rtl::OUString sFullpath ) : bSkipLinks( false )
36 {
37     sFullName = sFullpath;
38 }
39 
Directory(const rtl::OUString sFullPath,const rtl::OUString sEntry)40 Directory::Directory( const rtl::OUString sFullPath , const rtl::OUString sEntry ) : bSkipLinks( false )
41 {
42     sFullName       = sFullPath;
43     sDirectoryName  = sEntry;
44 }
45 
46 
Directory(const ByteString sFullPath)47 Directory::Directory( const ByteString sFullPath ) : bSkipLinks( false )
48 {
49     sDirectoryName = rtl::OUString( sFullPath.GetBuffer() , RTL_TEXTENCODING_UTF8 , sFullPath.Len() );
50 }
51 
lessDir(const Directory & rKey1,const Directory & rKey2)52 bool Directory::lessDir ( const Directory& rKey1, const Directory& rKey2 )
53 {
54     rtl::OUString sName1( ( static_cast< Directory >( rKey1 ) ).getDirectoryName() );
55     rtl::OUString sName2( ( static_cast< Directory >( rKey2 ) ).getDirectoryName() );
56 
57     return sName1.compareTo( sName2 ) < 0 ;
58 }
59 
60 
dump()61 void Directory::dump()
62 {
63 
64     for( std::vector< transex::File >::iterator iter = aFileVec.begin() ; iter != aFileVec.end() ; ++iter )
65     {
66         std::cout << "FILE " << rtl::OUStringToOString( (*iter).getFullName().getStr() , RTL_TEXTENCODING_UTF8 , (*iter).getFullName().getLength() ).getStr() << "\n";
67     }
68 
69     for( std::vector< transex::Directory >::iterator iter = aDirVec.begin() ; iter != aDirVec.end() ; ++iter )
70     {
71         std::cout << "DIR " << rtl::OUStringToOString( (*iter).getFullName().getStr() , RTL_TEXTENCODING_UTF8 , (*iter).getFullName().getLength() ).getStr() << "\n";
72     }
73 
74 }
75 
scanSubDir(int nLevels)76 void Directory::scanSubDir( int nLevels )
77 {
78     readDirectory( sFullName );
79     dump();
80     if( nLevels > 0 ) {
81         for( std::vector< transex::Directory >::iterator iter = aDirVec.begin() ; iter != aDirVec.end() || nLevels > 0 ; ++iter , nLevels-- )
82         {
83             ( *iter ).scanSubDir();
84         }
85     }
86 }
87 
setSkipLinks(bool is_skipped)88 void Directory::setSkipLinks( bool is_skipped )
89 {
90     bSkipLinks = is_skipped;
91 }
92 
readDirectory()93 void Directory::readDirectory()
94 {
95     readDirectory( sFullName );
96 }
97 
98 #ifdef WNT
99 #include <tools/prewin.h>
100 #include <windows.h>
101 #include <tools/postwin.h>
102 
readDirectory(const rtl::OUString & sFullpath)103 void Directory::readDirectory ( const rtl::OUString& sFullpath )
104 {
105     sal_Bool            fFinished;
106     HANDLE          hList;
107     TCHAR           szDir[MAX_PATH+1];
108     TCHAR           szSubDir[MAX_PATH+1];
109     WIN32_FIND_DATA FileData;
110 
111     rtl::OString sFullpathext = rtl::OUStringToOString( sFullpath , RTL_TEXTENCODING_UTF8 , sFullpath.getLength() );
112     const char *dirname = sFullpathext.getStr();
113 
114     // Get the proper directory path
115 	sprintf(szDir, "%s\\*", dirname);
116 
117     // Get the first file
118     hList = FindFirstFile(szDir, &FileData);
119     if (hList == INVALID_HANDLE_VALUE)
120     {
121         //FindClose(hList);
122         //printf("No files found %s\n", szDir ); return;
123     }
124     else
125     {
126         fFinished = sal_False;
127         while (!fFinished)
128         {
129 
130 			sprintf(szSubDir, "%s\\%s", dirname, FileData.cFileName);
131 			rtl::OString myfile( FileData.cFileName );
132 			rtl::OString mydir( szSubDir );
133 
134             if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
135             {
136                 if ( (strcmp(FileData.cFileName, ".") != 0 ) &&
137 					 (strcmp(FileData.cFileName, "..") != 0 ) )
138                 {
139 	                //sprintf(szSubDir, "%s\\%s", dirname, FileData.cFileName);
140 					transex::Directory aDir(	rtl::OStringToOUString( mydir , RTL_TEXTENCODING_UTF8 , mydir.getLength() ),
141 												rtl::OStringToOUString( myfile , RTL_TEXTENCODING_UTF8 , myfile.getLength() ) );
142 					aDirVec.push_back( aDir );
143                 }
144             }
145 			else
146 			{
147 				transex::File aFile(	rtl::OStringToOUString( mydir , RTL_TEXTENCODING_UTF8 , mydir.getLength() ),
148 										rtl::OStringToOUString( myfile , RTL_TEXTENCODING_UTF8 , myfile.getLength() ) );
149                 aFileVec.push_back( aFile );
150 			}
151             if (!FindNextFile(hList, &FileData))
152             {
153                 if (GetLastError() == ERROR_NO_MORE_FILES)
154                 {
155                     fFinished = sal_True;
156                 }
157             }
158         }
159     }
160 
161     FindClose(hList);
162 
163     ::std::sort( aFileVec.begin() , aFileVec.end() , File::lessFile );
164     ::std::sort( aDirVec.begin()  , aDirVec.end()  , Directory::lessDir  );
165 }
166 
167 #else
168 
169 class dirholder
170 {
171 private:
172     DIR *mpDir;
173 public:
dirholder(DIR * pDir)174     dirholder(DIR *pDir) : mpDir(pDir) {}
close()175     int close() { int nRet = mpDir ? closedir(mpDir) : 0; mpDir = NULL; return nRet; }
~dirholder()176     ~dirholder() { close(); }
177 };
178 
readDirectory(const rtl::OUString & sFullpath)179 void Directory::readDirectory( const rtl::OUString& sFullpath )
180 {
181     struct stat     statbuf;
182     struct stat     statbuf2;
183     struct dirent   *dirp;
184     DIR             *dir;
185 
186     if( sFullpath.getLength() < 1 ) return;
187 
188     rtl::OString   sFullpathext = rtl::OUStringToOString( sFullpath , RTL_TEXTENCODING_UTF8 , sFullpath.getLength() ).getStr();
189 
190     // stat
191 	if( stat( sFullpathext.getStr()  , &statbuf ) < 0 ){   printf("warning: Can not stat %s" , sFullpathext.getStr() ); return; } // error }
192 
193     if( S_ISDIR(statbuf.st_mode ) == 0 ) {  return; }// error }   return; // not dir
194 
195     if( (dir = opendir( sFullpathext.getStr() ) ) == NULL  ) {printf("readerror 2 in %s \n",sFullpathext.getStr()); return; } // error } return; // error
196 
197     dirholder aHolder(dir);
198 
199     sFullpathext += rtl::OString( "/" );
200 
201     const rtl::OString sDot ( "." ) ;
202     const rtl::OString sDDot( ".." );
203 
204     if ( chdir( sFullpathext.getStr() ) == -1 ) { printf("chdir error in %s \n",sFullpathext.getStr()); return; } // error
205 
206     while(  ( dirp = readdir( dir ) ) != NULL )
207     {
208         rtl::OString sEntryName(  dirp->d_name );
209 
210         if( sEntryName.equals( sDot )  || sEntryName.equals( sDDot ) )
211             continue;
212 
213         // add dir entry
214         rtl::OString sEntity = sFullpathext;
215         sEntity += sEntryName;
216 
217         // stat new entry
218         if( lstat( sEntity.getStr() , &statbuf2 ) < 0 )
219         {
220             printf("error on entry %s\n" , sEntity.getStr() ) ; // error
221             continue;
222         }
223 
224         // add file / dir to vector
225         switch( statbuf2.st_mode & S_IFMT )
226         {
227             case S_IFREG:
228 						{
229                             rtl::OString sFile = sFullpathext;
230                             sFile += sEntryName ;
231                             transex::File aFile( rtl::OStringToOUString( sEntity , RTL_TEXTENCODING_UTF8 , sEntity.getLength() ) ,
232                                                  rtl::OStringToOUString( sEntryName , RTL_TEXTENCODING_UTF8 , sEntryName.getLength() )
233                                                );
234 
235 							aFileVec.push_back( aFile ) ;
236                             break;
237                          }
238             case S_IFLNK:
239                         {
240                             if( bSkipLinks )    break;
241                         }
242             case S_IFDIR:
243 						{
244                             rtl::OString sDir = sFullpathext;
245                             sDir += sEntryName ;
246 
247                             transex::Directory aDir(
248                                                      rtl::OStringToOUString( sEntity , RTL_TEXTENCODING_UTF8 , sEntity.getLength() ) ,
249                                                      rtl::OStringToOUString( sEntryName , RTL_TEXTENCODING_UTF8 , sEntryName.getLength() )
250                                                    ) ;
251                             aDirVec.push_back( aDir ) ;
252                             break;
253                          }
254         }
255     }
256     if ( chdir( ".." ) == -1 ) { printf("chdir error in .. \n"); return; } // error
257     if( aHolder.close() < 0 )   return ; // error
258 
259     std::sort( aFileVec.begin() , aFileVec.end() , File::lessFile );
260     std::sort( aDirVec.begin()  , aDirVec.end()  , Directory::lessDir  );
261 
262 }
263 
264 #endif
265 }
266 
267