xref: /haiku/headers/private/package/hpkg/ReaderImplBase.h (revision b3263ad3e1662cc419849a2d2cf539f9636613dc)
1ad6a8dbeSOliver Tappe /*
2fe707a23SIngo Weinhold  * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3ad6a8dbeSOliver Tappe  * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
4ad6a8dbeSOliver Tappe  * Distributed under the terms of the MIT License.
5ad6a8dbeSOliver Tappe  */
6ad6a8dbeSOliver Tappe #ifndef _PACKAGE__HPKG__PRIVATE__READER_IMPL_BASE_H_
7ad6a8dbeSOliver Tappe #define _PACKAGE__HPKG__PRIVATE__READER_IMPL_BASE_H_
8ad6a8dbeSOliver Tappe 
9ad6a8dbeSOliver Tappe 
101f633814SIngo Weinhold #include <errno.h>
111f633814SIngo Weinhold #include <sys/stat.h>
121f633814SIngo Weinhold 
131f633814SIngo Weinhold #include <ByteOrder.h>
14ad6a8dbeSOliver Tappe #include <SupportDefs.h>
15ad6a8dbeSOliver Tappe 
160f4e11e7SIngo Weinhold #include <Array.h>
17ad6a8dbeSOliver Tappe #include <util/SinglyLinkedList.h>
18ad6a8dbeSOliver Tappe 
19d03ac965SIngo Weinhold #include <package/hpkg/ErrorOutput.h>
20ad6a8dbeSOliver Tappe #include <package/hpkg/PackageAttributeValue.h>
21ad6a8dbeSOliver Tappe #include <package/hpkg/PackageContentHandler.h>
22ad6a8dbeSOliver Tappe #include <package/hpkg/PackageInfoAttributeValue.h>
23ad6a8dbeSOliver Tappe 
24ad6a8dbeSOliver Tappe 
25*b3263ad3SIngo Weinhold class BCompressionAlgorithm;
26*b3263ad3SIngo Weinhold class BDecompressionParameters;
27*b3263ad3SIngo Weinhold 
28*b3263ad3SIngo Weinhold 
29ad6a8dbeSOliver Tappe namespace BPackageKit {
30ad6a8dbeSOliver Tappe 
31ad6a8dbeSOliver Tappe namespace BHPKG {
32ad6a8dbeSOliver Tappe 
33ad6a8dbeSOliver Tappe 
3446122852SIngo Weinhold class BAbstractBufferedDataReader;
35ad6a8dbeSOliver Tappe class BErrorOutput;
36ad6a8dbeSOliver Tappe 
37ad6a8dbeSOliver Tappe 
38ad6a8dbeSOliver Tappe namespace BPrivate {
39ad6a8dbeSOliver Tappe 
40ad6a8dbeSOliver Tappe 
411f633814SIngo Weinhold class PackageFileHeapReader;
42ad6a8dbeSOliver Tappe 
43ad6a8dbeSOliver Tappe 
441f633814SIngo Weinhold struct PackageFileSection {
45ad6a8dbeSOliver Tappe 	uint32			uncompressedLength;
46ad6a8dbeSOliver Tappe 	uint8*			data;
47ad6a8dbeSOliver Tappe 	uint64			offset;
48ad6a8dbeSOliver Tappe 	uint64			currentOffset;
49ad6a8dbeSOliver Tappe 	uint64			stringsLength;
50ad6a8dbeSOliver Tappe 	uint64			stringsCount;
51ad6a8dbeSOliver Tappe 	char**			strings;
52ad6a8dbeSOliver Tappe 	const char*		name;
53ad6a8dbeSOliver Tappe 
541f633814SIngo Weinhold 	PackageFileSection(const char* _name)
55ad6a8dbeSOliver Tappe 		:
56ad6a8dbeSOliver Tappe 		data(NULL),
57ad6a8dbeSOliver Tappe 		strings(NULL),
58ad6a8dbeSOliver Tappe 		name(_name)
59ad6a8dbeSOliver Tappe 	{
60ad6a8dbeSOliver Tappe 	}
61ad6a8dbeSOliver Tappe 
621f633814SIngo Weinhold 	~PackageFileSection()
63ad6a8dbeSOliver Tappe 	{
64ad6a8dbeSOliver Tappe 		delete[] strings;
65ad6a8dbeSOliver Tappe 		delete[] data;
66ad6a8dbeSOliver Tappe 	}
67ad6a8dbeSOliver Tappe };
68ad6a8dbeSOliver Tappe 
691f633814SIngo Weinhold 
701f633814SIngo Weinhold class ReaderImplBase {
71e07b8bd2SIngo Weinhold public:
72e07b8bd2SIngo Weinhold 	inline	const PackageFileSection& PackageAttributesSection() const
73e07b8bd2SIngo Weinhold 									{ return fPackageAttributesSection; }
74e07b8bd2SIngo Weinhold 
751f633814SIngo Weinhold protected:
761f633814SIngo Weinhold 								ReaderImplBase(const char* fileType,
771f633814SIngo Weinhold 									BErrorOutput* errorOutput);
781f633814SIngo Weinhold 	virtual						~ReaderImplBase();
791f633814SIngo Weinhold 
801f633814SIngo Weinhold 			int					FD() const;
811f633814SIngo Weinhold 
821f633814SIngo Weinhold 			BErrorOutput*		ErrorOutput() const;
831f633814SIngo Weinhold 
8447039b85SIngo Weinhold 			uint16				MinorFormatVersion() const
8547039b85SIngo Weinhold 									{ return fMinorFormatVersion; }
8647039b85SIngo Weinhold 
8746122852SIngo Weinhold 			uint64				UncompressedHeapSize() const;
8846122852SIngo Weinhold 
8946122852SIngo Weinhold 			PackageFileHeapReader* RawHeapReader() const
9046122852SIngo Weinhold 									{ return fRawHeapReader; }
9146122852SIngo Weinhold 			BAbstractBufferedDataReader* HeapReader() const
921f633814SIngo Weinhold 									{ return fHeapReader; }
9346122852SIngo Weinhold 									// equals RawHeapReader(), if uncached
9446122852SIngo Weinhold 
9546122852SIngo Weinhold 			BAbstractBufferedDataReader* DetachHeapReader(
9646122852SIngo Weinhold 									PackageFileHeapReader** _rawHeapReader
9746122852SIngo Weinhold 										= NULL);
9846122852SIngo Weinhold 									// Detaches both raw and (if applicable)
9946122852SIngo Weinhold 									// cached heap reader. The called gains
10046122852SIngo Weinhold 									// ownership. The FD may need to be set on
10146122852SIngo Weinhold 									// the raw heap reader, if it shall be used
10246122852SIngo Weinhold 									// after destroying this object and Init()
10346122852SIngo Weinhold 									// has been called with keepFD == true.
1041f633814SIngo Weinhold 
1051f633814SIngo Weinhold protected:
1061f633814SIngo Weinhold 			class AttributeHandlerContext;
1071f633814SIngo Weinhold 			class AttributeHandler;
1081f633814SIngo Weinhold 			class IgnoreAttributeHandler;
109fe707a23SIngo Weinhold 			class PackageInfoAttributeHandlerBase;
1101f633814SIngo Weinhold 			class PackageVersionAttributeHandler;
1111f633814SIngo Weinhold 			class PackageResolvableAttributeHandler;
1121f633814SIngo Weinhold 			class PackageResolvableExpressionAttributeHandler;
1134489c88bSIngo Weinhold 			class GlobalWritableFileInfoAttributeHandler;
114fe707a23SIngo Weinhold 			class UserSettingsFileInfoAttributeHandler;
1150f4e11e7SIngo Weinhold 			class UserAttributeHandler;
1161f633814SIngo Weinhold 			class PackageAttributeHandler;
1171f633814SIngo Weinhold 			class LowLevelAttributeHandler;
1181f633814SIngo Weinhold 
1191f633814SIngo Weinhold 			typedef BPackageAttributeValue AttributeValue;
120ad6a8dbeSOliver Tappe 			typedef SinglyLinkedList<AttributeHandler> AttributeHandlerList;
121ad6a8dbeSOliver Tappe 
122ad6a8dbeSOliver Tappe protected:
12379d5ddb7SIngo Weinhold 			template<typename Header, uint32 kMagic, uint16 kVersion,
12479d5ddb7SIngo Weinhold 				uint16 kMinorVersion>
125d59e0febSIngo Weinhold 			status_t			Init(int fd, bool keepFD, Header& header,
126d59e0febSIngo Weinhold 									uint32 flags);
1271f633814SIngo Weinhold 			status_t			InitHeapReader(uint32 compression,
1281f633814SIngo Weinhold 									uint32 chunkSize, off_t offset,
1291f633814SIngo Weinhold 									uint64 compressedSize,
1301f633814SIngo Weinhold 									uint64 uncompressedSize);
13146122852SIngo Weinhold 	virtual	status_t			CreateCachedHeapReader(
13246122852SIngo Weinhold 									PackageFileHeapReader* heapReader,
13346122852SIngo Weinhold 									BAbstractBufferedDataReader*&
13446122852SIngo Weinhold 										_cachedReader);
1351f633814SIngo Weinhold 			status_t			InitSection(PackageFileSection& section,
1361f633814SIngo Weinhold 									uint64 endOffset, uint64 length,
1371f633814SIngo Weinhold 									uint64 maxSaneLength, uint64 stringsLength,
1381f633814SIngo Weinhold 									uint64 stringsCount);
1391f633814SIngo Weinhold 			status_t			PrepareSection(PackageFileSection& section);
140ad6a8dbeSOliver Tappe 
141ad6a8dbeSOliver Tappe 			status_t			ParseStrings();
142ad6a8dbeSOliver Tappe 
143ad6a8dbeSOliver Tappe 			status_t			ParsePackageAttributesSection(
144ad6a8dbeSOliver Tappe 									AttributeHandlerContext* context,
145ad6a8dbeSOliver Tappe 									AttributeHandler* rootAttributeHandler);
146ad6a8dbeSOliver Tappe 			status_t			ParseAttributeTree(
14797aabbedSIngo Weinhold 									AttributeHandlerContext* context,
14897aabbedSIngo Weinhold 									bool& _sectionHandled);
149ad6a8dbeSOliver Tappe 
150ad6a8dbeSOliver Tappe 	virtual	status_t			ReadAttributeValue(uint8 type, uint8 encoding,
151ad6a8dbeSOliver Tappe 									AttributeValue& _value);
152ad6a8dbeSOliver Tappe 
153ad6a8dbeSOliver Tappe 			status_t			ReadUnsignedLEB128(uint64& _value);
154ad6a8dbeSOliver Tappe 
155ad6a8dbeSOliver Tappe 			status_t			ReadBuffer(off_t offset, void* buffer,
156ad6a8dbeSOliver Tappe 									size_t size);
1571f633814SIngo Weinhold 			status_t			ReadSection(const PackageFileSection& section);
158ad6a8dbeSOliver Tappe 
159ad6a8dbeSOliver Tappe 	inline	AttributeHandler*	CurrentAttributeHandler() const;
160ad6a8dbeSOliver Tappe 	inline	void				PushAttributeHandler(
161ad6a8dbeSOliver Tappe 									AttributeHandler* handler);
162ad6a8dbeSOliver Tappe 	inline	AttributeHandler*	PopAttributeHandler();
163ad6a8dbeSOliver Tappe 	inline	void				ClearAttributeHandlerStack();
164ad6a8dbeSOliver Tappe 
1651f633814SIngo Weinhold 	inline	PackageFileSection*	CurrentSection();
1661f633814SIngo Weinhold 	inline	void				SetCurrentSection(PackageFileSection* section);
167ad6a8dbeSOliver Tappe 
168ad6a8dbeSOliver Tappe protected:
1691f633814SIngo Weinhold 			PackageFileSection	fPackageAttributesSection;
170ad6a8dbeSOliver Tappe 
171ad6a8dbeSOliver Tappe private:
1721f633814SIngo Weinhold 			status_t			_Init(int fd, bool keepFD);
1731f633814SIngo Weinhold 
17497aabbedSIngo Weinhold 			status_t			_ParseAttributeTree(
17597aabbedSIngo Weinhold 									AttributeHandlerContext* context);
17697aabbedSIngo Weinhold 
177ad6a8dbeSOliver Tappe 	template<typename Type>
178ad6a8dbeSOliver Tappe 	inline	status_t			_Read(Type& _value);
179ad6a8dbeSOliver Tappe 
180ad6a8dbeSOliver Tappe 			status_t			_ReadSectionBuffer(void* buffer, size_t size);
181ad6a8dbeSOliver Tappe 
182ad6a8dbeSOliver Tappe 			status_t			_ReadAttribute(uint8& _id,
183ad6a8dbeSOliver Tappe 									AttributeValue& _value,
184ad6a8dbeSOliver Tappe 									bool* _hasChildren = NULL,
185ad6a8dbeSOliver Tappe 									uint64* _tag = NULL);
186ad6a8dbeSOliver Tappe 
187ad6a8dbeSOliver Tappe 			status_t			_ReadString(const char*& _string,
188ad6a8dbeSOliver Tappe 									size_t* _stringLength = NULL);
189ad6a8dbeSOliver Tappe 
190ad6a8dbeSOliver Tappe private:
1911f633814SIngo Weinhold 			const char*			fFileType;
192ad6a8dbeSOliver Tappe 			BErrorOutput*		fErrorOutput;
193ad6a8dbeSOliver Tappe 			int					fFD;
194ad6a8dbeSOliver Tappe 			bool				fOwnsFD;
19547039b85SIngo Weinhold 			uint16				fMinorFormatVersion;
19679d5ddb7SIngo Weinhold 			uint16				fCurrentMinorFormatVersion;
197ad6a8dbeSOliver Tappe 
19846122852SIngo Weinhold 			PackageFileHeapReader* fRawHeapReader;
19946122852SIngo Weinhold 			BAbstractBufferedDataReader* fHeapReader;
2001f633814SIngo Weinhold 
2011f633814SIngo Weinhold 			PackageFileSection*	fCurrentSection;
202ad6a8dbeSOliver Tappe 
203ad6a8dbeSOliver Tappe 			AttributeHandlerList fAttributeHandlerStack;
204ad6a8dbeSOliver Tappe };
205ad6a8dbeSOliver Tappe 
206ad6a8dbeSOliver Tappe 
2071f633814SIngo Weinhold // #pragma mark - attribute handlers
2081f633814SIngo Weinhold 
2091f633814SIngo Weinhold 
2101f633814SIngo Weinhold class ReaderImplBase::AttributeHandlerContext {
2111f633814SIngo Weinhold public:
2121f633814SIngo Weinhold 			BErrorOutput*			errorOutput;
2131f633814SIngo Weinhold 			union {
2141f633814SIngo Weinhold 				BPackageContentHandler*			packageContentHandler;
2151f633814SIngo Weinhold 				BLowLevelPackageContentHandler*	lowLevelHandler;
2161f633814SIngo Weinhold 			};
2171f633814SIngo Weinhold 			bool					hasLowLevelHandler;
21847039b85SIngo Weinhold 			bool					ignoreUnknownAttributes;
2191f633814SIngo Weinhold 
2201f633814SIngo Weinhold 			BHPKGPackageSectionID	section;
2211f633814SIngo Weinhold 
2221f633814SIngo Weinhold public:
2231f633814SIngo Weinhold 								AttributeHandlerContext(
2241f633814SIngo Weinhold 									BErrorOutput* errorOutput,
2251f633814SIngo Weinhold 									BPackageContentHandler*
2261f633814SIngo Weinhold 										packageContentHandler,
22747039b85SIngo Weinhold 									BHPKGPackageSectionID section,
22847039b85SIngo Weinhold 									bool ignoreUnknownAttributes);
2291f633814SIngo Weinhold 								AttributeHandlerContext(
2301f633814SIngo Weinhold 									BErrorOutput* errorOutput,
2311f633814SIngo Weinhold 									BLowLevelPackageContentHandler*
2321f633814SIngo Weinhold 										lowLevelHandler,
23347039b85SIngo Weinhold 									BHPKGPackageSectionID section,
23447039b85SIngo Weinhold 									bool ignoreUnknownAttributes);
2351f633814SIngo Weinhold 
2361f633814SIngo Weinhold 			void				ErrorOccurred();
2371f633814SIngo Weinhold };
2381f633814SIngo Weinhold 
2391f633814SIngo Weinhold 
2401f633814SIngo Weinhold class ReaderImplBase::AttributeHandler
2411f633814SIngo Weinhold 	: public SinglyLinkedListLinkImpl<AttributeHandler> {
2421f633814SIngo Weinhold public:
2431f633814SIngo Weinhold 	virtual						~AttributeHandler();
2441f633814SIngo Weinhold 
2451f633814SIngo Weinhold 			void				SetLevel(int level);
2461f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2471f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
2481f633814SIngo Weinhold 									const AttributeValue& value,
2491f633814SIngo Weinhold 									AttributeHandler** _handler);
2501f633814SIngo Weinhold 
2510a345af7SOliver Tappe 	virtual	status_t			NotifyDone(AttributeHandlerContext* context);
2520a345af7SOliver Tappe 
2531f633814SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
2541f633814SIngo Weinhold 
2551f633814SIngo Weinhold protected:
2561f633814SIngo Weinhold 			int					fLevel;
2571f633814SIngo Weinhold };
2581f633814SIngo Weinhold 
2591f633814SIngo Weinhold 
2601f633814SIngo Weinhold class ReaderImplBase::IgnoreAttributeHandler : public AttributeHandler {
2611f633814SIngo Weinhold };
2621f633814SIngo Weinhold 
2631f633814SIngo Weinhold 
264fe707a23SIngo Weinhold class ReaderImplBase::PackageInfoAttributeHandlerBase
265fe707a23SIngo Weinhold 	: public AttributeHandler {
2660a345af7SOliver Tappe private:
2670a345af7SOliver Tappe 	typedef	AttributeHandler	super;
268fe707a23SIngo Weinhold public:
269fe707a23SIngo Weinhold 								PackageInfoAttributeHandlerBase(
270fe707a23SIngo Weinhold 									BPackageInfoAttributeValue&
271fe707a23SIngo Weinhold 										packageInfoValue);
272fe707a23SIngo Weinhold 
2730a345af7SOliver Tappe 	virtual	status_t			NotifyDone(AttributeHandlerContext* context);
274fe707a23SIngo Weinhold 
275fe707a23SIngo Weinhold protected:
276fe707a23SIngo Weinhold 			BPackageInfoAttributeValue& fPackageInfoValue;
277fe707a23SIngo Weinhold };
278fe707a23SIngo Weinhold 
279fe707a23SIngo Weinhold 
280fe707a23SIngo Weinhold class ReaderImplBase::PackageVersionAttributeHandler
281fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
2820a345af7SOliver Tappe private:
2830a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
2841f633814SIngo Weinhold public:
2851f633814SIngo Weinhold 								PackageVersionAttributeHandler(
2861f633814SIngo Weinhold 									BPackageInfoAttributeValue&
2871f633814SIngo Weinhold 										packageInfoValue,
2881f633814SIngo Weinhold 									BPackageVersionData& versionData,
2891f633814SIngo Weinhold 									bool notify);
2901f633814SIngo Weinhold 
2911f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2921f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
2931f633814SIngo Weinhold 									const AttributeValue& value,
2941f633814SIngo Weinhold 									AttributeHandler** _handler);
2951f633814SIngo Weinhold 
2960a345af7SOliver Tappe 	virtual	status_t			NotifyDone(AttributeHandlerContext* context);
2971f633814SIngo Weinhold 
2981f633814SIngo Weinhold private:
2991f633814SIngo Weinhold 			BPackageVersionData& fPackageVersionData;
3001f633814SIngo Weinhold 			bool				fNotify;
3011f633814SIngo Weinhold };
3021f633814SIngo Weinhold 
3031f633814SIngo Weinhold 
3041f633814SIngo Weinhold class ReaderImplBase::PackageResolvableAttributeHandler
305fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3060a345af7SOliver Tappe private:
3070a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
3081f633814SIngo Weinhold public:
3091f633814SIngo Weinhold 								PackageResolvableAttributeHandler(
3101f633814SIngo Weinhold 									BPackageInfoAttributeValue&
3111f633814SIngo Weinhold 										packageInfoValue);
3121f633814SIngo Weinhold 
3131f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
3141f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3151f633814SIngo Weinhold 									const AttributeValue& value,
3161f633814SIngo Weinhold 									AttributeHandler** _handler);
3171f633814SIngo Weinhold };
3181f633814SIngo Weinhold 
3191f633814SIngo Weinhold 
3201f633814SIngo Weinhold class ReaderImplBase::PackageResolvableExpressionAttributeHandler
321fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3220a345af7SOliver Tappe private:
3230a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
3241f633814SIngo Weinhold public:
3251f633814SIngo Weinhold 								PackageResolvableExpressionAttributeHandler(
3261f633814SIngo Weinhold 									BPackageInfoAttributeValue&
3271f633814SIngo Weinhold 										packageInfoValue);
3281f633814SIngo Weinhold 
3291f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
3301f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3311f633814SIngo Weinhold 									const AttributeValue& value,
3321f633814SIngo Weinhold 									AttributeHandler** _handler);
333fe707a23SIngo Weinhold };
3341f633814SIngo Weinhold 
3351f633814SIngo Weinhold 
3364489c88bSIngo Weinhold class ReaderImplBase::GlobalWritableFileInfoAttributeHandler
337fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3380a345af7SOliver Tappe private:
3390a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
340fe707a23SIngo Weinhold public:
3414489c88bSIngo Weinhold 								GlobalWritableFileInfoAttributeHandler(
342fe707a23SIngo Weinhold 									BPackageInfoAttributeValue&
343fe707a23SIngo Weinhold 										packageInfoValue);
344fe707a23SIngo Weinhold 
345fe707a23SIngo Weinhold 	virtual	status_t			HandleAttribute(
346fe707a23SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
347fe707a23SIngo Weinhold 									const AttributeValue& value,
348fe707a23SIngo Weinhold 									AttributeHandler** _handler);
349fe707a23SIngo Weinhold };
350fe707a23SIngo Weinhold 
351fe707a23SIngo Weinhold 
352fe707a23SIngo Weinhold class ReaderImplBase::UserSettingsFileInfoAttributeHandler
353fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3540a345af7SOliver Tappe private:
3550a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
356fe707a23SIngo Weinhold public:
357fe707a23SIngo Weinhold 								UserSettingsFileInfoAttributeHandler(
358fe707a23SIngo Weinhold 									BPackageInfoAttributeValue&
359fe707a23SIngo Weinhold 										packageInfoValue);
360fe707a23SIngo Weinhold 
361fe707a23SIngo Weinhold 	virtual	status_t			HandleAttribute(
362fe707a23SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
363fe707a23SIngo Weinhold 									const AttributeValue& value,
364fe707a23SIngo Weinhold 									AttributeHandler** _handler);
3651f633814SIngo Weinhold };
3661f633814SIngo Weinhold 
3671f633814SIngo Weinhold 
3680f4e11e7SIngo Weinhold class ReaderImplBase::UserAttributeHandler
3690f4e11e7SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3700a345af7SOliver Tappe private:
3710a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
3720f4e11e7SIngo Weinhold public:
3730f4e11e7SIngo Weinhold 								UserAttributeHandler(
3740f4e11e7SIngo Weinhold 									BPackageInfoAttributeValue&
3750f4e11e7SIngo Weinhold 										packageInfoValue);
3760f4e11e7SIngo Weinhold 
3770f4e11e7SIngo Weinhold 	virtual	status_t			HandleAttribute(
3780f4e11e7SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3790f4e11e7SIngo Weinhold 									const AttributeValue& value,
3800f4e11e7SIngo Weinhold 									AttributeHandler** _handler);
3810f4e11e7SIngo Weinhold 
3820a345af7SOliver Tappe 	virtual	status_t			NotifyDone(AttributeHandlerContext* context);
3830f4e11e7SIngo Weinhold 
3840f4e11e7SIngo Weinhold private:
3850f4e11e7SIngo Weinhold 			Array<const char*>	fGroups;
3860f4e11e7SIngo Weinhold };
3870f4e11e7SIngo Weinhold 
3880f4e11e7SIngo Weinhold 
3891f633814SIngo Weinhold class ReaderImplBase::PackageAttributeHandler : public AttributeHandler {
3900a345af7SOliver Tappe private:
3910a345af7SOliver Tappe 	typedef	AttributeHandler	super;
3921f633814SIngo Weinhold public:
3931f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
3941f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3951f633814SIngo Weinhold 									const AttributeValue& value,
3961f633814SIngo Weinhold 									AttributeHandler** _handler);
3971f633814SIngo Weinhold 
3981f633814SIngo Weinhold private:
3991f633814SIngo Weinhold 			BPackageInfoAttributeValue fPackageInfoValue;
4001f633814SIngo Weinhold };
4011f633814SIngo Weinhold 
4021f633814SIngo Weinhold 
4031f633814SIngo Weinhold class ReaderImplBase::LowLevelAttributeHandler : public AttributeHandler {
4040a345af7SOliver Tappe private:
4050a345af7SOliver Tappe 	typedef	AttributeHandler	super;
4061f633814SIngo Weinhold public:
4071f633814SIngo Weinhold 								LowLevelAttributeHandler();
4081f633814SIngo Weinhold 								LowLevelAttributeHandler(uint8 id,
4091f633814SIngo Weinhold 									const BPackageAttributeValue& value,
4101f633814SIngo Weinhold 									void* parentToken, void* token);
4111f633814SIngo Weinhold 
4121f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
4131f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
4141f633814SIngo Weinhold 									const AttributeValue& value,
4151f633814SIngo Weinhold 									AttributeHandler** _handler);
4160a345af7SOliver Tappe 
4170a345af7SOliver Tappe 	virtual	status_t			NotifyDone(AttributeHandlerContext* context);
4181f633814SIngo Weinhold 
4191f633814SIngo Weinhold private:
4201f633814SIngo Weinhold 			void*				fParentToken;
4211f633814SIngo Weinhold 			void*				fToken;
4221f633814SIngo Weinhold 			uint8				fID;
4231f633814SIngo Weinhold 			AttributeValue		fValue;
4241f633814SIngo Weinhold };
4251f633814SIngo Weinhold 
4261f633814SIngo Weinhold 
4271f633814SIngo Weinhold // #pragma mark - template and inline methods
4281f633814SIngo Weinhold 
4291f633814SIngo Weinhold 
43079d5ddb7SIngo Weinhold template<typename Header, uint32 kMagic, uint16 kVersion, uint16 kMinorVersion>
4311f633814SIngo Weinhold status_t
432d59e0febSIngo Weinhold ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags)
4331f633814SIngo Weinhold {
4341f633814SIngo Weinhold 	status_t error = _Init(fd, keepFD);
4351f633814SIngo Weinhold 	if (error != B_OK)
4361f633814SIngo Weinhold 		return error;
4371f633814SIngo Weinhold 
4381f633814SIngo Weinhold 	// stat the file
4391f633814SIngo Weinhold 	struct stat st;
4401f633814SIngo Weinhold 	if (fstat(FD(), &st) < 0) {
4411f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Failed to access %s file: %s\n",
4421f633814SIngo Weinhold 			fFileType, strerror(errno));
4431f633814SIngo Weinhold 		return errno;
4441f633814SIngo Weinhold 	}
4451f633814SIngo Weinhold 
4461f633814SIngo Weinhold 	// read the header
4471f633814SIngo Weinhold 	if ((error = ReadBuffer(0, &header, sizeof(header))) != B_OK)
4481f633814SIngo Weinhold 		return error;
4491f633814SIngo Weinhold 
4501f633814SIngo Weinhold 	// check the header
4511f633814SIngo Weinhold 
4521f633814SIngo Weinhold 	// magic
4531f633814SIngo Weinhold 	if (B_BENDIAN_TO_HOST_INT32(header.magic) != kMagic) {
4541f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Invalid "
4551f633814SIngo Weinhold 			"magic\n", fFileType);
4561f633814SIngo Weinhold 		return B_BAD_DATA;
4571f633814SIngo Weinhold 	}
4581f633814SIngo Weinhold 
4591f633814SIngo Weinhold 	// version
4601f633814SIngo Weinhold 	if (B_BENDIAN_TO_HOST_INT16(header.version) != kVersion) {
461d59e0febSIngo Weinhold 		if ((flags & B_HPKG_READER_DONT_PRINT_VERSION_MISMATCH_MESSAGE) == 0) {
4621f633814SIngo Weinhold 			ErrorOutput()->PrintError("Error: Invalid/unsupported %s file "
4631f633814SIngo Weinhold 				"version (%d)\n", fFileType,
4641f633814SIngo Weinhold 				B_BENDIAN_TO_HOST_INT16(header.version));
465d59e0febSIngo Weinhold 		}
4661f633814SIngo Weinhold 		return B_MISMATCHED_VALUES;
4671f633814SIngo Weinhold 	}
4681f633814SIngo Weinhold 
46947039b85SIngo Weinhold 	fMinorFormatVersion = B_BENDIAN_TO_HOST_INT16(header.minor_version);
47079d5ddb7SIngo Weinhold 	fCurrentMinorFormatVersion = kMinorVersion;
47147039b85SIngo Weinhold 
4721f633814SIngo Weinhold 	// header size
4731f633814SIngo Weinhold 	uint64 heapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size);
4741f633814SIngo Weinhold 	if (heapOffset < (off_t)sizeof(header)) {
4751f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Invalid header "
4761f633814SIngo Weinhold 			"size (%" B_PRIu64 ")\n", fFileType, heapOffset);
4771f633814SIngo Weinhold 		return B_BAD_DATA;
4781f633814SIngo Weinhold 	}
4791f633814SIngo Weinhold 
4801f633814SIngo Weinhold 	// total size
4811f633814SIngo Weinhold 	uint64 totalSize = B_BENDIAN_TO_HOST_INT64(header.total_size);
4821f633814SIngo Weinhold 	if (totalSize != (uint64)st.st_size) {
4831f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Total size in "
4841f633814SIngo Weinhold 			"header (%" B_PRIu64 ") doesn't agree with total file size (%"
4851f633814SIngo Weinhold 			B_PRIdOFF ")\n", fFileType, totalSize, st.st_size);
4861f633814SIngo Weinhold 		return B_BAD_DATA;
4871f633814SIngo Weinhold 	}
4881f633814SIngo Weinhold 
4891f633814SIngo Weinhold 	// heap size
4901f633814SIngo Weinhold 	uint64 compressedHeapSize
4911f633814SIngo Weinhold 		= B_BENDIAN_TO_HOST_INT64(header.heap_size_compressed);
4921f633814SIngo Weinhold 	if (compressedHeapSize > totalSize
4931f633814SIngo Weinhold 		|| heapOffset > totalSize - compressedHeapSize) {
4941f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Heap size in "
4951f633814SIngo Weinhold 			"header (%" B_PRIu64 ") doesn't agree with total file size (%"
4961f633814SIngo Weinhold 			B_PRIu64 ") and heap offset (%" B_PRIu64 ")\n", fFileType,
4971f633814SIngo Weinhold 			compressedHeapSize, totalSize, heapOffset);
4981f633814SIngo Weinhold 		return B_BAD_DATA;
4991f633814SIngo Weinhold 	}
5001f633814SIngo Weinhold 
5011f633814SIngo Weinhold 	error = InitHeapReader(
50247039b85SIngo Weinhold 		B_BENDIAN_TO_HOST_INT16(header.heap_compression),
5031f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT32(header.heap_chunk_size), heapOffset,
5041f633814SIngo Weinhold 		compressedHeapSize,
5051f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT64(header.heap_size_uncompressed));
5061f633814SIngo Weinhold 	if (error != B_OK)
5071f633814SIngo Weinhold 		return error;
5081f633814SIngo Weinhold 
5091f633814SIngo Weinhold 	return B_OK;
5101f633814SIngo Weinhold }
5111f633814SIngo Weinhold 
5121f633814SIngo Weinhold 
513ad6a8dbeSOliver Tappe inline int
514ad6a8dbeSOliver Tappe ReaderImplBase::FD() const
515ad6a8dbeSOliver Tappe {
516ad6a8dbeSOliver Tappe 	return fFD;
517ad6a8dbeSOliver Tappe }
518ad6a8dbeSOliver Tappe 
519ad6a8dbeSOliver Tappe 
520ad6a8dbeSOliver Tappe inline BErrorOutput*
521ad6a8dbeSOliver Tappe ReaderImplBase::ErrorOutput() const
522ad6a8dbeSOliver Tappe {
523ad6a8dbeSOliver Tappe 	return fErrorOutput;
524ad6a8dbeSOliver Tappe }
525ad6a8dbeSOliver Tappe 
526ad6a8dbeSOliver Tappe 
5271f633814SIngo Weinhold PackageFileSection*
528ad6a8dbeSOliver Tappe ReaderImplBase::CurrentSection()
529ad6a8dbeSOliver Tappe {
530ad6a8dbeSOliver Tappe 	return fCurrentSection;
531ad6a8dbeSOliver Tappe }
532ad6a8dbeSOliver Tappe 
533ad6a8dbeSOliver Tappe 
534ad6a8dbeSOliver Tappe void
5351f633814SIngo Weinhold ReaderImplBase::SetCurrentSection(PackageFileSection* section)
536ad6a8dbeSOliver Tappe {
537ad6a8dbeSOliver Tappe 	fCurrentSection = section;
538ad6a8dbeSOliver Tappe }
539ad6a8dbeSOliver Tappe 
540ad6a8dbeSOliver Tappe 
541ad6a8dbeSOliver Tappe template<typename Type>
542ad6a8dbeSOliver Tappe status_t
543ad6a8dbeSOliver Tappe ReaderImplBase::_Read(Type& _value)
544ad6a8dbeSOliver Tappe {
545ad6a8dbeSOliver Tappe 	return _ReadSectionBuffer(&_value, sizeof(Type));
546ad6a8dbeSOliver Tappe }
547ad6a8dbeSOliver Tappe 
548ad6a8dbeSOliver Tappe 
549ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler*
550ad6a8dbeSOliver Tappe ReaderImplBase::CurrentAttributeHandler() const
551ad6a8dbeSOliver Tappe {
552ad6a8dbeSOliver Tappe 	return fAttributeHandlerStack.Head();
553ad6a8dbeSOliver Tappe }
554ad6a8dbeSOliver Tappe 
555ad6a8dbeSOliver Tappe 
556ad6a8dbeSOliver Tappe inline void
557ad6a8dbeSOliver Tappe ReaderImplBase::PushAttributeHandler(AttributeHandler* handler)
558ad6a8dbeSOliver Tappe {
559ad6a8dbeSOliver Tappe 	fAttributeHandlerStack.Add(handler);
560ad6a8dbeSOliver Tappe }
561ad6a8dbeSOliver Tappe 
562ad6a8dbeSOliver Tappe 
563ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler*
564ad6a8dbeSOliver Tappe ReaderImplBase::PopAttributeHandler()
565ad6a8dbeSOliver Tappe {
566ad6a8dbeSOliver Tappe 	return fAttributeHandlerStack.RemoveHead();
567ad6a8dbeSOliver Tappe }
568ad6a8dbeSOliver Tappe 
569ad6a8dbeSOliver Tappe 
570ad6a8dbeSOliver Tappe inline void
571ad6a8dbeSOliver Tappe ReaderImplBase::ClearAttributeHandlerStack()
572ad6a8dbeSOliver Tappe {
573ad6a8dbeSOliver Tappe 	fAttributeHandlerStack.MakeEmpty();
574ad6a8dbeSOliver Tappe }
575ad6a8dbeSOliver Tappe 
576ad6a8dbeSOliver Tappe 
577ad6a8dbeSOliver Tappe }	// namespace BPrivate
578ad6a8dbeSOliver Tappe 
579ad6a8dbeSOliver Tappe }	// namespace BHPKG
580ad6a8dbeSOliver Tappe 
581ad6a8dbeSOliver Tappe }	// namespace BPackageKit
582ad6a8dbeSOliver Tappe 
583ad6a8dbeSOliver Tappe 
584ad6a8dbeSOliver Tappe #endif	// _PACKAGE__HPKG__PRIVATE__READER_IMPL_BASE_H_
585