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