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/RepositoryInfo.h>
11
12#include <stdlib.h>
13
14#include <new>
15
16#include <driver_settings.h>
17#include <File.h>
18#include <Message.h>
19
20#include <package/PackageInfo.h>
21
22
23namespace BPackageKit {
24
25
26const uint8 BRepositoryInfo::kDefaultPriority	= 50;
27
28const char* BRepositoryInfo::kNameField			= "name";
29const char* BRepositoryInfo::kURLField			= "url";
30const char* BRepositoryInfo::kVendorField		= "vendor";
31const char* BRepositoryInfo::kSummaryField		= "summary";
32const char* BRepositoryInfo::kPriorityField		= "priority";
33const char* BRepositoryInfo::kArchitectureField	= "architecture";
34const char* BRepositoryInfo::kLicenseNameField	= "licenseName";
35const char* BRepositoryInfo::kLicenseTextField	= "licenseText";
36
37
38BRepositoryInfo::BRepositoryInfo()
39	:
40	fInitStatus(B_NO_INIT),
41	fPriority(kDefaultPriority),
42	fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT)
43{
44}
45
46
47BRepositoryInfo::BRepositoryInfo(BMessage* data)
48	:
49	inherited(data),
50	fLicenseTexts(5)
51{
52	fInitStatus = SetTo(data);
53}
54
55
56BRepositoryInfo::BRepositoryInfo(const BEntry& entry)
57{
58	fInitStatus = SetTo(entry);
59}
60
61
62BRepositoryInfo::~BRepositoryInfo()
63{
64}
65
66
67/*static*/ BRepositoryInfo*
68BRepositoryInfo::Instantiate(BMessage* data)
69{
70	if (validate_instantiation(data, "BPackageKit::BRepositoryInfo"))
71		return new (std::nothrow) BRepositoryInfo(data);
72
73	return NULL;
74}
75
76
77status_t
78BRepositoryInfo::Archive(BMessage* data, bool deep) const
79{
80	status_t result = inherited::Archive(data, deep);
81	if (result != B_OK)
82		return result;
83
84	if ((result = data->AddString(kNameField, fName)) != B_OK)
85		return result;
86	if ((result = data->AddString(kURLField, fOriginalBaseURL)) != B_OK)
87		return result;
88	if ((result = data->AddString(kVendorField, fVendor)) != B_OK)
89		return result;
90	result = data->AddString(kSummaryField, fSummary);
91	if (result != B_OK)
92		return result;
93	if ((result = data->AddUInt8(kPriorityField, fPriority)) != B_OK)
94		return result;
95	if ((result = data->AddUInt8(kArchitectureField, fArchitecture)) != B_OK)
96		return result;
97	for (int i = 0; i < fLicenseNames.CountStrings(); ++i) {
98		result = data->AddString(kLicenseNameField, fLicenseNames.StringAt(i));
99		if (result != B_OK)
100			return result;
101	}
102	for (int i = 0; i < fLicenseTexts.CountStrings(); ++i) {
103		result = data->AddString(kLicenseTextField, fLicenseTexts.StringAt(i));
104		if (result != B_OK)
105			return result;
106	}
107
108	return B_OK;
109}
110
111
112status_t
113BRepositoryInfo::InitCheck() const
114{
115	return fInitStatus;
116}
117
118
119status_t
120BRepositoryInfo::SetTo(const BMessage* data)
121{
122	if (data == NULL)
123		return B_BAD_VALUE;
124
125	status_t result;
126	if ((result = data->FindString(kNameField, &fName)) != B_OK)
127		return result;
128	if ((result = data->FindString(kURLField, &fOriginalBaseURL)) != B_OK)
129		return result;
130	if ((result = data->FindString(kVendorField, &fVendor)) != B_OK)
131		return result;
132	result = data->FindString(kSummaryField, &fSummary);
133	if (result != B_OK)
134		return result;
135	if ((result = data->FindUInt8(kPriorityField, &fPriority)) != B_OK)
136		return result;
137	result = data->FindUInt8(kArchitectureField, (uint8*)&fArchitecture);
138	if (result != B_OK)
139		return result;
140	if (fArchitecture == B_PACKAGE_ARCHITECTURE_ANY)
141		return B_BAD_DATA;
142
143	const char* licenseName;
144	const char* licenseText;
145	for (int i = 0;
146		data->FindString(kLicenseNameField, i, &licenseName) == B_OK
147			&& data->FindString(kLicenseTextField, i, &licenseText) == B_OK;
148		++i) {
149		if (!fLicenseNames.Add(licenseName) || !fLicenseTexts.Add(licenseText))
150			return B_NO_MEMORY;
151	}
152
153	return B_OK;
154}
155
156
157status_t
158BRepositoryInfo::SetTo(const BEntry& entry)
159{
160	BFile file(&entry, B_READ_ONLY);
161	status_t result = file.InitCheck();
162	if (result != B_OK)
163		return result;
164
165	off_t size;
166	if ((result = file.GetSize(&size)) != B_OK)
167		return result;
168
169	BString configString;
170	char* buffer = configString.LockBuffer(size);
171	if (buffer == NULL)
172		return B_NO_MEMORY;
173
174	if ((result = file.Read(buffer, size)) < size) {
175		configString.UnlockBuffer(0);
176		return (result >= 0) ? B_IO_ERROR : result;
177	}
178
179	buffer[size] = '\0';
180	configString.UnlockBuffer(size);
181
182	void* settingsHandle = parse_driver_settings_string(configString.String());
183	if (settingsHandle == NULL)
184		return B_BAD_DATA;
185
186	const char* name = get_driver_parameter(settingsHandle, "name", NULL, NULL);
187	const char* url = get_driver_parameter(settingsHandle, "url", NULL, NULL);
188	const char* vendor
189		= get_driver_parameter(settingsHandle, "vendor", NULL, NULL);
190	const char* summary
191		= get_driver_parameter(settingsHandle, "summary", NULL, NULL);
192	const char* priorityString
193		= get_driver_parameter(settingsHandle, "priority", NULL, NULL);
194	const char* architectureString
195		= get_driver_parameter(settingsHandle, "architecture", NULL, NULL);
196
197	unload_driver_settings(settingsHandle);
198
199	if (name == NULL || *name == '\0' || url == NULL || *url == '\0'
200		|| vendor == NULL || *vendor == '\0'
201		|| summary == NULL || *summary == '\0'
202		|| priorityString == NULL || *priorityString == '\0'
203		|| architectureString == NULL || *architectureString == '\0') {
204		return B_BAD_DATA;
205	}
206
207	BPackageArchitecture architecture;
208	if (BPackageInfo::GetArchitectureByName(architectureString, architecture)
209			!= B_OK || architecture == B_PACKAGE_ARCHITECTURE_ANY) {
210		return B_BAD_DATA;
211	}
212
213	fName = name;
214	fOriginalBaseURL = url;
215	fVendor = vendor;
216	fSummary = summary;
217	fPriority = atoi(priorityString);
218	fArchitecture = architecture;
219
220	fInitStatus = B_OK;
221
222	return B_OK;
223}
224
225
226const BString&
227BRepositoryInfo::Name() const
228{
229	return fName;
230}
231
232
233const BString&
234BRepositoryInfo::OriginalBaseURL() const
235{
236	return fOriginalBaseURL;
237}
238
239
240const BString&
241BRepositoryInfo::Vendor() const
242{
243	return fVendor;
244}
245
246
247const BString&
248BRepositoryInfo::Summary() const
249{
250	return fSummary;
251}
252
253
254uint8
255BRepositoryInfo::Priority() const
256{
257	return fPriority;
258}
259
260
261BPackageArchitecture
262BRepositoryInfo::Architecture() const
263{
264	return fArchitecture;
265}
266
267
268const BStringList&
269BRepositoryInfo::LicenseNames() const
270{
271	return fLicenseNames;
272}
273
274
275const BStringList&
276BRepositoryInfo::LicenseTexts() const
277{
278	return fLicenseTexts;
279}
280
281
282void
283BRepositoryInfo::SetName(const BString& name)
284{
285	fName = name;
286}
287
288
289void
290BRepositoryInfo::SetOriginalBaseURL(const BString& url)
291{
292	fOriginalBaseURL = url;
293}
294
295
296void
297BRepositoryInfo::SetVendor(const BString& vendor)
298{
299	fVendor = vendor;
300}
301
302
303void
304BRepositoryInfo::SetSummary(const BString& summary)
305{
306	fSummary = summary;
307}
308
309
310void
311BRepositoryInfo::SetPriority(uint8 priority)
312{
313	fPriority = priority;
314}
315
316
317void
318BRepositoryInfo::SetArchitecture(BPackageArchitecture architecture)
319{
320	fArchitecture = architecture;
321}
322
323
324status_t
325BRepositoryInfo::AddLicense(const BString& licenseName,
326	const BString& licenseText)
327{
328	if (!fLicenseNames.Add(licenseName) || !fLicenseTexts.Add(licenseText))
329		return B_NO_MEMORY;
330
331	return B_OK;
332}
333
334
335void
336BRepositoryInfo::ClearLicenses()
337{
338	fLicenseNames.MakeEmpty();
339	fLicenseTexts.MakeEmpty();
340}
341
342
343}	// namespace BPackageKit
344