xref: /haiku/headers/private/package/hpkg/ReaderImplBase.h (revision e527b796319f21ca025f68e1964df140daa6de35)
1ad6a8dbeSOliver Tappe /*
2*e527b796SIngo Weinhold  * Copyright 2009-2014, 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>
14*e527b796SIngo Weinhold #include <DataIO.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 
25b3263ad3SIngo Weinhold class BCompressionAlgorithm;
26b3263ad3SIngo Weinhold class BDecompressionParameters;
27b3263ad3SIngo Weinhold 
28b3263ad3SIngo 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 
80*e527b796SIngo Weinhold 			BPositionIO*		File() 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(
96*e527b796SIngo Weinhold 									PackageFileHeapReader*& _rawHeapReader);
9746122852SIngo Weinhold 									// Detaches both raw and (if applicable)
9846122852SIngo Weinhold 									// cached heap reader. The called gains
99*e527b796SIngo Weinhold 									// ownership of both. The file may need to
100*e527b796SIngo Weinhold 									// be set on the raw heap reader, if it
101*e527b796SIngo Weinhold 									// shall be used after destroying this
102*e527b796SIngo Weinhold 									// object and Init() has been called with
103*e527b796SIngo Weinhold 									// keepFile == 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>
125*e527b796SIngo Weinhold 			status_t			Init(BPositionIO* file, bool keepFile,
126*e527b796SIngo Weinhold 									Header& header, 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:
172*e527b796SIngo Weinhold 			status_t			_Init(BPositionIO* file, bool keepFile);
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;
193*e527b796SIngo Weinhold 			BPositionIO*		fFile;
194*e527b796SIngo Weinhold 			bool				fOwnsFile;
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
432*e527b796SIngo Weinhold ReaderImplBase::Init(BPositionIO* file, bool keepFile, Header& header, uint32 flags)
4331f633814SIngo Weinhold {
434*e527b796SIngo Weinhold 	status_t error = _Init(file, keepFile);
4351f633814SIngo Weinhold 	if (error != B_OK)
4361f633814SIngo Weinhold 		return error;
4371f633814SIngo Weinhold 
438*e527b796SIngo Weinhold 	// get the file size
439*e527b796SIngo Weinhold 	off_t fileSize;
440*e527b796SIngo Weinhold 	error = fFile->GetSize(&fileSize);
441*e527b796SIngo Weinhold 	if (error != B_OK) {
442*e527b796SIngo Weinhold 		ErrorOutput()->PrintError("Error: Failed to get size of %s file: %s\n",
443*e527b796SIngo Weinhold 			fFileType, strerror(error));
4441f633814SIngo Weinhold 		return errno;
4451f633814SIngo Weinhold 	}
4461f633814SIngo Weinhold 
4471f633814SIngo Weinhold 	// read the header
4481f633814SIngo Weinhold 	if ((error = ReadBuffer(0, &header, sizeof(header))) != B_OK)
4491f633814SIngo Weinhold 		return error;
4501f633814SIngo Weinhold 
4511f633814SIngo Weinhold 	// check the header
4521f633814SIngo Weinhold 
4531f633814SIngo Weinhold 	// magic
4541f633814SIngo Weinhold 	if (B_BENDIAN_TO_HOST_INT32(header.magic) != kMagic) {
4551f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Invalid "
4561f633814SIngo Weinhold 			"magic\n", fFileType);
4571f633814SIngo Weinhold 		return B_BAD_DATA;
4581f633814SIngo Weinhold 	}
4591f633814SIngo Weinhold 
4601f633814SIngo Weinhold 	// version
4611f633814SIngo Weinhold 	if (B_BENDIAN_TO_HOST_INT16(header.version) != kVersion) {
462d59e0febSIngo Weinhold 		if ((flags & B_HPKG_READER_DONT_PRINT_VERSION_MISMATCH_MESSAGE) == 0) {
4631f633814SIngo Weinhold 			ErrorOutput()->PrintError("Error: Invalid/unsupported %s file "
4641f633814SIngo Weinhold 				"version (%d)\n", fFileType,
4651f633814SIngo Weinhold 				B_BENDIAN_TO_HOST_INT16(header.version));
466d59e0febSIngo Weinhold 		}
4671f633814SIngo Weinhold 		return B_MISMATCHED_VALUES;
4681f633814SIngo Weinhold 	}
4691f633814SIngo Weinhold 
47047039b85SIngo Weinhold 	fMinorFormatVersion = B_BENDIAN_TO_HOST_INT16(header.minor_version);
47179d5ddb7SIngo Weinhold 	fCurrentMinorFormatVersion = kMinorVersion;
47247039b85SIngo Weinhold 
4731f633814SIngo Weinhold 	// header size
4741f633814SIngo Weinhold 	uint64 heapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size);
4751f633814SIngo Weinhold 	if (heapOffset < (off_t)sizeof(header)) {
4761f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Invalid header "
4771f633814SIngo Weinhold 			"size (%" B_PRIu64 ")\n", fFileType, heapOffset);
4781f633814SIngo Weinhold 		return B_BAD_DATA;
4791f633814SIngo Weinhold 	}
4801f633814SIngo Weinhold 
4811f633814SIngo Weinhold 	// total size
4821f633814SIngo Weinhold 	uint64 totalSize = B_BENDIAN_TO_HOST_INT64(header.total_size);
483*e527b796SIngo Weinhold 	if (totalSize != (uint64)fileSize) {
4841f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Total size in "
4851f633814SIngo Weinhold 			"header (%" B_PRIu64 ") doesn't agree with total file size (%"
486*e527b796SIngo Weinhold 			B_PRIdOFF ")\n", fFileType, totalSize, fileSize);
4871f633814SIngo Weinhold 		return B_BAD_DATA;
4881f633814SIngo Weinhold 	}
4891f633814SIngo Weinhold 
4901f633814SIngo Weinhold 	// heap size
4911f633814SIngo Weinhold 	uint64 compressedHeapSize
4921f633814SIngo Weinhold 		= B_BENDIAN_TO_HOST_INT64(header.heap_size_compressed);
4931f633814SIngo Weinhold 	if (compressedHeapSize > totalSize
4941f633814SIngo Weinhold 		|| heapOffset > totalSize - compressedHeapSize) {
4951f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Heap size in "
4961f633814SIngo Weinhold 			"header (%" B_PRIu64 ") doesn't agree with total file size (%"
4971f633814SIngo Weinhold 			B_PRIu64 ") and heap offset (%" B_PRIu64 ")\n", fFileType,
4981f633814SIngo Weinhold 			compressedHeapSize, totalSize, heapOffset);
4991f633814SIngo Weinhold 		return B_BAD_DATA;
5001f633814SIngo Weinhold 	}
5011f633814SIngo Weinhold 
5021f633814SIngo Weinhold 	error = InitHeapReader(
50347039b85SIngo Weinhold 		B_BENDIAN_TO_HOST_INT16(header.heap_compression),
5041f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT32(header.heap_chunk_size), heapOffset,
5051f633814SIngo Weinhold 		compressedHeapSize,
5061f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT64(header.heap_size_uncompressed));
5071f633814SIngo Weinhold 	if (error != B_OK)
5081f633814SIngo Weinhold 		return error;
5091f633814SIngo Weinhold 
5101f633814SIngo Weinhold 	return B_OK;
5111f633814SIngo Weinhold }
5121f633814SIngo Weinhold 
5131f633814SIngo Weinhold 
514*e527b796SIngo Weinhold inline BPositionIO*
515*e527b796SIngo Weinhold ReaderImplBase::File() const
516ad6a8dbeSOliver Tappe {
517*e527b796SIngo Weinhold 	return fFile;
518ad6a8dbeSOliver Tappe }
519ad6a8dbeSOliver Tappe 
520ad6a8dbeSOliver Tappe 
521ad6a8dbeSOliver Tappe inline BErrorOutput*
522ad6a8dbeSOliver Tappe ReaderImplBase::ErrorOutput() const
523ad6a8dbeSOliver Tappe {
524ad6a8dbeSOliver Tappe 	return fErrorOutput;
525ad6a8dbeSOliver Tappe }
526ad6a8dbeSOliver Tappe 
527ad6a8dbeSOliver Tappe 
5281f633814SIngo Weinhold PackageFileSection*
529ad6a8dbeSOliver Tappe ReaderImplBase::CurrentSection()
530ad6a8dbeSOliver Tappe {
531ad6a8dbeSOliver Tappe 	return fCurrentSection;
532ad6a8dbeSOliver Tappe }
533ad6a8dbeSOliver Tappe 
534ad6a8dbeSOliver Tappe 
535ad6a8dbeSOliver Tappe void
5361f633814SIngo Weinhold ReaderImplBase::SetCurrentSection(PackageFileSection* section)
537ad6a8dbeSOliver Tappe {
538ad6a8dbeSOliver Tappe 	fCurrentSection = section;
539ad6a8dbeSOliver Tappe }
540ad6a8dbeSOliver Tappe 
541ad6a8dbeSOliver Tappe 
542ad6a8dbeSOliver Tappe template<typename Type>
543ad6a8dbeSOliver Tappe status_t
544ad6a8dbeSOliver Tappe ReaderImplBase::_Read(Type& _value)
545ad6a8dbeSOliver Tappe {
546ad6a8dbeSOliver Tappe 	return _ReadSectionBuffer(&_value, sizeof(Type));
547ad6a8dbeSOliver Tappe }
548ad6a8dbeSOliver Tappe 
549ad6a8dbeSOliver Tappe 
550ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler*
551ad6a8dbeSOliver Tappe ReaderImplBase::CurrentAttributeHandler() const
552ad6a8dbeSOliver Tappe {
553ad6a8dbeSOliver Tappe 	return fAttributeHandlerStack.Head();
554ad6a8dbeSOliver Tappe }
555ad6a8dbeSOliver Tappe 
556ad6a8dbeSOliver Tappe 
557ad6a8dbeSOliver Tappe inline void
558ad6a8dbeSOliver Tappe ReaderImplBase::PushAttributeHandler(AttributeHandler* handler)
559ad6a8dbeSOliver Tappe {
560ad6a8dbeSOliver Tappe 	fAttributeHandlerStack.Add(handler);
561ad6a8dbeSOliver Tappe }
562ad6a8dbeSOliver Tappe 
563ad6a8dbeSOliver Tappe 
564ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler*
565ad6a8dbeSOliver Tappe ReaderImplBase::PopAttributeHandler()
566ad6a8dbeSOliver Tappe {
567ad6a8dbeSOliver Tappe 	return fAttributeHandlerStack.RemoveHead();
568ad6a8dbeSOliver Tappe }
569ad6a8dbeSOliver Tappe 
570ad6a8dbeSOliver Tappe 
571ad6a8dbeSOliver Tappe inline void
572ad6a8dbeSOliver Tappe ReaderImplBase::ClearAttributeHandlerStack()
573ad6a8dbeSOliver Tappe {
574ad6a8dbeSOliver Tappe 	fAttributeHandlerStack.MakeEmpty();
575ad6a8dbeSOliver Tappe }
576ad6a8dbeSOliver Tappe 
577ad6a8dbeSOliver Tappe 
578ad6a8dbeSOliver Tappe }	// namespace BPrivate
579ad6a8dbeSOliver Tappe 
580ad6a8dbeSOliver Tappe }	// namespace BHPKG
581ad6a8dbeSOliver Tappe 
582ad6a8dbeSOliver Tappe }	// namespace BPackageKit
583ad6a8dbeSOliver Tappe 
584ad6a8dbeSOliver Tappe 
585ad6a8dbeSOliver Tappe #endif	// _PACKAGE__HPKG__PRIVATE__READER_IMPL_BASE_H_
586