SourceForge.jp

dkutilFileSystem.h

説明を見る。
00001 
00007 #ifndef _dkutilFileSystem__h_
00008 #define _dkutilFileSystem__h_
00009 
00010 #if defined(WIN32) 
00011 #include "dkutilFSWin32Common.h"
00012 #endif
00013 
00014 #ifdef USE_DKINGYO_INCLUDE_SETTING_LIKE_BOOST
00015 #include <dkutil/include/dkutilBoostPolicy.h>
00016 #include <dkutil/dkutilFunction01.h>
00017 #else
00018 #   ifdef _MSC_VER
00019 #       include "include/dkutilBoostPolicy.h"
00020 #       include "dkutilFunction01.h"
00021 #   else
00022 #       include "dkutilBoostPolicy.h"
00023 #       include "dkutilFunction01.h"
00024 #   endif
00025 #endif
00026 
00027 
00028 
00029 
00030 namespace dkutil{
00031 namespace policy{
00033     extern const char *f_readonly;
00035     extern const char *f_writeonly;
00037     extern const char *f_postscriptonly;
00039     extern const char *f_read;  
00041     extern const char *f_write;
00043   extern const char *f_postscript;
00045     extern const char *f_binary;
00047     extern const char *f_text;
00048 
00049     
00050 }//end of policy namespace
00051 
00053 inline std::string SafeGetCurrentDirectory(){
00054     char buff[MAX_PATH * 2]="";
00055     DWORD r = ::GetCurrentDirectory(sizeof(buff),buff);
00056     size_t len = strlen(buff);
00057     if(r != len) throw std::logic_error("SafeGetCurrentDirectory Buffer Was Lost");
00058     return std::string(buff);
00059 }
00065 
00066 inline bool SafeSetCurrentDirectory(const std::string &s,bool bForce=true){
00067     if(bForce==true){//強制的にDirectoryを作る
00068         if(false==FileAndFolderExist(s.c_str())){
00069             DKUTIL_RETURN_FALSE(CreateDirectory(s.c_str()));
00070         }
00071     }
00072     if(FALSE==SetCurrentDirectory(s.c_str()))
00073     {
00074         return false;
00075     }
00076     return true;
00077 }
00078 
00080 inline bool isWildCard(const char *wcard){
00081     char *ptr = dkutil::GetFileExtension(wcard);
00082     if(ptr == wcard || ptr == NULL) return false;
00083     return true;
00084 }
00090 
00091 inline bool FileExtensionCompare(const std::string &s,const char *exe){
00092     std::string tmp = dkutil::GetFileExtension(s.c_str());
00093     if(tmp != exe){
00094         return false;
00095     }
00096     return true;
00097 }
00098 
00100 inline bool FileFullPathToFileFolderPath(const std::string &src,std::string &dest){
00101     if(src.empty()) return false;
00102     if(src.length() <= 3) return false;
00103     std::string::const_reverse_iterator rit=src.rbegin();
00104     for(;rit != src.rend();rit++)
00105     {
00106         if((*rit) == '\\'){
00107             std::string::const_reverse_iterator tit = rit;
00108             dest.clear();
00109             for(;tit != src.rend();tit++){
00110                 dest.insert(dest.begin(),(*tit));
00111             }
00112             return true;
00113         }
00114     }
00115     return false;
00116 }
00127 
00128 inline bool FileFullPathToFilePath(const std::string &src,std::string &dest){
00129     if(src.empty()) return false;
00130     std::string::const_iterator it=src.begin();
00131     std::string::const_iterator re=src.begin();
00132     for(;it != src.end();it++)
00133     {
00134         if('\\'==(*it)){
00135             re = it;
00136         }
00137             
00138     }
00139     if(re==src.begin()) return false;
00140     //dest.clear();
00141     for(;re != src.end();re++){
00142         dest +=(*re);
00143     }
00144     //dest.insert(re,src.end());
00145     return true;
00146 }
00147 
00148 
00155 
00156 inline bool DirectoryPlusFileName(std::string &dir,const char *filename){
00157     size_t len = strlen(filename);
00158     if(len >= 2){
00159         if((dkutil::isAlpha(filename[0]) && filename[1] == ':')){
00160             return false;
00161         }
00162     }
00163     if(!dir.empty()){
00164         if(*(dir.end() - 1) != '\\'){
00165             dir.insert(dir.end(),'\\');
00166         }
00167     }
00168     if('\\' == *filename){
00169         dir += (filename + 1);
00170     }else{
00171         dir += filename;
00172     }
00173 
00174     
00175     return true;
00176 }
00178 inline bool isRelativityPath(const char *s,size_t size){
00179     if(size <= 3){
00180         if(s[1] == '.'){
00181             goto LabelSucceeded;
00182         }
00183         std::string str = s;
00184         str += " path is invalid!!" ;
00185         str += __FILE__;
00186         str += to_string(__LINE__);
00187         throw std::invalid_argument(str);
00188     }
00189 LabelSucceeded:
00190     if(dkutil::isAlpha(s[0]) && s[1]==':') return false;
00191     return true;
00192 }
00194 inline bool isAbsolutelyPath(const char *s,size_t size){
00195     return !isRelativityPath(s,size);
00196 }
00199 inline bool LocalPathErrorCorrection(std::string &str){
00200     std::string::iterator it=str.begin();
00201     size_t count=0;
00202     bool r=false;
00203     for(;it!=str.end();it++,count++){
00204         if(*it=='\\' && count + 2 < str.size()){
00205             if(*(it + 1) == '.' && *(it + 2) == '\\')
00206             {
00207                 it = str.erase(it,it + 2);
00208                 r = true;
00209             }
00210         }
00211     }
00212     return r;
00213 }
00214 
00215 
00216 
00217 
00219 class file_operator{
00220 
00221     std::string mfilename;
00222     std::string mmode;
00223     FILE *mfp;
00224     void check_fp()const{
00225         DK_TRUE_ASSERT_OR_THROW(
00226             !mfp,
00227             std::runtime_error("file_operator:openしてない。")
00228         );
00229     }
00230 public:
00231     file_operator(const char *filename=NULL,
00232         const char *mode=policy::f_readonly,
00233         const char *type=policy::f_binary)
00234     {
00235         mfp=NULL;
00236         if(filename){mfilename=filename;}
00237         mmode = mode;
00238         mmode += type;
00239     }
00240     file_operator(const file_operator &c){
00241         mfp=NULL;
00242         mfilename = c.filename();//.c_str();
00243         mmode = c.mode();//.c_str();
00244         
00245         
00246     }
00247 
00248     virtual ~file_operator(){close();}
00249     bool reset(const char *filename,const char *mode,const char *type){
00250         close();
00251         DK_TRUE_ASSERT_OR_THROW((filename==NULL || mode==NULL || type==NULL),
00252             std::invalid_argument("file_operator::resetinvalid argument"));
00253 
00254         mfilename=filename;
00255         mmode = mode;
00256         mmode += type;
00257         return true;
00258     }
00259     const char *filename()const{return mfilename.c_str();}
00260     const char *mode()const{return mmode.c_str();}
00261     bool open(){
00262         close();
00263         mfp=::fopen(mfilename.c_str(),mmode.c_str());
00264         if(mfp==NULL) return false;
00265         return true;
00266     }
00267     const FILE *handle()const{return mfp;}
00268     /*size_t read(const void *buf,size_t size){
00269         check_fp();
00270         return fread(const_cast<void *>(buf),1,size,mfp);
00271     }
00272     size_t write(const void *buf,size_t size){
00273         check_fp();
00274         return fwrite(const_cast<void *>(buf),1,size,mfp);
00275     }*/
00276     size_t read(void *buf,size_t size){
00277         check_fp();
00278         return fread((buf),1,size,mfp);
00279     }
00280     size_t write(void *buf,size_t size){
00281         check_fp();
00282         return fwrite((buf),1,size,mfp);
00283     }
00284     bool eof()const{
00285         check_fp();
00286         return ( 0 != feof(mfp) );
00287     }
00288     bool error()const{
00289         check_fp();
00290         return ( 0 != ferror(mfp) );
00291     }
00292     bool seek(long offset, int origin ){
00293         check_fp();
00294         return (0 == fseek(mfp,offset,origin) );
00295     }
00296     
00297     void close(){
00298         if(mfp){::fclose(mfp);mfp=NULL;}
00299     }
00300 
00301 };
00302 
00303 
00304 
00305 
00306 template<
00307     class PATH=boost::filesystem::path,
00308     class DIR_IT=boost::filesystem::directory_iterator
00309 >
00310 class file_finder_base{
00311 public:
00312     struct dir_data{
00313         dir_data(const char *getdir){
00314             dir = getdir;
00315         }
00316         dir_data(std::string getsdir){
00317             dir = getsdir;
00318         }
00319         std::string dir;
00320     };
00321     typedef std::deque<dir_data> QUEUE_TYPE;
00322     typedef std::list<std::string> CONTAINER_TYPE;
00323     typedef CONTAINER_TYPE::iterator iterator;
00324     typedef CONTAINER_TYPE::const_iterator const_iterator;
00325 private:
00326     PATH mpath;
00327     DIR_IT mdirit;
00328     QUEUE_TYPE mq;
00329     CONTAINER_TYPE mc;
00330 
00331 
00332     void AllClear(){
00333         mq.clear();
00334         mc.clear();
00335     }
00337     void PushDirectory(QUEUE_TYPE &q,const char *dir)
00338     {
00339         namespace fs = boost::filesystem;
00340         DIR_IT end;
00341         PATH path(dir,boost::filesystem::native);
00342         for( DIR_IT it(path); it != end; ++it)
00343         {
00344             if( fs::is_directory(*it)){
00345                 q.push_back(dir_data(it->native_directory_string()));
00346                 PushDirectory(q,it->native_directory_string().c_str());
00347             }/*else{
00348                 //dODS("native file string=%s",it->native_file_string());
00349             }*/
00350         }
00351     }
00352     void (*LOGIC_TYPE)(const char *,const char *,CONTAINER_TYPE);
00354     void SearchLogic_Boost(const char *name,const char *dir,CONTAINER_TYPE &c)
00355     {
00356         namespace fs = boost::filesystem;
00357         DIR_IT end;
00358         PATH path(dir,boost::filesystem::native);
00359         for( DIR_IT it(path); it != end; ++it)
00360         {
00361             if( fs::is_directory(*it)){
00362             }else{
00363                 //dODS(it->native_file_string().c_str());
00364                 //めっけ!
00365                 if(name==it->native_file_string())
00366                 {
00367                     c.push_back(it->native_file_string());
00368                 }
00369             }
00370         }
00371     }
00373     bool isFolder(WIN32_FIND_DATA &FindFileData){
00374         return (
00375             FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
00376             && strcmp(FindFileData.cFileName,"..")!=0 
00377             && strcmp(FindFileData.cFileName,".")!=0
00378             );
00379     }
00381     int SearchLogic_WildCard(const char *wc,const char *dir,CONTAINER_TYPE &c)
00382     {
00383         int result=edk_FileNotFound;
00384         char path[MAX_PATH];
00385         char fullpath[MAX_PATH];
00386         {
00387             //ディレクトリのパス生成
00388             size_t len=strlen(dir);
00389             dkstrcpy_amap(path,sizeof(path),dir,len);
00390             if(path[len]!='\\'){
00391                 char s[2]={'\\','\0'};
00392                 dkstrcat_amap2(path,sizeof(path),s);
00393             }
00394             
00395             //フルパスを記憶しておく
00396             dkstrcpy_amap(fullpath,sizeof(fullpath),path,strlen(path));
00397             //検索パスを作成
00398             dkstrcat_amap2(path,sizeof(path),wc);
00399         }
00400 
00401         WIN32_FIND_DATA FindFileData;
00402         HANDLE hFind = FindFirstFile(path, &FindFileData);
00403         
00404 
00405         if(hFind != INVALID_HANDLE_VALUE){
00406             char buff[MAX_PATH];
00407             do{
00408                 NULL_CHAR_ARRAY(buff);
00409                 dkstrcpy_amap(buff,sizeof(buff),fullpath,strlen(fullpath));
00410                 dkstrcat_amap2(buff,sizeof(buff),FindFileData.cFileName);
00411                 c.push_back(buff);
00412 
00413                 if(0==FindNextFile(hFind, &FindFileData)){
00414                     break;
00415                 }
00416             } while(true);
00417             FindClose(hFind);
00418             result = edk_SUCCEEDED;
00419         }
00420         else{
00421             //VISUAL_LASTERROR();
00422         }
00423         return result;
00424     }
00425     
00426 
00427 
00428 public:
00429     file_finder_base(){}
00430     virtual ~file_finder_base(){}
00431     iterator begin(){return mc.begin();}
00432     iterator end(){return mc.end();}
00438     void FindFromFolderLogic(const char *wc,const char *dir,CONTAINER_TYPE &receptacle){
00439         SearchLogic_WildCard(wc,dir,receptacle);
00440     }
00442     void find_from_folder(const char *wc,const char *dir){
00443         FindFromFolderLogic(wc,dir,mc);
00444     }
00450     void FindWildCardLogic(const char *wc,const char *dir,CONTAINER_TYPE &receptacle){
00451         AllClear();
00452         PushDirectory(mq,dir);
00453         SearchLogic_WildCard(wc,dir,receptacle);
00454         QUEUE_TYPE::iterator it=mq.begin();
00455         for(;it != mq.end();it++)
00456         {
00457             SearchLogic_WildCard(wc,(*it).dir.c_str(),receptacle);
00458         }
00459     }
00465     bool find_wc(const char *wc,const char *dir){
00466         FindWildCardLogic(wc,dir,mc);
00467         if(mc.empty())return false;
00468         return true;
00469     }
00475     void FindLogic(const char *filename,const char *dir,CONTAINER_TYPE &receptacle){
00476         AllClear();
00477         //ディレクトリをキューに詰める。
00478         PushDirectory(mq,dir);
00479         //まずは生ディレクトリから
00480         SearchLogic_Boost(filename,dir,receptacle);
00481         //次は検索したディレクトリから
00482         QUEUE_TYPE::iterator it=mq.begin();
00483         for(;it != mq.end();it++)
00484         {
00485             SearchLogic_Boost(filename,(*it).dir.c_str(),receptacle);
00486         }
00487     }
00493     bool find(const char *filename,const char *dir){
00494         FindLogic(filename,dir,mc);
00495         if(mc.empty()) return false;
00496         return true;
00497     }
00498 
00499     
00500 
00501 
00502 };
00503 
00505 typedef file_finder_base<> file_finder;
00506 
00507 
00508 
00512 
00513 class scoped_current_directory{
00514     std::string mPreviousDir;
00515 public:
00516     scoped_current_directory(const char *dir=NULL){
00517         try{
00518             if(dir){
00519                 reset(dir);
00520             }
00521         }catch(...){
00522             undo();//戻してやる
00523             throw;//受け取ったものをまた投げてやる
00524         }
00525     }
00526     virtual ~scoped_current_directory(){undo();}
00528     bool reset(const char *dir,bool bForce=false)
00529     {
00530         synchronized lock;
00531         if(empty()==false){//すでに使用済みだったら一時戻す。
00532             undo();
00533         }
00534 
00535         if(bForce==true){//強制的にDirectoryを作る
00536             if(false==FileAndFolderExist(dir)){
00537                 DKUTIL_RETURN_FALSE(CreateDirectory(dir));
00538             }
00539         }else{
00540             DKUTIL_RETURN_FALSE(FileAndFolderExist(dir));
00541         }
00542         mPreviousDir = SafeGetCurrentDirectory();
00543         if(FALSE==SetCurrentDirectory(dir))
00544         {//まぁ、エラーは0%に近いような気がするが・・・
00545             mPreviousDir.clear();
00546             return false;
00547         }
00548         return true;
00549     }
00551     bool undo(){
00552         synchronized lock;
00553         if(mPreviousDir.empty()) return false;
00554         if(FALSE==SetCurrentDirectory(mPreviousDir.c_str()))
00555         {
00556             return false;
00557         }
00558         mPreviousDir.clear();
00559         return true;
00560     }
00561     bool empty()const{return mPreviousDir.empty();}
00562     const std::string &previous_directory()const{return mPreviousDir;}
00563 
00564 };
00565 
00566 }//end of dkutil namespace
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575 #endif //end of include once 

dkutil 1.02リリース前 d金魚専用マニュアルバージョンに対してSun Dec 28 21:23:08 2003に生成されました。 doxygen 1.3.5