packagefs: Add support for hpkg format V1
* Add union-like class PackageData which wraps the V1 and V2 BPackageData classes. * GlobalFactory: Create a data reader depending on the data format version. * Package: Add a loader for V1 format and try that, if the other one fails.
This commit is contained in:
@@ -91,7 +91,20 @@ HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES =
|
||||
ZlibDecompressor.cpp
|
||||
;
|
||||
|
||||
Includes [ FGristFiles $(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES) ]
|
||||
HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES_V1 =
|
||||
HPKGDefsV1.cpp
|
||||
PackageContentHandlerV1.cpp
|
||||
PackageDataV1.cpp
|
||||
PackageDataReaderV1.cpp
|
||||
PackageEntryV1.cpp
|
||||
PackageEntryAttributeV1.cpp
|
||||
PackageReaderImplV1.cpp
|
||||
ReaderImplBaseV1.cpp
|
||||
;
|
||||
|
||||
Includes
|
||||
[ FGristFiles $(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES)
|
||||
$(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES_V1) ]
|
||||
: [ BuildFeatureAttribute zlib : headers ] ;
|
||||
|
||||
local libSharedSources =
|
||||
@@ -104,6 +117,7 @@ KernelAddon packagefs
|
||||
$(HAIKU_PACKAGE_FS_SOURCES)
|
||||
$(HAIKU_PACKAGE_FS_SHARED_SOURCES)
|
||||
$(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES)
|
||||
$(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES_V1)
|
||||
$(libSharedSources)
|
||||
|
||||
: $(HAIKU_STATIC_LIBSUPC++) kernel_libz.a
|
||||
@@ -114,5 +128,7 @@ SEARCH on [ FGristFiles $(HAIKU_PACKAGE_FS_SHARED_SOURCES) ]
|
||||
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||
SEARCH on [ FGristFiles $(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES) ]
|
||||
+= [ FDirName $(HAIKU_TOP) src kits package hpkg ] ;
|
||||
SEARCH on [ FGristFiles $(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES_V1) ]
|
||||
+= [ FDirName $(HAIKU_TOP) src kits package hpkg v1 ] ;
|
||||
SEARCH on [ FGristFiles $(libSharedSources) ]
|
||||
+= [ FDirName $(HAIKU_TOP) src kits shared ] ;
|
||||
|
||||
@@ -28,7 +28,7 @@ using BPackageKit::BHPKG::BFDDataReader;
|
||||
|
||||
|
||||
static status_t
|
||||
read_package_data(const BPackageData& data, BDataReader* dataReader,
|
||||
read_package_data(const PackageData& data, BDataReader* dataReader,
|
||||
off_t offset, void* buffer, size_t* bufferSize)
|
||||
{
|
||||
// create a PackageDataReader
|
||||
@@ -128,7 +128,7 @@ UnpackingAttributeCookie::ReadAttribute(PackageNode* packageNode,
|
||||
PackageNodeAttribute* attribute, off_t offset, void* buffer,
|
||||
size_t* bufferSize)
|
||||
{
|
||||
const BPackageData& data = attribute->Data();
|
||||
const PackageData& data = attribute->Data();
|
||||
if (data.IsEncodedInline()) {
|
||||
// inline data
|
||||
BBufferDataReader dataReader(data.InlineData(), data.CompressedSize());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||
* Copyright 2009-2013, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <package/hpkg/HPKGDefsPrivate.h>
|
||||
#include <package/hpkg/HPKGDefs.h>
|
||||
|
||||
#include "PackageData.h"
|
||||
|
||||
|
||||
static const uint32 kMaxCachedBuffers = 32;
|
||||
@@ -18,9 +20,13 @@ static const uint32 kMaxCachedBuffers = 32;
|
||||
|
||||
GlobalFactory::GlobalFactory()
|
||||
:
|
||||
fBufferCache(B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB, kMaxCachedBuffers),
|
||||
fPackageDataReaderFactory(&fBufferCache)
|
||||
fBufferCache(BPackageKit::BHPKG::B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB,
|
||||
kMaxCachedBuffers),
|
||||
fPackageDataReaderFactoryV1(&fBufferCache),
|
||||
fPackageDataReaderFactoryV2(&fBufferCache)
|
||||
{
|
||||
STATIC_ASSERT((int)BPackageKit::BHPKG::B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB
|
||||
== (int)BPackageKit::BHPKG::V1::B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,10 +73,20 @@ GlobalFactory::Default()
|
||||
|
||||
status_t
|
||||
GlobalFactory::CreatePackageDataReader(BDataReader* dataReader,
|
||||
const BPackageData& data, BAbstractBufferedDataReader*& _reader)
|
||||
const PackageData& data, BAbstractBufferedDataReader*& _reader)
|
||||
{
|
||||
return fPackageDataReaderFactory.CreatePackageDataReader(dataReader, data,
|
||||
_reader);
|
||||
switch (data.Version()) {
|
||||
case 1:
|
||||
return fPackageDataReaderFactoryV1.CreatePackageDataReader(
|
||||
dataReader, data.DataV1(), _reader);
|
||||
|
||||
case 2:
|
||||
return fPackageDataReaderFactoryV2.CreatePackageDataReader(
|
||||
dataReader, data.DataV2(), _reader);
|
||||
|
||||
default:
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define GLOBAL_FACTORY_H
|
||||
|
||||
|
||||
#include <package/hpkg/HPKGDefs.h>
|
||||
#include <package/hpkg/PackageDataReader.h>
|
||||
#include <package/hpkg/v1/PackageDataReader.h>
|
||||
|
||||
#include "BlockBufferCacheKernel.h"
|
||||
|
||||
@@ -15,8 +15,13 @@
|
||||
using BPackageKit::BHPKG::BDataReader;
|
||||
using BPackageKit::BHPKG::BPackageData;
|
||||
using BPackageKit::BHPKG::BAbstractBufferedDataReader;
|
||||
using BPackageKit::BHPKG::BPackageDataReaderFactory;
|
||||
using BPackageKit::BHPKG::B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB;
|
||||
|
||||
typedef BPackageKit::BHPKG::V1::BPackageDataReaderFactory
|
||||
BPackageDataReaderFactoryV1;
|
||||
typedef BPackageKit::BHPKG::BPackageDataReaderFactory
|
||||
BPackageDataReaderFactoryV2;
|
||||
|
||||
class PackageData;
|
||||
|
||||
|
||||
class GlobalFactory {
|
||||
@@ -30,7 +35,7 @@ public:
|
||||
static GlobalFactory* Default();
|
||||
|
||||
status_t CreatePackageDataReader(BDataReader* dataReader,
|
||||
const BPackageData& data,
|
||||
const PackageData& data,
|
||||
BAbstractBufferedDataReader*& _reader);
|
||||
|
||||
private:
|
||||
@@ -40,7 +45,8 @@ private:
|
||||
static GlobalFactory* sDefaultInstance;
|
||||
|
||||
BlockBufferCacheKernel fBufferCache;
|
||||
BPackageDataReaderFactory fPackageDataReaderFactory;
|
||||
BPackageDataReaderFactoryV1 fPackageDataReaderFactoryV1;
|
||||
BPackageDataReaderFactoryV2 fPackageDataReaderFactoryV2;
|
||||
};
|
||||
|
||||
#endif // GLOBAL_FACTORY_H
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
#include <package/hpkg/PackageEntry.h>
|
||||
#include <package/hpkg/PackageEntryAttribute.h>
|
||||
#include <package/hpkg/PackageReaderImpl.h>
|
||||
#include <package/hpkg/v1/PackageEntry.h>
|
||||
#include <package/hpkg/v1/PackageEntryAttribute.h>
|
||||
#include <package/hpkg/v1/PackageReaderImpl.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
#include "DebugSupport.h"
|
||||
@@ -28,8 +31,23 @@
|
||||
|
||||
|
||||
using namespace BPackageKit;
|
||||
using namespace BPackageKit::BHPKG;
|
||||
using BPackageKit::BHPKG::BPrivate::PackageReaderImpl;
|
||||
|
||||
typedef BPackageKit::BHPKG::BErrorOutput BErrorOutput;
|
||||
typedef BPackageKit::BHPKG::BPackageInfoAttributeValue
|
||||
BPackageInfoAttributeValue;
|
||||
typedef BPackageKit::BHPKG::BPackageVersionData BPackageVersionData;
|
||||
|
||||
// current format version types
|
||||
typedef BPackageKit::BHPKG::BPackageContentHandler BPackageContentHandler;
|
||||
typedef BPackageKit::BHPKG::BPackageEntry BPackageEntry;
|
||||
typedef BPackageKit::BHPKG::BPackageEntryAttribute BPackageEntryAttribute;
|
||||
typedef BPackageKit::BHPKG::BPrivate::PackageReaderImpl PackageReaderImpl;
|
||||
|
||||
// format version V1 types
|
||||
typedef BPackageKit::BHPKG::V1::BPackageContentHandler BPackageContentHandlerV1;
|
||||
typedef BPackageKit::BHPKG::V1::BPackageEntry BPackageEntryV1;
|
||||
typedef BPackageKit::BHPKG::V1::BPackageEntryAttribute BPackageEntryAttributeV1;
|
||||
typedef BPackageKit::BHPKG::V1::BPrivate::PackageReaderImpl PackageReaderImplV1;
|
||||
|
||||
|
||||
const char* const kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = {
|
||||
@@ -95,7 +113,8 @@ struct Package::LoaderContentHandler : BPackageContentHandler {
|
||||
PackageNode* node;
|
||||
if (S_ISREG(mode)) {
|
||||
// file
|
||||
node = new(std::nothrow) PackageFile(fPackage, mode, entry->Data());
|
||||
node = new(std::nothrow) PackageFile(fPackage, mode,
|
||||
PackageData(entry->Data()));
|
||||
} else if (S_ISLNK(mode)) {
|
||||
// symlink
|
||||
String path;
|
||||
@@ -153,7 +172,8 @@ struct Package::LoaderContentHandler : BPackageContentHandler {
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
|
||||
PackageNodeAttribute* nodeAttribute = new(std::nothrow)
|
||||
PackageNodeAttribute(attribute->Type(), attribute->Data());
|
||||
PackageNodeAttribute(attribute->Type(),
|
||||
PackageData(attribute->Data()));
|
||||
if (nodeAttribute == NULL)
|
||||
RETURN_ERROR(B_NO_MEMORY)
|
||||
|
||||
@@ -309,6 +329,258 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - LoaderContentHandlerV1
|
||||
|
||||
|
||||
struct Package::LoaderContentHandlerV1 : BPackageContentHandlerV1 {
|
||||
LoaderContentHandlerV1(Package* package)
|
||||
:
|
||||
fPackage(package),
|
||||
fErrorOccurred(false)
|
||||
{
|
||||
}
|
||||
|
||||
status_t Init()
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandleEntry(BPackageEntryV1* entry)
|
||||
{
|
||||
if (fErrorOccurred)
|
||||
return B_OK;
|
||||
|
||||
PackageDirectory* parentDir = NULL;
|
||||
if (entry->Parent() != NULL) {
|
||||
parentDir = dynamic_cast<PackageDirectory*>(
|
||||
(PackageNode*)entry->Parent()->UserToken());
|
||||
if (parentDir == NULL)
|
||||
RETURN_ERROR(B_BAD_DATA);
|
||||
}
|
||||
|
||||
// get the file mode -- filter out write permissions
|
||||
mode_t mode = entry->Mode() & ~(mode_t)(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||
|
||||
// create the package node
|
||||
PackageNode* node;
|
||||
if (S_ISREG(mode)) {
|
||||
// file
|
||||
node = new(std::nothrow) PackageFile(fPackage, mode,
|
||||
PackageData(entry->Data()));
|
||||
} else if (S_ISLNK(mode)) {
|
||||
// symlink
|
||||
String path;
|
||||
if (!path.SetTo(entry->SymlinkPath()))
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
|
||||
PackageSymlink* symlink = new(std::nothrow) PackageSymlink(
|
||||
fPackage, mode);
|
||||
if (symlink == NULL)
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
|
||||
symlink->SetSymlinkPath(path);
|
||||
node = symlink;
|
||||
} else if (S_ISDIR(mode)) {
|
||||
// directory
|
||||
node = new(std::nothrow) PackageDirectory(fPackage, mode);
|
||||
} else
|
||||
RETURN_ERROR(B_BAD_DATA);
|
||||
|
||||
if (node == NULL)
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
BReference<PackageNode> nodeReference(node, true);
|
||||
|
||||
String entryName;
|
||||
if (!entryName.SetTo(entry->Name()))
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
|
||||
status_t error = node->Init(parentDir, entryName);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
node->SetModifiedTime(entry->ModifiedTime());
|
||||
|
||||
// add it to the parent directory
|
||||
if (parentDir != NULL)
|
||||
parentDir->AddChild(node);
|
||||
else
|
||||
fPackage->AddNode(node);
|
||||
|
||||
entry->SetUserToken(node);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandleEntryAttribute(BPackageEntryV1* entry,
|
||||
BPackageEntryAttributeV1* attribute)
|
||||
{
|
||||
if (fErrorOccurred)
|
||||
return B_OK;
|
||||
|
||||
PackageNode* node = (PackageNode*)entry->UserToken();
|
||||
|
||||
String name;
|
||||
if (!name.SetTo(attribute->Name()))
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
|
||||
PackageNodeAttribute* nodeAttribute = new(std::nothrow)
|
||||
PackageNodeAttribute(attribute->Type(),
|
||||
PackageData(attribute->Data()));
|
||||
if (nodeAttribute == NULL)
|
||||
RETURN_ERROR(B_NO_MEMORY)
|
||||
|
||||
nodeAttribute->Init(name);
|
||||
node->AddAttribute(nodeAttribute);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandleEntryDone(BPackageEntryV1* entry)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandlePackageAttribute(
|
||||
const BPackageInfoAttributeValue& value)
|
||||
{
|
||||
switch (value.attributeID) {
|
||||
case B_PACKAGE_INFO_NAME:
|
||||
{
|
||||
String name;
|
||||
if (!name.SetTo(value.string))
|
||||
return B_NO_MEMORY;
|
||||
fPackage->SetName(name);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case B_PACKAGE_INFO_INSTALL_PATH:
|
||||
{
|
||||
String path;
|
||||
if (!path.SetTo(value.string))
|
||||
return B_NO_MEMORY;
|
||||
fPackage->SetInstallPath(path);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case B_PACKAGE_INFO_VERSION:
|
||||
{
|
||||
::Version* version;
|
||||
status_t error = Version::Create(value.version.major,
|
||||
value.version.minor, value.version.micro,
|
||||
value.version.preRelease, value.version.revision, version);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
fPackage->SetVersion(version);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case B_PACKAGE_INFO_ARCHITECTURE:
|
||||
if (value.unsignedInt >= B_PACKAGE_ARCHITECTURE_ENUM_COUNT)
|
||||
RETURN_ERROR(B_BAD_VALUE);
|
||||
|
||||
fPackage->SetArchitecture(
|
||||
(BPackageArchitecture)value.unsignedInt);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_PROVIDES:
|
||||
{
|
||||
// create a version object, if a version is specified
|
||||
::Version* version = NULL;
|
||||
if (value.resolvable.haveVersion) {
|
||||
const BPackageVersionData& versionInfo
|
||||
= value.resolvable.version;
|
||||
status_t error = Version::Create(versionInfo.major,
|
||||
versionInfo.minor, versionInfo.micro,
|
||||
versionInfo.preRelease, versionInfo.revision, version);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
}
|
||||
ObjectDeleter< ::Version> versionDeleter(version);
|
||||
|
||||
// create a version object, if a compatible version is specified
|
||||
::Version* compatibleVersion = NULL;
|
||||
if (value.resolvable.haveCompatibleVersion) {
|
||||
const BPackageVersionData& versionInfo
|
||||
= value.resolvable.compatibleVersion;
|
||||
status_t error = Version::Create(versionInfo.major,
|
||||
versionInfo.minor, versionInfo.micro,
|
||||
versionInfo.preRelease, versionInfo.revision,
|
||||
compatibleVersion);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
}
|
||||
ObjectDeleter< ::Version> compatibleVersionDeleter(
|
||||
compatibleVersion);
|
||||
|
||||
// create the resolvable
|
||||
Resolvable* resolvable = new(std::nothrow) Resolvable(fPackage);
|
||||
if (resolvable == NULL)
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
ObjectDeleter<Resolvable> resolvableDeleter(resolvable);
|
||||
|
||||
status_t error = resolvable->Init(value.resolvable.name,
|
||||
versionDeleter.Detach(), compatibleVersionDeleter.Detach());
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
fPackage->AddResolvable(resolvableDeleter.Detach());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case B_PACKAGE_INFO_REQUIRES:
|
||||
{
|
||||
// create the dependency
|
||||
Dependency* dependency = new(std::nothrow) Dependency(fPackage);
|
||||
if (dependency == NULL)
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
ObjectDeleter<Dependency> dependencyDeleter(dependency);
|
||||
|
||||
status_t error = dependency->Init(
|
||||
value.resolvableExpression.name);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
// create a version object, if a version is specified
|
||||
::Version* version = NULL;
|
||||
if (value.resolvableExpression.haveOpAndVersion) {
|
||||
const BPackageVersionData& versionInfo
|
||||
= value.resolvableExpression.version;
|
||||
status_t error = Version::Create(versionInfo.major,
|
||||
versionInfo.minor, versionInfo.micro,
|
||||
versionInfo.preRelease, versionInfo.revision, version);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
dependency->SetVersionRequirement(
|
||||
value.resolvableExpression.op, version);
|
||||
}
|
||||
|
||||
fPackage->AddDependency(dependencyDeleter.Detach());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual void HandleErrorOccurred()
|
||||
{
|
||||
fErrorOccurred = true;
|
||||
}
|
||||
|
||||
private:
|
||||
Package* fPackage;
|
||||
bool fErrorOccurred;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - Package
|
||||
|
||||
|
||||
@@ -368,22 +640,38 @@ Package::Load()
|
||||
|
||||
// initialize package reader
|
||||
LoaderErrorOutput errorOutput(this);
|
||||
PackageReaderImpl packageReader(&errorOutput);
|
||||
|
||||
// try current package file format version
|
||||
{
|
||||
PackageReaderImpl packageReader(&errorOutput);
|
||||
status_t error = packageReader.Init(fd, false);
|
||||
if (error == B_OK) {
|
||||
// parse content
|
||||
LoaderContentHandler handler(this);
|
||||
error = handler.Init();
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
RETURN_ERROR(packageReader.ParseContent(&handler));
|
||||
}
|
||||
|
||||
if (error != B_MISMATCHED_VALUES)
|
||||
RETURN_ERROR(error);
|
||||
}
|
||||
|
||||
// try package file format version 1
|
||||
PackageReaderImplV1 packageReader(&errorOutput);
|
||||
status_t error = packageReader.Init(fd, false);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
// parse content
|
||||
LoaderContentHandler handler(this);
|
||||
LoaderContentHandlerV1 handler(this);
|
||||
error = handler.Init();
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
error = packageReader.ParseContent(&handler);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
return B_OK;
|
||||
RETURN_ERROR(packageReader.ParseContent(&handler));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ public:
|
||||
private:
|
||||
struct LoaderErrorOutput;
|
||||
struct LoaderContentHandler;
|
||||
struct LoaderContentHandlerV1;
|
||||
|
||||
private:
|
||||
mutex fLock;
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2013, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PACKAGE_DATA_H
|
||||
#define PACKAGE_DATA_H
|
||||
|
||||
|
||||
#include <package/hpkg/PackageData.h>
|
||||
#include <package/hpkg/v1/PackageData.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
typedef BPackageKit::BHPKG::BPackageData PackageDataV2;
|
||||
typedef BPackageKit::BHPKG::V1::BPackageData PackageDataV1;
|
||||
|
||||
|
||||
class PackageData {
|
||||
public:
|
||||
explicit PackageData(const PackageDataV1& data);
|
||||
explicit PackageData(const PackageDataV2& data);
|
||||
|
||||
uint8 Version() const { return fVersion; }
|
||||
const PackageDataV1& DataV1() const;
|
||||
const PackageDataV2& DataV2() const;
|
||||
|
||||
uint64 CompressedSize() const;
|
||||
uint64 UncompressedSize() const;
|
||||
|
||||
bool IsEncodedInline() const;
|
||||
const uint8* InlineData() const;
|
||||
|
||||
private:
|
||||
static const size_t kDataSize = sizeof(PackageDataV1)
|
||||
> sizeof(PackageDataV2)
|
||||
? sizeof(PackageDataV1)
|
||||
: sizeof(PackageDataV2);
|
||||
|
||||
private:
|
||||
union {
|
||||
char fData[kDataSize];
|
||||
uint64 fAlignmentDummy;
|
||||
};
|
||||
uint8 fVersion;
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
PackageData::PackageData(const PackageDataV1& data)
|
||||
:
|
||||
fVersion(1)
|
||||
{
|
||||
memcpy(&fData, &data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
PackageData::PackageData(const PackageDataV2& data)
|
||||
:
|
||||
fVersion(1)
|
||||
{
|
||||
memcpy(&fData, &data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
inline const PackageDataV1&
|
||||
PackageData::DataV1() const
|
||||
{
|
||||
return *(PackageDataV1*)&fData;
|
||||
}
|
||||
|
||||
|
||||
inline const PackageDataV2&
|
||||
PackageData::DataV2() const
|
||||
{
|
||||
return *(PackageDataV2*)&fData;
|
||||
}
|
||||
|
||||
|
||||
inline uint64
|
||||
PackageData::CompressedSize() const
|
||||
{
|
||||
if (fVersion == 1)
|
||||
return DataV1().CompressedSize();
|
||||
return DataV2().CompressedSize();
|
||||
}
|
||||
|
||||
|
||||
inline uint64
|
||||
PackageData::UncompressedSize() const
|
||||
{
|
||||
if (fVersion == 1)
|
||||
return DataV1().UncompressedSize();
|
||||
return DataV2().UncompressedSize();
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
PackageData::IsEncodedInline() const
|
||||
{
|
||||
if (fVersion == 1)
|
||||
return DataV1().IsEncodedInline();
|
||||
return DataV2().IsEncodedInline();
|
||||
}
|
||||
|
||||
|
||||
inline const uint8*
|
||||
PackageData::InlineData() const
|
||||
{
|
||||
if (fVersion == 1)
|
||||
return DataV1().InlineData();
|
||||
return DataV2().InlineData();
|
||||
}
|
||||
|
||||
|
||||
#endif // PACKAGE_DATA_H
|
||||
@@ -48,7 +48,7 @@ private:
|
||||
|
||||
|
||||
struct PackageFile::DataAccessor {
|
||||
DataAccessor(BPackageData* data)
|
||||
DataAccessor(PackageData* data)
|
||||
:
|
||||
fData(data),
|
||||
fDataReader(NULL),
|
||||
@@ -128,7 +128,7 @@ struct PackageFile::DataAccessor {
|
||||
|
||||
private:
|
||||
mutex fLock;
|
||||
BPackageData* fData;
|
||||
PackageData* fData;
|
||||
BDataReader* fDataReader;
|
||||
BAbstractBufferedDataReader* fReader;
|
||||
void* fFileCache;
|
||||
@@ -138,7 +138,7 @@ private:
|
||||
// #pragma mark - PackageFile
|
||||
|
||||
|
||||
PackageFile::PackageFile(Package* package, mode_t mode, const BPackageData& data)
|
||||
PackageFile::PackageFile(Package* package, mode_t mode, const PackageData& data)
|
||||
:
|
||||
PackageLeafNode(package, mode),
|
||||
fData(data),
|
||||
|
||||
@@ -6,18 +6,14 @@
|
||||
#define PACKAGE_FILE_H
|
||||
|
||||
|
||||
#include <package/hpkg/PackageData.h>
|
||||
|
||||
#include "PackageData.h"
|
||||
#include "PackageLeafNode.h"
|
||||
|
||||
|
||||
using BPackageKit::BHPKG::BPackageData;
|
||||
|
||||
|
||||
class PackageFile : public PackageLeafNode {
|
||||
public:
|
||||
PackageFile(Package* package, mode_t mode,
|
||||
const BPackageData& data);
|
||||
const PackageData& data);
|
||||
virtual ~PackageFile();
|
||||
|
||||
virtual status_t VFSInit(dev_t deviceID, ino_t nodeID);
|
||||
@@ -34,7 +30,7 @@ private:
|
||||
struct DataAccessor;
|
||||
|
||||
private:
|
||||
BPackageData fData;
|
||||
PackageData fData;
|
||||
DataAccessor* fDataAccessor;
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
PackageNodeAttribute::PackageNodeAttribute(uint32 type,
|
||||
const BPackageData& data)
|
||||
const PackageData& data)
|
||||
:
|
||||
fData(data),
|
||||
fName(),
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
|
||||
#include <util/DoublyLinkedList.h>
|
||||
|
||||
#include <package/hpkg/PackageData.h>
|
||||
#include "PackageData.h"
|
||||
|
||||
#include "String.h"
|
||||
|
||||
|
||||
using BPackageKit::BHPKG::BPackageData;
|
||||
|
||||
class PackageNode;
|
||||
|
||||
|
||||
@@ -22,12 +20,12 @@ class PackageNodeAttribute
|
||||
: public DoublyLinkedListLinkImpl<PackageNodeAttribute> {
|
||||
public:
|
||||
PackageNodeAttribute(uint32 type,
|
||||
const BPackageData& data);
|
||||
const PackageData& data);
|
||||
~PackageNodeAttribute();
|
||||
|
||||
const String& Name() const { return fName; }
|
||||
uint32 Type() const { return fType; }
|
||||
const BPackageData& Data() const { return fData; }
|
||||
const PackageData& Data() const { return fData; }
|
||||
|
||||
void Init(const String& name);
|
||||
|
||||
@@ -37,7 +35,7 @@ public:
|
||||
{ return fIndexCookie; }
|
||||
|
||||
protected:
|
||||
BPackageData fData;
|
||||
PackageData fData;
|
||||
String fName;
|
||||
void* fIndexCookie;
|
||||
uint32 fType;
|
||||
|
||||
Reference in New Issue
Block a user