1 // -*- mode: cpp; mode: fold -*-
3 // $Id: filelistdb.cc,v 1.4 1999/02/27 08:00:05 jgg Exp $
4 /* ######################################################################
8 The mmap class should probably go someplace else..
10 ##################################################################### */
12 // Include files /*{{{*/
14 #pragma implementation "dsync/filelistdb.h"
17 #include <dsync/filelistdb.h>
18 #include <dsync/error.h>
21 // FileListDB::dsFileListDB - Constructor /*{{{*/
22 // ---------------------------------------------------------------------
24 dsFileListDB::dsFileListDB()
28 // FileListDB::Generate - Build the directory map /*{{{*/
29 // ---------------------------------------------------------------------
30 /* This sucks the offset of every directory record into a stl map for
32 bool dsFileListDB::Generate(dsFList::IO &IO)
34 // Iterate over the file
36 while (List.Step(IO) == true)
38 // Record the current location so we can jump to it
39 unsigned long Pos = IO.Tell();
40 string LastSymlink = IO.LastSymlink;
42 if (List.Tag == dsFList::tTrailer)
45 // We only index directory start records
46 if (List.Tag != dsFList::tDirStart)
49 // Store it in the map
50 Location &Loc = Map[List.Dir.Name];
52 Loc.LastSymlink = LastSymlink;
58 // FileListDB::Lookup - Find a directory and file /*{{{*/
59 // ---------------------------------------------------------------------
60 /* We use a caching scheme, if the last lookup is in the same directory
61 we do not re-seek but mearly look at the next entries till termination
62 then wraps around. In the case of a largely unchanged directory this
63 gives huge speed increases. */
64 bool dsFileListDB::Lookup(dsFList::IO &IO,const char *Dir,const char *File,
67 map<string,Location>::const_iterator I = Map.find(Dir);
71 // See if we should reseek
73 if (LastDir != Dir || LastDir.empty() == true)
76 IO.LastSymlink = I->second.LastSymlink;
77 if (IO.Seek(I->second.Offset) == false)
82 List.Head = IO.Header;
83 while (List.Step(IO) == true)
85 // Oops, ran out of directories
86 if (List.Tag == dsFList::tDirEnd ||
87 List.Tag == dsFList::tDirStart ||
88 List.Tag == dsFList::tTrailer)
97 IO.LastSymlink = I->second.LastSymlink;
98 if (IO.Seek(I->second.Offset) == false)
105 // Skip over non directory contents
106 if (List.Tag == dsFList::tDirMarker ||
107 List.Tag == dsFList::tDirEnd ||
108 List.Tag == dsFList::tDirStart ||
112 if (List.Entity->Name == File)
119 // MMapIO::dsMMapIO - Constructor /*{{{*/
120 // ---------------------------------------------------------------------
122 dsMMapIO::dsMMapIO(string File) : Fd(File,FileFd::ReadOnly),
123 Map(Fd,MMap::Public | MMap::ReadOnly)
128 // MMapIO::Read - Read bytes from the map /*{{{*/
129 // ---------------------------------------------------------------------
131 bool dsMMapIO::Read(void *Buf,unsigned long Len)
133 if (Pos + Len > Map.Size())
134 return _error->Error("Attempt to read past end of mmap");
135 memcpy(Buf,(unsigned char *)Map.Data() + Pos,Len);
140 // MMapIO::Write - Write bytes (fail) /*{{{*/
141 // ---------------------------------------------------------------------
143 bool dsMMapIO::Write(const void *Buf,unsigned long Len)
145 return _error->Error("Attempt to write to read only mmap");
148 // MMapIO::Seek - Jump to a spot /*{{{*/
149 // ---------------------------------------------------------------------
151 bool dsMMapIO::Seek(unsigned long Bytes)
153 if (Bytes > Map.Size())
154 return _error->Error("Attempt to seek past end of mmap");
159 // MMapIO::Tell - Return the current location /*{{{*/
160 // ---------------------------------------------------------------------
162 unsigned long dsMMapIO::Tell()