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
|
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 ] ;
|
: [ BuildFeatureAttribute zlib : headers ] ;
|
||||||
|
|
||||||
local libSharedSources =
|
local libSharedSources =
|
||||||
@@ -104,6 +117,7 @@ KernelAddon packagefs
|
|||||||
$(HAIKU_PACKAGE_FS_SOURCES)
|
$(HAIKU_PACKAGE_FS_SOURCES)
|
||||||
$(HAIKU_PACKAGE_FS_SHARED_SOURCES)
|
$(HAIKU_PACKAGE_FS_SHARED_SOURCES)
|
||||||
$(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES)
|
$(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES)
|
||||||
|
$(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES_V1)
|
||||||
$(libSharedSources)
|
$(libSharedSources)
|
||||||
|
|
||||||
: $(HAIKU_STATIC_LIBSUPC++) kernel_libz.a
|
: $(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 ] ;
|
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
SEARCH on [ FGristFiles $(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES) ]
|
SEARCH on [ FGristFiles $(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES) ]
|
||||||
+= [ FDirName $(HAIKU_TOP) src kits package hpkg ] ;
|
+= [ 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) ]
|
SEARCH on [ FGristFiles $(libSharedSources) ]
|
||||||
+= [ FDirName $(HAIKU_TOP) src kits shared ] ;
|
+= [ FDirName $(HAIKU_TOP) src kits shared ] ;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ using BPackageKit::BHPKG::BFDDataReader;
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
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)
|
off_t offset, void* buffer, size_t* bufferSize)
|
||||||
{
|
{
|
||||||
// create a PackageDataReader
|
// create a PackageDataReader
|
||||||
@@ -128,7 +128,7 @@ UnpackingAttributeCookie::ReadAttribute(PackageNode* packageNode,
|
|||||||
PackageNodeAttribute* attribute, off_t offset, void* buffer,
|
PackageNodeAttribute* attribute, off_t offset, void* buffer,
|
||||||
size_t* bufferSize)
|
size_t* bufferSize)
|
||||||
{
|
{
|
||||||
const BPackageData& data = attribute->Data();
|
const PackageData& data = attribute->Data();
|
||||||
if (data.IsEncodedInline()) {
|
if (data.IsEncodedInline()) {
|
||||||
// inline data
|
// inline data
|
||||||
BBufferDataReader dataReader(data.InlineData(), data.CompressedSize());
|
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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -8,7 +8,9 @@
|
|||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include <package/hpkg/HPKGDefsPrivate.h>
|
#include <package/hpkg/HPKGDefs.h>
|
||||||
|
|
||||||
|
#include "PackageData.h"
|
||||||
|
|
||||||
|
|
||||||
static const uint32 kMaxCachedBuffers = 32;
|
static const uint32 kMaxCachedBuffers = 32;
|
||||||
@@ -18,9 +20,13 @@ static const uint32 kMaxCachedBuffers = 32;
|
|||||||
|
|
||||||
GlobalFactory::GlobalFactory()
|
GlobalFactory::GlobalFactory()
|
||||||
:
|
:
|
||||||
fBufferCache(B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB, kMaxCachedBuffers),
|
fBufferCache(BPackageKit::BHPKG::B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB,
|
||||||
fPackageDataReaderFactory(&fBufferCache)
|
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
|
status_t
|
||||||
GlobalFactory::CreatePackageDataReader(BDataReader* dataReader,
|
GlobalFactory::CreatePackageDataReader(BDataReader* dataReader,
|
||||||
const BPackageData& data, BAbstractBufferedDataReader*& _reader)
|
const PackageData& data, BAbstractBufferedDataReader*& _reader)
|
||||||
{
|
{
|
||||||
return fPackageDataReaderFactory.CreatePackageDataReader(dataReader, data,
|
switch (data.Version()) {
|
||||||
_reader);
|
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
|
#define GLOBAL_FACTORY_H
|
||||||
|
|
||||||
|
|
||||||
#include <package/hpkg/HPKGDefs.h>
|
|
||||||
#include <package/hpkg/PackageDataReader.h>
|
#include <package/hpkg/PackageDataReader.h>
|
||||||
|
#include <package/hpkg/v1/PackageDataReader.h>
|
||||||
|
|
||||||
#include "BlockBufferCacheKernel.h"
|
#include "BlockBufferCacheKernel.h"
|
||||||
|
|
||||||
@@ -15,8 +15,13 @@
|
|||||||
using BPackageKit::BHPKG::BDataReader;
|
using BPackageKit::BHPKG::BDataReader;
|
||||||
using BPackageKit::BHPKG::BPackageData;
|
using BPackageKit::BHPKG::BPackageData;
|
||||||
using BPackageKit::BHPKG::BAbstractBufferedDataReader;
|
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 {
|
class GlobalFactory {
|
||||||
@@ -30,7 +35,7 @@ public:
|
|||||||
static GlobalFactory* Default();
|
static GlobalFactory* Default();
|
||||||
|
|
||||||
status_t CreatePackageDataReader(BDataReader* dataReader,
|
status_t CreatePackageDataReader(BDataReader* dataReader,
|
||||||
const BPackageData& data,
|
const PackageData& data,
|
||||||
BAbstractBufferedDataReader*& _reader);
|
BAbstractBufferedDataReader*& _reader);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -40,7 +45,8 @@ private:
|
|||||||
static GlobalFactory* sDefaultInstance;
|
static GlobalFactory* sDefaultInstance;
|
||||||
|
|
||||||
BlockBufferCacheKernel fBufferCache;
|
BlockBufferCacheKernel fBufferCache;
|
||||||
BPackageDataReaderFactory fPackageDataReaderFactory;
|
BPackageDataReaderFactoryV1 fPackageDataReaderFactoryV1;
|
||||||
|
BPackageDataReaderFactoryV2 fPackageDataReaderFactoryV2;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GLOBAL_FACTORY_H
|
#endif // GLOBAL_FACTORY_H
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
#include <package/hpkg/PackageEntry.h>
|
#include <package/hpkg/PackageEntry.h>
|
||||||
#include <package/hpkg/PackageEntryAttribute.h>
|
#include <package/hpkg/PackageEntryAttribute.h>
|
||||||
#include <package/hpkg/PackageReaderImpl.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 <util/AutoLock.h>
|
||||||
|
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
@@ -28,8 +31,23 @@
|
|||||||
|
|
||||||
|
|
||||||
using namespace BPackageKit;
|
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] = {
|
const char* const kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = {
|
||||||
@@ -95,7 +113,8 @@ struct Package::LoaderContentHandler : BPackageContentHandler {
|
|||||||
PackageNode* node;
|
PackageNode* node;
|
||||||
if (S_ISREG(mode)) {
|
if (S_ISREG(mode)) {
|
||||||
// file
|
// 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)) {
|
} else if (S_ISLNK(mode)) {
|
||||||
// symlink
|
// symlink
|
||||||
String path;
|
String path;
|
||||||
@@ -153,7 +172,8 @@ struct Package::LoaderContentHandler : BPackageContentHandler {
|
|||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
|
||||||
PackageNodeAttribute* nodeAttribute = new(std::nothrow)
|
PackageNodeAttribute* nodeAttribute = new(std::nothrow)
|
||||||
PackageNodeAttribute(attribute->Type(), attribute->Data());
|
PackageNodeAttribute(attribute->Type(),
|
||||||
|
PackageData(attribute->Data()));
|
||||||
if (nodeAttribute == NULL)
|
if (nodeAttribute == NULL)
|
||||||
RETURN_ERROR(B_NO_MEMORY)
|
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
|
// #pragma mark - Package
|
||||||
|
|
||||||
|
|
||||||
@@ -368,22 +640,38 @@ Package::Load()
|
|||||||
|
|
||||||
// initialize package reader
|
// initialize package reader
|
||||||
LoaderErrorOutput errorOutput(this);
|
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);
|
status_t error = packageReader.Init(fd, false);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
// parse content
|
// parse content
|
||||||
LoaderContentHandler handler(this);
|
LoaderContentHandlerV1 handler(this);
|
||||||
error = handler.Init();
|
error = handler.Init();
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
error = packageReader.ParseContent(&handler);
|
RETURN_ERROR(packageReader.ParseContent(&handler));
|
||||||
if (error != B_OK)
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
struct LoaderErrorOutput;
|
struct LoaderErrorOutput;
|
||||||
struct LoaderContentHandler;
|
struct LoaderContentHandler;
|
||||||
|
struct LoaderContentHandlerV1;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutex fLock;
|
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 {
|
struct PackageFile::DataAccessor {
|
||||||
DataAccessor(BPackageData* data)
|
DataAccessor(PackageData* data)
|
||||||
:
|
:
|
||||||
fData(data),
|
fData(data),
|
||||||
fDataReader(NULL),
|
fDataReader(NULL),
|
||||||
@@ -128,7 +128,7 @@ struct PackageFile::DataAccessor {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
mutex fLock;
|
mutex fLock;
|
||||||
BPackageData* fData;
|
PackageData* fData;
|
||||||
BDataReader* fDataReader;
|
BDataReader* fDataReader;
|
||||||
BAbstractBufferedDataReader* fReader;
|
BAbstractBufferedDataReader* fReader;
|
||||||
void* fFileCache;
|
void* fFileCache;
|
||||||
@@ -138,7 +138,7 @@ private:
|
|||||||
// #pragma mark - PackageFile
|
// #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),
|
PackageLeafNode(package, mode),
|
||||||
fData(data),
|
fData(data),
|
||||||
|
|||||||
@@ -6,18 +6,14 @@
|
|||||||
#define PACKAGE_FILE_H
|
#define PACKAGE_FILE_H
|
||||||
|
|
||||||
|
|
||||||
#include <package/hpkg/PackageData.h>
|
#include "PackageData.h"
|
||||||
|
|
||||||
#include "PackageLeafNode.h"
|
#include "PackageLeafNode.h"
|
||||||
|
|
||||||
|
|
||||||
using BPackageKit::BHPKG::BPackageData;
|
|
||||||
|
|
||||||
|
|
||||||
class PackageFile : public PackageLeafNode {
|
class PackageFile : public PackageLeafNode {
|
||||||
public:
|
public:
|
||||||
PackageFile(Package* package, mode_t mode,
|
PackageFile(Package* package, mode_t mode,
|
||||||
const BPackageData& data);
|
const PackageData& data);
|
||||||
virtual ~PackageFile();
|
virtual ~PackageFile();
|
||||||
|
|
||||||
virtual status_t VFSInit(dev_t deviceID, ino_t nodeID);
|
virtual status_t VFSInit(dev_t deviceID, ino_t nodeID);
|
||||||
@@ -34,7 +30,7 @@ private:
|
|||||||
struct DataAccessor;
|
struct DataAccessor;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BPackageData fData;
|
PackageData fData;
|
||||||
DataAccessor* fDataAccessor;
|
DataAccessor* fDataAccessor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
|
|
||||||
PackageNodeAttribute::PackageNodeAttribute(uint32 type,
|
PackageNodeAttribute::PackageNodeAttribute(uint32 type,
|
||||||
const BPackageData& data)
|
const PackageData& data)
|
||||||
:
|
:
|
||||||
fData(data),
|
fData(data),
|
||||||
fName(),
|
fName(),
|
||||||
|
|||||||
@@ -8,13 +8,11 @@
|
|||||||
|
|
||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
#include <package/hpkg/PackageData.h>
|
#include "PackageData.h"
|
||||||
|
|
||||||
#include "String.h"
|
#include "String.h"
|
||||||
|
|
||||||
|
|
||||||
using BPackageKit::BHPKG::BPackageData;
|
|
||||||
|
|
||||||
class PackageNode;
|
class PackageNode;
|
||||||
|
|
||||||
|
|
||||||
@@ -22,12 +20,12 @@ class PackageNodeAttribute
|
|||||||
: public DoublyLinkedListLinkImpl<PackageNodeAttribute> {
|
: public DoublyLinkedListLinkImpl<PackageNodeAttribute> {
|
||||||
public:
|
public:
|
||||||
PackageNodeAttribute(uint32 type,
|
PackageNodeAttribute(uint32 type,
|
||||||
const BPackageData& data);
|
const PackageData& data);
|
||||||
~PackageNodeAttribute();
|
~PackageNodeAttribute();
|
||||||
|
|
||||||
const String& Name() const { return fName; }
|
const String& Name() const { return fName; }
|
||||||
uint32 Type() const { return fType; }
|
uint32 Type() const { return fType; }
|
||||||
const BPackageData& Data() const { return fData; }
|
const PackageData& Data() const { return fData; }
|
||||||
|
|
||||||
void Init(const String& name);
|
void Init(const String& name);
|
||||||
|
|
||||||
@@ -37,7 +35,7 @@ public:
|
|||||||
{ return fIndexCookie; }
|
{ return fIndexCookie; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BPackageData fData;
|
PackageData fData;
|
||||||
String fName;
|
String fName;
|
||||||
void* fIndexCookie;
|
void* fIndexCookie;
|
||||||
uint32 fType;
|
uint32 fType;
|
||||||
|
|||||||
Reference in New Issue
Block a user