www.pudn.com > λ²Ù×÷.zip > DL.CPP


////////////////////////////////////////////////////////// 
//                                                      // 
//           ******************************             // 
//           ****  Browning's Classes  ****             // 
//           ******************************             // 
//                                                      // 
//                  Class DL_3.Cpp                      // 
//                                                      // 
//       Public Domain           Roy G. Browning        // 
//       December 1989           The Fulcrum's Edge     // 
//                                                      // 
//       Zortech C/C++           version 2.01           // 
//                                                      // 
//       Ztc -o -mti DL_3                               // 
//                                                      // 
//       Initiated               05-01-1989             // 
////////////////////////////////////////////////////////// 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//                   Charity Request                    // 
//                                                      // 
//       If benefit is derived in any fashion from      // 
//       this public code it is requested that a        // 
//       donation be made to a children's charity       // 
//       if sufficient funds are available.             // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//                  C++ing How Series                   // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
#include "DL_3.Hpp" 
 
////////////////////////////////////////////////////////// 
//                    Cmp_FileName()                    // 
//                                                      // 
//       Compares two filenames together for the qsort  // 
//       If a numerical filename is passed it is con-   // 
//       verted to an integer value for processing.     // 
////////////////////////////////////////////////////////// 
 
static int Cmp_FileName(const FIND **p1, const FIND **p2) 
{ 
       int  k1 = atoi((*p1)->name), 
            k2 = atoi((*p2)->name); 
 
       if (k1 && k2) 
              return (k1 - k2); 
 
       return strcmp((*p1)->name, (*p2)->name); 
} 
 
////////////////////////////////////////////////////////// 
//                     Cmp_FileExt()                    // 
//                                                      // 
//      Compares two file extensions together for       // 
//      the qsort.  If they match then the filename     // 
//      is used instead.                                // 
////////////////////////////////////////////////////////// 
 
inline int Cmp_FileExt(const FIND **p1, const FIND **p2) 
{ 
 
       int i = strcmp(strchr((*p1)->name,'.')+one, 
                      strchr((*p2)->name,'.')+one); 
 
       if (i) 
              return (i); 
 
       Cmp_FileName(p1,p2); 
} 
 
////////////////////////////////////////////////////////// 
//                    Cmp_FileDate()                    // 
//                                                      // 
//      Compares two file dates together for the        // 
//      qsort.  If they match then the file times       // 
//      are used instead.                               // 
////////////////////////////////////////////////////////// 
 
inline int Cmp_FileDate(const FIND **p1, const FIND **p2) 
{ 
       int i = (*p1)->date - (*p2)->date; 
 
       if (i) 
              return (i); 
 
       if ((*p1)->time > (*p2)->time) 
              return one; 
 
       if ((*p1)->time < (*p2)->time) 
              return minusone; 
 
       Cmp_FileName(p1,p2); 
} 
 
////////////////////////////////////////////////////////// 
//                    Cmp_FileSize()                    // 
//                                                      // 
//      Compares two file sizes together for the        // 
//      qsort.  If they match the file names are        // 
//      used instead.                                   // 
////////////////////////////////////////////////////////// 
 
inline int Cmp_FileSize(const FIND **p1, const FIND **p2) 
{ 
       if ((*p1)->size > (*p2)->size) 
              return one; 
 
       if ((*p1)->size < (*p2)->size) 
              return minusone; 
 
       Cmp_FileName(p1,p2); 
} 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//            Class FileList::FileList()                // 
//                                                      // 
//      Constructor                                     // 
//                                                      // 
//      Stores the specified disk directory struct-     // 
//      ures in dynamic memory accessed via an ar-      // 
//      ray of pointers also allocated.  Assigns a      // 
//      pointer to the structure pointer array and      // 
//      reallocates to the number of returned files.    // 
//                                                      // 
//      char *name - Drive\Path\Pattern                 // 
//                                                      // 
//      int attrib - File attributes to search for      // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
static 
FileList::FileList(const char* name,const int attrib) 
{ 
     FIND dta; 
     union REGS inregs, outregs; 
 
 
     num_files = zero; 
     match_numbers_allocated = zero; 
 
     bdos(0x1A,&dta); 
 
     inregs.x.ax = 0x4E00; 
     inregs.x.dx = (int) name; 
     inregs.x.cx = attrib; 
     intdos(&inregs,&outregs); 
 
     if (outregs.x.cflag) { 
          num_files = error; 
          return; 
     } 
 
     F = (FIND **)new FIND *[MAXFILES]; 
 
     if (!F) { 
          cerr << "Error: F array not allocated!\n"; 
          exit(error); 
     } 
 
     for (int i = zero; !outregs.x.cflag && (i < MAXFILES); i++) { 
          num_files++; 
          F[i] = (FIND *)new FIND; 
 
          if (F[i]) 
               *F[i] = dta; 
          else { 
               cerr << "Error: F[i] structure not", 
                    "allocated!\n"; 
               exit(error); 
          } 
 
          inregs.x.ax= 0x4F00; 
          intdos(&inregs,&outregs); 
     } 
 
     F = realloc(F,num_files*sizeof(FIND *)); 
} 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//             Class FileList::~FileList()              // 
//                                                      // 
//       Destructor for Class FileList.                 // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
FileList::~FileList() 
{ 
     for (; zero < num_files--;) 
          delete F[num_files]; 
 
     delete F; 
 
     if (match_numbers_allocated) 
          delete match_numbers; 
} 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//          Class FileList::FileName_Match()            // 
//                                                      // 
//       Returns an array of integers that indicate     // 
//       the relative offset of each matching file-     // 
//       name.ext within the directory structures.      // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
static int * 
FileList::FileName_Match(char *string) const 
{ 
     int *num; 
 
     match_numbers = num = new int[num_files]; 
 
     if (!match_numbers) { 
          cerr << "Error: `num' array not allocated!\n"; 
          return NULL; 
     } else { 
          match_numbers_allocated = true; 
     } 
 
     int i = num_files; 
     strupr(string); 
     do { 
          if(strstr(F[i]->name,string)) 
               *(num++) = i; 
     } while (i--); 
     *num++ = zero; 
 
     match_numbers = realloc(match_numbers, 
                            (num - match_numbers) << one); 
 
     return match_numbers; 
} 
////////////////////////////////////////////////////////// 
//                                                      // 
//                Class FileList::Print()               // 
//                                                      // 
//       Prints a formated display of the directory     // 
//       structures.                                    // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
static void 
FileList::Print() const 
{ 
       int    m, 
              h; 
 
       for (int i = zero; i < num_files; i++) { 
              cout << F[i]->name << "\t"; 
 
              if (strlen(F[i]->name) < eight) 
                     cout << "\t"; 
 
              cout << form("%9lu",F[i]->size) << " "; 
 
              cout << form("%02d", 
                          ((F[i]->date >> five) & 0x0F)) 
                   << "/" 
                   << form("%02d",(F[i]->date & 0x001F)) 
                   << "/" 
                   << form("%02d",(((F[i]->date >> nine) 
                                  & 0x7F) | 80)); 
 
              m = (F[i]->time >> five) & 0x3F; 
              h = (F[i]->time >> eleven) & 0x1F; 
              cout << " " << form("%2d",h) 
                   << ":" 
                   << form("%02d",m); 
 
              if (h > 12) 
                     cout << " pm"; 
              else 
                     cout << " am"; 
 
              cout << "\n"; 
       } 
} 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//            Class FileName::FileName()                // 
//                           :FileList()                // 
//                                                      // 
//      Constructor                                     // 
//                                                      // 
//      Creates an instance of FileList via its con-    // 
//      structor then sorts the directory structures    // 
//      in ascending order according to File Names.     // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
inline FileName::FileName(const char *name,const int attrib) 
                :FileList(name,attrib) 
{ 
     qsort(F, num_files, sizeof(FIND *), Cmp_FileName); 
} 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//            Class FileSize::FileSize()                // 
//                           :FileList()                // 
//                                                      // 
//      Constructor                                     // 
//                                                      // 
//      Creates an instance of FileList via its con-    // 
//      structor then sorts the directory structures    // 
//      in ascending order according to File Sizes.     // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
inline FileSize::FileSize(const char *name,const int attrib) 
                :FileList(name,attrib) 
{ 
     qsort(F, num_files, sizeof(FIND *), Cmp_FileSize); 
} 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//            Class FileDate::FileDate()                // 
//                           :FileList()                // 
//                                                      // 
//      Constructor                                     // 
//                                                      // 
//      Creates an instance of FileList via its con-    // 
//      structor then sorts the directory structures    // 
//      in ascending order according to File Dates.     // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
inline FileDate::FileDate(const char *name,const int attrib) 
                :FileList(name,attrib) 
{ 
     qsort(F, num_files, sizeof(FIND *), Cmp_FileDate); 
} 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//            Class FileExt::FileExt()                  // 
//                          :FileList()                 // 
//                                                      // 
//      Constructor                                     // 
//                                                      // 
//      Creates an instance of FileList via its con-    // 
//      structor then sorts the directory structures    // 
//      in ascending order according to File Ext's.     // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
inline FileExt::FileExt(const char *name,const int attrib) 
               :FileList(name,attrib) 
{ 
     qsort(F, num_files, sizeof(FIND *), Cmp_FileExt); 
} 
 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//      First_Object() creates a FileList object        // 
//      that is not sorted, the default.  Implemented   // 
//      as a seperate function allowing the destructor  // 
//      to be called.                                   // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
inline void 
First_Object() 
{ 
       FileList test1; 
 
       if (test1.Number() != error) 
              test1.Print(); 
       else 
              cerr << "\tNo files to print.\n"; 
       cout << "\n"; 
} 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//      Second_Object() creates a FileName object       // 
//      that is sorted by the file name.  Implemented   // 
//      as a seperate function allowing the destructor  // 
//      to be called.                                   // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
inline void 
Second_Object() 
{ 
       FileName test2; 
 
       if (test2.Number() != error) 
              test2.Print(); 
       else 
              cerr << "\tNo files to print\n"; 
       cout << "\n"; 
} 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//      Third_Object() creates a FileExt object         // 
//      that is sorted by the file extension.           // 
//      Implemented as a seperate function allowing     // 
//      the destructor to be called.                    // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
inline void 
Third_Object() 
{ 
       FileExt test3; 
 
       if (test3.Number() != error) 
              test3.Print(); 
       else 
              cerr << "\tNo files to print\n"; 
       cout << "\n"; 
} 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//      Fourth_Object() creates a FileDate object       // 
//      that is sorted by the file date and time.       // 
//      Implemented as a seperate function allowing     // 
//      the destructor to be called.                    // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
inline void 
Fourth_Object() 
{ 
       FileDate test4; 
 
       if (test4.Number() != error) 
              test4.Print(); 
       else 
              cerr << "\tNo files to print\n"; 
       cout << "\n"; 
 
} 
 
 
////////////////////////////////////////////////////////// 
//                                                      // 
//      Main() tests FileList  FileName  FileExt        // 
//                   FileDate  FileSize                 // 
//                                                      // 
////////////////////////////////////////////////////////// 
 
main() 
{ 
// 
// Test the sorting methods 
// 
 
     First_Object(); 
     Second_Object(); 
     Third_Object(); 
     Fourth_Object(); 
 
     FileSize test5("*.*",FA_DIREC | FA_HIDDEN); 
 
     if (test5.Number() != error) 
          test5.Print(); 
     else 
          cerr << "\tNo files to print\n"; 
     cout << "\n"; 
 
// 
// Test the FileName_Match member 
// 
 
     cout << "Testing FileSize::FileName_Match()" 
          << " for \"com\".\n\n"; 
     FIND test;  
     int *i = test5.FileName_Match("com"); 
     while (*i) { 
          test = test5.Element(*i); 
          int j = *i++; 
          cout << "test5 file " << ++j << " is: " 
               << test.name << "\n"; 
     }; 
 
// 
// Test the Element and Number members 
// 
 
     test = test5.Element(two); 
     cout << "\nThird element of test5 is: " << test.name 
          << "\n\nTotal number of files = " 
          << test5.Number() << "\n\n"; 
 
     cout << "\nFinished\n"; 
 
     exit(zero); 
}