xref: /haiku/src/kits/package/RepositoryCache.cpp (revision fc75f2df0c666dcc61be83c4facdd3132340c2fb)
1 /*
2  * Copyright 2011, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Oliver Tappe <zooey@hirschkaefer.de>
7  */
8 
9 
10 #include <package/RepositoryCache.h>
11 
12 #include <stdio.h>
13 
14 #include <new>
15 
16 #include <Directory.h>
17 #include <File.h>
18 #include <FindDirectory.h>
19 #include <Path.h>
20 
21 #include <package/hpkg/ErrorOutput.h>
22 #include <package/hpkg/PackageInfoAttributeValue.h>
23 #include <package/hpkg/RepositoryContentHandler.h>
24 #include <package/hpkg/RepositoryReader.h>
25 #include <package/PackageInfo.h>
26 #include <package/RepositoryInfo.h>
27 
28 
29 namespace BPackageKit {
30 
31 
32 using namespace BHPKG;
33 
34 
35 // #pragma mark - RepositoryContentHandler
36 
37 
38 struct BRepositoryCache::RepositoryContentHandler : BRepositoryContentHandler {
39 	RepositoryContentHandler(BRepositoryInfo* repositoryInfo,
40 		BPackageInfoSet& packages)
41 		:
42 		fRepositoryInfo(repositoryInfo),
43 		fPackages(packages)
44 	{
45 	}
46 
47 	virtual status_t HandleEntry(BPackageEntry* entry)
48 	{
49 		return B_OK;
50 	}
51 
52 	virtual status_t HandleEntryAttribute(BPackageEntry* entry,
53 		BPackageEntryAttribute* attribute)
54 	{
55 		return B_OK;
56 	}
57 
58 	virtual status_t HandleEntryDone(BPackageEntry* entry)
59 	{
60 		return B_OK;
61 	}
62 
63 	virtual status_t HandlePackageAttribute(
64 		const BPackageInfoAttributeValue& value)
65 	{
66 		switch (value.attributeID) {
67 			case B_PACKAGE_INFO_NAME:
68 				fPackageInfo.SetName(value.string);
69 				break;
70 
71 			case B_PACKAGE_INFO_SUMMARY:
72 				fPackageInfo.SetSummary(value.string);
73 				break;
74 
75 			case B_PACKAGE_INFO_DESCRIPTION:
76 				fPackageInfo.SetDescription(value.string);
77 				break;
78 
79 			case B_PACKAGE_INFO_VENDOR:
80 				fPackageInfo.SetVendor(value.string);
81 				break;
82 
83 			case B_PACKAGE_INFO_PACKAGER:
84 				fPackageInfo.SetPackager(value.string);
85 				break;
86 
87 			case B_PACKAGE_INFO_FLAGS:
88 				fPackageInfo.SetFlags(value.unsignedInt);
89 				break;
90 
91 			case B_PACKAGE_INFO_ARCHITECTURE:
92 				fPackageInfo.SetArchitecture(
93 					(BPackageArchitecture)value.unsignedInt);
94 				break;
95 
96 			case B_PACKAGE_INFO_VERSION:
97 				fPackageInfo.SetVersion(value.version);
98 				break;
99 
100 			case B_PACKAGE_INFO_COPYRIGHTS:
101 				fPackageInfo.AddCopyright(value.string);
102 				break;
103 
104 			case B_PACKAGE_INFO_LICENSES:
105 				fPackageInfo.AddLicense(value.string);
106 				break;
107 
108 			case B_PACKAGE_INFO_PROVIDES:
109 				fPackageInfo.AddProvides(value.resolvable);
110 				break;
111 
112 			case B_PACKAGE_INFO_REQUIRES:
113 				fPackageInfo.AddRequires(value.resolvableExpression);
114 				break;
115 
116 			case B_PACKAGE_INFO_SUPPLEMENTS:
117 				fPackageInfo.AddSupplements(value.resolvableExpression);
118 				break;
119 
120 			case B_PACKAGE_INFO_CONFLICTS:
121 				fPackageInfo.AddConflicts(value.resolvableExpression);
122 				break;
123 
124 			case B_PACKAGE_INFO_FRESHENS:
125 				fPackageInfo.AddFreshens(value.resolvableExpression);
126 				break;
127 
128 			case B_PACKAGE_INFO_REPLACES:
129 				fPackageInfo.AddReplaces(value.string);
130 				break;
131 
132 			case B_PACKAGE_INFO_URLS:
133 				fPackageInfo.AddURL(value.string);
134 				break;
135 
136 			case B_PACKAGE_INFO_SOURCE_URLS:
137 				fPackageInfo.AddSourceURL(value.string);
138 				break;
139 
140 			case B_PACKAGE_INFO_INSTALL_PATH:
141 				fPackageInfo.SetInstallPath(value.string);
142 				break;
143 
144 			case B_PACKAGE_INFO_CHECKSUM:
145 			{
146 				fPackageInfo.SetChecksum(value.string);
147 				status_t result = fPackageInfo.InitCheck();
148 				if (result != B_OK)
149 					return result;
150 
151 				result = fPackages.AddInfo(fPackageInfo);
152 				if (result != B_OK)
153 					return result;
154 
155 				fPackageInfo.Clear();
156 				break;
157 			}
158 
159 			default:
160 				return B_BAD_DATA;
161 		}
162 
163 		return B_OK;
164 	}
165 
166 	virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo)
167 	{
168 		*fRepositoryInfo = repositoryInfo;
169 
170 		return B_OK;
171 	}
172 
173 	virtual void HandleErrorOccurred()
174 	{
175 	}
176 
177 private:
178 	BRepositoryInfo*	fRepositoryInfo;
179 	BPackageInfo		fPackageInfo;
180 	BPackageInfoSet&	fPackages;
181 };
182 
183 
184 // #pragma mark - StandardErrorOutput
185 
186 
187 class BRepositoryCache::StandardErrorOutput : public BErrorOutput {
188 	virtual	void PrintErrorVarArgs(const char* format, va_list args)
189 	{
190 		vfprintf(stderr, format, args);
191 	}
192 };
193 
194 
195 // #pragma mark - BRepositoryCache
196 
197 
198 BRepositoryCache::BRepositoryCache()
199 	:
200 	fIsUserSpecific(false),
201 	fPackages()
202 {
203 }
204 
205 
206 BRepositoryCache::~BRepositoryCache()
207 {
208 }
209 
210 
211 const BEntry&
212 BRepositoryCache::Entry() const
213 {
214 	return fEntry;
215 }
216 
217 
218 const BRepositoryInfo&
219 BRepositoryCache::Info() const
220 {
221 	return fInfo;
222 }
223 
224 
225 bool
226 BRepositoryCache::IsUserSpecific() const
227 {
228 	return fIsUserSpecific;
229 }
230 
231 
232 void
233 BRepositoryCache::SetIsUserSpecific(bool isUserSpecific)
234 {
235 	fIsUserSpecific = isUserSpecific;
236 }
237 
238 
239 status_t
240 BRepositoryCache::SetTo(const BEntry& entry)
241 {
242 	// unset
243 	fPackages.MakeEmpty();
244 	fEntry.Unset();
245 
246 	// init package info set
247 	status_t result = fPackages.Init();
248 	if (result != B_OK)
249 		return result;
250 
251 	// get cache file path
252 	fEntry = entry;
253 
254 	BPath repositoryCachePath;
255 	if ((result = entry.GetPath(&repositoryCachePath)) != B_OK)
256 		return result;
257 
258 	// read repository cache
259 	StandardErrorOutput errorOutput;
260 	BRepositoryReader repositoryReader(&errorOutput);
261 	if ((result = repositoryReader.Init(repositoryCachePath.Path())) != B_OK)
262 		return result;
263 
264 	RepositoryContentHandler handler(&fInfo, fPackages);
265 	if ((result = repositoryReader.ParseContent(&handler)) != B_OK)
266 		return result;
267 
268 	BPath userSettingsPath;
269 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &userSettingsPath) == B_OK) {
270 		BDirectory userSettingsDir(userSettingsPath.Path());
271 		fIsUserSpecific = userSettingsDir.Contains(&entry);
272 	} else
273 		fIsUserSpecific = false;
274 
275 	return B_OK;
276 }
277 
278 
279 uint32
280 BRepositoryCache::CountPackages() const
281 {
282 	return fPackages.CountInfos();
283 }
284 
285 
286 BRepositoryCache::Iterator
287 BRepositoryCache::GetIterator() const
288 {
289 	return fPackages.GetIterator();
290 }
291 
292 
293 }	// namespace BPackageKit
294