"Fossies" - the Fresh Open Source Software Archive

Member "qdiff-0.9.1/tfiletools.h" (21 Oct 2008, 8422 Bytes) of package /linux/privat/old/qdiff-0.9.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*GPL*START*
    2  *
    3  * tfilesync.h - file and directory handling tolls header file
    4  * 
    5  * Copyright (C) 2000 by Johannes Overmann <Johannes.Overmann@gmx.de>
    6  * 
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
   10  * (at your option) any later version.
   11  * 
   12  * This program is distributed in the hope that it will be useful,
   13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  * GNU General Public License for more details.
   16  * 
   17  * You should have received a copy of the GNU General Public License
   18  * along with this program; if not, write to the Free Software
   19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   20  * *GPL*END*/  
   21 
   22 #ifndef _ngw_tfiletools_h_
   23 #define _ngw_tfiletools_h_
   24 
   25 #include <sys/stat.h>
   26 #include <sys/types.h>
   27 #include <unistd.h>
   28 #include <assert.h>
   29 #include "tstring.h"
   30 #include "texception.h"
   31 #include "tmap.h"
   32 #include "tvector.h"
   33 
   34 // history:
   35 // 2001:
   36 // 25 Jun 2001: created (Dir and File taken from filesync.cc)
   37 
   38 #ifdef __STRICT_ANSI__
   39 #define S_ISVTX       01000
   40 #define S_ISLNK(a)    0
   41 #define S_ISSOCK(a)   0
   42 #define S_IFMT        0170000
   43 #endif
   44 
   45 
   46 // own device type which is a simple 64 bit unsigned integer
   47 typedef unsigned long long mydev_t;
   48 inline mydev_t dev_t2mydev_t(const dev_t& dev) {
   49 #ifdef __APPLE__
   50    return *(reinterpret_cast<const unsigned int*>(&dev));
   51 #else
   52    return *(reinterpret_cast<const mydev_t*>(&dev));
   53 #endif
   54 }
   55 inline dev_t mydev_t2dev_t(mydev_t dev) {
   56    return *(reinterpret_cast<const dev_t*>(&dev));
   57 }
   58    
   59 
   60 // file instance information (needed for hardlink structure)
   61 struct TFileInstance {
   62    TFileInstance(mydev_t d = 0, ino_t i = 0): device(d), inode(i) {}
   63    mydev_t device;
   64    ino_t inode;
   65 };
   66 inline bool operator < (const TFileInstance& d1, const TFileInstance& d2) {
   67    if(d1.device < d2.device) return true;
   68    return d1.inode < d2.inode;
   69 }
   70 inline bool operator == (const TFileInstance& d1, const TFileInstance& d2) {
   71    return (d1.inode == d2.inode) && (d1.device == d2.device);
   72 }
   73 inline bool operator != (const TFileInstance& d1, const TFileInstance& d2) {
   74    return (d1.inode != d2.inode) || (d1.device != d2.device);
   75 }
   76 
   77 class TFile {
   78  public:
   79    // cons & des
   80    TFile(const tstring& fname = tstring()): name_(fname), stated(false) {}
   81    ~TFile() {}
   82    void invalidateStat() const { const_cast<TFile*>(this)->stated = false; }
   83    
   84    // read only interface
   85    
   86    // file types 
   87    enum FileType { FT_UNKNOWN, FT_REGULAR, FT_DIR, FT_SYMLINK, FT_CHARDEV, FT_BLOCKDEV, FT_FIFO, FT_SOCKET };
   88    
   89    // name
   90    const tstring& name() const {if(name_.empty()) throw TNotInitializedException("TFile"); return name_;}
   91    tstring filename() const {tstring r= name_; r.extractFilename(); return r;}
   92    tstring pathname() const {tstring r= name_; r.extractPath(); return r;}
   93 
   94    // stat fields
   95    mydev_t device() const {getstat(); return dev_t2mydev_t(statbuf.st_dev);}
   96    ino_t inode() const {getstat(); return statbuf.st_ino;}
   97    nlink_t hardlinks() const {getstat(); return statbuf.st_nlink;}
   98    uid_t userid() const {getstat(); return statbuf.st_uid;}
   99    gid_t groupid() const {getstat(); return statbuf.st_gid;}
  100    mydev_t devicetype() const {getstat(); return dev_t2mydev_t(statbuf.st_rdev);}
  101    off_t size() const {getstat(); return statbuf.st_size;}
  102    time_t atime() const {getstat(); return statbuf.st_atime;}
  103    time_t mtime() const {getstat(); return statbuf.st_mtime;}
  104    time_t ctime() const {getstat(); return statbuf.st_ctime;}
  105    // mode fields
  106    mode_t protection() const { getstat(); return statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO); }
  107    bool isdir() const { getstat(); return S_ISDIR(statbuf.st_mode); }
  108    bool isregular() const { getstat(); return S_ISREG(statbuf.st_mode); }
  109    bool issymlink() const { getstat(); return S_ISLNK(statbuf.st_mode); }
  110    bool ischardev() const { getstat(); return S_ISCHR(statbuf.st_mode); }
  111    bool isblockdev() const { getstat(); return S_ISBLK(statbuf.st_mode); }
  112    bool isfifo() const { getstat(); return S_ISFIFO(statbuf.st_mode); }
  113    bool issocket() const { getstat(); return S_ISSOCK(statbuf.st_mode); }
  114    bool devicetypeApplies() const { return ischardev() || isblockdev(); }
  115    mode_t filetypebits() const { return statbuf.st_mode & S_IFMT; }
  116    TFileInstance instance() const { return TFileInstance(device(), inode()); }
  117    FileType filetype() const;
  118    tstring filetypeLongStr() const;
  119    char filetypeChar() const;
  120    tstring filetypeStr7() const;
  121    static void followLinks(bool follow = true) { follow_links = follow; }
  122    static size_t numStated() { return num_stated; }
  123    
  124  private:
  125    // private helpers
  126    void getstat() const;
  127 
  128    // private data
  129    tstring name_;
  130    struct stat statbuf;
  131    bool stated;
  132 
  133    // private static data
  134    static bool follow_links;
  135    static size_t num_stated;
  136 
  137    // avoid implicit comparison
  138    bool operator==(const TFile&);
  139 };
  140 
  141 
  142 class TDir;
  143 
  144 class TSubTreeContext {
  145  public:
  146    TSubTreeContext(bool cross_filesystems, size_t max_depth = 0xffffffff): root(0), cross_filesystems(cross_filesystems), max_depth(max_depth) {}
  147    TDir *root;
  148    bool cross_filesystems;
  149    size_t max_depth;
  150 };
  151 
  152 
  153 class TDir: public TFile {
  154  public:
  155    TDir(): TFile(), scanned(false), subTreeContext(0), depth(0) {}
  156    TDir(const tstring& fname, TSubTreeContext& subTreeContext_, size_t depth = 0): TFile(fname), scanned(false), subTreeContext(&subTreeContext_), depth(depth) { init(); }
  157    TDir(const TFile& file_, TSubTreeContext& subTreeContext_, size_t depth = 0): TFile(file_), scanned(false), subTreeContext(&subTreeContext_), depth(depth) { init(); }
  158    ~TDir() {}
  159 
  160    // read only interface
  161    const TFile& file(const tstring& fname) const { scan(); if(name2fileid.contains(fname)) return files[name2fileid[fname]]; else throw TNotFoundException(); }
  162    const TDir & dir (const tstring& fname) const { scan(); if(name2dirid .contains(fname)) return dirs [name2dirid [fname]]; else throw TNotFoundException(); }
  163    const TFile& file(size_t index) const { scan(); if(index >= files.size()) throw TZeroBasedIndexOutOfRangeException(index, files.size()); return files[index];}
  164    const TDir & dir (size_t index) const { scan(); if(index >= dirs .size()) throw TZeroBasedIndexOutOfRangeException(index, dirs .size()); return dirs [index];}
  165    size_t numFiles() const { scan(); return files.size();}
  166    size_t numDirs () const { scan(); return dirs .size();}
  167    bool containsFile(const tstring& fname) const { scan(); return name2fileid.contains(fname); }
  168    bool containsDir (const tstring& fname) const { scan(); return name2dirid .contains(fname); }
  169    bool contains    (const tstring& fname) const { return containsDir(fname) || containsFile(fname); }
  170    bool isEmpty() const { return dirs.empty() && files.empty(); }
  171    void invalidateContents() { freeMem(); }
  172    size_t numRecursive(bool low_mem = true, const char *verbose = 0, bool count_files = true, bool count_dirs = true) const;
  173    void freeMem() const { if(scanned) { TDir *t = const_cast<TDir*>(this); t->dirs.clear(); t->files.clear(); t->name2fileid.clear(); t->name2dirid.clear(); t->scanned = false; } }
  174    static void resetVerboseNum() { old_verbose_num = verbose_num = 0; };
  175    static void noLeafOptimize(bool no_opt) {
  176       no_leaf_optimize = no_opt;
  177 #ifdef WIN32
  178       no_leaf_optimize = true;
  179 #endif      
  180    }
  181    
  182  private:
  183    // private helpers
  184    void scan() const;
  185    void init() { assert(subTreeContext); if(subTreeContext->root == 0) subTreeContext->root = this; }
  186    
  187    // private data
  188    bool scanned;
  189    tmap<tstring,int> name2fileid;
  190    tmap<int,TFile> files;
  191    tmap<tstring,int> name2dirid;
  192    tmap<int,TDir> dirs;
  193    TSubTreeContext *subTreeContext;
  194    size_t depth;
  195    
  196    // private static data
  197    static size_t verbose_num;
  198    static size_t old_verbose_num;
  199    static bool no_leaf_optimize;
  200    
  201    // forbid implicit comparison
  202    bool operator==(const TDir&);
  203 };
  204 
  205 // global functions
  206 tvector<tstring> findFilesRecursive(const TDir& dir);
  207 tvector<tstring> filterExtensions(const tvector<tstring>& list, const tvector<tstring>& extensions, bool remove = false);
  208 void makeDirectoriesIncludingParentsIfNecessary(const tstring& dirname, bool verbose = false, bool dummy = false);
  209 
  210 
  211 #endif /* _ngw_tfiletools_h_ */
  212