]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/OS/FileSystem.cxx
...
[cpPlugins.git] / lib / cpPlugins / OS / FileSystem.cxx
1 #include <cpPlugins/OS/FileSystem.h>
2 #include <cpPlugins/OS/tinydir.h>
3 #include <fstream>
4 #include <sstream>
5
6 // -------------------------------------------------------------------------
7 std::string cpPlugins::OS::FileSystem::
8 CanonicalPath( const std::string& path )
9 {
10   std::string ret = "";
11 #ifdef cpExtensions_OS_Windows
12   TCHAR  buffer[ 4096 ] = TEXT( "" );
13   TCHAR** lppPart = { NULL };
14   GetFullPathName( path.c_str( ), 4096, buffer, lppPart );
15   ret = std::string( buffer );
16 #else // cpExtensions_OS_Windows
17   char* canonical_path = realpath( path.c_str( ), NULL );
18   if( canonical_path != NULL )
19   {
20     ret = canonical_path;
21     free( canonical_path );
22
23   } // fi
24 #endif // cpExtensions_OS_Windows
25   return( ret );
26 }
27
28 // -------------------------------------------------------------------------
29 std::pair< std::string, std::string > cpPlugins::OS::FileSystem::
30 SplitPath( const std::string& path )
31 {
32   size_t found = path.find_last_of( "/\\" );
33   return(
34     std::pair< std::string, std::string >(
35       path.substr( 0, found + 1 ), path.substr( found + 1 )
36       )
37     );
38 }
39
40 // -------------------------------------------------------------------------
41 std::set< std::string > cpPlugins::OS::FileSystem::
42 LoadDirContents(
43   const std::string& path, bool recursive,
44   const std::string& pattern
45   )
46 {
47   // Prepare inputs and outputs
48   std::stringstream path_stream;
49   path_stream << path << cpPlugins_PATH_SEPARATOR;
50   std::string path_str = path_stream.str( );
51   std::set< std::string > output;
52
53   // Process data
54   tinydir_dir dir;
55   if( tinydir_open_sorted( &dir, path.c_str( ) ) != -1 )
56   {
57     for( auto i = 0; i < dir.n_files; i++ )
58     {
59       tinydir_file file;
60       if( tinydir_readfile_n( &dir, &file , i ) != -1 )
61       {
62         std::string fname = path_str + file.name;
63         if( file.is_dir )
64         {
65           if( recursive )
66           {
67             if( fname != "." && fname != ".." )
68             {
69               auto tmp = Self::LoadDirContents( fname, true );
70               output.insert( tmp.begin( ), tmp.end( ) );
71
72             } // fi
73
74           } // fi
75         }
76         else
77         {
78           if( pattern != "" )
79           {
80             if( Self::Glob( fname, path_str + pattern ) )
81               output.insert( fname );
82           }
83           else
84             output.insert( fname );
85
86         } // fi
87
88       } // fi
89
90     } // rof
91
92   } // fi
93   tinydir_close( &dir );
94   return( output );
95 }
96
97 // -------------------------------------------------------------------------
98 int cpPlugins::OS::FileSystem::
99 GlobMatch( const char* target, const char* pattern )
100 {
101   char* pat = const_cast< char* >( pattern );
102   char* end = strchr( pat, ']' );
103   char* ptr;
104   if( *pat == '[' && end != NULL )
105   {
106     if( end == pat + 1 )
107     {
108       end = strchr( pat + 2, ']' );
109       if( end == NULL )
110         return( 0 );
111
112     } // fi
113
114     if( end - pat == 4 && pat[ 2 ] == '-' && pat[ 1 ] <= pattern[ 3 ] )
115     {
116       if( *target >= pat[ 1 ] && *target <= pat[ 3 ] )
117         return( 5 );
118       else
119         return( 0 );
120
121     } // fi
122
123     ptr = strchr( pat + 1, *target );
124     if( ptr != NULL && ptr < end )
125       return( end - pat + 1 );
126     else
127       return( 0 );
128
129   } // fi
130
131   if( *pat == '?' && *target != 0 )
132     return( 1 );
133   if( *pat == '*' )
134     return( 0 );
135   if( *target == 0 || *pat == 0 )
136     return( 0 );
137   if( *target == *pat )
138     return( 1 );
139   return( 0 );
140 }
141
142 // -------------------------------------------------------------------------
143 bool cpPlugins::OS::FileSystem::
144 Glob( const std::string& line, const std::string& pattern )
145 {
146   const char* target = line.c_str( );
147   const char* pat = pattern.c_str( );
148   int gobble;
149
150   while( ( gobble = GlobMatch( target, pat ) ) )
151   {
152     target++;
153     pat += gobble;
154
155   } // elihw
156   if( *target == 0 && *pat == 0 )
157     return( true );
158   else if( *pat == '*' )
159   {
160     while( pat[ 1 ] == '*' )
161       pat++;
162     if( pat[ 1 ] == 0 )
163       return( true );
164     while( *target )
165       if( Glob( target++, pat + 1 ) )
166         return( 1 );
167
168   } // fi
169   return( false );
170 }
171
172 // -------------------------------------------------------------------------
173 bool cpPlugins::OS::FileSystem::
174 Read( std::string& buffer, const std::string& fname )
175 {
176   buffer = "";
177   std::ifstream file_stream( fname.c_str( ) );
178   if( !file_stream )
179     return( false );
180   file_stream.seekg( 0, std::ios::end );
181   buffer.reserve( ( unsigned int )( file_stream.tellg( ) ) );
182   file_stream.seekg( 0, std::ios::beg );
183   buffer.assign(
184     ( std::istreambuf_iterator< char >( file_stream ) ),
185     std::istreambuf_iterator< char >( )
186     );
187   file_stream.close( );
188   return( true );
189 }
190
191 // -------------------------------------------------------------------------
192 bool cpPlugins::OS::FileSystem::
193 Write( const std::string& buffer, const std::string& fname )
194 {
195   std::ofstream file_stream( fname.c_str( ), std::ofstream::binary );
196   if( !file_stream )
197     return( false );
198   file_stream.write( buffer.c_str( ), buffer.size( ) );
199   return( true );
200 }
201
202 // eof - $RCSfile$