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