xref: /haiku/headers/private/package/hpkg/ReaderImplBase.h (revision 6d1f6cad344087032dc3e8a5402d2668022c142d)
1ad6a8dbeSOliver Tappe /*
2e527b796SIngo 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>
14e527b796SIngo Weinhold #include <DataIO.h>
15ad6a8dbeSOliver Tappe 
160f4e11e7SIngo Weinhold #include <Array.h>
17*6d1f6cadSAugustin Cavalier #include <util/BumpAllocator.h>
18ad6a8dbeSOliver Tappe #include <util/SinglyLinkedList.h>
19ad6a8dbeSOliver Tappe 
20d03ac965SIngo Weinhold #include <package/hpkg/ErrorOutput.h>
21ad6a8dbeSOliver Tappe #include <package/hpkg/PackageAttributeValue.h>
22ad6a8dbeSOliver Tappe #include <package/hpkg/PackageContentHandler.h>
23ad6a8dbeSOliver Tappe #include <package/hpkg/PackageInfoAttributeValue.h>
24ad6a8dbeSOliver Tappe 
25ad6a8dbeSOliver Tappe 
26b3263ad3SIngo Weinhold class BCompressionAlgorithm;
27b3263ad3SIngo Weinhold class BDecompressionParameters;
28b3263ad3SIngo Weinhold 
29b3263ad3SIngo Weinhold 
30ad6a8dbeSOliver Tappe namespace BPackageKit {
31ad6a8dbeSOliver Tappe 
32ad6a8dbeSOliver Tappe namespace BHPKG {
33ad6a8dbeSOliver Tappe 
34ad6a8dbeSOliver Tappe 
3546122852SIngo Weinhold class BAbstractBufferedDataReader;
36ad6a8dbeSOliver Tappe class BErrorOutput;
37ad6a8dbeSOliver Tappe 
38ad6a8dbeSOliver Tappe 
39ad6a8dbeSOliver Tappe namespace BPrivate {
40ad6a8dbeSOliver Tappe 
41ad6a8dbeSOliver Tappe 
421f633814SIngo Weinhold class PackageFileHeapReader;
43ad6a8dbeSOliver Tappe 
44ad6a8dbeSOliver Tappe 
451f633814SIngo Weinhold struct PackageFileSection {
46ad6a8dbeSOliver Tappe 	uint32			uncompressedLength;
47ad6a8dbeSOliver Tappe 	uint8*			data;
48ad6a8dbeSOliver Tappe 	uint64			offset;
49ad6a8dbeSOliver Tappe 	uint64			currentOffset;
50ad6a8dbeSOliver Tappe 	uint64			stringsLength;
51ad6a8dbeSOliver Tappe 	uint64			stringsCount;
52ad6a8dbeSOliver Tappe 	char**			strings;
53ad6a8dbeSOliver Tappe 	const char*		name;
54ad6a8dbeSOliver Tappe 
PackageFileSectionPackageFileSection551f633814SIngo Weinhold 	PackageFileSection(const char* _name)
56ad6a8dbeSOliver Tappe 		:
57ad6a8dbeSOliver Tappe 		data(NULL),
58ad6a8dbeSOliver Tappe 		strings(NULL),
59ad6a8dbeSOliver Tappe 		name(_name)
60ad6a8dbeSOliver Tappe 	{
61ad6a8dbeSOliver Tappe 	}
62ad6a8dbeSOliver Tappe 
~PackageFileSectionPackageFileSection631f633814SIngo Weinhold 	~PackageFileSection()
64ad6a8dbeSOliver Tappe 	{
65ad6a8dbeSOliver Tappe 		delete[] strings;
66ad6a8dbeSOliver Tappe 		delete[] data;
67ad6a8dbeSOliver Tappe 	}
68ad6a8dbeSOliver Tappe };
69ad6a8dbeSOliver Tappe 
701f633814SIngo Weinhold 
711f633814SIngo Weinhold class ReaderImplBase {
72e07b8bd2SIngo Weinhold public:
PackageAttributesSection()73e07b8bd2SIngo Weinhold 	inline	const PackageFileSection& PackageAttributesSection() const
74e07b8bd2SIngo Weinhold 									{ return fPackageAttributesSection; }
75e07b8bd2SIngo Weinhold 
761f633814SIngo Weinhold protected:
771f633814SIngo Weinhold 								ReaderImplBase(const char* fileType,
781f633814SIngo Weinhold 									BErrorOutput* errorOutput);
791f633814SIngo Weinhold 	virtual						~ReaderImplBase();
801f633814SIngo Weinhold 
81e527b796SIngo Weinhold 			BPositionIO*		File() const;
821f633814SIngo Weinhold 
831f633814SIngo Weinhold 			BErrorOutput*		ErrorOutput() const;
841f633814SIngo Weinhold 
MinorFormatVersion()8547039b85SIngo Weinhold 			uint16				MinorFormatVersion() const
8647039b85SIngo Weinhold 									{ return fMinorFormatVersion; }
8747039b85SIngo Weinhold 
8846122852SIngo Weinhold 			uint64				UncompressedHeapSize() const;
8946122852SIngo Weinhold 
RawHeapReader()9046122852SIngo Weinhold 			PackageFileHeapReader* RawHeapReader() const
9146122852SIngo Weinhold 									{ return fRawHeapReader; }
HeapReader()9246122852SIngo Weinhold 			BAbstractBufferedDataReader* HeapReader() const
931f633814SIngo Weinhold 									{ return fHeapReader; }
9446122852SIngo Weinhold 									// equals RawHeapReader(), if uncached
9546122852SIngo Weinhold 
9646122852SIngo Weinhold 			BAbstractBufferedDataReader* DetachHeapReader(
97e527b796SIngo Weinhold 									PackageFileHeapReader*& _rawHeapReader);
9846122852SIngo Weinhold 									// Detaches both raw and (if applicable)
9946122852SIngo Weinhold 									// cached heap reader. The called gains
100e527b796SIngo Weinhold 									// ownership of both. The file may need to
101e527b796SIngo Weinhold 									// be set on the raw heap reader, if it
102e527b796SIngo Weinhold 									// shall be used after destroying this
103e527b796SIngo Weinhold 									// object and Init() has been called with
104e527b796SIngo Weinhold 									// keepFile == true.
1051f633814SIngo Weinhold 
1061f633814SIngo Weinhold protected:
1071f633814SIngo Weinhold 			class AttributeHandlerContext;
1081f633814SIngo Weinhold 			class AttributeHandler;
1091f633814SIngo Weinhold 			class IgnoreAttributeHandler;
110fe707a23SIngo Weinhold 			class PackageInfoAttributeHandlerBase;
1111f633814SIngo Weinhold 			class PackageVersionAttributeHandler;
1121f633814SIngo Weinhold 			class PackageResolvableAttributeHandler;
1131f633814SIngo Weinhold 			class PackageResolvableExpressionAttributeHandler;
1144489c88bSIngo Weinhold 			class GlobalWritableFileInfoAttributeHandler;
115fe707a23SIngo Weinhold 			class UserSettingsFileInfoAttributeHandler;
1160f4e11e7SIngo Weinhold 			class UserAttributeHandler;
1171f633814SIngo Weinhold 			class PackageAttributeHandler;
1181f633814SIngo Weinhold 			class LowLevelAttributeHandler;
1191f633814SIngo Weinhold 
1201f633814SIngo Weinhold 			typedef BPackageAttributeValue AttributeValue;
121ad6a8dbeSOliver Tappe 			typedef SinglyLinkedList<AttributeHandler> AttributeHandlerList;
122ad6a8dbeSOliver Tappe 
123ad6a8dbeSOliver Tappe protected:
12479d5ddb7SIngo Weinhold 			template<typename Header, uint32 kMagic, uint16 kVersion,
12579d5ddb7SIngo Weinhold 				uint16 kMinorVersion>
126e527b796SIngo Weinhold 			status_t			Init(BPositionIO* file, bool keepFile,
127e527b796SIngo Weinhold 									Header& header, uint32 flags);
1281f633814SIngo Weinhold 			status_t			InitHeapReader(uint32 compression,
1291f633814SIngo Weinhold 									uint32 chunkSize, off_t offset,
1301f633814SIngo Weinhold 									uint64 compressedSize,
1311f633814SIngo Weinhold 									uint64 uncompressedSize);
13246122852SIngo Weinhold 	virtual	status_t			CreateCachedHeapReader(
13346122852SIngo Weinhold 									PackageFileHeapReader* heapReader,
13446122852SIngo Weinhold 									BAbstractBufferedDataReader*&
13546122852SIngo Weinhold 										_cachedReader);
1361f633814SIngo Weinhold 			status_t			InitSection(PackageFileSection& section,
1371f633814SIngo Weinhold 									uint64 endOffset, uint64 length,
1381f633814SIngo Weinhold 									uint64 maxSaneLength, uint64 stringsLength,
1391f633814SIngo Weinhold 									uint64 stringsCount);
1401f633814SIngo Weinhold 			status_t			PrepareSection(PackageFileSection& section);
141ad6a8dbeSOliver Tappe 
142ad6a8dbeSOliver Tappe 			status_t			ParseStrings();
143ad6a8dbeSOliver Tappe 
144ad6a8dbeSOliver Tappe 			status_t			ParsePackageAttributesSection(
145ad6a8dbeSOliver Tappe 									AttributeHandlerContext* context,
146ad6a8dbeSOliver Tappe 									AttributeHandler* rootAttributeHandler);
147ad6a8dbeSOliver Tappe 			status_t			ParseAttributeTree(
14897aabbedSIngo Weinhold 									AttributeHandlerContext* context,
14997aabbedSIngo Weinhold 									bool& _sectionHandled);
150ad6a8dbeSOliver Tappe 
151ad6a8dbeSOliver Tappe 	virtual	status_t			ReadAttributeValue(uint8 type, uint8 encoding,
152ad6a8dbeSOliver Tappe 									AttributeValue& _value);
153ad6a8dbeSOliver Tappe 
154ad6a8dbeSOliver Tappe 			status_t			ReadUnsignedLEB128(uint64& _value);
155ad6a8dbeSOliver Tappe 
156ad6a8dbeSOliver Tappe 			status_t			ReadBuffer(off_t offset, void* buffer,
157ad6a8dbeSOliver Tappe 									size_t size);
1581f633814SIngo Weinhold 			status_t			ReadSection(const PackageFileSection& section);
159ad6a8dbeSOliver Tappe 
160ad6a8dbeSOliver Tappe 	inline	AttributeHandler*	CurrentAttributeHandler() const;
161ad6a8dbeSOliver Tappe 	inline	void				PushAttributeHandler(
162ad6a8dbeSOliver Tappe 									AttributeHandler* handler);
163ad6a8dbeSOliver Tappe 	inline	AttributeHandler*	PopAttributeHandler();
164ad6a8dbeSOliver Tappe 	inline	void				ClearAttributeHandlerStack();
165ad6a8dbeSOliver Tappe 
1661f633814SIngo Weinhold 	inline	PackageFileSection*	CurrentSection();
1671f633814SIngo Weinhold 	inline	void				SetCurrentSection(PackageFileSection* section);
168ad6a8dbeSOliver Tappe 
169ad6a8dbeSOliver Tappe protected:
1701f633814SIngo Weinhold 			PackageFileSection	fPackageAttributesSection;
171ad6a8dbeSOliver Tappe 
172ad6a8dbeSOliver Tappe private:
173e527b796SIngo Weinhold 			status_t			_Init(BPositionIO* file, bool keepFile);
1741f633814SIngo Weinhold 
17597aabbedSIngo Weinhold 			status_t			_ParseAttributeTree(
17697aabbedSIngo Weinhold 									AttributeHandlerContext* context);
17797aabbedSIngo Weinhold 
178ad6a8dbeSOliver Tappe 	template<typename Type>
179ad6a8dbeSOliver Tappe 	inline	status_t			_Read(Type& _value);
180ad6a8dbeSOliver Tappe 
181ad6a8dbeSOliver Tappe 			status_t			_ReadSectionBuffer(void* buffer, size_t size);
182ad6a8dbeSOliver Tappe 
183ad6a8dbeSOliver Tappe 			status_t			_ReadAttribute(uint8& _id,
184ad6a8dbeSOliver Tappe 									AttributeValue& _value,
185ad6a8dbeSOliver Tappe 									bool* _hasChildren = NULL,
186ad6a8dbeSOliver Tappe 									uint64* _tag = NULL);
187ad6a8dbeSOliver Tappe 
188ad6a8dbeSOliver Tappe 			status_t			_ReadString(const char*& _string,
189ad6a8dbeSOliver Tappe 									size_t* _stringLength = NULL);
190ad6a8dbeSOliver Tappe 
191ad6a8dbeSOliver Tappe private:
1921f633814SIngo Weinhold 			const char*			fFileType;
193ad6a8dbeSOliver Tappe 			BErrorOutput*		fErrorOutput;
194e527b796SIngo Weinhold 			BPositionIO*		fFile;
195e527b796SIngo Weinhold 			bool				fOwnsFile;
19647039b85SIngo Weinhold 			uint16				fMinorFormatVersion;
19779d5ddb7SIngo Weinhold 			uint16				fCurrentMinorFormatVersion;
198ad6a8dbeSOliver Tappe 
19946122852SIngo Weinhold 			PackageFileHeapReader* fRawHeapReader;
20046122852SIngo Weinhold 			BAbstractBufferedDataReader* fHeapReader;
2011f633814SIngo Weinhold 
2021f633814SIngo Weinhold 			PackageFileSection*	fCurrentSection;
203ad6a8dbeSOliver Tappe 
204ad6a8dbeSOliver Tappe 			AttributeHandlerList fAttributeHandlerStack;
205ad6a8dbeSOliver Tappe };
206ad6a8dbeSOliver Tappe 
207ad6a8dbeSOliver Tappe 
2081f633814SIngo Weinhold // #pragma mark - attribute handlers
2091f633814SIngo Weinhold 
2101f633814SIngo Weinhold 
2111f633814SIngo Weinhold class ReaderImplBase::AttributeHandlerContext {
2121f633814SIngo Weinhold public:
2131f633814SIngo Weinhold 			BErrorOutput*			errorOutput;
2141f633814SIngo Weinhold 			union {
2151f633814SIngo Weinhold 				BPackageContentHandler*			packageContentHandler;
2161f633814SIngo Weinhold 				BLowLevelPackageContentHandler*	lowLevelHandler;
2171f633814SIngo Weinhold 			};
2181f633814SIngo Weinhold 			bool					hasLowLevelHandler;
21947039b85SIngo Weinhold 			bool					ignoreUnknownAttributes;
2201f633814SIngo Weinhold 
2211f633814SIngo Weinhold 			BHPKGPackageSectionID	section;
2221f633814SIngo Weinhold 
223*6d1f6cadSAugustin Cavalier 			BumpAllocator<>			handlersAllocator;
224*6d1f6cadSAugustin Cavalier 
2251f633814SIngo Weinhold public:
2261f633814SIngo Weinhold 								AttributeHandlerContext(
2271f633814SIngo Weinhold 									BErrorOutput* errorOutput,
2281f633814SIngo Weinhold 									BPackageContentHandler*
2291f633814SIngo Weinhold 										packageContentHandler,
23047039b85SIngo Weinhold 									BHPKGPackageSectionID section,
23147039b85SIngo Weinhold 									bool ignoreUnknownAttributes);
2321f633814SIngo Weinhold 								AttributeHandlerContext(
2331f633814SIngo Weinhold 									BErrorOutput* errorOutput,
2341f633814SIngo Weinhold 									BLowLevelPackageContentHandler*
2351f633814SIngo Weinhold 										lowLevelHandler,
23647039b85SIngo Weinhold 									BHPKGPackageSectionID section,
23747039b85SIngo Weinhold 									bool ignoreUnknownAttributes);
238*6d1f6cadSAugustin Cavalier 								~AttributeHandlerContext();
2391f633814SIngo Weinhold 
2401f633814SIngo Weinhold 			void				ErrorOccurred();
2411f633814SIngo Weinhold };
2421f633814SIngo Weinhold 
2431f633814SIngo Weinhold 
2441f633814SIngo Weinhold class ReaderImplBase::AttributeHandler
2451f633814SIngo Weinhold 	: public SinglyLinkedListLinkImpl<AttributeHandler> {
2461f633814SIngo Weinhold public:
247*6d1f6cadSAugustin Cavalier 			void*				operator new(size_t size, AttributeHandlerContext* context);
248*6d1f6cadSAugustin Cavalier 			void				operator delete(void* pointer);
249*6d1f6cadSAugustin Cavalier 
2501f633814SIngo Weinhold 	virtual						~AttributeHandler();
2511f633814SIngo Weinhold 
2521f633814SIngo Weinhold 			void				SetLevel(int level);
2531f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
2541f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
2551f633814SIngo Weinhold 									const AttributeValue& value,
2561f633814SIngo Weinhold 									AttributeHandler** _handler);
2571f633814SIngo Weinhold 
2580a345af7SOliver Tappe 	virtual	status_t			NotifyDone(AttributeHandlerContext* context);
2590a345af7SOliver Tappe 
2601f633814SIngo Weinhold 	virtual	status_t			Delete(AttributeHandlerContext* context);
2611f633814SIngo Weinhold 
2621f633814SIngo Weinhold protected:
2631f633814SIngo Weinhold 			int					fLevel;
264*6d1f6cadSAugustin Cavalier 
265*6d1f6cadSAugustin Cavalier private:
266*6d1f6cadSAugustin Cavalier 			bool				fDeleting;
2671f633814SIngo Weinhold };
2681f633814SIngo Weinhold 
2691f633814SIngo Weinhold 
2701f633814SIngo Weinhold class ReaderImplBase::IgnoreAttributeHandler : public AttributeHandler {
2711f633814SIngo Weinhold };
2721f633814SIngo Weinhold 
2731f633814SIngo Weinhold 
274fe707a23SIngo Weinhold class ReaderImplBase::PackageInfoAttributeHandlerBase
275fe707a23SIngo Weinhold 	: public AttributeHandler {
2760a345af7SOliver Tappe private:
2770a345af7SOliver Tappe 	typedef	AttributeHandler	super;
278fe707a23SIngo Weinhold public:
279fe707a23SIngo Weinhold 								PackageInfoAttributeHandlerBase(
280fe707a23SIngo Weinhold 									BPackageInfoAttributeValue&
281fe707a23SIngo Weinhold 										packageInfoValue);
282fe707a23SIngo Weinhold 
2830a345af7SOliver Tappe 	virtual	status_t			NotifyDone(AttributeHandlerContext* context);
284fe707a23SIngo Weinhold 
285fe707a23SIngo Weinhold protected:
286fe707a23SIngo Weinhold 			BPackageInfoAttributeValue& fPackageInfoValue;
287fe707a23SIngo Weinhold };
288fe707a23SIngo Weinhold 
289fe707a23SIngo Weinhold 
290fe707a23SIngo Weinhold class ReaderImplBase::PackageVersionAttributeHandler
291fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
2920a345af7SOliver Tappe private:
2930a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
2941f633814SIngo Weinhold public:
2951f633814SIngo Weinhold 								PackageVersionAttributeHandler(
2961f633814SIngo Weinhold 									BPackageInfoAttributeValue&
2971f633814SIngo Weinhold 										packageInfoValue,
2981f633814SIngo Weinhold 									BPackageVersionData& versionData,
2991f633814SIngo Weinhold 									bool notify);
3001f633814SIngo Weinhold 
3011f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
3021f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3031f633814SIngo Weinhold 									const AttributeValue& value,
3041f633814SIngo Weinhold 									AttributeHandler** _handler);
3051f633814SIngo Weinhold 
3060a345af7SOliver Tappe 	virtual	status_t			NotifyDone(AttributeHandlerContext* context);
3071f633814SIngo Weinhold 
3081f633814SIngo Weinhold private:
3091f633814SIngo Weinhold 			BPackageVersionData& fPackageVersionData;
3101f633814SIngo Weinhold 			bool				fNotify;
3111f633814SIngo Weinhold };
3121f633814SIngo Weinhold 
3131f633814SIngo Weinhold 
3141f633814SIngo Weinhold class ReaderImplBase::PackageResolvableAttributeHandler
315fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3160a345af7SOliver Tappe private:
3170a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
3181f633814SIngo Weinhold public:
3191f633814SIngo Weinhold 								PackageResolvableAttributeHandler(
3201f633814SIngo Weinhold 									BPackageInfoAttributeValue&
3211f633814SIngo Weinhold 										packageInfoValue);
3221f633814SIngo Weinhold 
3231f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
3241f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3251f633814SIngo Weinhold 									const AttributeValue& value,
3261f633814SIngo Weinhold 									AttributeHandler** _handler);
3271f633814SIngo Weinhold };
3281f633814SIngo Weinhold 
3291f633814SIngo Weinhold 
3301f633814SIngo Weinhold class ReaderImplBase::PackageResolvableExpressionAttributeHandler
331fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3320a345af7SOliver Tappe private:
3330a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
3341f633814SIngo Weinhold public:
3351f633814SIngo Weinhold 								PackageResolvableExpressionAttributeHandler(
3361f633814SIngo Weinhold 									BPackageInfoAttributeValue&
3371f633814SIngo Weinhold 										packageInfoValue);
3381f633814SIngo Weinhold 
3391f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
3401f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3411f633814SIngo Weinhold 									const AttributeValue& value,
3421f633814SIngo Weinhold 									AttributeHandler** _handler);
343fe707a23SIngo Weinhold };
3441f633814SIngo Weinhold 
3451f633814SIngo Weinhold 
3464489c88bSIngo Weinhold class ReaderImplBase::GlobalWritableFileInfoAttributeHandler
347fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3480a345af7SOliver Tappe private:
3490a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
350fe707a23SIngo Weinhold public:
3514489c88bSIngo Weinhold 								GlobalWritableFileInfoAttributeHandler(
352fe707a23SIngo Weinhold 									BPackageInfoAttributeValue&
353fe707a23SIngo Weinhold 										packageInfoValue);
354fe707a23SIngo Weinhold 
355fe707a23SIngo Weinhold 	virtual	status_t			HandleAttribute(
356fe707a23SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
357fe707a23SIngo Weinhold 									const AttributeValue& value,
358fe707a23SIngo Weinhold 									AttributeHandler** _handler);
359fe707a23SIngo Weinhold };
360fe707a23SIngo Weinhold 
361fe707a23SIngo Weinhold 
362fe707a23SIngo Weinhold class ReaderImplBase::UserSettingsFileInfoAttributeHandler
363fe707a23SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3640a345af7SOliver Tappe private:
3650a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
366fe707a23SIngo Weinhold public:
367fe707a23SIngo Weinhold 								UserSettingsFileInfoAttributeHandler(
368fe707a23SIngo Weinhold 									BPackageInfoAttributeValue&
369fe707a23SIngo Weinhold 										packageInfoValue);
370fe707a23SIngo Weinhold 
371fe707a23SIngo Weinhold 	virtual	status_t			HandleAttribute(
372fe707a23SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
373fe707a23SIngo Weinhold 									const AttributeValue& value,
374fe707a23SIngo Weinhold 									AttributeHandler** _handler);
3751f633814SIngo Weinhold };
3761f633814SIngo Weinhold 
3771f633814SIngo Weinhold 
3780f4e11e7SIngo Weinhold class ReaderImplBase::UserAttributeHandler
3790f4e11e7SIngo Weinhold 	: public PackageInfoAttributeHandlerBase {
3800a345af7SOliver Tappe private:
3810a345af7SOliver Tappe 	typedef	PackageInfoAttributeHandlerBase	super;
3820f4e11e7SIngo Weinhold public:
3830f4e11e7SIngo Weinhold 								UserAttributeHandler(
3840f4e11e7SIngo Weinhold 									BPackageInfoAttributeValue&
3850f4e11e7SIngo Weinhold 										packageInfoValue);
3860f4e11e7SIngo Weinhold 
3870f4e11e7SIngo Weinhold 	virtual	status_t			HandleAttribute(
3880f4e11e7SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
3890f4e11e7SIngo Weinhold 									const AttributeValue& value,
3900f4e11e7SIngo Weinhold 									AttributeHandler** _handler);
3910f4e11e7SIngo Weinhold 
3920a345af7SOliver Tappe 	virtual	status_t			NotifyDone(AttributeHandlerContext* context);
3930f4e11e7SIngo Weinhold 
3940f4e11e7SIngo Weinhold private:
3950f4e11e7SIngo Weinhold 			Array<const char*>	fGroups;
3960f4e11e7SIngo Weinhold };
3970f4e11e7SIngo Weinhold 
3980f4e11e7SIngo Weinhold 
3991f633814SIngo Weinhold class ReaderImplBase::PackageAttributeHandler : public AttributeHandler {
4000a345af7SOliver Tappe private:
4010a345af7SOliver Tappe 	typedef	AttributeHandler	super;
4021f633814SIngo Weinhold public:
4031f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
4041f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
4051f633814SIngo Weinhold 									const AttributeValue& value,
4061f633814SIngo Weinhold 									AttributeHandler** _handler);
4071f633814SIngo Weinhold 
4081f633814SIngo Weinhold private:
4091f633814SIngo Weinhold 			BPackageInfoAttributeValue fPackageInfoValue;
4101f633814SIngo Weinhold };
4111f633814SIngo Weinhold 
4121f633814SIngo Weinhold 
4131f633814SIngo Weinhold class ReaderImplBase::LowLevelAttributeHandler : public AttributeHandler {
4140a345af7SOliver Tappe private:
4150a345af7SOliver Tappe 	typedef	AttributeHandler	super;
4161f633814SIngo Weinhold public:
4171f633814SIngo Weinhold 								LowLevelAttributeHandler();
4181f633814SIngo Weinhold 								LowLevelAttributeHandler(uint8 id,
4191f633814SIngo Weinhold 									const BPackageAttributeValue& value,
4201f633814SIngo Weinhold 									void* parentToken, void* token);
4211f633814SIngo Weinhold 
4221f633814SIngo Weinhold 	virtual	status_t			HandleAttribute(
4231f633814SIngo Weinhold 									AttributeHandlerContext* context, uint8 id,
4241f633814SIngo Weinhold 									const AttributeValue& value,
4251f633814SIngo Weinhold 									AttributeHandler** _handler);
4260a345af7SOliver Tappe 
4270a345af7SOliver Tappe 	virtual	status_t			NotifyDone(AttributeHandlerContext* context);
4281f633814SIngo Weinhold 
4291f633814SIngo Weinhold private:
4301f633814SIngo Weinhold 			void*				fParentToken;
4311f633814SIngo Weinhold 			void*				fToken;
4321f633814SIngo Weinhold 			uint8				fID;
4331f633814SIngo Weinhold 			AttributeValue		fValue;
4341f633814SIngo Weinhold };
4351f633814SIngo Weinhold 
4361f633814SIngo Weinhold 
4371f633814SIngo Weinhold // #pragma mark - template and inline methods
4381f633814SIngo Weinhold 
4391f633814SIngo Weinhold 
44079d5ddb7SIngo Weinhold template<typename Header, uint32 kMagic, uint16 kVersion, uint16 kMinorVersion>
4411f633814SIngo Weinhold status_t
Init(BPositionIO * file,bool keepFile,Header & header,uint32 flags)442e527b796SIngo Weinhold ReaderImplBase::Init(BPositionIO* file, bool keepFile, Header& header, uint32 flags)
4431f633814SIngo Weinhold {
444e527b796SIngo Weinhold 	status_t error = _Init(file, keepFile);
4451f633814SIngo Weinhold 	if (error != B_OK)
4461f633814SIngo Weinhold 		return error;
4471f633814SIngo Weinhold 
448e527b796SIngo Weinhold 	// get the file size
449e527b796SIngo Weinhold 	off_t fileSize;
450e527b796SIngo Weinhold 	error = fFile->GetSize(&fileSize);
451e527b796SIngo Weinhold 	if (error != B_OK) {
4521606450bSIngo Weinhold 		if (error != B_NOT_SUPPORTED) {
4531606450bSIngo Weinhold 			ErrorOutput()->PrintError(
4541606450bSIngo Weinhold 				"Error: Failed to get size of %s file: %s\n",
455e527b796SIngo Weinhold 				fFileType, strerror(error));
4561606450bSIngo Weinhold 			return error;
4571606450bSIngo Weinhold 		}
4581606450bSIngo Weinhold 
4591606450bSIngo Weinhold 		// Might be a stream. We only use the file size for checking the total
4601606450bSIngo Weinhold 		// heap size, which we don't have to do.
4611606450bSIngo Weinhold 		fileSize = -1;
4621f633814SIngo Weinhold 	}
4631f633814SIngo Weinhold 
4646c331fc7SAlexander von Gluck IV 	// validate file is longer than header (when not a stream)
4656c331fc7SAlexander von Gluck IV 	if (fileSize >= 0 && fileSize < (off_t)sizeof(header)) {
4666c331fc7SAlexander von Gluck IV 		ErrorOutput()->PrintError("Error: Invalid %s file: Length shorter than "
4676c331fc7SAlexander von Gluck IV 			"header!\n", fFileType);
4686c331fc7SAlexander von Gluck IV 		return B_BAD_DATA;
4696c331fc7SAlexander von Gluck IV 	}
4706c331fc7SAlexander von Gluck IV 
4711f633814SIngo Weinhold 	// read the header
4721f633814SIngo Weinhold 	if ((error = ReadBuffer(0, &header, sizeof(header))) != B_OK)
4731f633814SIngo Weinhold 		return error;
4741f633814SIngo Weinhold 
4751f633814SIngo Weinhold 	// check the header
4761f633814SIngo Weinhold 
4771f633814SIngo Weinhold 	// magic
4781f633814SIngo Weinhold 	if (B_BENDIAN_TO_HOST_INT32(header.magic) != kMagic) {
4791f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Invalid "
4801f633814SIngo Weinhold 			"magic\n", fFileType);
4811f633814SIngo Weinhold 		return B_BAD_DATA;
4821f633814SIngo Weinhold 	}
4831f633814SIngo Weinhold 
4841f633814SIngo Weinhold 	// version
4851f633814SIngo Weinhold 	if (B_BENDIAN_TO_HOST_INT16(header.version) != kVersion) {
486d59e0febSIngo Weinhold 		if ((flags & B_HPKG_READER_DONT_PRINT_VERSION_MISMATCH_MESSAGE) == 0) {
4871f633814SIngo Weinhold 			ErrorOutput()->PrintError("Error: Invalid/unsupported %s file "
4881f633814SIngo Weinhold 				"version (%d)\n", fFileType,
4891f633814SIngo Weinhold 				B_BENDIAN_TO_HOST_INT16(header.version));
490d59e0febSIngo Weinhold 		}
4911f633814SIngo Weinhold 		return B_MISMATCHED_VALUES;
4921f633814SIngo Weinhold 	}
4931f633814SIngo Weinhold 
49447039b85SIngo Weinhold 	fMinorFormatVersion = B_BENDIAN_TO_HOST_INT16(header.minor_version);
49579d5ddb7SIngo Weinhold 	fCurrentMinorFormatVersion = kMinorVersion;
49647039b85SIngo Weinhold 
4971f633814SIngo Weinhold 	// header size
4981f633814SIngo Weinhold 	uint64 heapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size);
4991f633814SIngo Weinhold 	if (heapOffset < (off_t)sizeof(header)) {
5001f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Invalid header "
5011f633814SIngo Weinhold 			"size (%" B_PRIu64 ")\n", fFileType, heapOffset);
5021f633814SIngo Weinhold 		return B_BAD_DATA;
5031f633814SIngo Weinhold 	}
5041f633814SIngo Weinhold 
5051f633814SIngo Weinhold 	// total size
5061f633814SIngo Weinhold 	uint64 totalSize = B_BENDIAN_TO_HOST_INT64(header.total_size);
5071606450bSIngo Weinhold 	if (fileSize >= 0 && totalSize != (uint64)fileSize) {
5081f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Total size in "
5091f633814SIngo Weinhold 			"header (%" B_PRIu64 ") doesn't agree with total file size (%"
510e527b796SIngo Weinhold 			B_PRIdOFF ")\n", fFileType, totalSize, fileSize);
5111f633814SIngo Weinhold 		return B_BAD_DATA;
5121f633814SIngo Weinhold 	}
5131f633814SIngo Weinhold 
5141f633814SIngo Weinhold 	// heap size
5151f633814SIngo Weinhold 	uint64 compressedHeapSize
5161f633814SIngo Weinhold 		= B_BENDIAN_TO_HOST_INT64(header.heap_size_compressed);
5171f633814SIngo Weinhold 	if (compressedHeapSize > totalSize
5181f633814SIngo Weinhold 		|| heapOffset > totalSize - compressedHeapSize) {
5191f633814SIngo Weinhold 		ErrorOutput()->PrintError("Error: Invalid %s file: Heap size in "
5201f633814SIngo Weinhold 			"header (%" B_PRIu64 ") doesn't agree with total file size (%"
5211f633814SIngo Weinhold 			B_PRIu64 ") and heap offset (%" B_PRIu64 ")\n", fFileType,
5221f633814SIngo Weinhold 			compressedHeapSize, totalSize, heapOffset);
5231f633814SIngo Weinhold 		return B_BAD_DATA;
5241f633814SIngo Weinhold 	}
5251f633814SIngo Weinhold 
5261f633814SIngo Weinhold 	error = InitHeapReader(
52747039b85SIngo Weinhold 		B_BENDIAN_TO_HOST_INT16(header.heap_compression),
5281f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT32(header.heap_chunk_size), heapOffset,
5291f633814SIngo Weinhold 		compressedHeapSize,
5301f633814SIngo Weinhold 		B_BENDIAN_TO_HOST_INT64(header.heap_size_uncompressed));
5311f633814SIngo Weinhold 	if (error != B_OK)
5321f633814SIngo Weinhold 		return error;
5331f633814SIngo Weinhold 
5341f633814SIngo Weinhold 	return B_OK;
5351f633814SIngo Weinhold }
5361f633814SIngo Weinhold 
5371f633814SIngo Weinhold 
538e527b796SIngo Weinhold inline BPositionIO*
File()539e527b796SIngo Weinhold ReaderImplBase::File() const
540ad6a8dbeSOliver Tappe {
541e527b796SIngo Weinhold 	return fFile;
542ad6a8dbeSOliver Tappe }
543ad6a8dbeSOliver Tappe 
544ad6a8dbeSOliver Tappe 
545ad6a8dbeSOliver Tappe inline BErrorOutput*
ErrorOutput()546ad6a8dbeSOliver Tappe ReaderImplBase::ErrorOutput() const
547ad6a8dbeSOliver Tappe {
548ad6a8dbeSOliver Tappe 	return fErrorOutput;
549ad6a8dbeSOliver Tappe }
550ad6a8dbeSOliver Tappe 
551ad6a8dbeSOliver Tappe 
5521f633814SIngo Weinhold PackageFileSection*
CurrentSection()553ad6a8dbeSOliver Tappe ReaderImplBase::CurrentSection()
554ad6a8dbeSOliver Tappe {
555ad6a8dbeSOliver Tappe 	return fCurrentSection;
556ad6a8dbeSOliver Tappe }
557ad6a8dbeSOliver Tappe 
558ad6a8dbeSOliver Tappe 
559ad6a8dbeSOliver Tappe void
SetCurrentSection(PackageFileSection * section)5601f633814SIngo Weinhold ReaderImplBase::SetCurrentSection(PackageFileSection* section)
561ad6a8dbeSOliver Tappe {
562ad6a8dbeSOliver Tappe 	fCurrentSection = section;
563ad6a8dbeSOliver Tappe }
564ad6a8dbeSOliver Tappe 
565ad6a8dbeSOliver Tappe 
566ad6a8dbeSOliver Tappe template<typename Type>
567ad6a8dbeSOliver Tappe status_t
_Read(Type & _value)568ad6a8dbeSOliver Tappe ReaderImplBase::_Read(Type& _value)
569ad6a8dbeSOliver Tappe {
570ad6a8dbeSOliver Tappe 	return _ReadSectionBuffer(&_value, sizeof(Type));
571ad6a8dbeSOliver Tappe }
572ad6a8dbeSOliver Tappe 
573ad6a8dbeSOliver Tappe 
574ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler*
CurrentAttributeHandler()575ad6a8dbeSOliver Tappe ReaderImplBase::CurrentAttributeHandler() const
576ad6a8dbeSOliver Tappe {
577ad6a8dbeSOliver Tappe 	return fAttributeHandlerStack.Head();
578ad6a8dbeSOliver Tappe }
579ad6a8dbeSOliver Tappe 
580ad6a8dbeSOliver Tappe 
581ad6a8dbeSOliver Tappe inline void
PushAttributeHandler(AttributeHandler * handler)582ad6a8dbeSOliver Tappe ReaderImplBase::PushAttributeHandler(AttributeHandler* handler)
583ad6a8dbeSOliver Tappe {
584ad6a8dbeSOliver Tappe 	fAttributeHandlerStack.Add(handler);
585ad6a8dbeSOliver Tappe }
586ad6a8dbeSOliver Tappe 
587ad6a8dbeSOliver Tappe 
588ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler*
PopAttributeHandler()589ad6a8dbeSOliver Tappe ReaderImplBase::PopAttributeHandler()
590ad6a8dbeSOliver Tappe {
591ad6a8dbeSOliver Tappe 	return fAttributeHandlerStack.RemoveHead();
592ad6a8dbeSOliver Tappe }
593ad6a8dbeSOliver Tappe 
594ad6a8dbeSOliver Tappe 
595ad6a8dbeSOliver Tappe inline void
ClearAttributeHandlerStack()596ad6a8dbeSOliver Tappe ReaderImplBase::ClearAttributeHandlerStack()
597ad6a8dbeSOliver Tappe {
598ad6a8dbeSOliver Tappe 	fAttributeHandlerStack.MakeEmpty();
599ad6a8dbeSOliver Tappe }
600ad6a8dbeSOliver Tappe 
601ad6a8dbeSOliver Tappe 
602ad6a8dbeSOliver Tappe }	// namespace BPrivate
603ad6a8dbeSOliver Tappe 
604ad6a8dbeSOliver Tappe }	// namespace BHPKG
605ad6a8dbeSOliver Tappe 
606ad6a8dbeSOliver Tappe }	// namespace BPackageKit
607ad6a8dbeSOliver Tappe 
608ad6a8dbeSOliver Tappe 
609ad6a8dbeSOliver Tappe #endif	// _PACKAGE__HPKG__PRIVATE__READER_IMPL_BASE_H_
610