1/*
2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef PACKAGE_H
6#define PACKAGE_H
7
8
9#include <package/hpkg/DataReader.h>
10#include <package/PackageFlags.h>
11#include <package/PackageArchitecture.h>
12
13#include <WeakReferenceable.h>
14
15#include <util/DoublyLinkedList.h>
16#include <util/OpenHashTable.h>
17#include <util/StringHash.h>
18
19#include <lock.h>
20
21#include "Dependency.h"
22#include "PackageNode.h"
23#include "Resolvable.h"
24#include "String.h"
25
26
27using BPackageKit::BPackageArchitecture;
28using BPackageKit::BHPKG::BAbstractBufferedDataReader;
29
30
31class PackageLinkDirectory;
32class PackagesDirectory;
33class PackageSettings;
34class Volume;
35class Version;
36
37
38class Package : public BWeakReferenceable,
39	public DoublyLinkedListLinkImpl<Package> {
40public:
41								Package(::Volume* volume,
42									PackagesDirectory* directory,
43									dev_t deviceID, ino_t nodeID);
44								~Package();
45
46			status_t			Init(const char* fileName);
47			status_t			Load(const PackageSettings& settings);
48
49			::Volume*			Volume() const		{ return fVolume; }
50			const String&		FileName() const	{ return fFileName; }
51
52			void				SetName(const String& name);
53			const String&		Name() const		{ return fName; }
54
55			const String&		VersionedName() const
56									{ return fVersionedName; }
57
58			dev_t				DeviceID() const
59									{ return fDeviceID; }
60			ino_t				NodeID() const
61									{ return fNodeID; }
62			PackagesDirectory*	Directory() const
63									{ return fPackagesDirectory; }
64
65			void				SetInstallPath(const String& installPath);
66			const String&		InstallPath() const	{ return fInstallPath; }
67
68			void				SetVersion(::Version* version);
69									// takes over object ownership
70			::Version*			Version() const
71									{ return fVersion; }
72
73			void				SetFlags(uint32 flags)
74									{ fFlags = flags; }
75			uint32				Flags() const
76									{ return fFlags; }
77
78			void				SetArchitecture(
79									BPackageArchitecture architecture)
80									{ fArchitecture = architecture; }
81			BPackageArchitecture Architecture() const
82									{ return fArchitecture; }
83			const char*			ArchitectureName() const;
84
85			void				SetLinkDirectory(
86									PackageLinkDirectory* linkDirectory)
87									{ fLinkDirectory = linkDirectory; }
88			PackageLinkDirectory* LinkDirectory() const
89									{ return fLinkDirectory; }
90
91			Package*&			FileNameHashTableNext()
92									{ return fFileNameHashTableNext; }
93
94			void				AddNode(PackageNode* node);
95			void				AddResolvable(Resolvable* resolvable);
96			void				AddDependency(Dependency* dependency);
97
98			int					Open();
99			void				Close();
100
101			status_t			CreateDataReader(const PackageData& data,
102									BAbstractBufferedDataReader*& _reader);
103
104			const PackageNodeList& Nodes() const	{ return fNodes; }
105			const ResolvableList& Resolvables() const
106									{ return fResolvables; }
107			const DependencyList& Dependencies() const
108									{ return fDependencies; }
109
110private:
111			struct LoaderErrorOutput;
112			struct LoaderContentHandler;
113			struct LoaderContentHandlerV1;
114			struct HeapReader;
115			struct HeapReaderV1;
116			struct HeapReaderV2;
117			struct CachingPackageReader;
118
119private:
120			status_t			_Load(const PackageSettings& settings);
121			bool				_InitVersionedName();
122
123private:
124			mutex				fLock;
125			::Volume*			fVolume;
126			PackagesDirectory*	fPackagesDirectory;
127			String				fFileName;
128			String				fName;
129			String				fInstallPath;
130			String				fVersionedName;
131			::Version*			fVersion;
132			uint32				fFlags;
133			BPackageArchitecture fArchitecture;
134			PackageLinkDirectory* fLinkDirectory;
135			int					fFD;
136			uint32				fOpenCount;
137			HeapReader*			fHeapReader;
138			Package*			fFileNameHashTableNext;
139			ino_t				fNodeID;
140			dev_t				fDeviceID;
141			PackageNodeList		fNodes;
142			ResolvableList		fResolvables;
143			DependencyList		fDependencies;
144};
145
146
147struct PackageCloser {
148	PackageCloser(Package* package)
149		:
150		fPackage(package)
151	{
152	}
153
154	~PackageCloser()
155	{
156		if (fPackage != NULL)
157			fPackage->Close();
158	}
159
160	void Detach()
161	{
162		fPackage = NULL;
163	}
164
165private:
166	Package*	fPackage;
167};
168
169
170struct PackageFileNameHashDefinition {
171	typedef const char*		KeyType;
172	typedef	Package			ValueType;
173
174	size_t HashKey(const char* key) const
175	{
176		return hash_hash_string(key);
177	}
178
179	size_t Hash(const Package* value) const
180	{
181		return value->FileName().Hash();
182	}
183
184	bool Compare(const char* key, const Package* value) const
185	{
186		return strcmp(value->FileName(), key) == 0;
187	}
188
189	Package*& GetLink(Package* value) const
190	{
191		return value->FileNameHashTableNext();
192	}
193};
194
195
196typedef BOpenHashTable<PackageFileNameHashDefinition> PackageFileNameHashTable;
197typedef DoublyLinkedList<Package> PackageList;
198
199
200#endif	// PACKAGE_H
201