xref: /haiku/src/kits/package/RepositoryCache.cpp (revision 0d452c8f34013b611a54c746a71c05e28796eae2)
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 	// get cache file path
247 	fEntry = entry;
248 
249 	BPath repositoryCachePath;
250 	status_t result;
251 	if ((result = entry.GetPath(&repositoryCachePath)) != B_OK)
252 		return result;
253 
254 	// read repository cache
255 	StandardErrorOutput errorOutput;
256 	BRepositoryReader repositoryReader(&errorOutput);
257 	if ((result = repositoryReader.Init(repositoryCachePath.Path())) != B_OK)
258 		return result;
259 
260 	RepositoryContentHandler handler(&fInfo, fPackages);
261 	if ((result = repositoryReader.ParseContent(&handler)) != B_OK)
262 		return result;
263 
264 	BPath userSettingsPath;
265 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &userSettingsPath) == B_OK) {
266 		BDirectory userSettingsDir(userSettingsPath.Path());
267 		fIsUserSpecific = userSettingsDir.Contains(&entry);
268 	} else
269 		fIsUserSpecific = false;
270 
271 	return B_OK;
272 }
273 
274 
275 uint32
276 BRepositoryCache::CountPackages() const
277 {
278 	return fPackages.CountInfos();
279 }
280 
281 
282 BRepositoryCache::Iterator
283 BRepositoryCache::GetIterator() const
284 {
285 	return fPackages.GetIterator();
286 }
287 
288 
289 }	// namespace BPackageKit
290