Initial import into git.
[galago.git] / cpp / galago / contrib / indri / src / Path.cpp
blob0a7bc7d7c64a9a9bbea03b8263a94f9605b1a440
1 /*==========================================================================
2 * Copyright (c) 2004 University of Massachusetts. All Rights Reserved.
4 * Use of the Lemur Toolkit for Language Modeling and Information Retrieval
5 * is subject to the terms of the software license set forth in the LICENSE
6 * file included with this software, and also available at
7 * http://www.lemurproject.org/license.html
9 *==========================================================================
14 // Path.cpp
16 // 20 May 2004 -- tds
19 #include <string>
20 #include "indri/Path.hpp"
21 #include "lemur/Exception.hpp"
22 #include "lemur/lemur-compat.hpp"
23 #include <sys/stat.h>
24 #include <errno.h>
25 #include <iostream>
26 #include <stack>
27 #include "indri/DirectoryIterator.hpp"
28 #include "indri/delete_range.hpp"
29 #include "indri/XMLNode.hpp"
30 #include "indri/XMLReader.hpp"
32 #ifdef WIN32
33 #define PATH_SEPARATOR '\\'
34 #else
35 #define PATH_SEPARATOR '/'
36 #endif
38 static int path_last_separator( const std::string& path ) {
39 int i;
41 // skip any trailing slashes
42 for( i=path.size()-1; i>=0; i-- ) {
43 if( path[i] != PATH_SEPARATOR )
44 break;
47 for( ; i>=0; i-- ) {
48 if( path[i] == PATH_SEPARATOR )
49 break;
52 return i;
55 void indri::file::Path::create( const std::string& path ) {
56 if( lemur_compat::mkdir( path.c_str(), 0777 ) < 0 ) {
57 if( errno == EACCES ) {
58 LEMUR_THROW( LEMUR_IO_ERROR, "Couldn't create directory: '" + path + "' because of inadequate permissions." );
59 } else if( errno == ENOENT ) {
60 LEMUR_THROW( LEMUR_IO_ERROR, "Couldn't create directory: '" + path + "' because at least one of the parent directories does not exist." );
61 } else if( errno == EEXIST ) {
62 LEMUR_THROW( LEMUR_IO_ERROR, "Couldn't create directory: '" + path + "' because something already exists there." );
67 void indri::file::Path::remove( const std::string& path ) {
68 std::stack<indri::file::DirectoryIterator*> iterators;
69 indri::utility::StackDeleter<indri::file::DirectoryIterator> sd( iterators );
70 iterators.push( new indri::file::DirectoryIterator( path ) );
72 while( iterators.size() ) {
73 indri::file::DirectoryIterator* top = iterators.top();
75 // all done, so go up a level
76 if( (*top) == indri::file::DirectoryIterator::end() ) {
77 // release any search handles that may point
78 // to this directory
79 top->close();
81 int result = rmdir( top->base().c_str() );
82 if( result != 0 )
83 LEMUR_THROW( LEMUR_IO_ERROR, "indri::file::Path::remove couldn't remove directory '" + top->base() + "'." );
85 delete top;
86 iterators.pop();
87 continue;
90 std::string path = **top;
91 (*top)++;
93 if( indri::file::Path::isFile( path ) ) {
94 int result = lemur_compat::remove( path.c_str() );
95 if( result != 0 )
96 LEMUR_THROW( LEMUR_IO_ERROR, "indri::file::Path::remove couldn't remove file '" + path + "'." );
97 } else {
98 iterators.push( new indri::file::DirectoryIterator( path ) );
103 std::string indri::file::Path::trim( const std::string& path ) {
104 if( path.size() && path[path.length()-1] == PATH_SEPARATOR ) {
105 return path.substr( 0, path.length()-1 );
108 return path;
111 std::string indri::file::Path::relative( const std::string& basePath, const std::string absolutePath ) {
112 std::string relativePath = absolutePath.substr( basePath.length() );
114 while( relativePath.length() && relativePath[0] == PATH_SEPARATOR )
115 relativePath = relativePath.substr(1);
117 return relativePath;
120 void indri::file::Path::make( const std::string& path ) {
121 if( !indri::file::Path::isDirectory( path ) ) {
122 std::string parent = indri::file::Path::directory( path );
123 if( path == parent )
124 return;
126 indri::file::Path::make( parent );
129 lemur_compat::mkdir( path.c_str(), 0755 );
132 char indri::file::Path::pathSeparator() {
133 return PATH_SEPARATOR;
136 bool indri::file::Path::isDirectory( const std::string& path ) {
137 struct stat s;
138 int result = stat( path.c_str(), &s );
139 bool actualDirectory = (result >= 0) && (s.st_mode & S_IFDIR);
141 return actualDirectory;
144 bool indri::file::Path::exists( const std::string& path ) {
145 struct stat s;
146 return stat( path.c_str(), &s ) >= 0;
149 bool indri::file::Path::isFile( const std::string& path ) {
150 struct stat s;
151 int result = stat( path.c_str(), &s );
152 bool actualFile = (result >= 0) && (s.st_mode & S_IFREG);
154 return actualFile;
157 std::string indri::file::Path::combine( const std::string& root, const std::string& addition ) {
158 if( !root.size() )
159 return addition;
161 if( *(root.end()-1) == PATH_SEPARATOR )
162 return root + addition;
164 return root + PATH_SEPARATOR + addition;
167 std::string indri::file::Path::directory( const std::string& path ) {
168 int last = path_last_separator( path );
170 if( last > 0 ) {
171 return path.substr( 0, last );
174 return path;
177 std::string indri::file::Path::filename( const std::string& path ) {
178 int last = path_last_separator( path );
180 if( last != std::string::npos ) {
181 return path.substr( last+1 );
184 return path;
187 std::string indri::file::Path::extension( const std::string& path ) {
188 int last = path_last_separator( path );
189 std::string::size_type lastDot = path.find_last_of( '.' );
191 if( int(lastDot) > last ) {
192 return path.substr( lastDot+1 );
195 return std::string();
198 std::string indri::file::Path::basename( const std::string& path ) {
199 int last = path_last_separator( path );
200 std::string::size_type lastDot = path.find_last_of( '.' );
202 if( int(lastDot) > last ) {
203 return path.substr( 0, lastDot );
206 return path;