1/*
2 * Copyright 2011-2013, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Oliver Tappe <zooey@hirschkaefer.de>
7 *		Ingo Weinhold <ingo_weinhold@gmx.de>
8 */
9
10
11#include <package/RepositoryCache.h>
12
13#include <stdio.h>
14
15#include <new>
16
17#include <Directory.h>
18#include <File.h>
19#include <FindDirectory.h>
20#include <Path.h>
21
22#include <package/hpkg/ErrorOutput.h>
23#include <package/hpkg/PackageInfoAttributeValue.h>
24#include <package/hpkg/RepositoryContentHandler.h>
25#include <package/hpkg/RepositoryReader.h>
26#include <package/hpkg/StandardErrorOutput.h>
27#include <package/PackageInfo.h>
28#include <package/RepositoryInfo.h>
29
30#include <package/PackageInfoContentHandler.h>
31
32
33namespace BPackageKit {
34
35
36using namespace BHPKG;
37
38
39// #pragma mark - RepositoryContentHandler
40
41
42struct BRepositoryCache::RepositoryContentHandler : BRepositoryContentHandler {
43	RepositoryContentHandler(BRepositoryInfo& repositoryInfo,
44		BPackageInfoSet& packages, BErrorOutput* errorOutput)
45		:
46		fRepositoryInfo(repositoryInfo),
47		fPackageInfo(),
48		fPackages(packages),
49		fPackageInfoContentHandler(fPackageInfo, errorOutput)
50	{
51	}
52
53	virtual status_t HandlePackage(const char* packageName)
54	{
55		fPackageInfo.Clear();
56		return B_OK;
57	}
58
59
60	virtual status_t HandlePackageAttribute(
61		const BPackageInfoAttributeValue& value)
62	{
63		return fPackageInfoContentHandler.HandlePackageAttribute(value);
64	}
65
66	virtual status_t HandlePackageDone(const char* packageName)
67	{
68		status_t result = fPackageInfo.InitCheck();
69		if (result != B_OK)
70			return result;
71
72		result = fPackages.AddInfo(fPackageInfo);
73		if (result != B_OK)
74			return result;
75
76		return B_OK;
77	}
78
79	virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo)
80	{
81		fRepositoryInfo = repositoryInfo;
82
83		return B_OK;
84	}
85
86	virtual void HandleErrorOccurred()
87	{
88	}
89
90private:
91	BRepositoryInfo&			fRepositoryInfo;
92	BPackageInfo				fPackageInfo;
93	BPackageInfoSet&			fPackages;
94	BPackageInfoContentHandler	fPackageInfoContentHandler;
95};
96
97
98// #pragma mark - BRepositoryCache
99
100
101BRepositoryCache::BRepositoryCache()
102	:
103	fIsUserSpecific(false),
104	fPackages()
105{
106}
107
108
109BRepositoryCache::~BRepositoryCache()
110{
111}
112
113
114const BEntry&
115BRepositoryCache::Entry() const
116{
117	return fEntry;
118}
119
120
121const BRepositoryInfo&
122BRepositoryCache::Info() const
123{
124	return fInfo;
125}
126
127
128bool
129BRepositoryCache::IsUserSpecific() const
130{
131	return fIsUserSpecific;
132}
133
134
135void
136BRepositoryCache::SetIsUserSpecific(bool isUserSpecific)
137{
138	fIsUserSpecific = isUserSpecific;
139}
140
141
142status_t
143BRepositoryCache::SetTo(const BEntry& entry)
144{
145	// unset
146	fPackages.MakeEmpty();
147	fEntry.Unset();
148
149	// get cache file path
150	fEntry = entry;
151
152	BPath repositoryCachePath;
153	status_t result;
154	if ((result = entry.GetPath(&repositoryCachePath)) != B_OK)
155		return result;
156
157	// read repository cache
158	BStandardErrorOutput errorOutput;
159	BRepositoryReader repositoryReader(&errorOutput);
160	if ((result = repositoryReader.Init(repositoryCachePath.Path())) != B_OK)
161		return result;
162
163	RepositoryContentHandler handler(fInfo, fPackages, &errorOutput);
164	if ((result = repositoryReader.ParseContent(&handler)) != B_OK)
165		return result;
166
167	BPath userSettingsPath;
168	if (find_directory(B_USER_SETTINGS_DIRECTORY, &userSettingsPath) == B_OK) {
169		BDirectory userSettingsDir(userSettingsPath.Path());
170		fIsUserSpecific = userSettingsDir.Contains(&entry);
171	} else
172		fIsUserSpecific = false;
173
174	return B_OK;
175}
176
177
178uint32
179BRepositoryCache::CountPackages() const
180{
181	return fPackages.CountInfos();
182}
183
184
185BRepositoryCache::Iterator
186BRepositoryCache::GetIterator() const
187{
188	return fPackages.GetIterator();
189}
190
191
192}	// namespace BPackageKit
193