xref: /haiku/headers/private/package/hpkg/ReaderImplBase.h (revision 79d5ddb77bd498e2975ceed8360c06cf709ff618)
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 
16ad6a8dbeSOliver Tappe #include <util/SinglyLinkedList.h>
17ad6a8dbeSOliver Tappe 
18d03ac965SIngo Weinhold #include <package/hpkg/ErrorOutput.h>
19ad6a8dbeSOliver Tappe #include <package/hpkg/PackageAttributeValue.h>
20ad6a8dbeSOliver Tappe #include <package/hpkg/PackageContentHandler.h>
21ad6a8dbeSOliver Tappe #include <package/hpkg/PackageInfoAttributeValue.h>
22ad6a8dbeSOliver Tappe 
23ad6a8dbeSOliver Tappe 
24ad6a8dbeSOliver Tappe namespace BPackageKit {
25ad6a8dbeSOliver Tappe 
26ad6a8dbeSOliver Tappe namespace BHPKG {
27ad6a8dbeSOliver Tappe 
28ad6a8dbeSOliver Tappe 
2946122852SIngo Weinhold class BAbstractBufferedDataReader;
30ad6a8dbeSOliver Tappe class BErrorOutput;
31ad6a8dbeSOliver Tappe 
32ad6a8dbeSOliver Tappe 
33ad6a8dbeSOliver Tappe namespace BPrivate {
34ad6a8dbeSOliver Tappe 
35ad6a8dbeSOliver Tappe 
361f633814SIngo Weinhold class PackageFileHeapReader;
37ad6a8dbeSOliver Tappe 
38ad6a8dbeSOliver Tappe 
391f633814SIngo Weinhold struct PackageFileSection {
40ad6a8dbeSOliver Tappe 	uint32			uncompressedLength;
41ad6a8dbeSOliver Tappe 	uint8*			data;
42ad6a8dbeSOliver Tappe 	uint64			offset;
43ad6a8dbeSOliver Tappe 	uint64			currentOffset;
44ad6a8dbeSOliver Tappe 	uint64			stringsLength;
45ad6a8dbeSOliver Tappe 	uint64			stringsCount;
46ad6a8dbeSOliver Tappe 	char**			strings;
47ad6a8dbeSOliver Tappe 	const char*		name;
48ad6a8dbeSOliver Tappe 
491f633814SIngo Weinhold 	PackageFileSection(const char* _name)
50ad6a8dbeSOliver Tappe 		:
51ad6a8dbeSOliver Tappe 		data(NULL),
52ad6a8dbeSOliver Tappe 		strings(NULL),
53ad6a8dbeSOliver Tappe 		name(_name)
54ad6a8dbeSOliver Tappe 	{
55ad6a8dbeSOliver Tappe 	}
56ad6a8dbeSOliver Tappe 
571f633814SIngo Weinhold 	~PackageFileSection()
58ad6a8dbeSOliver Tappe 	{
59ad6a8dbeSOliver Tappe 		delete[] strings;
60ad6a8dbeSOliver Tappe 		delete[] data;
61ad6a8dbeSOliver Tappe 	}
62ad6a8dbeSOliver Tappe };
63ad6a8dbeSOliver Tappe 
641f633814SIngo Weinhold 
651f633814SIngo Weinhold class ReaderImplBase {
661f633814SIngo Weinhold protected:
671f633814SIngo Weinhold 								ReaderImplBase(const char* fileType,
681f633814SIngo Weinhold 									BErrorOutput* errorOutput);
691f633814SIngo Weinhold 	virtual						~ReaderImplBase();
701f633814SIngo Weinhold 
711f633814SIngo Weinhold 			int					FD() const;
721f633814SIngo Weinhold 
731f633814SIngo Weinhold 			BErrorOutput*		ErrorOutput() const;
741f633814SIngo Weinhold 
7547039b85SIngo Weinhold 			uint16				MinorFormatVersion() const
7647039b85SIngo Weinhold 									{ return fMinorFormatVersion; }
7747039b85SIngo Weinhold 
7846122852SIngo Weinhold 			uint64				UncompressedHeapSize() const;
7946122852SIngo Weinhold 
8046122852SIngo Weinhold 			PackageFileHeapReader* RawHeapReader() const
8146122852SIngo Weinhold 									{ return fRawHeapReader; }
8246122852SIngo Weinhold 			BAbstractBufferedDataReader* HeapReader() const
831f633814SIngo Weinhold 									{ return fHeapReader; }
8446122852SIngo Weinhold 									// equals RawHeapReader(), if uncached
8546122852SIngo Weinhold 
8646122852SIngo Weinhold 			BAbstractBufferedDataReader* DetachHeapReader(
8746122852SIngo Weinhold 									PackageFileHeapReader** _rawHeapReader
8846122852SIngo Weinhold 										= NULL);
8946122852SIngo Weinhold 									// Detaches both raw and (if applicable)
9046122852SIngo Weinhold 									// cached heap reader. The called gains
9146122852SIngo Weinhold 									// ownership. The FD may need to be set on
9246122852SIngo Weinhold 									// the raw heap reader, if it shall be used
9346122852SIngo Weinhold 									// after destroying this object and Init()
9446122852SIngo Weinhold 									// has been called with keepFD == true.
951f633814SIngo Weinhold 
961f633814SIngo Weinhold protected:
971f633814SIngo Weinhold 			class AttributeHandlerContext;
981f633814SIngo Weinhold 			class AttributeHandler;
991f633814SIngo Weinhold 			class IgnoreAttributeHandler;
100fe707a23SIngo Weinhold 			class PackageInfoAttributeHandlerBase;
1011f633814SIngo Weinhold 			class PackageVersionAttributeHandler;
1021f633814SIngo Weinhold 			class PackageResolvableAttributeHandler;
1031f633814SIngo Weinhold 			class PackageResolvableExpressionAttributeHandler;
104fe707a23SIngo Weinhold 			class GlobalSettingsFileInfoAttributeHandler;
105fe707a23SIngo Weinhold 			class UserSettingsFileInfoAttributeHandler;
1061f633814SIngo Weinhold 			class PackageAttributeHandler;
1071f633814SIngo Weinhold 			class LowLevelAttributeHandler;
1081f633814SIngo Weinhold 
1091f633814SIngo Weinhold 			typedef BPackageAttributeValue AttributeValue;
110ad6a8dbeSOliver Tappe 			typedef SinglyLinkedList<AttributeHandler> AttributeHandlerList;
111ad6a8dbeSOliver Tappe 
112ad6a8dbeSOliver Tappe protected:
113*79d5ddb7SIngo Weinhold 			template<typename Header, uint32 kMagic, uint16 kVersion,
114*79d5ddb7SIngo Weinhold 				uint16 kMinorVersion>
115d59e0febSIngo Weinhold 			status_t			Init(int fd, bool keepFD, Header& header,
116d59e0febSIngo Weinhold 									uint32 flags);
1171f633814SIngo Weinhold 			status_t			InitHeapReader(uint32 compression,
1181f633814SIngo Weinhold 									uint32 chunkSize, off_t offset,
1191f633814SIngo Weinhold 									uint64 compressedSize,
1201f633814SIngo Weinhold 									uint64 uncompressedSize);
12146122852SIngo Weinhold 	virtual	status_t			CreateCachedHeapReader(
12246122852SIngo Weinhold 									PackageFileHeapReader* heapReader,
12346122852SIngo Weinhold 									BAbstractBufferedDataReader*&
12446122852SIngo Weinhold 										_cachedReader);
1251f633814SIngo Weinhold 			status_t			InitSection(PackageFileSection& section,
1261f633814SIngo Weinhold 									uint64 endOffset, uint64 length,
1271f633814SIngo Weinhold 									uint64 maxSaneLength, uint64 stringsLength,
1281f633814SIngo Weinhold 									uint64 stringsCount);
1291f633814SIngo Weinhold 			status_t			PrepareSection(PackageFileSection& section);
130ad6a8dbeSOliver Tappe 
131ad6a8dbeSOliver Tappe 			status_t			ParseStrings();
132ad6a8dbeSOliver Tappe 
133ad6a8dbeSOliver Tappe 			status_t			ParsePackageAttributesSection(
134ad6a8dbeSOliver Tappe 									AttributeHandlerContext* context,
135ad6a8dbeSOliver Tappe 									AttributeHandler* rootAttributeHandler);
136ad6a8dbeSOliver Tappe 			status_t			ParseAttributeTree(
13797aabbedSIngo Weinhold 									AttributeHandlerContext* context,
13897aabbedSIngo Weinhold 									bool& _sectionHandled);
139ad6a8dbeSOliver Tappe 
140ad6a8dbeSOliver Tappe 	virtual	status_t			ReadAttributeValue(uint8 type, uint8 encoding,
141ad6a8dbeSOliver Tappe 									AttributeValue& _value);
142ad6a8dbeSOliver Tappe 
143ad6a8dbeSOliver Tappe 			status_t			ReadUnsignedLEB128(uint64& _value);
144ad6a8dbeSOliver Tappe 
145ad6a8dbeSOliver Tappe 			status_t			ReadBuffer(off_t offset, void* buffer,
146ad6a8dbeSOliver Tappe 									size_t size);
1471f633814SIngo Weinhold 			status_t			ReadSection(const PackageFileSection& section);
148ad6a8dbeSOliver Tappe 
149ad6a8dbeSOliver Tappe 	inline	AttributeHandler*	CurrentAttributeHandler() const;
150ad6a8dbeSOliver Tappe 	inline	void				PushAttributeHandler(
151ad6a8dbeSOliver Tappe 									AttributeHandler* handler);
152ad6a8dbeSOliver Tappe 	inline	AttributeHandler*	PopAttributeHandler();
153ad6a8dbeSOliver Tappe 	inline	void				ClearAttributeHandlerStack();
154ad6a8dbeSOliver Tappe 
1551f633814SIngo Weinhold 	inline	PackageFileSection*	CurrentSection();
1561f633814SIngo Weinhold 	inline	void				SetCurrentSection(PackageFileSection* section);
157ad6a8dbeSOliver Tappe 
158ad6a8dbeSOliver Tappe protected:
1591f633814SIngo Weinhold 			PackageFileSection	fPackageAttributesSection;
160ad6a8dbeSOliver Tappe 
161ad6a8dbeSOliver Tappe private:
1621f633814SIngo Weinhold 			status_t			_Init(int fd, bool keepFD);
1631f633814SIngo Weinhold 
16497aabbedSIngo Weinhold 			status_t			_ParseAttributeTree(
16597aabbedSIngo Weinhold 									AttributeHandlerContext* context);
16697aabbedSIngo Weinhold 
167ad6a8dbeSOliver Tappe 	template<typename Type>
168ad6a8dbeSOliver Tappe 	inline	status_t			_Read(Type& _value);
169ad6a8dbeSOliver Tappe 
170ad6a8dbeSOliver Tappe 			status_t			_ReadSectionBuffer(void* buffer, size_t size);
171ad6a8dbeSOliver Tappe 
172ad6a8dbeSOliver Tappe 			status_t			_ReadAttribute(uint8& _id,
173ad6a8dbeSOliver Tappe 									AttributeValue& _value,
174ad6a8dbeSOliver Tappe 									bool* _hasChildren = NULL,
175ad6a8dbeSOliver Tappe 									uint64* _tag = NULL);
176ad6a8dbeSOliver Tappe 
177ad6a8dbeSOliver Tappe 			status_t			_ReadString(const char*& _string,
178ad6a8dbeSOliver Tappe 									size_t* _stringLength = NULL);
179ad6a8dbeSOliver Tappe 
180ad6a8dbeSOliver Tappe private:
1811f633814SIngo Weinhold 			const char*			fFileType;
182ad6a8dbeSOliver Tappe 			BErrorOutput*		fErrorOutput;
183ad6a8dbeSOliver Tappe 			int					fFD;
184ad6a8dbeSOliver Tappe 			bool				fOwnsFD;
18547039b85SIngo Weinhold 			uint16				fMinorFormatVersion;
186*79d5ddb7SIngo Weinhold 			uint16				fCurrentMinorFormatVersion;
187ad6a8dbeSOliver Tappe 
18846122852SIngo Weinhold 			PackageFileHeapReader* fRawHeapReader;
18946122852SIngo Weinhold 			BAbstractBufferedDataReader* fHeapReader;
1901f633814SIngo Weinhold 
1911f633814SIngo Weinhold 			PackageFileSection*	fCurrentSection;
192ad6a8dbeSOliver Tappe 
193ad6a8dbeSOliver Tappe 			AttributeHandlerList fAttributeHandlerStack;
194ad6a8dbeSOliver Tappe 
195ad6a8dbeSOliver Tappe 			uint8*				fScratchBuffer;
196ad6a8dbeSOliver Tappe 			size_t				fScratchBufferSize;
197ad6a8dbeSOliver Tappe };
198ad6a8dbeSOliver Tappe 
199ad6a8dbeSOliver Tappe 
2001f633814SIngo Weinhold // #pragma mark - attribute handlers
2011f633814SIngo Weinhold 
2021f633814SIngo Weinhold 
2031f633814SIngo Weinhold class ReaderImplBase::AttributeHandlerContext {
2041f633814SIngo Weinhold public:
2051f633814SIngo Weinhold 			BErrorOutput*			errorOutput;
2061f633814SIngo Weinhold 			union {
2071f633814SIngo Weinhold 				BPackageContentHandler*			packageContentHandler;
2081f633814SIngo Weinhold 				BLowLevelPackageContentHandler*	lowLevelHandler;
2091f633814SIngo Weinhold 			};
2101f633814SIngo Weinhold 			bool					hasLowLevelHandler;
21147039b85SIngo Weinhold 			bool					ignoreUnknownAttributes;
2121f633814SIngo Weinhold 
2131f633814SIngo Weinhold 			BHPKGPackageSectionID	section;
2141f633814SIngo Weinhold 
2151f633814SIngo Weinhold public:
2161f633814SIngo Weinhold 								AttributeHandlerContext(
2171f633814SIngo Weinhold 									BErrorOutput* errorOutput,
2181f633814SIngo Weinhold 									BPackageContentHandler*
2191f633814SIngo Weinhold 										packageContentHandler,
22047039b85SIngo Weinhold 									BHPKGPackageSectionID section,
22147039b85SIngo Weinhold 									bool ignoreUnknownAttributes);
2221f633814SIngo Weinhold 								AttributeHandlerContext(
2231f633814SIngo Weinhold 									BErrorOutput* errorOutput,
2241f633814SIngo Weinhold 									BLowLevelPackageContentHandler*
2251f633814SIngo Weinhold 										lowLevelHandler,
22647039b85SIngo Weinhold 									BHPKGPackageSectionID section,
22747039b85SIngo Weinhold 									bool ignoreUnknownAttributes);
2281f633814SIngo Weinhold 
2291f633814SIngo Weinhold 			void				ErrorOccurred();
2301f633814SIngo Weinhold };
2311f633814SIngo Weinhold 
2321f633814SIngo Weinhold 
2331f633814SIngo Weinhold class ReaderImplBase::AttributeHandler
2341f633814SIngo Weinhold 	: public SinglyLinkedListLinkImpl<AttributeHandler> {
2351f633814SIngo Weinhold public:
2361f633814SIngo Weinhold 	virtual						~AttributeHandler();
2371f633814SIngo Weinhold 
2381f633814SIngo Weinhold 			void				SetLevel(int level);
2391f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2401f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
2411f633814SIngo Weinhold 									const AttributeValue& value,
2421f633814SIngo Weinhold 									AttributeHandler** _handler);
2431f633814SIngo Weinhold 
2441f633814SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
2451f633814SIngo Weinhold 
2461f633814SIngo Weinhold protected:
2471f633814SIngo Weinhold 			int					fLevel;
2481f633814SIngo Weinhold };
2491f633814SIngo Weinhold 
2501f633814SIngo Weinhold 
2511f633814SIngo Weinhold class ReaderImplBase::IgnoreAttributeHandler : public AttributeHandler {
2521f633814SIngo Weinhold };
2531f633814SIngo Weinhold 
2541f633814SIngo Weinhold 
255fe707a23SIngo Weinhold class ReaderImplBase::PackageInfoAttributeHandlerBase
256fe707a23SIngo Weinhold 	: public AttributeHandler {
257fe707a23SIngo Weinhold public:
258fe707a23SIngo Weinhold 								PackageInfoAttributeHandlerBase(
259fe707a23SIngo Weinhold 									BPackageInfoAttributeValue&
260fe707a23SIngo Weinhold 										packageInfoValue);
261fe707a23SIngo Weinhold 
262fe707a23SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
263fe707a23SIngo Weinhold 
264fe707a23SIngo Weinhold protected:
265fe707a23SIngo Weinhold 			BPackageInfoAttributeValue& fPackageInfoValue;
266fe707a23SIngo Weinhold };
267fe707a23SIngo Weinhold 
268fe707a23SIngo Weinhold 
269fe707a23SIngo Weinhold class ReaderImplBase::PackageVersionAttributeHandler
270fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
2711f633814SIngo Weinhold public:
2721f633814SIngo Weinhold 								PackageVersionAttributeHandler(
2731f633814SIngo Weinhold 									BPackageInfoAttributeValue&
2741f633814SIngo Weinhold 										packageInfoValue,
2751f633814SIngo Weinhold 									BPackageVersionData& versionData,
2761f633814SIngo Weinhold 									bool notify);
2771f633814SIngo Weinhold 
2781f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2791f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
2801f633814SIngo Weinhold 									const AttributeValue& value,
2811f633814SIngo Weinhold 									AttributeHandler** _handler);
2821f633814SIngo Weinhold 
2831f633814SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
2841f633814SIngo Weinhold 
2851f633814SIngo Weinhold private:
2861f633814SIngo Weinhold 			BPackageVersionData& fPackageVersionData;
2871f633814SIngo Weinhold 			bool				fNotify;
2881f633814SIngo Weinhold };
2891f633814SIngo Weinhold 
2901f633814SIngo Weinhold 
2911f633814SIngo Weinhold class ReaderImplBase::PackageResolvableAttributeHandler
292fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
2931f633814SIngo Weinhold public:
2941f633814SIngo Weinhold 								PackageResolvableAttributeHandler(
2951f633814SIngo Weinhold 									BPackageInfoAttributeValue&
2961f633814SIngo Weinhold 										packageInfoValue);
2971f633814SIngo Weinhold 
2981f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2991f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3001f633814SIngo Weinhold 									const AttributeValue& value,
3011f633814SIngo Weinhold 									AttributeHandler** _handler);
3021f633814SIngo Weinhold };
3031f633814SIngo Weinhold 
3041f633814SIngo Weinhold 
3051f633814SIngo Weinhold class ReaderImplBase::PackageResolvableExpressionAttributeHandler
306fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3071f633814SIngo Weinhold public:
3081f633814SIngo Weinhold 								PackageResolvableExpressionAttributeHandler(
3091f633814SIngo Weinhold 									BPackageInfoAttributeValue&
3101f633814SIngo Weinhold 										packageInfoValue);
3111f633814SIngo Weinhold 
3121f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
3131f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3141f633814SIngo Weinhold 									const AttributeValue& value,
3151f633814SIngo Weinhold 									AttributeHandler** _handler);
316fe707a23SIngo Weinhold };
3171f633814SIngo Weinhold 
3181f633814SIngo Weinhold 
319fe707a23SIngo Weinhold class ReaderImplBase::GlobalSettingsFileInfoAttributeHandler
320fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
321fe707a23SIngo Weinhold public:
322fe707a23SIngo Weinhold 								GlobalSettingsFileInfoAttributeHandler(
323fe707a23SIngo Weinhold 									BPackageInfoAttributeValue&
324fe707a23SIngo Weinhold 										packageInfoValue);
325fe707a23SIngo Weinhold 
326fe707a23SIngo Weinhold 	virtual	status_t			HandleAttribute(
327fe707a23SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
328fe707a23SIngo Weinhold 									const AttributeValue& value,
329fe707a23SIngo Weinhold 									AttributeHandler** _handler);
330fe707a23SIngo Weinhold };
331fe707a23SIngo Weinhold 
332fe707a23SIngo Weinhold 
333fe707a23SIngo Weinhold class ReaderImplBase::UserSettingsFileInfoAttributeHandler
334fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
335fe707a23SIngo Weinhold public:
336fe707a23SIngo Weinhold 								UserSettingsFileInfoAttributeHandler(
337fe707a23SIngo Weinhold 									BPackageInfoAttributeValue&
338fe707a23SIngo Weinhold 										packageInfoValue);
339fe707a23SIngo Weinhold 
340fe707a23SIngo Weinhold 	virtual	status_t			HandleAttribute(
341fe707a23SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
342fe707a23SIngo Weinhold 									const AttributeValue& value,
343fe707a23SIngo Weinhold 									AttributeHandler** _handler);
3441f633814SIngo Weinhold };
3451f633814SIngo Weinhold 
3461f633814SIngo Weinhold 
3471f633814SIngo Weinhold class ReaderImplBase::PackageAttributeHandler : public AttributeHandler {
3481f633814SIngo Weinhold public:
3491f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
3501f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3511f633814SIngo Weinhold 									const AttributeValue& value,
3521f633814SIngo Weinhold 									AttributeHandler** _handler);
3531f633814SIngo Weinhold 
3541f633814SIngo Weinhold private:
3551f633814SIngo Weinhold 			BPackageInfoAttributeValue fPackageInfoValue;
3561f633814SIngo Weinhold };
3571f633814SIngo Weinhold 
3581f633814SIngo Weinhold 
3591f633814SIngo Weinhold class ReaderImplBase::LowLevelAttributeHandler : public AttributeHandler {
3601f633814SIngo Weinhold public:
3611f633814SIngo Weinhold 								LowLevelAttributeHandler();
3621f633814SIngo Weinhold 								LowLevelAttributeHandler(uint8 id,
3631f633814SIngo Weinhold 									const BPackageAttributeValue& value,
3641f633814SIngo Weinhold 									void* parentToken, void* token);
3651f633814SIngo Weinhold 
3661f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
3671f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3681f633814SIngo Weinhold 									const AttributeValue& value,
3691f633814SIngo Weinhold 									AttributeHandler** _handler);
3701f633814SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
3711f633814SIngo Weinhold 
3721f633814SIngo Weinhold private:
3731f633814SIngo Weinhold 			void*				fParentToken;
3741f633814SIngo Weinhold 			void*				fToken;
3751f633814SIngo Weinhold 			uint8				fID;
3761f633814SIngo Weinhold 			AttributeValue		fValue;
3771f633814SIngo Weinhold };
3781f633814SIngo Weinhold 
3791f633814SIngo Weinhold 
3801f633814SIngo Weinhold // #pragma mark - template and inline methods
3811f633814SIngo Weinhold 
3821f633814SIngo Weinhold 
383*79d5ddb7SIngo Weinhold template<typename Header, uint32 kMagic, uint16 kVersion, uint16 kMinorVersion>
3841f633814SIngo Weinhold status_t
385d59e0febSIngo Weinhold ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags)
3861f633814SIngo Weinhold {
3871f633814SIngo Weinhold 	status_t error = _Init(fd, keepFD);
3881f633814SIngo Weinhold 	if (error != B_OK)
3891f633814SIngo Weinhold 		return error;
3901f633814SIngo Weinhold 
3911f633814SIngo Weinhold 	// stat the file
3921f633814SIngo Weinhold 	struct stat st;
3931f633814SIngo Weinhold 	if (fstat(FD(), &st) < 0) {
3941f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Failed to access %s file: %s\n",
3951f633814SIngo Weinhold 			fFileType, strerror(errno));
3961f633814SIngo Weinhold 		return errno;
3971f633814SIngo Weinhold 	}
3981f633814SIngo Weinhold 
3991f633814SIngo Weinhold 	// read the header
4001f633814SIngo Weinhold 	if ((error = ReadBuffer(0, &header, sizeof(header))) != B_OK)
4011f633814SIngo Weinhold 		return error;
4021f633814SIngo Weinhold 
4031f633814SIngo Weinhold 	// check the header
4041f633814SIngo Weinhold 
4051f633814SIngo Weinhold 	// magic
4061f633814SIngo Weinhold 	if (B_BENDIAN_TO_HOST_INT32(header.magic) != kMagic) {
4071f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Invalid "
4081f633814SIngo Weinhold 			"magic\n", fFileType);
4091f633814SIngo Weinhold 		return B_BAD_DATA;
4101f633814SIngo Weinhold 	}
4111f633814SIngo Weinhold 
4121f633814SIngo Weinhold 	// version
4131f633814SIngo Weinhold 	if (B_BENDIAN_TO_HOST_INT16(header.version) != kVersion) {
414d59e0febSIngo Weinhold 		if ((flags & B_HPKG_READER_DONT_PRINT_VERSION_MISMATCH_MESSAGE) == 0) {
4151f633814SIngo Weinhold 			ErrorOutput()->PrintError("Error: Invalid/unsupported %s file "
4161f633814SIngo Weinhold 				"version (%d)\n", fFileType,
4171f633814SIngo Weinhold 				B_BENDIAN_TO_HOST_INT16(header.version));
418d59e0febSIngo Weinhold 		}
4191f633814SIngo Weinhold 		return B_MISMATCHED_VALUES;
4201f633814SIngo Weinhold 	}
4211f633814SIngo Weinhold 
42247039b85SIngo Weinhold 	fMinorFormatVersion = B_BENDIAN_TO_HOST_INT16(header.minor_version);
423*79d5ddb7SIngo Weinhold 	fCurrentMinorFormatVersion = kMinorVersion;
42447039b85SIngo Weinhold 
4251f633814SIngo Weinhold 	// header size
4261f633814SIngo Weinhold 	uint64 heapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size);
4271f633814SIngo Weinhold 	if (heapOffset < (off_t)sizeof(header)) {
4281f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Invalid header "
4291f633814SIngo Weinhold 			"size (%" B_PRIu64 ")\n", fFileType, heapOffset);
4301f633814SIngo Weinhold 		return B_BAD_DATA;
4311f633814SIngo Weinhold 	}
4321f633814SIngo Weinhold 
4331f633814SIngo Weinhold 	// total size
4341f633814SIngo Weinhold 	uint64 totalSize = B_BENDIAN_TO_HOST_INT64(header.total_size);
4351f633814SIngo Weinhold 	if (totalSize != (uint64)st.st_size) {
4361f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Total size in "
4371f633814SIngo Weinhold 			"header (%" B_PRIu64 ") doesn't agree with total file size (%"
4381f633814SIngo Weinhold 			B_PRIdOFF ")\n", fFileType, totalSize, st.st_size);
4391f633814SIngo Weinhold 		return B_BAD_DATA;
4401f633814SIngo Weinhold 	}
4411f633814SIngo Weinhold 
4421f633814SIngo Weinhold 	// heap size
4431f633814SIngo Weinhold 	uint64 compressedHeapSize
4441f633814SIngo Weinhold 		= B_BENDIAN_TO_HOST_INT64(header.heap_size_compressed);
4451f633814SIngo Weinhold 	if (compressedHeapSize > totalSize
4461f633814SIngo Weinhold 		|| heapOffset > totalSize - compressedHeapSize) {
4471f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Heap size in "
4481f633814SIngo Weinhold 			"header (%" B_PRIu64 ") doesn't agree with total file size (%"
4491f633814SIngo Weinhold 			B_PRIu64 ") and heap offset (%" B_PRIu64 ")\n", fFileType,
4501f633814SIngo Weinhold 			compressedHeapSize, totalSize, heapOffset);
4511f633814SIngo Weinhold 		return B_BAD_DATA;
4521f633814SIngo Weinhold 	}
4531f633814SIngo Weinhold 
4541f633814SIngo Weinhold 	error = InitHeapReader(
45547039b85SIngo Weinhold 		B_BENDIAN_TO_HOST_INT16(header.heap_compression),
4561f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT32(header.heap_chunk_size), heapOffset,
4571f633814SIngo Weinhold 		compressedHeapSize,
4581f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT64(header.heap_size_uncompressed));
4591f633814SIngo Weinhold 	if (error != B_OK)
4601f633814SIngo Weinhold 		return error;
4611f633814SIngo Weinhold 
4621f633814SIngo Weinhold 	return B_OK;
4631f633814SIngo Weinhold }
4641f633814SIngo Weinhold 
4651f633814SIngo Weinhold 
466ad6a8dbeSOliver Tappe inline int
467ad6a8dbeSOliver Tappe ReaderImplBase::FD() const
468ad6a8dbeSOliver Tappe {
469ad6a8dbeSOliver Tappe 	return fFD;
470ad6a8dbeSOliver Tappe }
471ad6a8dbeSOliver Tappe 
472ad6a8dbeSOliver Tappe 
473ad6a8dbeSOliver Tappe inline BErrorOutput*
474ad6a8dbeSOliver Tappe ReaderImplBase::ErrorOutput() const
475ad6a8dbeSOliver Tappe {
476ad6a8dbeSOliver Tappe 	return fErrorOutput;
477ad6a8dbeSOliver Tappe }
478ad6a8dbeSOliver Tappe 
479ad6a8dbeSOliver Tappe 
4801f633814SIngo Weinhold PackageFileSection*
481ad6a8dbeSOliver Tappe ReaderImplBase::CurrentSection()
482ad6a8dbeSOliver Tappe {
483ad6a8dbeSOliver Tappe 	return fCurrentSection;
484ad6a8dbeSOliver Tappe }
485ad6a8dbeSOliver Tappe 
486ad6a8dbeSOliver Tappe 
487ad6a8dbeSOliver Tappe void
4881f633814SIngo Weinhold ReaderImplBase::SetCurrentSection(PackageFileSection* section)
489ad6a8dbeSOliver Tappe {
490ad6a8dbeSOliver Tappe 	fCurrentSection = section;
491ad6a8dbeSOliver Tappe }
492ad6a8dbeSOliver Tappe 
493ad6a8dbeSOliver Tappe 
494ad6a8dbeSOliver Tappe template<typename Type>
495ad6a8dbeSOliver Tappe status_t
496ad6a8dbeSOliver Tappe ReaderImplBase::_Read(Type& _value)
497ad6a8dbeSOliver Tappe {
498ad6a8dbeSOliver Tappe 	return _ReadSectionBuffer(&_value, sizeof(Type));
499ad6a8dbeSOliver Tappe }
500ad6a8dbeSOliver Tappe 
501ad6a8dbeSOliver Tappe 
502ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler*
503ad6a8dbeSOliver Tappe ReaderImplBase::CurrentAttributeHandler() const
504ad6a8dbeSOliver Tappe {
505ad6a8dbeSOliver Tappe 	return fAttributeHandlerStack.Head();
506ad6a8dbeSOliver Tappe }
507ad6a8dbeSOliver Tappe 
508ad6a8dbeSOliver Tappe 
509ad6a8dbeSOliver Tappe inline void
510ad6a8dbeSOliver Tappe ReaderImplBase::PushAttributeHandler(AttributeHandler* handler)
511ad6a8dbeSOliver Tappe {
512ad6a8dbeSOliver Tappe 	fAttributeHandlerStack.Add(handler);
513ad6a8dbeSOliver Tappe }
514ad6a8dbeSOliver Tappe 
515ad6a8dbeSOliver Tappe 
516ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler*
517ad6a8dbeSOliver Tappe ReaderImplBase::PopAttributeHandler()
518ad6a8dbeSOliver Tappe {
519ad6a8dbeSOliver Tappe 	return fAttributeHandlerStack.RemoveHead();
520ad6a8dbeSOliver Tappe }
521ad6a8dbeSOliver Tappe 
522ad6a8dbeSOliver Tappe 
523ad6a8dbeSOliver Tappe inline void
524ad6a8dbeSOliver Tappe ReaderImplBase::ClearAttributeHandlerStack()
525ad6a8dbeSOliver Tappe {
526ad6a8dbeSOliver Tappe 	fAttributeHandlerStack.MakeEmpty();
527ad6a8dbeSOliver Tappe }
528ad6a8dbeSOliver Tappe 
529ad6a8dbeSOliver Tappe 
530ad6a8dbeSOliver Tappe }	// namespace BPrivate
531ad6a8dbeSOliver Tappe 
532ad6a8dbeSOliver Tappe }	// namespace BHPKG
533ad6a8dbeSOliver Tappe 
534ad6a8dbeSOliver Tappe }	// namespace BPackageKit
535ad6a8dbeSOliver Tappe 
536ad6a8dbeSOliver Tappe 
537ad6a8dbeSOliver Tappe #endif	// _PACKAGE__HPKG__PRIVATE__READER_IMPL_BASE_H_
538