xref: /haiku/headers/private/package/hpkg/ReaderImplBase.h (revision d03ac965a23ea05a1a771a4e80c5d15f7f042ce4)
1ad6a8dbeSOliver Tappe /*
2ad6a8dbeSOliver Tappe  * Copyright 2009, 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 
18*d03ac965SIngo 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 
29ad6a8dbeSOliver Tappe class BErrorOutput;
30ad6a8dbeSOliver Tappe 
31ad6a8dbeSOliver Tappe 
32ad6a8dbeSOliver Tappe namespace BPrivate {
33ad6a8dbeSOliver Tappe 
34ad6a8dbeSOliver Tappe 
351f633814SIngo Weinhold class PackageFileHeapReader;
36ad6a8dbeSOliver Tappe 
37ad6a8dbeSOliver Tappe 
381f633814SIngo Weinhold struct PackageFileSection {
39ad6a8dbeSOliver Tappe 	uint32			uncompressedLength;
40ad6a8dbeSOliver Tappe 	uint8*			data;
41ad6a8dbeSOliver Tappe 	uint64			offset;
42ad6a8dbeSOliver Tappe 	uint64			currentOffset;
43ad6a8dbeSOliver Tappe 	uint64			stringsLength;
44ad6a8dbeSOliver Tappe 	uint64			stringsCount;
45ad6a8dbeSOliver Tappe 	char**			strings;
46ad6a8dbeSOliver Tappe 	const char*		name;
47ad6a8dbeSOliver Tappe 
481f633814SIngo Weinhold 	PackageFileSection(const char* _name)
49ad6a8dbeSOliver Tappe 		:
50ad6a8dbeSOliver Tappe 		data(NULL),
51ad6a8dbeSOliver Tappe 		strings(NULL),
52ad6a8dbeSOliver Tappe 		name(_name)
53ad6a8dbeSOliver Tappe 	{
54ad6a8dbeSOliver Tappe 	}
55ad6a8dbeSOliver Tappe 
561f633814SIngo Weinhold 	~PackageFileSection()
57ad6a8dbeSOliver Tappe 	{
58ad6a8dbeSOliver Tappe 		delete[] strings;
59ad6a8dbeSOliver Tappe 		delete[] data;
60ad6a8dbeSOliver Tappe 	}
61ad6a8dbeSOliver Tappe };
62ad6a8dbeSOliver Tappe 
631f633814SIngo Weinhold 
641f633814SIngo Weinhold class ReaderImplBase {
651f633814SIngo Weinhold protected:
661f633814SIngo Weinhold 								ReaderImplBase(const char* fileType,
671f633814SIngo Weinhold 									BErrorOutput* errorOutput);
681f633814SIngo Weinhold 	virtual						~ReaderImplBase();
691f633814SIngo Weinhold 
701f633814SIngo Weinhold 			int					FD() const;
711f633814SIngo Weinhold 
721f633814SIngo Weinhold 			BErrorOutput*		ErrorOutput() const;
731f633814SIngo Weinhold 
741f633814SIngo Weinhold 			PackageFileHeapReader* HeapReader() const
751f633814SIngo Weinhold 									{ return fHeapReader; }
761f633814SIngo Weinhold 
771f633814SIngo Weinhold protected:
781f633814SIngo Weinhold 			class AttributeHandlerContext;
791f633814SIngo Weinhold 			class AttributeHandler;
801f633814SIngo Weinhold 			class IgnoreAttributeHandler;
811f633814SIngo Weinhold 			class PackageVersionAttributeHandler;
821f633814SIngo Weinhold 			class PackageResolvableAttributeHandler;
831f633814SIngo Weinhold 			class PackageResolvableExpressionAttributeHandler;
841f633814SIngo Weinhold 			class PackageAttributeHandler;
851f633814SIngo Weinhold 			class LowLevelAttributeHandler;
861f633814SIngo Weinhold 
871f633814SIngo Weinhold 			typedef BPackageAttributeValue AttributeValue;
88ad6a8dbeSOliver Tappe 			typedef SinglyLinkedList<AttributeHandler> AttributeHandlerList;
89ad6a8dbeSOliver Tappe 
90ad6a8dbeSOliver Tappe protected:
911f633814SIngo Weinhold 			template<typename Header, uint32 kMagic, uint16 kVersion>
921f633814SIngo Weinhold 			status_t			Init(int fd, bool keepFD, Header& header);
931f633814SIngo Weinhold 			status_t			InitHeapReader(uint32 compression,
941f633814SIngo Weinhold 									uint32 chunkSize, off_t offset,
951f633814SIngo Weinhold 									uint64 compressedSize,
961f633814SIngo Weinhold 									uint64 uncompressedSize);
971f633814SIngo Weinhold 			status_t			InitSection(PackageFileSection& section,
981f633814SIngo Weinhold 									uint64 endOffset, uint64 length,
991f633814SIngo Weinhold 									uint64 maxSaneLength, uint64 stringsLength,
1001f633814SIngo Weinhold 									uint64 stringsCount);
1011f633814SIngo Weinhold 			status_t			PrepareSection(PackageFileSection& section);
102ad6a8dbeSOliver Tappe 
103ad6a8dbeSOliver Tappe 			status_t			ParseStrings();
104ad6a8dbeSOliver Tappe 
105ad6a8dbeSOliver Tappe 			status_t			ParsePackageAttributesSection(
106ad6a8dbeSOliver Tappe 									AttributeHandlerContext* context,
107ad6a8dbeSOliver Tappe 									AttributeHandler* rootAttributeHandler);
108ad6a8dbeSOliver Tappe 			status_t			ParseAttributeTree(
10997aabbedSIngo Weinhold 									AttributeHandlerContext* context,
11097aabbedSIngo Weinhold 									bool& _sectionHandled);
111ad6a8dbeSOliver Tappe 
112ad6a8dbeSOliver Tappe 	virtual	status_t			ReadAttributeValue(uint8 type, uint8 encoding,
113ad6a8dbeSOliver Tappe 									AttributeValue& _value);
114ad6a8dbeSOliver Tappe 
115ad6a8dbeSOliver Tappe 			status_t			ReadUnsignedLEB128(uint64& _value);
116ad6a8dbeSOliver Tappe 
117ad6a8dbeSOliver Tappe 			status_t			ReadBuffer(off_t offset, void* buffer,
118ad6a8dbeSOliver Tappe 									size_t size);
1191f633814SIngo Weinhold 			status_t			ReadSection(const PackageFileSection& section);
120ad6a8dbeSOliver Tappe 
121ad6a8dbeSOliver Tappe 	inline	AttributeHandler*	CurrentAttributeHandler() const;
122ad6a8dbeSOliver Tappe 	inline	void				PushAttributeHandler(
123ad6a8dbeSOliver Tappe 									AttributeHandler* handler);
124ad6a8dbeSOliver Tappe 	inline	AttributeHandler*	PopAttributeHandler();
125ad6a8dbeSOliver Tappe 	inline	void				ClearAttributeHandlerStack();
126ad6a8dbeSOliver Tappe 
1271f633814SIngo Weinhold 	inline	PackageFileSection*	CurrentSection();
1281f633814SIngo Weinhold 	inline	void				SetCurrentSection(PackageFileSection* section);
129ad6a8dbeSOliver Tappe 
130ad6a8dbeSOliver Tappe protected:
1311f633814SIngo Weinhold 			PackageFileSection	fPackageAttributesSection;
132ad6a8dbeSOliver Tappe 
133ad6a8dbeSOliver Tappe private:
1341f633814SIngo Weinhold 			status_t			_Init(int fd, bool keepFD);
1351f633814SIngo Weinhold 
13697aabbedSIngo Weinhold 			status_t			_ParseAttributeTree(
13797aabbedSIngo Weinhold 									AttributeHandlerContext* context);
13897aabbedSIngo Weinhold 
139ad6a8dbeSOliver Tappe 	template<typename Type>
140ad6a8dbeSOliver Tappe 	inline	status_t			_Read(Type& _value);
141ad6a8dbeSOliver Tappe 
142ad6a8dbeSOliver Tappe 			status_t			_ReadSectionBuffer(void* buffer, size_t size);
143ad6a8dbeSOliver Tappe 
144ad6a8dbeSOliver Tappe 			status_t			_ReadAttribute(uint8& _id,
145ad6a8dbeSOliver Tappe 									AttributeValue& _value,
146ad6a8dbeSOliver Tappe 									bool* _hasChildren = NULL,
147ad6a8dbeSOliver Tappe 									uint64* _tag = NULL);
148ad6a8dbeSOliver Tappe 
149ad6a8dbeSOliver Tappe 			status_t			_ReadString(const char*& _string,
150ad6a8dbeSOliver Tappe 									size_t* _stringLength = NULL);
151ad6a8dbeSOliver Tappe 
152ad6a8dbeSOliver Tappe private:
1531f633814SIngo Weinhold 			const char*			fFileType;
154ad6a8dbeSOliver Tappe 			BErrorOutput*		fErrorOutput;
155ad6a8dbeSOliver Tappe 			int					fFD;
156ad6a8dbeSOliver Tappe 			bool				fOwnsFD;
157ad6a8dbeSOliver Tappe 
1581f633814SIngo Weinhold 			PackageFileHeapReader* fHeapReader;
1591f633814SIngo Weinhold 
1601f633814SIngo Weinhold 			PackageFileSection*	fCurrentSection;
161ad6a8dbeSOliver Tappe 
162ad6a8dbeSOliver Tappe 			AttributeHandlerList fAttributeHandlerStack;
163ad6a8dbeSOliver Tappe 
164ad6a8dbeSOliver Tappe 			uint8*				fScratchBuffer;
165ad6a8dbeSOliver Tappe 			size_t				fScratchBufferSize;
166ad6a8dbeSOliver Tappe };
167ad6a8dbeSOliver Tappe 
168ad6a8dbeSOliver Tappe 
1691f633814SIngo Weinhold // #pragma mark - attribute handlers
1701f633814SIngo Weinhold 
1711f633814SIngo Weinhold 
1721f633814SIngo Weinhold class ReaderImplBase::AttributeHandlerContext {
1731f633814SIngo Weinhold public:
1741f633814SIngo Weinhold 			BErrorOutput*			errorOutput;
1751f633814SIngo Weinhold 			union {
1761f633814SIngo Weinhold 				BPackageContentHandler*			packageContentHandler;
1771f633814SIngo Weinhold 				BLowLevelPackageContentHandler*	lowLevelHandler;
1781f633814SIngo Weinhold 			};
1791f633814SIngo Weinhold 			bool					hasLowLevelHandler;
1801f633814SIngo Weinhold 
1811f633814SIngo Weinhold 			BHPKGPackageSectionID	section;
1821f633814SIngo Weinhold 
1831f633814SIngo Weinhold public:
1841f633814SIngo Weinhold 								AttributeHandlerContext(
1851f633814SIngo Weinhold 									BErrorOutput* errorOutput,
1861f633814SIngo Weinhold 									BPackageContentHandler*
1871f633814SIngo Weinhold 										packageContentHandler,
1881f633814SIngo Weinhold 									BHPKGPackageSectionID section);
1891f633814SIngo Weinhold 								AttributeHandlerContext(
1901f633814SIngo Weinhold 									BErrorOutput* errorOutput,
1911f633814SIngo Weinhold 									BLowLevelPackageContentHandler*
1921f633814SIngo Weinhold 										lowLevelHandler,
1931f633814SIngo Weinhold 									BHPKGPackageSectionID section);
1941f633814SIngo Weinhold 
1951f633814SIngo Weinhold 			void				ErrorOccurred();
1961f633814SIngo Weinhold };
1971f633814SIngo Weinhold 
1981f633814SIngo Weinhold 
1991f633814SIngo Weinhold class ReaderImplBase::AttributeHandler
2001f633814SIngo Weinhold 	: public SinglyLinkedListLinkImpl<AttributeHandler> {
2011f633814SIngo Weinhold public:
2021f633814SIngo Weinhold 	virtual						~AttributeHandler();
2031f633814SIngo Weinhold 
2041f633814SIngo Weinhold 			void				SetLevel(int level);
2051f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2061f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
2071f633814SIngo Weinhold 									const AttributeValue& value,
2081f633814SIngo Weinhold 									AttributeHandler** _handler);
2091f633814SIngo Weinhold 
2101f633814SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
2111f633814SIngo Weinhold 
2121f633814SIngo Weinhold protected:
2131f633814SIngo Weinhold 			int					fLevel;
2141f633814SIngo Weinhold };
2151f633814SIngo Weinhold 
2161f633814SIngo Weinhold 
2171f633814SIngo Weinhold class ReaderImplBase::IgnoreAttributeHandler : public AttributeHandler {
2181f633814SIngo Weinhold };
2191f633814SIngo Weinhold 
2201f633814SIngo Weinhold 
2211f633814SIngo Weinhold class ReaderImplBase::PackageVersionAttributeHandler : public AttributeHandler {
2221f633814SIngo Weinhold public:
2231f633814SIngo Weinhold 								PackageVersionAttributeHandler(
2241f633814SIngo Weinhold 									BPackageInfoAttributeValue&
2251f633814SIngo Weinhold 										packageInfoValue,
2261f633814SIngo Weinhold 									BPackageVersionData& versionData,
2271f633814SIngo Weinhold 									bool notify);
2281f633814SIngo Weinhold 
2291f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2301f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
2311f633814SIngo Weinhold 									const AttributeValue& value,
2321f633814SIngo Weinhold 									AttributeHandler** _handler);
2331f633814SIngo Weinhold 
2341f633814SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
2351f633814SIngo Weinhold 
2361f633814SIngo Weinhold private:
2371f633814SIngo Weinhold 			BPackageInfoAttributeValue& fPackageInfoValue;
2381f633814SIngo Weinhold 			BPackageVersionData& fPackageVersionData;
2391f633814SIngo Weinhold 			bool				fNotify;
2401f633814SIngo Weinhold };
2411f633814SIngo Weinhold 
2421f633814SIngo Weinhold 
2431f633814SIngo Weinhold class ReaderImplBase::PackageResolvableAttributeHandler
2441f633814SIngo Weinhold 	: public AttributeHandler {
2451f633814SIngo Weinhold public:
2461f633814SIngo Weinhold 								PackageResolvableAttributeHandler(
2471f633814SIngo Weinhold 									BPackageInfoAttributeValue&
2481f633814SIngo Weinhold 										packageInfoValue);
2491f633814SIngo Weinhold 
2501f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2511f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
2521f633814SIngo Weinhold 									const AttributeValue& value,
2531f633814SIngo Weinhold 									AttributeHandler** _handler);
2541f633814SIngo Weinhold 
2551f633814SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
2561f633814SIngo Weinhold 
2571f633814SIngo Weinhold private:
2581f633814SIngo Weinhold 			BPackageInfoAttributeValue& fPackageInfoValue;
2591f633814SIngo Weinhold };
2601f633814SIngo Weinhold 
2611f633814SIngo Weinhold 
2621f633814SIngo Weinhold class ReaderImplBase::PackageResolvableExpressionAttributeHandler
2631f633814SIngo Weinhold 	: public AttributeHandler {
2641f633814SIngo Weinhold public:
2651f633814SIngo Weinhold 								PackageResolvableExpressionAttributeHandler(
2661f633814SIngo Weinhold 									BPackageInfoAttributeValue&
2671f633814SIngo Weinhold 										packageInfoValue);
2681f633814SIngo Weinhold 
2691f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2701f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
2711f633814SIngo Weinhold 									const AttributeValue& value,
2721f633814SIngo Weinhold 									AttributeHandler** _handler);
2731f633814SIngo Weinhold 
2741f633814SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
2751f633814SIngo Weinhold 
2761f633814SIngo Weinhold private:
2771f633814SIngo Weinhold 			BPackageInfoAttributeValue& fPackageInfoValue;
2781f633814SIngo Weinhold };
2791f633814SIngo Weinhold 
2801f633814SIngo Weinhold 
2811f633814SIngo Weinhold class ReaderImplBase::PackageAttributeHandler : public AttributeHandler {
2821f633814SIngo Weinhold public:
2831f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2841f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
2851f633814SIngo Weinhold 									const AttributeValue& value,
2861f633814SIngo Weinhold 									AttributeHandler** _handler);
2871f633814SIngo Weinhold 
2881f633814SIngo Weinhold private:
2891f633814SIngo Weinhold 			BPackageInfoAttributeValue fPackageInfoValue;
2901f633814SIngo Weinhold };
2911f633814SIngo Weinhold 
2921f633814SIngo Weinhold 
2931f633814SIngo Weinhold class ReaderImplBase::LowLevelAttributeHandler : public AttributeHandler {
2941f633814SIngo Weinhold public:
2951f633814SIngo Weinhold 								LowLevelAttributeHandler();
2961f633814SIngo Weinhold 								LowLevelAttributeHandler(uint8 id,
2971f633814SIngo Weinhold 									const BPackageAttributeValue& value,
2981f633814SIngo Weinhold 									void* parentToken, void* token);
2991f633814SIngo Weinhold 
3001f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
3011f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3021f633814SIngo Weinhold 									const AttributeValue& value,
3031f633814SIngo Weinhold 									AttributeHandler** _handler);
3041f633814SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
3051f633814SIngo Weinhold 
3061f633814SIngo Weinhold private:
3071f633814SIngo Weinhold 			void*				fParentToken;
3081f633814SIngo Weinhold 			void*				fToken;
3091f633814SIngo Weinhold 			uint8				fID;
3101f633814SIngo Weinhold 			AttributeValue		fValue;
3111f633814SIngo Weinhold };
3121f633814SIngo Weinhold 
3131f633814SIngo Weinhold 
3141f633814SIngo Weinhold // #pragma mark - template and inline methods
3151f633814SIngo Weinhold 
3161f633814SIngo Weinhold 
3171f633814SIngo Weinhold template<typename Header, uint32 kMagic, uint16 kVersion>
3181f633814SIngo Weinhold status_t
3191f633814SIngo Weinhold ReaderImplBase::Init(int fd, bool keepFD, Header& header)
3201f633814SIngo Weinhold {
3211f633814SIngo Weinhold 	status_t error = _Init(fd, keepFD);
3221f633814SIngo Weinhold 	if (error != B_OK)
3231f633814SIngo Weinhold 		return error;
3241f633814SIngo Weinhold 
3251f633814SIngo Weinhold 	// stat the file
3261f633814SIngo Weinhold 	struct stat st;
3271f633814SIngo Weinhold 	if (fstat(FD(), &st) < 0) {
3281f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Failed to access %s file: %s\n",
3291f633814SIngo Weinhold 			fFileType, strerror(errno));
3301f633814SIngo Weinhold 		return errno;
3311f633814SIngo Weinhold 	}
3321f633814SIngo Weinhold 
3331f633814SIngo Weinhold 	// read the header
3341f633814SIngo Weinhold 	if ((error = ReadBuffer(0, &header, sizeof(header))) != B_OK)
3351f633814SIngo Weinhold 		return error;
3361f633814SIngo Weinhold 
3371f633814SIngo Weinhold 	// check the header
3381f633814SIngo Weinhold 
3391f633814SIngo Weinhold 	// magic
3401f633814SIngo Weinhold 	if (B_BENDIAN_TO_HOST_INT32(header.magic) != kMagic) {
3411f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Invalid "
3421f633814SIngo Weinhold 			"magic\n", fFileType);
3431f633814SIngo Weinhold 		return B_BAD_DATA;
3441f633814SIngo Weinhold 	}
3451f633814SIngo Weinhold 
3461f633814SIngo Weinhold 	// version
3471f633814SIngo Weinhold 	if (B_BENDIAN_TO_HOST_INT16(header.version) != kVersion) {
3481f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid/unsupported %s file "
3491f633814SIngo Weinhold 			"version (%d)\n", fFileType,
3501f633814SIngo Weinhold 			B_BENDIAN_TO_HOST_INT16(header.version));
3511f633814SIngo Weinhold 		return B_MISMATCHED_VALUES;
3521f633814SIngo Weinhold 	}
3531f633814SIngo Weinhold 
3541f633814SIngo Weinhold 	// header size
3551f633814SIngo Weinhold 	uint64 heapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size);
3561f633814SIngo Weinhold 	if (heapOffset < (off_t)sizeof(header)) {
3571f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Invalid header "
3581f633814SIngo Weinhold 			"size (%" B_PRIu64 ")\n", fFileType, heapOffset);
3591f633814SIngo Weinhold 		return B_BAD_DATA;
3601f633814SIngo Weinhold 	}
3611f633814SIngo Weinhold 
3621f633814SIngo Weinhold 	// total size
3631f633814SIngo Weinhold 	uint64 totalSize = B_BENDIAN_TO_HOST_INT64(header.total_size);
3641f633814SIngo Weinhold 	if (totalSize != (uint64)st.st_size) {
3651f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Total size in "
3661f633814SIngo Weinhold 			"header (%" B_PRIu64 ") doesn't agree with total file size (%"
3671f633814SIngo Weinhold 			B_PRIdOFF ")\n", fFileType, totalSize, st.st_size);
3681f633814SIngo Weinhold 		return B_BAD_DATA;
3691f633814SIngo Weinhold 	}
3701f633814SIngo Weinhold 
3711f633814SIngo Weinhold 	// heap size
3721f633814SIngo Weinhold 	uint64 compressedHeapSize
3731f633814SIngo Weinhold 		= B_BENDIAN_TO_HOST_INT64(header.heap_size_compressed);
3741f633814SIngo Weinhold 	if (compressedHeapSize > totalSize
3751f633814SIngo Weinhold 		|| heapOffset > totalSize - compressedHeapSize) {
3761f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Heap size in "
3771f633814SIngo Weinhold 			"header (%" B_PRIu64 ") doesn't agree with total file size (%"
3781f633814SIngo Weinhold 			B_PRIu64 ") and heap offset (%" B_PRIu64 ")\n", fFileType,
3791f633814SIngo Weinhold 			compressedHeapSize, totalSize, heapOffset);
3801f633814SIngo Weinhold 		return B_BAD_DATA;
3811f633814SIngo Weinhold 	}
3821f633814SIngo Weinhold 
3831f633814SIngo Weinhold 	error = InitHeapReader(
3841f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT32(header.heap_compression),
3851f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT32(header.heap_chunk_size), heapOffset,
3861f633814SIngo Weinhold 		compressedHeapSize,
3871f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT64(header.heap_size_uncompressed));
3881f633814SIngo Weinhold 	if (error != B_OK)
3891f633814SIngo Weinhold 		return error;
3901f633814SIngo Weinhold 
3911f633814SIngo Weinhold 	return B_OK;
3921f633814SIngo Weinhold }
3931f633814SIngo Weinhold 
3941f633814SIngo Weinhold 
395ad6a8dbeSOliver Tappe inline int
396ad6a8dbeSOliver Tappe ReaderImplBase::FD() const
397ad6a8dbeSOliver Tappe {
398ad6a8dbeSOliver Tappe 	return fFD;
399ad6a8dbeSOliver Tappe }
400ad6a8dbeSOliver Tappe 
401ad6a8dbeSOliver Tappe 
402ad6a8dbeSOliver Tappe inline BErrorOutput*
403ad6a8dbeSOliver Tappe ReaderImplBase::ErrorOutput() const
404ad6a8dbeSOliver Tappe {
405ad6a8dbeSOliver Tappe 	return fErrorOutput;
406ad6a8dbeSOliver Tappe }
407ad6a8dbeSOliver Tappe 
408ad6a8dbeSOliver Tappe 
4091f633814SIngo Weinhold PackageFileSection*
410ad6a8dbeSOliver Tappe ReaderImplBase::CurrentSection()
411ad6a8dbeSOliver Tappe {
412ad6a8dbeSOliver Tappe 	return fCurrentSection;
413ad6a8dbeSOliver Tappe }
414ad6a8dbeSOliver Tappe 
415ad6a8dbeSOliver Tappe 
416ad6a8dbeSOliver Tappe void
4171f633814SIngo Weinhold ReaderImplBase::SetCurrentSection(PackageFileSection* section)
418ad6a8dbeSOliver Tappe {
419ad6a8dbeSOliver Tappe 	fCurrentSection = section;
420ad6a8dbeSOliver Tappe }
421ad6a8dbeSOliver Tappe 
422ad6a8dbeSOliver Tappe 
423ad6a8dbeSOliver Tappe template<typename Type>
424ad6a8dbeSOliver Tappe status_t
425ad6a8dbeSOliver Tappe ReaderImplBase::_Read(Type& _value)
426ad6a8dbeSOliver Tappe {
427ad6a8dbeSOliver Tappe 	return _ReadSectionBuffer(&_value, sizeof(Type));
428ad6a8dbeSOliver Tappe }
429ad6a8dbeSOliver Tappe 
430ad6a8dbeSOliver Tappe 
431ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler*
432ad6a8dbeSOliver Tappe ReaderImplBase::CurrentAttributeHandler() const
433ad6a8dbeSOliver Tappe {
434ad6a8dbeSOliver Tappe 	return fAttributeHandlerStack.Head();
435ad6a8dbeSOliver Tappe }
436ad6a8dbeSOliver Tappe 
437ad6a8dbeSOliver Tappe 
438ad6a8dbeSOliver Tappe inline void
439ad6a8dbeSOliver Tappe ReaderImplBase::PushAttributeHandler(AttributeHandler* handler)
440ad6a8dbeSOliver Tappe {
441ad6a8dbeSOliver Tappe 	fAttributeHandlerStack.Add(handler);
442ad6a8dbeSOliver Tappe }
443ad6a8dbeSOliver Tappe 
444ad6a8dbeSOliver Tappe 
445ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler*
446ad6a8dbeSOliver Tappe ReaderImplBase::PopAttributeHandler()
447ad6a8dbeSOliver Tappe {
448ad6a8dbeSOliver Tappe 	return fAttributeHandlerStack.RemoveHead();
449ad6a8dbeSOliver Tappe }
450ad6a8dbeSOliver Tappe 
451ad6a8dbeSOliver Tappe 
452ad6a8dbeSOliver Tappe inline void
453ad6a8dbeSOliver Tappe ReaderImplBase::ClearAttributeHandlerStack()
454ad6a8dbeSOliver Tappe {
455ad6a8dbeSOliver Tappe 	fAttributeHandlerStack.MakeEmpty();
456ad6a8dbeSOliver Tappe }
457ad6a8dbeSOliver Tappe 
458ad6a8dbeSOliver Tappe 
459ad6a8dbeSOliver Tappe }	// namespace BPrivate
460ad6a8dbeSOliver Tappe 
461ad6a8dbeSOliver Tappe }	// namespace BHPKG
462ad6a8dbeSOliver Tappe 
463ad6a8dbeSOliver Tappe }	// namespace BPackageKit
464ad6a8dbeSOliver Tappe 
465ad6a8dbeSOliver Tappe 
466ad6a8dbeSOliver Tappe #endif	// _PACKAGE__HPKG__PRIVATE__READER_IMPL_BASE_H_
467