GPS4Palm

Source Code Documentation


getdir.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * $RCSfile: getdir_8c-source.html,v $
00004  *
00005  *
00006  *   Store "directory" of a set of databases / files
00007  *   in 3 different databases (see parameters).
00008  *
00009  * History:
00010  * 2002-12-23:  first version, taken from the ZBoxZ application suite
00011  *                (Rev. 0.30) by Tom Zerucha
00012  *
00013  * This program is Copyright (C) 12/2002 Matthias Prinke
00014  * <matthias.prinke@surfeu.de> and covered by GNU's GPL.
00015  * In particular, this program is free software and comes WITHOUT
00016  * ANY WARRANTY.
00017  *
00018  * $Author: mp $
00019  *
00020  * $Date: 2007-10-08 20:40:33 $
00021  *
00022  * $Revision: 1.7.2.1 $
00023  *
00024  * $Log: getdir_8c-source.html,v $
00024  * Revision 1.7.2.1  2007-10-08 20:40:33  mp
00024  * updated for gps4palm V0.9.5 beta
00024  *
00025  * Revision 1.5  2005-02-26 14:50:23  mp
00026  * removed debug output
00027  *
00028  * Revision 1.4  2005/02/19 14:34:33  mp
00029  * removed #include <Unix/sys_types.h> (now included in stringil.h)
00030  *
00031  * Revision 1.3  2005/02/19 11:15:11  mp
00032  * added getdir_vfs(), modified name/creator of scratchpad DB
00033  *
00034  * Revision 1.2  2003/11/23 19:57:30  mp
00035  * moved CreateDatabase and DestroyDatabase from FileselForm.c
00036  *
00037  * Revision 1.1  2003/10/18 16:25:21  mp
00038  * imported from piv
00039  *
00040  *
00041  *
00042  ****************************************************************************/
00043 
00044 #include <PalmOS.h>
00045 #include <PalmCompatibility.h>
00046 #include <Extensions/ExpansionMgr/VFSMgr.h>
00047 #include "stringil.h"
00048 #include "getdir.h"
00049 #include "common.h"
00050 
00051 //#define VERBOSE
00052 
00053 
00054 /****************************************************************************/
00055 /**
00056  * \brief       Store "directory" of a set of databases (i.e. files)
00057  *              in 3 different database records.
00058  * <pre>
00059  *              filelist        < size0 (4 bytes) >< filename0 >
00060  *                              < size1 (4 bytes) >< filename1 >
00061  *                              ...
00062  *              filecard        < card0 > (card of 1st file)
00063  *                              < card1 > (card of 2nd file)
00064  *                              ...
00065  *              filelp          < ptr0 > (pointer to 1st filelist entry)
00066  *                              < ptr1 > (pointer to 2nd filelist entry)
00067  *                              ...
00068  * </pre>
00069  * \param       filelist        start of filelist record
00070  * \param       filecard        filecard record
00071  * \param       filelp          filelp record
00072  *
00073  * \return      Total number of files.
00074  ****************************************************************************/
00075 UInt16 getdir(char *filelist, char *filecard, char **filelp)
00076 {
00077   UInt16        cardno; /* card no. */
00078   UInt32        card;   /* card no. and File Streaming Flag */
00079   UInt16        attr;   /* attributes */
00080   UInt32        type;   /* type ID */
00081   UInt32        crea;   /* creator ID */
00082   UInt32        ndb;    /* number of databases on current card */
00083   UInt32        size;   /* size (payload) */
00084   UInt32        i;      /* index (database, list) */
00085   UInt32        j;      /* offset within record */
00086   UInt32        tmp;    /* start position of file suffix */ 
00087   UInt32        *flpt;  /* file list pointer */
00088   UInt32        *fl;    /* file list pointer */
00089   UInt32        disp;   /* displacement in filelist */
00090   UInt16        maxrow; /* total number of rows (files) */
00091   UInt16        n;      /* y-position of WinDrawChars() */
00092   Char          tp[44]; /* temporary filelist buffer */
00093   LocalID       lid;    /* local database ID */
00094 
00095   maxrow = 0;
00096   disp = 0;
00097   n = 15;
00098 
00099 #ifdef VERBOSE  
00100   WinDrawChars("Getting Directory...", 20, 0, 0);
00101 #endif
00102   
00103   /* search files on all cards */
00104   for (cardno = 0; cardno < MemNumCards(); cardno++) {
00105     ndb = DmNumDatabases(cardno);    
00106     j = maxrow;
00107     fl = flpt = MemPtrNew(ndb * 4);
00108     
00109     /* search all files on current card */
00110     for (i = 0; i < ndb; i++) {
00111       memset(tp, 0, SORTPREFIX); /* for robustness, if sortprefix is >4, and the sort opt is smaller */
00112       lid = DmGetDatabase(cardno, i);
00113       DmDatabaseInfo(cardno, lid, &tp[SORTPREFIX], &attr, NULL, NULL, NULL,
00114                      NULL, NULL, NULL, NULL, &type, &crea);
00115       /* check type and attributes: only file streams of type data are valid */
00116       if (!(attr & dmHdrAttrStream) || type != 'DATA')
00117         continue;
00118         
00119       /* check creator ID: only 'BOXR' is valid */
00120       if (crea != 'BOXR')
00121         continue;
00122         
00123       /* check filename suffix: only GIF and PNG valid */
00124       tmp = StrLen(&tp[SORTPREFIX]) - 4;
00125       if ( (StrCaselessCompare(&tp[SORTPREFIX + tmp], ".gif") != 0) &&
00126            (StrCaselessCompare(&tp[SORTPREFIX + tmp], ".png") != 0) )
00127         continue;
00128 
00129 #ifdef VERBOSE
00130       WinDrawChars(&tp[SORTPREFIX], StrLen(&tp[SORTPREFIX]), 0, n);
00131       n += 12;
00132 #endif 
00133      
00134       /*
00135        * Copy type, creator, size, i, backup/creation/modification date,
00136        * or nrecs into tp (4 bytes) for alternate sorting
00137        * (only using payload size here)
00138        */
00139       DmDatabaseSize(cardno, lid, NULL, NULL, &size);
00140       memcpy(tp, &size, 4);
00141 #ifdef VERBOSE
00142       {
00143         char t[10];
00144         StrIToA(t, *tp);
00145         WinDrawChars(t, StrLen(t), 0, n);
00146         n += 12;
00147       }
00148 #endif 
00149 
00150       /*
00151        * Write file list DB 
00152        *   Each entry consists of a <size><filename> pair.
00153        *   While the <size> entry always has 4 bytes, the
00154        *   filename has a variable length.
00155        */
00156       DmWrite(  filelist,       /* recordP: file list */
00157                 disp,           /* offset: see below */
00158                 tp,             /* srcP: pointer to <size><name> entry */
00159                 strlen(&tp[SORTPREFIX]) + SORTPREFIX + 1 /* bytes */
00160              );
00161 
00162       card = cardno | FS_FLAG;
00163       
00164       /* write card number to filecard */     
00165       DmWrite(filecard,         /* recordP: filecard */
00166               maxrow * 4,       /* offset */
00167               &card,            /* srcP */ 
00168               4                 /* bytes */
00169              );
00170 
00171       /* fl: array of pointers to file list entries */
00172       *fl++ = (UInt32) filelist + disp;
00173       
00174       /* calculate offset (displacement) for next file list entry */
00175       disp += strlen(&tp[SORTPREFIX]) + SORTPREFIX + 1;
00176       
00177       /* increment total number of rows (= files) on all cards */ 
00178       maxrow++;
00179     } /* for (i = 0; i < ndb; i++) */
00180     
00181     /*
00182      * Write file list pointer DB
00183      *  Each entry consists of a pointer to a file list entry (4 bytes).
00184      *  All entries for the current card are written as a block.
00185      */
00186     DmWrite(    filelp, /* recordP: file list pointers */
00187                 j * 4,  /* offset: number of files on prev. cards x (4 bytes) */
00188                 flpt,   /* srcP: array of file pointers fo current card */
00189                 (maxrow - j) * 4); /* bytes: number of files on current card
00190                                                x (4 bytes) */
00191     
00192     /* Deallocate array of file pointers */
00193     MemPtrFree(flpt);
00194   } /* for (cardno = 0; cardno < MemNumCards(); cardno++) */
00195 
00196   return maxrow;
00197 }
00198 
00199 
00200 /****************************************************************************/
00201 /**
00202  * \brief       Store directory on external memory cards (VFS)
00203  *              in 3 different database records.
00204  * <pre>
00205  *              filelist        < size0 (4 bytes) >< filename0 >
00206  *                              < size1 (4 bytes) >< filename1 >
00207  *                              ...
00208  *              filecard        < vol0 > (volume of 1st file)
00209  *                              < vol1 > (volume of 2nd file)
00210  *                              ...
00211  *              filelp          < ptr0 > (pointer to 1st filelist entry)
00212  *                              < ptr1 > (pointer to 2nd filelist entry)
00213  *                              ...
00214  * </pre>
00215  * \param       filelist        start of filelist record
00216  * \param       filecard        filecard record
00217  * \param       filelp          filelp record
00218  * \param       files           number of files already found
00219  *                                (File Streaming API)
00220  *
00221  * \return      Total number of files.
00222  ****************************************************************************/
00223  UInt16 getdir_vfs(char *filelist, char *filecard, char **filelp, UInt16 files)
00224 {
00225   UInt16        volRefNum;      /* VFS volume reference number */
00226   UInt32        volIterator;    /* VFS volume iterator */
00227   FileRef       dirRef;         /* directory reference */
00228   FileRef       fileRef;        /* file reference */
00229   UInt32        card;           /* card/volume number */
00230   UInt32        size;           /* file size */
00231   UInt16        file_cnt;       /* file counter */
00232   UInt32        flp;            /* ptr to filelist entry (typecasted) */
00233   UInt32        tmp;            /* start position of file suffix */ 
00234   UInt32        disp;           /* displacement in filelist */
00235   UInt16        n;              /* y-position of WinDrawChars() */
00236   Err           err;            /* error code */
00237   
00238   n = 15;
00239   file_cnt = files;
00240   
00241   /* find end of records */
00242   if (file_cnt > 0) {
00243     disp = (UInt32)(filelp[files-1]) - (UInt32)*filelp ;
00244     disp += StrLen(filelp[files-1] + SORTPREFIX) + SORTPREFIX + 1;
00245     flp = (UInt32)filelist + disp;
00246   } else {
00247     disp     = 0;
00248     flp = (UInt32)filelist;
00249   }
00250 
00251 #ifdef VERBOSE
00252   {
00253     Char tmp[40];
00254     
00255     StrCopy(tmp, "Getting VFS Directory...");
00256     WinDrawChars(tmp, StrLen(tmp), 0, 0);
00257   }
00258 #endif
00259   
00260   volIterator = vfsIteratorStart;
00261 
00262   /* Iterate through all VFS volumes */
00263   while (volIterator != vfsIteratorStop) {
00264     err = VFSVolumeEnumerate(&volRefNum, &volIterator);
00265     
00266     if (err == errNone) {
00267 
00268       /* Open the directory and iterate through the files in it. */
00269       err = VFSFileOpen(volRefNum, FILEDIR, vfsModeRead, &dirRef);
00270   
00271       if (err == errNone) {
00272         UInt32          fileIterator;
00273         FileInfoType    fileInfo;
00274         Char            fileName[FILENAMEMAXLEN];
00275         MemPtr          pathName;
00276 
00277         fileInfo.nameP = fileName;
00278         fileInfo.nameBufLen = sizeof(fileName);
00279         fileIterator = expIteratorStart;
00280     
00281         /* Iterate through all the files in the open directory */
00282         while (fileIterator != expIteratorStop) {
00283           /* Get the next file */
00284           err = VFSDirEntryEnumerate(dirRef, &fileIterator, &fileInfo);
00285           
00286           if (err == errNone) {
00287             /* Process the file */
00288             
00289             /* filter filename suffix */
00290             tmp = StrLen(fileInfo.nameP) - 4;
00291             if ( (StrCaselessCompare(&fileInfo.nameP[tmp], ".gif") != 0) &&
00292                  (StrCaselessCompare(&fileInfo.nameP[tmp], ".png") != 0) )
00293               continue;
00294 
00295 #ifdef VERBOSE
00296             WinDrawChars(fileInfo.nameP, StrLen(fileInfo.nameP), 0, n);
00297             n += 12;
00298 #endif
00299 
00300             /* generate absolute file path */
00301             pathName = MemPtrNew(sizeof(FILEDIR) + StrLen(fileInfo.nameP) + 2);
00302             StrCopy(pathName, FILEDIR);
00303             StrCat(pathName, "/");
00304             StrCat(pathName, fileInfo.nameP);
00305             
00306             /* open file to get size */
00307             err = VFSFileOpen(volRefNum, pathName, vfsModeRead, &fileRef);
00308             
00309             if (!err) {
00310               err = VFSFileSize(fileRef, &size);
00311               
00312               if (err) {
00313                 size = 0;
00314               }
00315               VFSFileClose(fileRef);
00316             }
00317             MemPtrFree(pathName);
00318             
00319             /* write file size to filelist */
00320             DmWrite(filelist,                   /* recordP: file list */
00321                     disp,                       /* offset */
00322                     &size,                      /* srcP: pointer to size */
00323                     sizeof(size)                /* bytes (4) */
00324             );
00325             disp += sizeof(size);
00326 
00327             /* write file name to filelist */
00328             DmWrite(filelist,                   /* recordP: filelist */
00329                     disp,                       /* offset */
00330                     fileInfo.nameP,             /* srcP: pointer to file name */
00331                     StrLen(fileInfo.nameP) + 1  /* bytes */
00332             );
00333             disp += StrLen(fileInfo.nameP) + 1;
00334             
00335             /* volume/card reference number */
00336             card = volRefNum | VFS_FLAG;
00337 
00338             /* write volume reference number to filecard */
00339             DmWrite(filecard,                   /* recordP: filecard */
00340                     file_cnt * 4,               /* offset */ 
00341                     &card,                      /* srcP */
00342                     4                           /* bytes */
00343             );
00344             
00345             /* write pointer to filelist entry to filelp */
00346             DmWrite(filelp,                     /* recordP: filelist pointers */
00347                     file_cnt * 4,               /* offset */
00348                     &flp,                       /* srcP */
00349                     4                           /* bytes */
00350             );
00351 
00352             /* pointer to next file list entry */
00353             flp = (UInt32)filelist + disp;
00354             
00355             /* increment file count */
00356             file_cnt++;
00357             
00358           } else {
00359             /* handle directory open error */
00360 #ifdef VERBOSE
00361             {
00362               Char tmp[40];
00363 
00364               StrCopy(tmp, "Cannot open file: ");
00365               StrIToH(&tmp[StrLen(tmp)], err);
00366               WinDrawChars(tmp, StrLen(tmp), 0, n);
00367               n += 12;
00368             }
00369 #endif
00370             break;
00371           }
00372           
00373         } /* while (fileIterator != expIteratorStop) */
00374     
00375         err = VFSFileClose(dirRef);
00376 
00377 
00378       } else {
00379         /* handle error... */
00380 
00381 #ifdef VERBOSE
00382         {
00383           Char tmp[40];
00384         
00385           StrCopy(tmp, "Cannot open directory: ");
00386           StrIToH(&tmp[StrLen(tmp)], err);
00387           WinDrawChars(tmp, StrLen(tmp), 0, n);
00388           n += 12;
00389         }
00390 #endif
00391         break;
00392       }
00393     } 
00394   } /* while (volIterator != vfsIteratorStop) */
00395   
00396   return file_cnt;
00397 }
00398 
00399 
00400 /****************************************************************************/
00401 /**
00402  * \brief       Create scratchpad database with 3 records.
00403  *
00404  *
00405  * \note        All parameters are returned 'by reference', because the memory
00406  *              locations of the database records are determined by this
00407  *              function.
00408  *
00409  * \param       ref             pointer to database reference
00410  * \param       filelist        pointer to start of filelist record
00411  * \param       filecard        pointer to filecard record
00412  * \param       filelp          pointer to filelp record
00413  *
00414  ****************************************************************************/
00415 void CreateDatabase(DmOpenRef *ref,
00416                              char **filelist, char **filecard, char ***filelp)
00417 {
00418   LocalID       lid;            /* local database ID */
00419   DmOpenRef     scratch;        /* scratchpad DB reference */
00420   MemHandle     hand;           /* DB record memory handle */
00421   UInt16        dbrec = 0;      /* index of new record */
00422   
00423   /* open/create scratchpad database */
00424   lid = DmFindDatabase(0, "GPS4PALMSCRATCHPAD");
00425   if (!lid) {
00426     DmCreateDatabase(0, "GPS4PALMSCRATCHPAD", kCreatorId, 'DATA', false);
00427     lid = DmFindDatabase(0, "GPS4PALMSCRATCHPAD");
00428   }
00429   scratch = DmOpenDatabase(0, lid, dmModeReadWrite);
00430   
00431   if (!scratch)
00432     ErrDisplay("Could not access scratchpad!");
00433   
00434   hand = DmNewRecord(scratch, &dbrec, FILELISTRECORDSIZE);
00435   *filelist = MemHandleLock(hand);
00436   hand = DmNewRecord(scratch, &dbrec, FILELPRECORDSIZE);
00437   *filelp = MemHandleLock(hand);
00438   hand = DmNewRecord(scratch, &dbrec, FILECARDRECORDSIZE);
00439   *filecard = MemHandleLock(hand);
00440  
00441   *ref = scratch;
00442 }
00443 
00444 
00445 /****************************************************************************/
00446 /**
00447  * \brief       Remove all records and close scratchpad database
00448  *
00449  * \param       ref             database reference
00450  * \param       filelist        start of filelist record
00451  * \param       filecard        filecard record
00452  * \param       filelp          filelp record
00453  *
00454  ****************************************************************************/
00455 void DestroyDatabase(DmOpenRef ref,
00456                               char *filelist, char *filecard, char **filelp)
00457 {
00458   MemPtrUnlock(filelp);
00459   MemPtrUnlock(filecard);
00460   MemPtrUnlock(filelist);
00461   
00462   /* remove all records from scratchpad DB */
00463   while (DmNumRecords(ref))
00464     DmRemoveRecord(ref, 0);
00465 
00466   /* close scratchpad DB */
00467   DmCloseDatabase(ref);
00468 }

Created: Mon, 08 Oct 2007 22:33:16 +0200
Copyright ©2004 M. Prinke