Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006 #include "vul_file_iterator.h"
00007 #include <vcl_string.h>
00008 #include <vcl_cassert.h>
00009
00010 #include <vul/vul_file.h>
00011 #include <vul/vul_reg_exp.h>
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if defined(VCL_WIN32) && !defined(__CYGWIN__)
00021
00022 #if defined(VCL_BORLAND_56)
00023 # include <stdint.h>
00024 #endif
00025
00026 #include <io.h>
00027
00028 struct vul_file_iterator_data
00029 {
00030 struct _finddata_t data_;
00031 # if defined VCL_VC_6 || defined VCL_VC_5 || defined VCL_BORLAND_55 || defined __MINGW32__
00032 typedef long handle_type;
00033 # else
00034 typedef intptr_t handle_type;
00035 #endif
00036 handle_type handle_;
00037
00038 vcl_string found_;
00039 char const* name_;
00040 vul_reg_exp reg_exp_;
00041 vcl_string original_dirname_;
00042
00043 handle_type find_first(const char* dirname, struct _finddata_t* data)
00044 {
00045 return _findfirst(const_cast<char*>(dirname), data);
00046 }
00047
00048 vul_file_iterator_data(char const* glob);
00049
00050 void mkname() {
00051
00052 found_ = original_dirname_ + "\\" + data_.name;
00053 name_ = found_.c_str();
00054
00055 }
00056
00057
00058 void next() {
00059 assert(handle_ != 0);
00060 do
00061 {
00062 if (_findnext(handle_, &data_) != 0) {
00063 _findclose(handle_);
00064 handle_ = -1L;
00065 return;
00066 }
00067 } while ( ! reg_exp_.find(data_.name) );
00068 mkname();
00069 }
00070
00071
00072
00073 char const* value() {
00074 if (handle_ == -1L) return 0;
00075 return name_;
00076 }
00077
00078
00079 char const* value_filename() {
00080 if (handle_ == -1L) return 0;
00081 return data_.name;
00082 }
00083
00084 ~vul_file_iterator_data() {
00085 if (handle_ != -1L)
00086 _findclose(handle_);
00087 }
00088 };
00089
00090 vul_file_iterator_data::vul_file_iterator_data(char const* glob)
00091 {
00092 original_dirname_ = vul_file::dirname(glob);
00093 handle_ = find_first((original_dirname_ + "\\*").c_str(), &data_);
00094
00095 vcl_string baseglob = vul_file::basename(glob);
00096 vcl_string::iterator i = baseglob.begin();
00097 bool prev_slash=false, in_sqr_brackets=false;
00098
00099 vcl_string re = "^";
00100 while (i != baseglob.end())
00101 {
00102 if (*i=='\\' && !prev_slash)
00103 prev_slash = true;
00104 else if (prev_slash)
00105 {
00106 prev_slash = false;
00107 re.append(1,('\\'));
00108 re.append(1,*i);
00109 }
00110 else if (*i=='[' && !in_sqr_brackets)
00111 {
00112 in_sqr_brackets = true;
00113 re.append(1,'[');
00114 }
00115 else if (*i==']' && in_sqr_brackets)
00116 {
00117 in_sqr_brackets = false;
00118 re.append(1,']');
00119 }
00120 else if (*i=='?' && !in_sqr_brackets)
00121 re.append(1,'.');
00122 else if (*i=='*' && !in_sqr_brackets)
00123 re.append(".*");
00124 else
00125 re.append(vul_reg_exp::protect(*i));
00126
00127 ++i;
00128 }
00129
00130 re += '$';
00131
00132 reg_exp_.compile(re.c_str());
00133
00134
00135 if (handle_ != -1L)
00136 {
00137 while ( ! reg_exp_.find(data_.name) )
00138 {
00139 if (_findnext(handle_, &data_) != 0) {
00140 _findclose(handle_);
00141 handle_ = -1L;
00142 return;
00143 }
00144 }
00145 mkname();
00146 }
00147 }
00148
00149 #else // !defined(VCL_WIN32) || defined(__CYGWIN__)
00150
00151 #include <dirent.h>
00152
00153 struct vul_file_iterator_data
00154 {
00155 vcl_string original_dirname_;
00156 DIR* dir_handle_;
00157 dirent* de_;
00158 vcl_string found_;
00159 char const* name_;
00160 vul_reg_exp reg_exp_;
00161
00162 vul_file_iterator_data(char const* glob);
00163
00164 void mkname() {
00165
00166 found_ = original_dirname_ + de_->d_name;
00167 name_ = found_.c_str();
00168
00169 }
00170
00171 void next() {
00172
00173
00174 if(dir_handle_ == 0) {
00175 return;
00176 }
00177 do
00178 {
00179 de_ = readdir(dir_handle_);
00180 if (de_==0) {
00181 closedir(dir_handle_);
00182 dir_handle_ = 0;
00183 return;
00184 }
00185 } while ( ! reg_exp_.find(de_->d_name) );
00186 mkname();
00187 }
00188
00189
00190 char const* value() {
00191 if (!dir_handle_) return 0;
00192 return name_;
00193 }
00194
00195
00196 char const* value_filename() {
00197 if (!dir_handle_) return 0;
00198 return de_->d_name;
00199 }
00200
00201 ~vul_file_iterator_data() {
00202 if (dir_handle_)
00203 closedir(dir_handle_);
00204 }
00205 };
00206
00207 vul_file_iterator_data::vul_file_iterator_data(char const* glob)
00208 {
00209 original_dirname_ = vul_file::dirname(glob) + "/";
00210
00211 vcl_string baseglob = vul_file::basename(glob);
00212 vcl_string::iterator i = baseglob.begin();
00213 bool prev_slash=false, in_sqr_brackets=false;
00214
00215 vcl_string re = "^";
00216 while (i != baseglob.end())
00217 {
00218 if (*i=='\\' && !prev_slash)
00219 prev_slash = true;
00220 else if (prev_slash)
00221 {
00222 prev_slash = false;
00223 re += '\\';
00224 re += *i;
00225 }
00226 else if (*i=='[' && !in_sqr_brackets)
00227 {
00228 in_sqr_brackets = true;
00229 re += '[';
00230 }
00231 else if (*i==']' && in_sqr_brackets)
00232 {
00233 in_sqr_brackets = false;
00234 re += ']';
00235 }
00236 else if (*i=='?' && !in_sqr_brackets)
00237 re += '.';
00238 else if (*i=='*' && !in_sqr_brackets)
00239 re += ".*";
00240 else
00241 re += vul_reg_exp::protect(*i);
00242
00243 ++i;
00244 }
00245
00246 re += '$';
00247
00248 reg_exp_.compile(re.c_str());
00249
00250 dir_handle_ = opendir(original_dirname_.c_str());
00251
00252 next();
00253 }
00254
00255 #endif // !defined(VCL_WIN32) || defined(__CYGWIN__)
00256
00257
00258
00259 vul_file_iterator::vul_file_iterator(char const* glob)
00260 {
00261 p = 0;
00262 reset(glob);
00263 }
00264
00265 vul_file_iterator::vul_file_iterator(vcl_string const& glob)
00266 {
00267 p = 0;
00268 reset(glob.c_str());
00269 }
00270
00271 vul_file_iterator::~vul_file_iterator()
00272 {
00273 delete p;
00274 }
00275
00276 void vul_file_iterator::reset(char const* glob)
00277 {
00278 delete p;
00279 p = new vul_file_iterator_data(glob);
00280 }
00281
00282 char const* vul_file_iterator::operator()()
00283 {
00284 return p->value();
00285 }
00286
00287 char const* vul_file_iterator::filename()
00288 {
00289 return p->value_filename();
00290 }
00291
00292 vul_file_iterator::operator vul_file_iterator::safe_bool() const
00293 {
00294 return (p->value() != 0)? VCL_SAFE_BOOL_TRUE : 0;
00295 }
00296
00297 bool vul_file_iterator::operator!() const
00298 {
00299 return (p->value() != 0)? false : true;
00300 }
00301
00302 vul_file_iterator& vul_file_iterator::operator++()
00303 {
00304 p->next();
00305 return *this;
00306 }