123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- // -*- mode: cpp; mode: fold -*-
- // Description /*{{{*/
- // $Id: filelistdb.cc,v 1.4 1999/02/27 08:00:05 jgg Exp $
- /* ######################################################################
-
- File List Database
- The mmap class should probably go someplace else..
-
- ##################################################################### */
- /*}}}*/
- // Include files /*{{{*/
- #ifdef __GNUG__
- #pragma implementation "dsync/filelistdb.h"
- #endif
- #include <dsync/filelistdb.h>
- #include <dsync/error.h>
- #include <string.h>
- /*}}}*/
- // FileListDB::dsFileListDB - Constructor /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- dsFileListDB::dsFileListDB()
- {
- }
- /*}}}*/
- // FileListDB::Generate - Build the directory map /*{{{*/
- // ---------------------------------------------------------------------
- /* This sucks the offset of every directory record into a stl map for
- quick lookup. */
- bool dsFileListDB::Generate(dsFList::IO &IO)
- {
- // Iterate over the file
- dsFList List;
- while (List.Step(IO) == true)
- {
- // Record the current location so we can jump to it
- unsigned long Pos = IO.Tell();
- string LastSymlink = IO.LastSymlink;
- if (List.Tag == dsFList::tTrailer)
- return true;
-
- // We only index directory start records
- if (List.Tag != dsFList::tDirStart)
- continue;
-
- // Store it in the map
- Location &Loc = Map[List.Dir.Name];
- Loc.Offset = Pos;
- Loc.LastSymlink = LastSymlink;
- }
-
- return false;
- }
- /*}}}*/
- // FileListDB::Lookup - Find a directory and file /*{{{*/
- // ---------------------------------------------------------------------
- /* We use a caching scheme, if the last lookup is in the same directory
- we do not re-seek but mearly look at the next entries till termination
- then wraps around. In the case of a largely unchanged directory this
- gives huge speed increases. */
- bool dsFileListDB::Lookup(dsFList::IO &IO,const char *Dir,const char *File,
- dsFList &List)
- {
- map<string,Location>::const_iterator I = Map.find(Dir);
- if (I == Map.end())
- return false;
-
- // See if we should reseek
- bool Restart = true;
- if (LastDir != Dir || LastDir.empty() == true)
- {
- Restart = false;
- IO.LastSymlink = I->second.LastSymlink;
- if (IO.Seek(I->second.Offset) == false)
- return false;
- LastDir = Dir;
- }
- List.Head = IO.Header;
- while (List.Step(IO) == true)
- {
- // Oops, ran out of directories
- if (List.Tag == dsFList::tDirEnd ||
- List.Tag == dsFList::tDirStart ||
- List.Tag == dsFList::tTrailer)
- {
- if (Restart == false)
- {
- LastDir = string();
- return false;
- }
-
- Restart = false;
- IO.LastSymlink = I->second.LastSymlink;
- if (IO.Seek(I->second.Offset) == false)
- return false;
- LastDir = Dir;
- continue;
- }
-
- // Skip over non directory contents
- if (List.Tag == dsFList::tDirMarker ||
- List.Tag == dsFList::tDirEnd ||
- List.Tag == dsFList::tDirStart ||
- List.Entity == 0)
- continue;
- if (List.Entity->Name == File)
- return true;
- }
- return false;
- }
- /*}}}*/
- // MMapIO::dsMMapIO - Constructor /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- dsMMapIO::dsMMapIO(string File) : Fd(File,FileFd::ReadOnly),
- Map(Fd,MMap::Public | MMap::ReadOnly)
- {
- Pos = 0;
- }
- /*}}}*/
- // MMapIO::Read - Read bytes from the map /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool dsMMapIO::Read(void *Buf,unsigned long Len)
- {
- if (Pos + Len > Map.Size())
- return _error->Error("Attempt to read past end of mmap");
- memcpy(Buf,(unsigned char *)Map.Data() + Pos,Len);
- Pos += Len;
- return true;
- }
- /*}}}*/
- // MMapIO::Write - Write bytes (fail) /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool dsMMapIO::Write(const void *Buf,unsigned long Len)
- {
- return _error->Error("Attempt to write to read only mmap");
- }
- /*}}}*/
- // MMapIO::Seek - Jump to a spot /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool dsMMapIO::Seek(unsigned long Bytes)
- {
- if (Bytes > Map.Size())
- return _error->Error("Attempt to seek past end of mmap");
- Pos = Bytes;
- return true;
- }
- /*}}}*/
- // MMapIO::Tell - Return the current location /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- unsigned long dsMMapIO::Tell()
- {
- return Pos;
- }
- /*}}}*/
|