Base revisions
[ntk/apt.git] / apt-pkg / pkgcachegen.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: pkgcachegen.cc,v 1.1 1998/07/02 02:58:12 jgg Exp $
4 /* ######################################################################
5
6 Package Cache Generator - Generator for the cache structure.
7
8 This builds the cache structure from the abstract package list parser.
9
10 ##################################################################### */
11 /*}}}*/
12 // Include Files /*{{{*/
13 #include <pkglib/pkgcachegen.h>
14 #include <pkglib/error.h>
15 #include <pkglib/version.h>
16
17 #include <sys/stat.h>
18 #include <unistd.h>
19 /*}}}*/
20
21 // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/
22 // ---------------------------------------------------------------------
23 /* We set the diry flag and make sure that is written to the disk */
24 pkgCacheGenerator::pkgCacheGenerator(DynamicMMap &Map) : Map(Map), Cache(Map)
25 {
26 if (_error->PendingError() == true)
27 return;
28
29 if (Map.Size() == 0)
30 {
31 Map.RawAllocate(sizeof(pkgCache::Header));
32 *Cache.HeaderP = pkgCache::Header();
33 }
34 Cache.HeaderP->Dirty = true;
35 Map.Sync(0,sizeof(pkgCache::Header));
36 Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0]));
37 }
38 /*}}}*/
39 // CacheGenerator::~pkgCacheGenerator - Destructor /*{{{*/
40 // ---------------------------------------------------------------------
41 /* We sync the data then unset the dirty flag in two steps so as to
42 advoid a problem during a crash */
43 pkgCacheGenerator::~pkgCacheGenerator()
44 {
45 if (_error->PendingError() == true)
46 return;
47 if (Map.Sync() == false)
48 return;
49
50 Cache.HeaderP->Dirty = false;
51 Map.Sync(0,sizeof(pkgCache::Header));
52 }
53 /*}}}*/
54 // CacheGenerator::MergeList - Merge the package list /*{{{*/
55 // ---------------------------------------------------------------------
56 /* This provides the generation of the entries in the cache. Each loop
57 goes through a single package record from the underlying parse engine. */
58 bool pkgCacheGenerator::MergeList(ListParser &List)
59 {
60 List.Owner = this;
61
62 do
63 {
64 // Get a pointer to the package structure
65 string Package = List.Package();
66 pkgCache::PkgIterator Pkg = Cache.FindPkg(Package);
67 if (Pkg.end() == false)
68 {
69 if (NewPackage(Pkg,Package) == false)
70 return false;
71
72 if (List.NewPackage(Pkg) == false)
73 return false;
74 }
75 if (List.UsePackage(Pkg) == false)
76 return false;
77
78 /* Get a pointer to the version structure. We know the list is sorted
79 so we use that fact in the search. Insertion of new versions is
80 done with correct sorting */
81 string Version = List.Version();
82 pkgCache::VerIterator Ver = Pkg.VersionList();
83 unsigned long *Last = &Pkg->VersionList;
84 int Res;
85 for (; Ver.end() == false; Ver++, Last = &Ver->NextVer)
86 {
87 Res = pkgVersionCompare(Version.begin(),Version.end(),Ver.VerStr(),
88 Ver.VerStr() + strlen(Ver.VerStr()));
89 if (Res >= 0)
90 break;
91 }
92
93 /* We already have a version for this item, record that we
94 saw it */
95 if (Res == 0)
96 {
97 if (NewFileVer(Ver,List) == false)
98 return false;
99
100 continue;
101 }
102
103 // Add a new version
104 *Last = NewVersion(Ver,*Last);
105 if (List.NewVersion(Ver) == false)
106 return false;
107
108 if (NewFileVer(Ver,List) == false)
109 return false;
110 }
111 while (List.Step() == true);
112
113 return true;
114 }
115 /*}}}*/
116 // CacheGenerator::NewPackage - Add a new package /*{{{*/
117 // ---------------------------------------------------------------------
118 /* This creates a new package structure and adds it to the hash table */
119 bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator Pkg,string Name)
120 {
121 // Get a structure
122 unsigned long Package = Map.Allocate(sizeof(pkgCache::Package));
123 if (Package == 0)
124 return false;
125
126 Pkg = pkgCache::PkgIterator(Cache,Cache.PackageP + Package);
127
128 // Insert it into the hash table
129 unsigned long Hash = Map.Hash(Name);
130 Pkg->NextPackage = Cache.HeaderP->HashTable[Hash];
131 Cache.HeaderP->HashTable[Hash] = Package;
132
133 // Set the name and the ID
134 Pkg->Name = Map.WriteString(Name);
135 if (Pkg->Name == 0)
136 return false;
137 Pkg->ID = Cache.HeaderP->PackageCount++;
138
139 return true;
140 }
141 /*}}}*/
142 // CacheGenerator::NewFileVer - Create a new File<->Version association /*{{{*/
143 // ---------------------------------------------------------------------
144 /* */
145 bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator Ver,
146 ListParser &List)
147 {
148 }
149 /*}}}*/
150 // CacheGenerator::NewVersion - Create a new Version /*{{{*/
151 // ---------------------------------------------------------------------
152 /* */
153 unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
154 unsigned long Next)
155 {
156 }
157 /*}}}*/
158 // CacheGenerator::SelectFile - Select the current file being parsed /*{{{*/
159 // ---------------------------------------------------------------------
160 /* This is used to select which file is to be associated with all newly
161 added versions. */
162 bool pkgCacheGenerator::SelectFile(string File,unsigned long Flags)
163 {
164 struct stat Buf;
165 if (stat(File.c_str(),&Buf) == -1)
166 return _error->Errno("stat","Couldn't stat ",File.c_str());
167
168 // Get some space for the structure
169 CurrentFile = Cache.PkgFileP + Map.Allocate(sizeof(*CurrentFile));
170 if (CurrentFile == Cache.PkgFileP)
171 return false;
172
173 // Fill it in
174 CurrentFile->FileName = Map.WriteString(File);
175 CurrentFile->Size = Buf.st_size;
176 CurrentFile->mtime = Buf.st_mtime;
177 CurrentFile->NextFile = Cache.HeaderP->FileList;
178 CurrentFile->Flags = Flags;
179 PkgFileName = File;
180
181 if (CurrentFile->FileName == 0)
182 return false;
183 }
184 /*}}}*/