]> git.decadent.org.uk Git - dak.git/blob - tools/dsync-0.0/libdsync/filelistdb.cc
LOCAL: Remove replay check
[dak.git] / tools / dsync-0.0 / libdsync / filelistdb.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description                                                          /*{{{*/
3 // $Id: filelistdb.cc,v 1.4 1999/02/27 08:00:05 jgg Exp $
4 /* ######################################################################
5    
6    File List Database
7
8    The mmap class should probably go someplace else..
9    
10    ##################################################################### */
11                                                                         /*}}}*/
12 // Include files                                                        /*{{{*/
13 #ifdef __GNUG__
14 #pragma implementation "dsync/filelistdb.h"
15 #endif
16
17 #include <dsync/filelistdb.h>
18 #include <dsync/error.h>
19                                                                         /*}}}*/
20
21 // FileListDB::dsFileListDB - Constructor                               /*{{{*/
22 // ---------------------------------------------------------------------
23 /* */
24 dsFileListDB::dsFileListDB()
25 {
26 }
27                                                                         /*}}}*/
28 // FileListDB::Generate - Build the directory map                       /*{{{*/
29 // ---------------------------------------------------------------------
30 /* This sucks the offset of every directory record into a stl map for 
31    quick lookup. */
32 bool dsFileListDB::Generate(dsFList::IO &IO)
33 {
34    // Iterate over the file
35    dsFList List;
36    while (List.Step(IO) == true)
37    {
38       // Record the current location so we can jump to it
39       unsigned long Pos = IO.Tell();
40       string LastSymlink = IO.LastSymlink;
41
42       if (List.Tag == dsFList::tTrailer)
43          return true;
44          
45       // We only index directory start records
46       if (List.Tag != dsFList::tDirStart)
47          continue;
48       
49       // Store it in the map
50       Location &Loc = Map[List.Dir.Name];
51       Loc.Offset = Pos;
52       Loc.LastSymlink = LastSymlink;
53    }
54   
55    return false;
56 }
57                                                                         /*}}}*/
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,
65                           dsFList &List)
66 {
67    map<string,Location>::const_iterator I = Map.find(Dir);
68    if (I == Map.end())
69       return false;
70    
71    // See if we should reseek
72    bool Restart = true;
73    if (LastDir != Dir || LastDir.empty() == true)
74    {
75       Restart = false;
76       IO.LastSymlink = I->second.LastSymlink;
77       if (IO.Seek(I->second.Offset) == false)
78          return false;
79       LastDir = Dir;
80    }
81
82    List.Head = IO.Header;
83    while (List.Step(IO) == true)
84    {
85       // Oops, ran out of directories
86       if (List.Tag == dsFList::tDirEnd ||
87           List.Tag == dsFList::tDirStart ||
88           List.Tag == dsFList::tTrailer)
89       {
90          if (Restart == false)
91          {
92             LastDir = string();
93             return false;
94          }
95          
96          Restart = false;
97          IO.LastSymlink = I->second.LastSymlink;
98          if (IO.Seek(I->second.Offset) == false)
99             return false;
100          LastDir = Dir;
101
102          continue;
103       }
104       
105       // Skip over non directory contents
106       if (List.Tag == dsFList::tDirMarker ||
107           List.Tag == dsFList::tDirEnd ||
108           List.Tag == dsFList::tDirStart ||
109           List.Entity == 0)
110          continue;
111
112       if (List.Entity->Name == File)
113          return true;
114    }
115    return false;
116 }
117                                                                         /*}}}*/
118
119 // MMapIO::dsMMapIO - Constructor                                       /*{{{*/
120 // ---------------------------------------------------------------------
121 /* */
122 dsMMapIO::dsMMapIO(string File) : Fd(File,FileFd::ReadOnly), 
123               Map(Fd,MMap::Public | MMap::ReadOnly)
124 {
125    Pos = 0;
126 }
127                                                                         /*}}}*/
128 // MMapIO::Read - Read bytes from the map                               /*{{{*/
129 // ---------------------------------------------------------------------
130 /* */
131 bool dsMMapIO::Read(void *Buf,unsigned long Len)
132 {
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);
136    Pos += Len;
137    return true;
138 }
139                                                                         /*}}}*/
140 // MMapIO::Write - Write bytes (fail)                                   /*{{{*/
141 // ---------------------------------------------------------------------
142 /* */
143 bool dsMMapIO::Write(const void *Buf,unsigned long Len)
144 {
145    return _error->Error("Attempt to write to read only mmap");
146 }
147                                                                         /*}}}*/
148 // MMapIO::Seek - Jump to a spot                                        /*{{{*/
149 // ---------------------------------------------------------------------
150 /* */
151 bool dsMMapIO::Seek(unsigned long Bytes)
152 {
153    if (Bytes > Map.Size())
154       return _error->Error("Attempt to seek past end of mmap");
155    Pos = Bytes;
156    return true;
157 }
158                                                                         /*}}}*/
159 // MMapIO::Tell - Return the current location                           /*{{{*/
160 // ---------------------------------------------------------------------
161 /* */
162 unsigned long dsMMapIO::Tell()
163 {
164    return Pos;
165 }
166                                                                         /*}}}*/