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 160f4e11e7SIngo Weinhold #include <Array.h> 17ad6a8dbeSOliver Tappe #include <util/SinglyLinkedList.h> 18ad6a8dbeSOliver Tappe 19d03ac965SIngo Weinhold #include <package/hpkg/ErrorOutput.h> 20ad6a8dbeSOliver Tappe #include <package/hpkg/PackageAttributeValue.h> 21ad6a8dbeSOliver Tappe #include <package/hpkg/PackageContentHandler.h> 22ad6a8dbeSOliver Tappe #include <package/hpkg/PackageInfoAttributeValue.h> 23ad6a8dbeSOliver Tappe 24ad6a8dbeSOliver Tappe 25*b3263ad3SIngo Weinhold class BCompressionAlgorithm; 26*b3263ad3SIngo Weinhold class BDecompressionParameters; 27*b3263ad3SIngo Weinhold 28*b3263ad3SIngo Weinhold 29ad6a8dbeSOliver Tappe namespace BPackageKit { 30ad6a8dbeSOliver Tappe 31ad6a8dbeSOliver Tappe namespace BHPKG { 32ad6a8dbeSOliver Tappe 33ad6a8dbeSOliver Tappe 3446122852SIngo Weinhold class BAbstractBufferedDataReader; 35ad6a8dbeSOliver Tappe class BErrorOutput; 36ad6a8dbeSOliver Tappe 37ad6a8dbeSOliver Tappe 38ad6a8dbeSOliver Tappe namespace BPrivate { 39ad6a8dbeSOliver Tappe 40ad6a8dbeSOliver Tappe 411f633814SIngo Weinhold class PackageFileHeapReader; 42ad6a8dbeSOliver Tappe 43ad6a8dbeSOliver Tappe 441f633814SIngo Weinhold struct PackageFileSection { 45ad6a8dbeSOliver Tappe uint32 uncompressedLength; 46ad6a8dbeSOliver Tappe uint8* data; 47ad6a8dbeSOliver Tappe uint64 offset; 48ad6a8dbeSOliver Tappe uint64 currentOffset; 49ad6a8dbeSOliver Tappe uint64 stringsLength; 50ad6a8dbeSOliver Tappe uint64 stringsCount; 51ad6a8dbeSOliver Tappe char** strings; 52ad6a8dbeSOliver Tappe const char* name; 53ad6a8dbeSOliver Tappe 541f633814SIngo Weinhold PackageFileSection(const char* _name) 55ad6a8dbeSOliver Tappe : 56ad6a8dbeSOliver Tappe data(NULL), 57ad6a8dbeSOliver Tappe strings(NULL), 58ad6a8dbeSOliver Tappe name(_name) 59ad6a8dbeSOliver Tappe { 60ad6a8dbeSOliver Tappe } 61ad6a8dbeSOliver Tappe 621f633814SIngo Weinhold ~PackageFileSection() 63ad6a8dbeSOliver Tappe { 64ad6a8dbeSOliver Tappe delete[] strings; 65ad6a8dbeSOliver Tappe delete[] data; 66ad6a8dbeSOliver Tappe } 67ad6a8dbeSOliver Tappe }; 68ad6a8dbeSOliver Tappe 691f633814SIngo Weinhold 701f633814SIngo Weinhold class ReaderImplBase { 71e07b8bd2SIngo Weinhold public: 72e07b8bd2SIngo Weinhold inline const PackageFileSection& PackageAttributesSection() const 73e07b8bd2SIngo Weinhold { return fPackageAttributesSection; } 74e07b8bd2SIngo Weinhold 751f633814SIngo Weinhold protected: 761f633814SIngo Weinhold ReaderImplBase(const char* fileType, 771f633814SIngo Weinhold BErrorOutput* errorOutput); 781f633814SIngo Weinhold virtual ~ReaderImplBase(); 791f633814SIngo Weinhold 801f633814SIngo Weinhold int FD() const; 811f633814SIngo Weinhold 821f633814SIngo Weinhold BErrorOutput* ErrorOutput() const; 831f633814SIngo Weinhold 8447039b85SIngo Weinhold uint16 MinorFormatVersion() const 8547039b85SIngo Weinhold { return fMinorFormatVersion; } 8647039b85SIngo Weinhold 8746122852SIngo Weinhold uint64 UncompressedHeapSize() const; 8846122852SIngo Weinhold 8946122852SIngo Weinhold PackageFileHeapReader* RawHeapReader() const 9046122852SIngo Weinhold { return fRawHeapReader; } 9146122852SIngo Weinhold BAbstractBufferedDataReader* HeapReader() const 921f633814SIngo Weinhold { return fHeapReader; } 9346122852SIngo Weinhold // equals RawHeapReader(), if uncached 9446122852SIngo Weinhold 9546122852SIngo Weinhold BAbstractBufferedDataReader* DetachHeapReader( 9646122852SIngo Weinhold PackageFileHeapReader** _rawHeapReader 9746122852SIngo Weinhold = NULL); 9846122852SIngo Weinhold // Detaches both raw and (if applicable) 9946122852SIngo Weinhold // cached heap reader. The called gains 10046122852SIngo Weinhold // ownership. The FD may need to be set on 10146122852SIngo Weinhold // the raw heap reader, if it shall be used 10246122852SIngo Weinhold // after destroying this object and Init() 10346122852SIngo Weinhold // has been called with keepFD == true. 1041f633814SIngo Weinhold 1051f633814SIngo Weinhold protected: 1061f633814SIngo Weinhold class AttributeHandlerContext; 1071f633814SIngo Weinhold class AttributeHandler; 1081f633814SIngo Weinhold class IgnoreAttributeHandler; 109fe707a23SIngo Weinhold class PackageInfoAttributeHandlerBase; 1101f633814SIngo Weinhold class PackageVersionAttributeHandler; 1111f633814SIngo Weinhold class PackageResolvableAttributeHandler; 1121f633814SIngo Weinhold class PackageResolvableExpressionAttributeHandler; 1134489c88bSIngo Weinhold class GlobalWritableFileInfoAttributeHandler; 114fe707a23SIngo Weinhold class UserSettingsFileInfoAttributeHandler; 1150f4e11e7SIngo Weinhold class UserAttributeHandler; 1161f633814SIngo Weinhold class PackageAttributeHandler; 1171f633814SIngo Weinhold class LowLevelAttributeHandler; 1181f633814SIngo Weinhold 1191f633814SIngo Weinhold typedef BPackageAttributeValue AttributeValue; 120ad6a8dbeSOliver Tappe typedef SinglyLinkedList<AttributeHandler> AttributeHandlerList; 121ad6a8dbeSOliver Tappe 122ad6a8dbeSOliver Tappe protected: 12379d5ddb7SIngo Weinhold template<typename Header, uint32 kMagic, uint16 kVersion, 12479d5ddb7SIngo Weinhold uint16 kMinorVersion> 125d59e0febSIngo Weinhold status_t Init(int fd, bool keepFD, Header& header, 126d59e0febSIngo Weinhold uint32 flags); 1271f633814SIngo Weinhold status_t InitHeapReader(uint32 compression, 1281f633814SIngo Weinhold uint32 chunkSize, off_t offset, 1291f633814SIngo Weinhold uint64 compressedSize, 1301f633814SIngo Weinhold uint64 uncompressedSize); 13146122852SIngo Weinhold virtual status_t CreateCachedHeapReader( 13246122852SIngo Weinhold PackageFileHeapReader* heapReader, 13346122852SIngo Weinhold BAbstractBufferedDataReader*& 13446122852SIngo Weinhold _cachedReader); 1351f633814SIngo Weinhold status_t InitSection(PackageFileSection& section, 1361f633814SIngo Weinhold uint64 endOffset, uint64 length, 1371f633814SIngo Weinhold uint64 maxSaneLength, uint64 stringsLength, 1381f633814SIngo Weinhold uint64 stringsCount); 1391f633814SIngo Weinhold status_t PrepareSection(PackageFileSection& section); 140ad6a8dbeSOliver Tappe 141ad6a8dbeSOliver Tappe status_t ParseStrings(); 142ad6a8dbeSOliver Tappe 143ad6a8dbeSOliver Tappe status_t ParsePackageAttributesSection( 144ad6a8dbeSOliver Tappe AttributeHandlerContext* context, 145ad6a8dbeSOliver Tappe AttributeHandler* rootAttributeHandler); 146ad6a8dbeSOliver Tappe status_t ParseAttributeTree( 14797aabbedSIngo Weinhold AttributeHandlerContext* context, 14897aabbedSIngo Weinhold bool& _sectionHandled); 149ad6a8dbeSOliver Tappe 150ad6a8dbeSOliver Tappe virtual status_t ReadAttributeValue(uint8 type, uint8 encoding, 151ad6a8dbeSOliver Tappe AttributeValue& _value); 152ad6a8dbeSOliver Tappe 153ad6a8dbeSOliver Tappe status_t ReadUnsignedLEB128(uint64& _value); 154ad6a8dbeSOliver Tappe 155ad6a8dbeSOliver Tappe status_t ReadBuffer(off_t offset, void* buffer, 156ad6a8dbeSOliver Tappe size_t size); 1571f633814SIngo Weinhold status_t ReadSection(const PackageFileSection& section); 158ad6a8dbeSOliver Tappe 159ad6a8dbeSOliver Tappe inline AttributeHandler* CurrentAttributeHandler() const; 160ad6a8dbeSOliver Tappe inline void PushAttributeHandler( 161ad6a8dbeSOliver Tappe AttributeHandler* handler); 162ad6a8dbeSOliver Tappe inline AttributeHandler* PopAttributeHandler(); 163ad6a8dbeSOliver Tappe inline void ClearAttributeHandlerStack(); 164ad6a8dbeSOliver Tappe 1651f633814SIngo Weinhold inline PackageFileSection* CurrentSection(); 1661f633814SIngo Weinhold inline void SetCurrentSection(PackageFileSection* section); 167ad6a8dbeSOliver Tappe 168ad6a8dbeSOliver Tappe protected: 1691f633814SIngo Weinhold PackageFileSection fPackageAttributesSection; 170ad6a8dbeSOliver Tappe 171ad6a8dbeSOliver Tappe private: 1721f633814SIngo Weinhold status_t _Init(int fd, bool keepFD); 1731f633814SIngo Weinhold 17497aabbedSIngo Weinhold status_t _ParseAttributeTree( 17597aabbedSIngo Weinhold AttributeHandlerContext* context); 17697aabbedSIngo Weinhold 177ad6a8dbeSOliver Tappe template<typename Type> 178ad6a8dbeSOliver Tappe inline status_t _Read(Type& _value); 179ad6a8dbeSOliver Tappe 180ad6a8dbeSOliver Tappe status_t _ReadSectionBuffer(void* buffer, size_t size); 181ad6a8dbeSOliver Tappe 182ad6a8dbeSOliver Tappe status_t _ReadAttribute(uint8& _id, 183ad6a8dbeSOliver Tappe AttributeValue& _value, 184ad6a8dbeSOliver Tappe bool* _hasChildren = NULL, 185ad6a8dbeSOliver Tappe uint64* _tag = NULL); 186ad6a8dbeSOliver Tappe 187ad6a8dbeSOliver Tappe status_t _ReadString(const char*& _string, 188ad6a8dbeSOliver Tappe size_t* _stringLength = NULL); 189ad6a8dbeSOliver Tappe 190ad6a8dbeSOliver Tappe private: 1911f633814SIngo Weinhold const char* fFileType; 192ad6a8dbeSOliver Tappe BErrorOutput* fErrorOutput; 193ad6a8dbeSOliver Tappe int fFD; 194ad6a8dbeSOliver Tappe bool fOwnsFD; 19547039b85SIngo Weinhold uint16 fMinorFormatVersion; 19679d5ddb7SIngo Weinhold uint16 fCurrentMinorFormatVersion; 197ad6a8dbeSOliver Tappe 19846122852SIngo Weinhold PackageFileHeapReader* fRawHeapReader; 19946122852SIngo Weinhold BAbstractBufferedDataReader* fHeapReader; 2001f633814SIngo Weinhold 2011f633814SIngo Weinhold PackageFileSection* fCurrentSection; 202ad6a8dbeSOliver Tappe 203ad6a8dbeSOliver Tappe AttributeHandlerList fAttributeHandlerStack; 204ad6a8dbeSOliver Tappe }; 205ad6a8dbeSOliver Tappe 206ad6a8dbeSOliver Tappe 2071f633814SIngo Weinhold // #pragma mark - attribute handlers 2081f633814SIngo Weinhold 2091f633814SIngo Weinhold 2101f633814SIngo Weinhold class ReaderImplBase::AttributeHandlerContext { 2111f633814SIngo Weinhold public: 2121f633814SIngo Weinhold BErrorOutput* errorOutput; 2131f633814SIngo Weinhold union { 2141f633814SIngo Weinhold BPackageContentHandler* packageContentHandler; 2151f633814SIngo Weinhold BLowLevelPackageContentHandler* lowLevelHandler; 2161f633814SIngo Weinhold }; 2171f633814SIngo Weinhold bool hasLowLevelHandler; 21847039b85SIngo Weinhold bool ignoreUnknownAttributes; 2191f633814SIngo Weinhold 2201f633814SIngo Weinhold BHPKGPackageSectionID section; 2211f633814SIngo Weinhold 2221f633814SIngo Weinhold public: 2231f633814SIngo Weinhold AttributeHandlerContext( 2241f633814SIngo Weinhold BErrorOutput* errorOutput, 2251f633814SIngo Weinhold BPackageContentHandler* 2261f633814SIngo Weinhold packageContentHandler, 22747039b85SIngo Weinhold BHPKGPackageSectionID section, 22847039b85SIngo Weinhold bool ignoreUnknownAttributes); 2291f633814SIngo Weinhold AttributeHandlerContext( 2301f633814SIngo Weinhold BErrorOutput* errorOutput, 2311f633814SIngo Weinhold BLowLevelPackageContentHandler* 2321f633814SIngo Weinhold lowLevelHandler, 23347039b85SIngo Weinhold BHPKGPackageSectionID section, 23447039b85SIngo Weinhold bool ignoreUnknownAttributes); 2351f633814SIngo Weinhold 2361f633814SIngo Weinhold void ErrorOccurred(); 2371f633814SIngo Weinhold }; 2381f633814SIngo Weinhold 2391f633814SIngo Weinhold 2401f633814SIngo Weinhold class ReaderImplBase::AttributeHandler 2411f633814SIngo Weinhold : public SinglyLinkedListLinkImpl<AttributeHandler> { 2421f633814SIngo Weinhold public: 2431f633814SIngo Weinhold virtual ~AttributeHandler(); 2441f633814SIngo Weinhold 2451f633814SIngo Weinhold void SetLevel(int level); 2461f633814SIngo Weinhold virtual status_t HandleAttribute( 2471f633814SIngo Weinhold AttributeHandlerContext* context, uint8 id, 2481f633814SIngo Weinhold const AttributeValue& value, 2491f633814SIngo Weinhold AttributeHandler** _handler); 2501f633814SIngo Weinhold 2510a345af7SOliver Tappe virtual status_t NotifyDone(AttributeHandlerContext* context); 2520a345af7SOliver Tappe 2531f633814SIngo Weinhold virtual status_t Delete(AttributeHandlerContext* context); 2541f633814SIngo Weinhold 2551f633814SIngo Weinhold protected: 2561f633814SIngo Weinhold int fLevel; 2571f633814SIngo Weinhold }; 2581f633814SIngo Weinhold 2591f633814SIngo Weinhold 2601f633814SIngo Weinhold class ReaderImplBase::IgnoreAttributeHandler : public AttributeHandler { 2611f633814SIngo Weinhold }; 2621f633814SIngo Weinhold 2631f633814SIngo Weinhold 264fe707a23SIngo Weinhold class ReaderImplBase::PackageInfoAttributeHandlerBase 265fe707a23SIngo Weinhold : public AttributeHandler { 2660a345af7SOliver Tappe private: 2670a345af7SOliver Tappe typedef AttributeHandler super; 268fe707a23SIngo Weinhold public: 269fe707a23SIngo Weinhold PackageInfoAttributeHandlerBase( 270fe707a23SIngo Weinhold BPackageInfoAttributeValue& 271fe707a23SIngo Weinhold packageInfoValue); 272fe707a23SIngo Weinhold 2730a345af7SOliver Tappe virtual status_t NotifyDone(AttributeHandlerContext* context); 274fe707a23SIngo Weinhold 275fe707a23SIngo Weinhold protected: 276fe707a23SIngo Weinhold BPackageInfoAttributeValue& fPackageInfoValue; 277fe707a23SIngo Weinhold }; 278fe707a23SIngo Weinhold 279fe707a23SIngo Weinhold 280fe707a23SIngo Weinhold class ReaderImplBase::PackageVersionAttributeHandler 281fe707a23SIngo Weinhold : public PackageInfoAttributeHandlerBase { 2820a345af7SOliver Tappe private: 2830a345af7SOliver Tappe typedef PackageInfoAttributeHandlerBase super; 2841f633814SIngo Weinhold public: 2851f633814SIngo Weinhold PackageVersionAttributeHandler( 2861f633814SIngo Weinhold BPackageInfoAttributeValue& 2871f633814SIngo Weinhold packageInfoValue, 2881f633814SIngo Weinhold BPackageVersionData& versionData, 2891f633814SIngo Weinhold bool notify); 2901f633814SIngo Weinhold 2911f633814SIngo Weinhold virtual status_t HandleAttribute( 2921f633814SIngo Weinhold AttributeHandlerContext* context, uint8 id, 2931f633814SIngo Weinhold const AttributeValue& value, 2941f633814SIngo Weinhold AttributeHandler** _handler); 2951f633814SIngo Weinhold 2960a345af7SOliver Tappe virtual status_t NotifyDone(AttributeHandlerContext* context); 2971f633814SIngo Weinhold 2981f633814SIngo Weinhold private: 2991f633814SIngo Weinhold BPackageVersionData& fPackageVersionData; 3001f633814SIngo Weinhold bool fNotify; 3011f633814SIngo Weinhold }; 3021f633814SIngo Weinhold 3031f633814SIngo Weinhold 3041f633814SIngo Weinhold class ReaderImplBase::PackageResolvableAttributeHandler 305fe707a23SIngo Weinhold : public PackageInfoAttributeHandlerBase { 3060a345af7SOliver Tappe private: 3070a345af7SOliver Tappe typedef PackageInfoAttributeHandlerBase super; 3081f633814SIngo Weinhold public: 3091f633814SIngo Weinhold PackageResolvableAttributeHandler( 3101f633814SIngo Weinhold BPackageInfoAttributeValue& 3111f633814SIngo Weinhold packageInfoValue); 3121f633814SIngo Weinhold 3131f633814SIngo Weinhold virtual status_t HandleAttribute( 3141f633814SIngo Weinhold AttributeHandlerContext* context, uint8 id, 3151f633814SIngo Weinhold const AttributeValue& value, 3161f633814SIngo Weinhold AttributeHandler** _handler); 3171f633814SIngo Weinhold }; 3181f633814SIngo Weinhold 3191f633814SIngo Weinhold 3201f633814SIngo Weinhold class ReaderImplBase::PackageResolvableExpressionAttributeHandler 321fe707a23SIngo Weinhold : public PackageInfoAttributeHandlerBase { 3220a345af7SOliver Tappe private: 3230a345af7SOliver Tappe typedef PackageInfoAttributeHandlerBase super; 3241f633814SIngo Weinhold public: 3251f633814SIngo Weinhold PackageResolvableExpressionAttributeHandler( 3261f633814SIngo Weinhold BPackageInfoAttributeValue& 3271f633814SIngo Weinhold packageInfoValue); 3281f633814SIngo Weinhold 3291f633814SIngo Weinhold virtual status_t HandleAttribute( 3301f633814SIngo Weinhold AttributeHandlerContext* context, uint8 id, 3311f633814SIngo Weinhold const AttributeValue& value, 3321f633814SIngo Weinhold AttributeHandler** _handler); 333fe707a23SIngo Weinhold }; 3341f633814SIngo Weinhold 3351f633814SIngo Weinhold 3364489c88bSIngo Weinhold class ReaderImplBase::GlobalWritableFileInfoAttributeHandler 337fe707a23SIngo Weinhold : public PackageInfoAttributeHandlerBase { 3380a345af7SOliver Tappe private: 3390a345af7SOliver Tappe typedef PackageInfoAttributeHandlerBase super; 340fe707a23SIngo Weinhold public: 3414489c88bSIngo Weinhold GlobalWritableFileInfoAttributeHandler( 342fe707a23SIngo Weinhold BPackageInfoAttributeValue& 343fe707a23SIngo Weinhold packageInfoValue); 344fe707a23SIngo Weinhold 345fe707a23SIngo Weinhold virtual status_t HandleAttribute( 346fe707a23SIngo Weinhold AttributeHandlerContext* context, uint8 id, 347fe707a23SIngo Weinhold const AttributeValue& value, 348fe707a23SIngo Weinhold AttributeHandler** _handler); 349fe707a23SIngo Weinhold }; 350fe707a23SIngo Weinhold 351fe707a23SIngo Weinhold 352fe707a23SIngo Weinhold class ReaderImplBase::UserSettingsFileInfoAttributeHandler 353fe707a23SIngo Weinhold : public PackageInfoAttributeHandlerBase { 3540a345af7SOliver Tappe private: 3550a345af7SOliver Tappe typedef PackageInfoAttributeHandlerBase super; 356fe707a23SIngo Weinhold public: 357fe707a23SIngo Weinhold UserSettingsFileInfoAttributeHandler( 358fe707a23SIngo Weinhold BPackageInfoAttributeValue& 359fe707a23SIngo Weinhold packageInfoValue); 360fe707a23SIngo Weinhold 361fe707a23SIngo Weinhold virtual status_t HandleAttribute( 362fe707a23SIngo Weinhold AttributeHandlerContext* context, uint8 id, 363fe707a23SIngo Weinhold const AttributeValue& value, 364fe707a23SIngo Weinhold AttributeHandler** _handler); 3651f633814SIngo Weinhold }; 3661f633814SIngo Weinhold 3671f633814SIngo Weinhold 3680f4e11e7SIngo Weinhold class ReaderImplBase::UserAttributeHandler 3690f4e11e7SIngo Weinhold : public PackageInfoAttributeHandlerBase { 3700a345af7SOliver Tappe private: 3710a345af7SOliver Tappe typedef PackageInfoAttributeHandlerBase super; 3720f4e11e7SIngo Weinhold public: 3730f4e11e7SIngo Weinhold UserAttributeHandler( 3740f4e11e7SIngo Weinhold BPackageInfoAttributeValue& 3750f4e11e7SIngo Weinhold packageInfoValue); 3760f4e11e7SIngo Weinhold 3770f4e11e7SIngo Weinhold virtual status_t HandleAttribute( 3780f4e11e7SIngo Weinhold AttributeHandlerContext* context, uint8 id, 3790f4e11e7SIngo Weinhold const AttributeValue& value, 3800f4e11e7SIngo Weinhold AttributeHandler** _handler); 3810f4e11e7SIngo Weinhold 3820a345af7SOliver Tappe virtual status_t NotifyDone(AttributeHandlerContext* context); 3830f4e11e7SIngo Weinhold 3840f4e11e7SIngo Weinhold private: 3850f4e11e7SIngo Weinhold Array<const char*> fGroups; 3860f4e11e7SIngo Weinhold }; 3870f4e11e7SIngo Weinhold 3880f4e11e7SIngo Weinhold 3891f633814SIngo Weinhold class ReaderImplBase::PackageAttributeHandler : public AttributeHandler { 3900a345af7SOliver Tappe private: 3910a345af7SOliver Tappe typedef AttributeHandler super; 3921f633814SIngo Weinhold public: 3931f633814SIngo Weinhold virtual status_t HandleAttribute( 3941f633814SIngo Weinhold AttributeHandlerContext* context, uint8 id, 3951f633814SIngo Weinhold const AttributeValue& value, 3961f633814SIngo Weinhold AttributeHandler** _handler); 3971f633814SIngo Weinhold 3981f633814SIngo Weinhold private: 3991f633814SIngo Weinhold BPackageInfoAttributeValue fPackageInfoValue; 4001f633814SIngo Weinhold }; 4011f633814SIngo Weinhold 4021f633814SIngo Weinhold 4031f633814SIngo Weinhold class ReaderImplBase::LowLevelAttributeHandler : public AttributeHandler { 4040a345af7SOliver Tappe private: 4050a345af7SOliver Tappe typedef AttributeHandler super; 4061f633814SIngo Weinhold public: 4071f633814SIngo Weinhold LowLevelAttributeHandler(); 4081f633814SIngo Weinhold LowLevelAttributeHandler(uint8 id, 4091f633814SIngo Weinhold const BPackageAttributeValue& value, 4101f633814SIngo Weinhold void* parentToken, void* token); 4111f633814SIngo Weinhold 4121f633814SIngo Weinhold virtual status_t HandleAttribute( 4131f633814SIngo Weinhold AttributeHandlerContext* context, uint8 id, 4141f633814SIngo Weinhold const AttributeValue& value, 4151f633814SIngo Weinhold AttributeHandler** _handler); 4160a345af7SOliver Tappe 4170a345af7SOliver Tappe virtual status_t NotifyDone(AttributeHandlerContext* context); 4181f633814SIngo Weinhold 4191f633814SIngo Weinhold private: 4201f633814SIngo Weinhold void* fParentToken; 4211f633814SIngo Weinhold void* fToken; 4221f633814SIngo Weinhold uint8 fID; 4231f633814SIngo Weinhold AttributeValue fValue; 4241f633814SIngo Weinhold }; 4251f633814SIngo Weinhold 4261f633814SIngo Weinhold 4271f633814SIngo Weinhold // #pragma mark - template and inline methods 4281f633814SIngo Weinhold 4291f633814SIngo Weinhold 43079d5ddb7SIngo Weinhold template<typename Header, uint32 kMagic, uint16 kVersion, uint16 kMinorVersion> 4311f633814SIngo Weinhold status_t 432d59e0febSIngo Weinhold ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags) 4331f633814SIngo Weinhold { 4341f633814SIngo Weinhold status_t error = _Init(fd, keepFD); 4351f633814SIngo Weinhold if (error != B_OK) 4361f633814SIngo Weinhold return error; 4371f633814SIngo Weinhold 4381f633814SIngo Weinhold // stat the file 4391f633814SIngo Weinhold struct stat st; 4401f633814SIngo Weinhold if (fstat(FD(), &st) < 0) { 4411f633814SIngo Weinhold ErrorOutput()->PrintError("Error: Failed to access %s file: %s\n", 4421f633814SIngo Weinhold fFileType, strerror(errno)); 4431f633814SIngo Weinhold return errno; 4441f633814SIngo Weinhold } 4451f633814SIngo Weinhold 4461f633814SIngo Weinhold // read the header 4471f633814SIngo Weinhold if ((error = ReadBuffer(0, &header, sizeof(header))) != B_OK) 4481f633814SIngo Weinhold return error; 4491f633814SIngo Weinhold 4501f633814SIngo Weinhold // check the header 4511f633814SIngo Weinhold 4521f633814SIngo Weinhold // magic 4531f633814SIngo Weinhold if (B_BENDIAN_TO_HOST_INT32(header.magic) != kMagic) { 4541f633814SIngo Weinhold ErrorOutput()->PrintError("Error: Invalid %s file: Invalid " 4551f633814SIngo Weinhold "magic\n", fFileType); 4561f633814SIngo Weinhold return B_BAD_DATA; 4571f633814SIngo Weinhold } 4581f633814SIngo Weinhold 4591f633814SIngo Weinhold // version 4601f633814SIngo Weinhold if (B_BENDIAN_TO_HOST_INT16(header.version) != kVersion) { 461d59e0febSIngo Weinhold if ((flags & B_HPKG_READER_DONT_PRINT_VERSION_MISMATCH_MESSAGE) == 0) { 4621f633814SIngo Weinhold ErrorOutput()->PrintError("Error: Invalid/unsupported %s file " 4631f633814SIngo Weinhold "version (%d)\n", fFileType, 4641f633814SIngo Weinhold B_BENDIAN_TO_HOST_INT16(header.version)); 465d59e0febSIngo Weinhold } 4661f633814SIngo Weinhold return B_MISMATCHED_VALUES; 4671f633814SIngo Weinhold } 4681f633814SIngo Weinhold 46947039b85SIngo Weinhold fMinorFormatVersion = B_BENDIAN_TO_HOST_INT16(header.minor_version); 47079d5ddb7SIngo Weinhold fCurrentMinorFormatVersion = kMinorVersion; 47147039b85SIngo Weinhold 4721f633814SIngo Weinhold // header size 4731f633814SIngo Weinhold uint64 heapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size); 4741f633814SIngo Weinhold if (heapOffset < (off_t)sizeof(header)) { 4751f633814SIngo Weinhold ErrorOutput()->PrintError("Error: Invalid %s file: Invalid header " 4761f633814SIngo Weinhold "size (%" B_PRIu64 ")\n", fFileType, heapOffset); 4771f633814SIngo Weinhold return B_BAD_DATA; 4781f633814SIngo Weinhold } 4791f633814SIngo Weinhold 4801f633814SIngo Weinhold // total size 4811f633814SIngo Weinhold uint64 totalSize = B_BENDIAN_TO_HOST_INT64(header.total_size); 4821f633814SIngo Weinhold if (totalSize != (uint64)st.st_size) { 4831f633814SIngo Weinhold ErrorOutput()->PrintError("Error: Invalid %s file: Total size in " 4841f633814SIngo Weinhold "header (%" B_PRIu64 ") doesn't agree with total file size (%" 4851f633814SIngo Weinhold B_PRIdOFF ")\n", fFileType, totalSize, st.st_size); 4861f633814SIngo Weinhold return B_BAD_DATA; 4871f633814SIngo Weinhold } 4881f633814SIngo Weinhold 4891f633814SIngo Weinhold // heap size 4901f633814SIngo Weinhold uint64 compressedHeapSize 4911f633814SIngo Weinhold = B_BENDIAN_TO_HOST_INT64(header.heap_size_compressed); 4921f633814SIngo Weinhold if (compressedHeapSize > totalSize 4931f633814SIngo Weinhold || heapOffset > totalSize - compressedHeapSize) { 4941f633814SIngo Weinhold ErrorOutput()->PrintError("Error: Invalid %s file: Heap size in " 4951f633814SIngo Weinhold "header (%" B_PRIu64 ") doesn't agree with total file size (%" 4961f633814SIngo Weinhold B_PRIu64 ") and heap offset (%" B_PRIu64 ")\n", fFileType, 4971f633814SIngo Weinhold compressedHeapSize, totalSize, heapOffset); 4981f633814SIngo Weinhold return B_BAD_DATA; 4991f633814SIngo Weinhold } 5001f633814SIngo Weinhold 5011f633814SIngo Weinhold error = InitHeapReader( 50247039b85SIngo Weinhold B_BENDIAN_TO_HOST_INT16(header.heap_compression), 5031f633814SIngo Weinhold B_BENDIAN_TO_HOST_INT32(header.heap_chunk_size), heapOffset, 5041f633814SIngo Weinhold compressedHeapSize, 5051f633814SIngo Weinhold B_BENDIAN_TO_HOST_INT64(header.heap_size_uncompressed)); 5061f633814SIngo Weinhold if (error != B_OK) 5071f633814SIngo Weinhold return error; 5081f633814SIngo Weinhold 5091f633814SIngo Weinhold return B_OK; 5101f633814SIngo Weinhold } 5111f633814SIngo Weinhold 5121f633814SIngo Weinhold 513ad6a8dbeSOliver Tappe inline int 514ad6a8dbeSOliver Tappe ReaderImplBase::FD() const 515ad6a8dbeSOliver Tappe { 516ad6a8dbeSOliver Tappe return fFD; 517ad6a8dbeSOliver Tappe } 518ad6a8dbeSOliver Tappe 519ad6a8dbeSOliver Tappe 520ad6a8dbeSOliver Tappe inline BErrorOutput* 521ad6a8dbeSOliver Tappe ReaderImplBase::ErrorOutput() const 522ad6a8dbeSOliver Tappe { 523ad6a8dbeSOliver Tappe return fErrorOutput; 524ad6a8dbeSOliver Tappe } 525ad6a8dbeSOliver Tappe 526ad6a8dbeSOliver Tappe 5271f633814SIngo Weinhold PackageFileSection* 528ad6a8dbeSOliver Tappe ReaderImplBase::CurrentSection() 529ad6a8dbeSOliver Tappe { 530ad6a8dbeSOliver Tappe return fCurrentSection; 531ad6a8dbeSOliver Tappe } 532ad6a8dbeSOliver Tappe 533ad6a8dbeSOliver Tappe 534ad6a8dbeSOliver Tappe void 5351f633814SIngo Weinhold ReaderImplBase::SetCurrentSection(PackageFileSection* section) 536ad6a8dbeSOliver Tappe { 537ad6a8dbeSOliver Tappe fCurrentSection = section; 538ad6a8dbeSOliver Tappe } 539ad6a8dbeSOliver Tappe 540ad6a8dbeSOliver Tappe 541ad6a8dbeSOliver Tappe template<typename Type> 542ad6a8dbeSOliver Tappe status_t 543ad6a8dbeSOliver Tappe ReaderImplBase::_Read(Type& _value) 544ad6a8dbeSOliver Tappe { 545ad6a8dbeSOliver Tappe return _ReadSectionBuffer(&_value, sizeof(Type)); 546ad6a8dbeSOliver Tappe } 547ad6a8dbeSOliver Tappe 548ad6a8dbeSOliver Tappe 549ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler* 550ad6a8dbeSOliver Tappe ReaderImplBase::CurrentAttributeHandler() const 551ad6a8dbeSOliver Tappe { 552ad6a8dbeSOliver Tappe return fAttributeHandlerStack.Head(); 553ad6a8dbeSOliver Tappe } 554ad6a8dbeSOliver Tappe 555ad6a8dbeSOliver Tappe 556ad6a8dbeSOliver Tappe inline void 557ad6a8dbeSOliver Tappe ReaderImplBase::PushAttributeHandler(AttributeHandler* handler) 558ad6a8dbeSOliver Tappe { 559ad6a8dbeSOliver Tappe fAttributeHandlerStack.Add(handler); 560ad6a8dbeSOliver Tappe } 561ad6a8dbeSOliver Tappe 562ad6a8dbeSOliver Tappe 563ad6a8dbeSOliver Tappe inline ReaderImplBase::AttributeHandler* 564ad6a8dbeSOliver Tappe ReaderImplBase::PopAttributeHandler() 565ad6a8dbeSOliver Tappe { 566ad6a8dbeSOliver Tappe return fAttributeHandlerStack.RemoveHead(); 567ad6a8dbeSOliver Tappe } 568ad6a8dbeSOliver Tappe 569ad6a8dbeSOliver Tappe 570ad6a8dbeSOliver Tappe inline void 571ad6a8dbeSOliver Tappe ReaderImplBase::ClearAttributeHandlerStack() 572ad6a8dbeSOliver Tappe { 573ad6a8dbeSOliver Tappe fAttributeHandlerStack.MakeEmpty(); 574ad6a8dbeSOliver Tappe } 575ad6a8dbeSOliver Tappe 576ad6a8dbeSOliver Tappe 577ad6a8dbeSOliver Tappe } // namespace BPrivate 578ad6a8dbeSOliver Tappe 579ad6a8dbeSOliver Tappe } // namespace BHPKG 580ad6a8dbeSOliver Tappe 581ad6a8dbeSOliver Tappe } // namespace BPackageKit 582ad6a8dbeSOliver Tappe 583ad6a8dbeSOliver Tappe 584ad6a8dbeSOliver Tappe #endif // _PACKAGE__HPKG__PRIVATE__READER_IMPL_BASE_H_ 585