gdir.cpp

Go to the documentation of this file.
00001 // gdir.cpp -- Version 0.0
00002 
00003 #include <string.h>
00004 #include <errno.h>
00005 #include "gdir.h"
00006 #include "gfilestat.h"
00007 ////////////////////////////////////////////////////////////
00008 // Static members
00009 // ---------------------------------------------------------
00010 t_uchar gDirGeneric::slashChr=gSLASHCHR;
00011 
00012 ////////////////////////////////////////////////////////////
00013 gFileSysName::gFileSysName (char* s,
00014                             eFileSystemName aFSysName,
00015                             bool isADirectory)
00016     : gString( s ),
00017       fsysName( aFSysName ),
00018       isDirectory( isADirectory ),
00019       myStat( nil )
00020 {
00021 }
00022 
00023 gFileSysName::gFileSysName (char* s,
00024                             eFileSystemName aFSysName,
00025                             gFileStat& aStat)
00026     : gString( s ),
00027       fsysName( aFSysName ),
00028       isDirectory( aFSysName==e_FSysDir )
00029 {
00030  myStat = new gFileStat;
00031  ASSERTION(myStat!=nil,"myStat!=nil");
00032  myStat->CopyStat( aStat );
00033 }
00034 
00035 gFileSysName::~gFileSysName ()
00036 {
00037     delete myStat;
00038     myStat = nil;
00039 }
00040 
00041 bool gFileSysName::IsStrOk ()
00042 {
00043  bool isStrict = isDirectory==false;
00044  unsigned i, n=Length();
00045 
00046  if ( IsOk()==false ) return false;
00047  for (i=0; i<n; i++) {
00048      if ( gFileControl::Self().IsOkStrict( str[i], isStrict )==false )
00049          return false;
00050  }
00051  return true;
00052 }
00053 
00054 char* gFileSysName::Str ()
00055 {
00056  ASSERTION(str!=nil,"str!=nil");
00057  return gString::Str();
00058 }
00059 
00060 gFileStat& gFileSysName::GetStat ()
00061 {
00062  ASSERTION(myStat!=nil,"myStat!=nil");
00063  return *myStat;
00064 }
00065 ////////////////////////////////////////////////////////////
00066 gFileName::gFileName ()
00067     : gFileSysName( "\0", e_FSysNoName, false )
00068 {
00069 }
00070 
00071 gFileName::gFileName (char* s)
00072     : gFileSysName( s, e_FSysFile, false )
00073 {
00074 }
00075 
00076 gFileName::gFileName (gString& s)
00077     : gFileSysName( s.Str(), e_FSysFile, false )
00078 {
00079 }
00080 
00081 gFileName::gFileName (gString& s, gFileStat& aStat)
00082     : gFileSysName( s.Str(), e_FSysFile, aStat )
00083 {
00084 }
00085 
00086 gFileName::~gFileName ()
00087 {
00088 }
00089 ////////////////////////////////////////////////////////////
00090 gDirName::gDirName ()
00091     : gFileSysName( "\0", e_FSysNoName, true )
00092 {
00093 }
00094 
00095 gDirName::gDirName (char* s)
00096     : gFileSysName( "\0", e_FSysDir, true )
00097 {
00098  SetDirName( s );
00099 }
00100 
00101 gDirName::gDirName (gString& s)
00102     : gFileSysName( "\0", e_FSysDir, true )
00103 {
00104  SetDirName( s.Str() );
00105 }
00106 
00107 gDirName::gDirName (gString& s, gFileStat& aStat)
00108     : gFileSysName( s.Str(), e_FSysDir, aStat )
00109 {
00110  SetDirName( s.Str() );
00111 }
00112 
00113 gDirName::~gDirName ()
00114 {
00115 }
00116 
00117 char* gDirName::Str ()
00118 {
00119  return dirStr.Str();
00120 }
00121 
00122 char* gDirName::Name ()
00123 {
00124  ASSERTION(str!=nil,"str!=nil");
00125  return (char*)str;
00126 }
00127 
00128 void gDirName::SetDirName (char* s)
00129 {
00130  ASSERTION(s!=nil,"s!=nil");
00131  thisBuildDirStr( s );
00132 }
00133 
00134 t_uchar* gDirName::ToString (t_uchar* uBuf)
00135 {
00136  return dirStr.ToString( uBuf );
00137 }
00138 
00139 void gDirName::thisBuildDirStr (char* s)
00140 {
00141  gString sTemp( s );
00142  char* sPtr = sTemp.Str();
00143  int pIdx, len = (int)sTemp.Length();
00144 
00145  for (pIdx=len; pIdx>0; ) {
00146      pIdx--;
00147      if ( sPtr[pIdx]==gSLASHCHR )
00148          sPtr[pIdx] = 0;
00149      else
00150          break;
00151  }
00152  Set( sPtr );
00153  dirStr.Set( sPtr );
00154  dirStr.Add( gSLASHCHR );
00155 }
00156 ////////////////////////////////////////////////////////////
00157 gDirStream::gDirStream (char* dName)
00158     : gFile( gFile::e_Binary, dName, true ),
00159       pdir( nil ),
00160       dirName( dName ),
00161       dStat( dName ),
00162       isDirOpened( false )
00163 {
00164 #ifdef gDOS_SPEC
00165  lastOpError = 0;
00166 #endif //gDOS_SPEC
00167  if ( lastOpError==0 ) doOpenDir( dName );
00168 }
00169 
00170 gDirStream::~gDirStream ()
00171 {
00172  doCloseDir();
00173 }
00174 
00175 bool gDirStream::IsOpened ()
00176 {
00177  return isDirOpened;
00178 }
00179 
00180 int gDirStream::doOpenDir (char* dName)
00181 {
00182  ASSERTION(dName!=0 && dName[0]!=0,"dName!=0");
00183  lastOpError = 0;
00184  pdir = opendir( dName );
00185  isDirOpened = pdir!=NULL;
00186  DBGPRINT_MIN("doOpenDir(%s): isDirOpened?%d\n",dName,isDirOpened);
00187  if ( isDirOpened==false ) return lastOpError = errno;
00188  return 0;
00189 }
00190 
00191 int gDirStream::doCloseDir ()
00192 {
00193  if ( isDirOpened ) {
00194      ASSERTION(pdir!=nil,"pdir!=nil");
00195      closedir( pdir );
00196      pdir = nil;
00197  }
00198  isDirOpened = false;
00199  return 0;
00200 }
00201 ////////////////////////////////////////////////////////////
00202 // gDirGeneric - Generic directory handling
00203 // ---------------------------------------------------------
00204 gDirGeneric::gDirGeneric (eStorage kind)
00205     : lastOpError( 0 ),
00206       slashStr( (char)slashChr )
00207 {
00208 }
00209 
00210 gDirGeneric::~gDirGeneric ()
00211 {
00212 }
00213 
00214 bool gDirGeneric::IsNameOk (char* s)
00215 {
00216  unsigned posBad;
00217  return thisNameOk( s, posBad );
00218 }
00219 
00220 bool gDirGeneric::AllNamesOk (int depthLevel)
00221 {
00222  unsigned posBad;
00223  int notOkDepth;
00224  if ( depthLevel<0 ) return true;
00225  return thisAllNamesOk( depthLevel, posBad, notOkDepth );
00226 }
00227 
00228 gFileSysName* gDirGeneric::GetName (unsigned idx)
00229 {
00230  gFileSysName* fSysPtr = (gFileSysName*)GetObjectPtr( idx );
00231  ASSERTION(fSysPtr!=nil,"fSysPtr!=nil");
00232  return fSysPtr;
00233 }
00234 
00235 t_uchar* gDirGeneric::ToString (t_uchar* uBuf)
00236 {
00237  return nil;
00238 }
00239 
00240 bool gDirGeneric::SaveGuts (FILE* f)
00241 {
00242  bool isOk=true;
00243  unsigned i, n=N();
00244  char* s;
00245 
00246  if ( CanSave( f )==false ) return false;
00247 
00248  // Only stores one depth level
00249  isOk = AllNamesOk( 0 );
00250  if ( isOk==false ) return false;
00251  for (i=1; i<=n; i++) {
00252      gStorage* aObj = GetObjectPtr( i );
00253      s = ((gString*)aObj)->Str();
00254      isOk = fprintf( f, "%s\n", s )==1;
00255  }
00256  return isOk;
00257 }
00258 
00259 bool gDirGeneric::RestoreGuts (FILE* f)
00260 {
00261  gUCharBuffer sTemp;
00262  char* s;
00263 
00264  if ( CanRestore( f )==false ) return false;
00265 
00266  while ( fgets( (char*)sTemp.uBuf, sTemp.size, f )!=nil ) {
00267      s = sTemp.Str();
00268      if ( IsNameOk( s )==false ) return false;
00269      Add( s );
00270  }
00271  return true;
00272 }
00273 
00274 bool gDirGeneric::thisNameOk (char* s, unsigned& posBad)
00275 {
00276  unsigned pos=0, countSlash=0;
00277  char c='\0';
00278  t_uchar chr=0;
00279 
00280  ASSERTION(s!=nil,"s!=nil");
00281  posBad = 0;
00282  while ( (c = s[pos++])!=0 ) {
00283      chr = (t_uchar)c;
00284      posBad = pos;
00285      if ( chr<' ' ) return false;
00286      countSlash += chr==slashChr;
00287  }
00288  if ( chr==0 ) return false;
00289  posBad = 1;
00290  if ( strcmp(s,".")==0 || strcmp(s,"..")==0 ) return false;
00291  // If it is a file-name, no slash,
00292  // otherwise must be a directory (e.g. 'etc/') with slash at end.
00293  if ( countSlash>1 ) return false;
00294  if ( countSlash>0 && chr!=slashChr ) return false;
00295  if ( slashStr.Match( s ) ) return false;
00296  posBad = 0;
00297  return true;
00298 }
00299 
00300 bool gDirGeneric::thisAllNamesOk (unsigned depthLevel,
00301                                   unsigned& posBad,
00302                                   int& notOkDepth)
00303 {
00304  bool isOk;
00305  char* s;
00306 
00307  posBad = 0;
00308  notOkDepth = 0;
00309  ASSERTION(depthLevel>=0,"depthLevel>=0");
00310  ASSERTION(depthLevel==0,"TODO: depthLevel not 0...");
00311  unsigned i, n=N();
00312 
00313  for (i=1; i<=n; i++) {
00314      gStorage* aObj = GetObjectPtr( i );
00315      s = ((gString*)aObj)->Str();
00316      isOk = IsNameOk( s );
00317      if ( isOk==false ) {
00318          posBad = i;
00319          return false;
00320      }
00321  }
00322  return true;
00323 }
00324 ////////////////////////////////////////////////////////////
00325 gDir::gDir (char* dName)
00326     : gDirGeneric( e_StoreExtend ),
00327       dirStream( dName ),
00328       dirCount( -1 )
00329 {
00330  lastOpError = dirStream.lastOpError;
00331  //DBGPRINT_MIN("OPENED?%d gDir(%s):lastOpError=%d\n",dirStream.IsOpened(),dirStream.Name(),lastOpError);
00332  if ( dName!=nil ) sDirName.SetDirName( dName );
00333  if ( dirStream.IsOpened() ) {
00334      thisDelete();
00335      thisScanDir();
00336  }
00337 }
00338 
00339 gDir::gDir (gString& dName)
00340     : gDirGeneric( e_StoreExtend ),
00341       dirStream( dName.Str() ),
00342       dirCount( -1 )
00343 {
00344  lastOpError = dirStream.lastOpError;
00345  if ( dName.IsEmpty()==false ) sDirName.SetDirName( dName.Str() );
00346  if ( dirStream.IsOpened() ) {
00347      thisDelete();
00348      thisScanDir();
00349  }
00350 }
00351 
00352 gDir::~gDir ()
00353 {
00354 }
00355 
00356 gFileStat* gDir::GetStat (unsigned idx)
00357 {
00358  gFileSysName* fSysPtr = GetName( idx );
00359  // fSysPtr is always non-nil
00360  gFileStat* statPtr = fSysPtr->GetStatPtr();
00361  ASSERTION(statPtr!=nil,"statPtr!=nil");
00362  return statPtr;
00363 }
00364 
00365 bool gDir::GetNameDir (unsigned idx, gString& resName)
00366 {
00367  gString resFullName;
00368  return GetFullNameDir( idx, resName, resFullName );
00369 }
00370 
00371 bool gDir::GetFullNameDir (unsigned idx, gString& resName, gString& resFullName)
00372 {
00373  gFileSysName* fSysPtr = GetName( idx );
00374  resName.Set( fSysPtr->Str() );
00375  resFullName = sDirName.Str();
00376  resFullName.AddString( resName );
00377  return fSysPtr->GetStatPtr()->IsDirectory();
00378 }
00379 
00380 void gDir::AddDir (char* s)
00381 {
00382  ASSERTION(s!=nil && s[0]!=0,"AddDir(1)");
00383  gString sTemp( s );
00384  gDirName* sName = new gDirName( sTemp );
00385  thisAddSystemName( sName );
00386 }
00387 
00388 void gDir::AddFile (char* s)
00389 {
00390  ASSERTION(s!=nil && s[0]!=0,"AddFile(1)");
00391  gString sTemp( s );
00392  gFileName* sName = new gFileName( sTemp );
00393  thisAddSystemName( sName );
00394 }
00395 
00396 int gDir::thisScanDir ()
00397 {
00398  bool isOk, isDir;
00399  struct dirent tDirEnt;
00400  struct dirent* dp;
00401  char* s;
00402  int counter=0;
00403  DIR* apDir;
00404 
00405  apDir = dirStream.pdir;
00406  ASSERTION(dirStream.dirName.IsEmpty()==false,"thisScanDir(1)");
00407  ASSERTION(apDir!=NULL,"thisScanDir(2)");
00408  //
00409  // SYS-CALL: int getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
00410  // Used: ==> struct dirent *readdir(DIR *dir)
00411  //
00412  for (lastOpError=0; ; counter++) {
00413      gFileStat aStat;
00414      dp = readdir( apDir );
00415      if ( counter==0 && dp==NULL ) lastOpError = errno;
00416      if ( dp==NULL ) break;
00417      memset( &tDirEnt, 0, sizeof(tDirEnt) );
00418      memcpy( &tDirEnt, dp, sizeof(tDirEnt) );
00419      // d_reclen is the size, d_name the name itself
00420      s = (char*)tDirEnt.d_name;
00421      if ( strcmp(s,".")==0 || strcmp(s,"..")==0 ) continue;
00422      gString sTemp( sDirName.Name() );
00423      sTemp.Add( gSLASHCHR );
00424      sTemp.Add( s );
00425      aStat.Update( sTemp.Str() );
00426      isOk = aStat.HasStat();
00427      if ( isOk==false ) {
00428          errUnstatL.Add( sTemp );
00429          continue;
00430      }
00431      isDir = aStat.statusL.IsDirectory();
00432      thisAddStatName( isDir?e_FSysDir:e_FSysFile, s, aStat );
00433  }
00434  DBGPRINT_MIN("dirStream(%s):%d\n",dirStream.Name(),lastOpError);
00435  return lastOpError;
00436 }
00437 
00438 int gDir::thisAddStatName (eFileSystemName aFSysName, char* s, gFileStat& aStat)
00439 {
00440  gFileSysName* aPtr=nil;
00441 
00442  ASSERTION(s!=nil && s[0]!=0,"AddDir(1)");
00443  gString sTemp( s );
00444 
00445  switch ( aFSysName ) {
00446  case e_FSysFile:
00447      aPtr = new gFileName( sTemp, aStat );
00448      break;
00449  case e_FSysDir:
00450      aPtr = new gDirName( sTemp, aStat );
00451  case e_FSysNoName:
00452  default:
00453      break;
00454  }
00455 
00456  return thisAddSystemName( aPtr );
00457 }
00458 
00459 int gDir::thisAddSystemName (gFileSysName* aPtr)
00460 {
00461  ASSERTION(aPtr!=nil,"aPtr!=nil");
00462  return thisAppend( aPtr )==false;
00463 }
00464 ////////////////////////////////////////////////////////////
00465 

Generated on Sat Aug 18 02:40:52 2007 for xpfweb_v2x lib by  doxygen 1.4.2