* Changed the UnzipEngine to be a BCommandPipe::LineReader itself, this
simplified the code somewhat (maintaining of state). * UnzipEngine does a more complete parsing of the .zip contents and maintains a hashmap of item names to byte size entries. During unzipping later on, this allows to know how many bytes were unzipped for the given item. * Test whether folders from the .zip already exists, and exclude them from the item count, since unzip will not report creating folders that already existed. * Added the unzipping of packages in the _package_ folder to WorkerThread, but it is currently commented out to keep Installer in a working state. It would work, but the problem is that the progress bar would reset itself at the moment (for every package). * Started a ProgressReporter class that will later be used by all CopyEngine and UnzipEngine instances. This is work in progress and not yet part of the build. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32959 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -3,12 +3,13 @@ SubDir HAIKU_TOP src apps installer ;
|
|||||||
UsePrivateHeaders shared storage tracker ;
|
UsePrivateHeaders shared storage tracker ;
|
||||||
SubDirHdrs [ FDirName $(HAIKU_TOP) src kits tracker ] ;
|
SubDirHdrs [ FDirName $(HAIKU_TOP) src kits tracker ] ;
|
||||||
|
|
||||||
Application Installer :
|
Application Installer :
|
||||||
CopyEngine.cpp
|
CopyEngine.cpp
|
||||||
InstallerApp.cpp
|
InstallerApp.cpp
|
||||||
InstallerWindow.cpp
|
InstallerWindow.cpp
|
||||||
PackageViews.cpp
|
PackageViews.cpp
|
||||||
PartitionMenuItem.cpp
|
PartitionMenuItem.cpp
|
||||||
|
UnzipEngine.cpp
|
||||||
WorkerThread.cpp
|
WorkerThread.cpp
|
||||||
: be tracker translation $(TARGET_LIBSTDC++)
|
: be tracker translation libshared.a $(TARGET_LIBSTDC++)
|
||||||
: Installer.rdef ;
|
: Installer.rdef ;
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Stephan Aßmus <[email protected]>
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ProgressReporter.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
using std::nothrow;
|
||||||
|
|
||||||
|
|
||||||
|
ProgressReporter::ProgressReporter(const BMessenger& messenger,
|
||||||
|
BMessage* message)
|
||||||
|
:
|
||||||
|
fBytesRead(0),
|
||||||
|
fItemsCopied(0),
|
||||||
|
fTimeRead(0),
|
||||||
|
|
||||||
|
fBytesWritten(0),
|
||||||
|
fTimeWritten(0),
|
||||||
|
|
||||||
|
fBytesToCopy(0),
|
||||||
|
fItemsToCopy(0),
|
||||||
|
|
||||||
|
fMessenger(messenger),
|
||||||
|
fMessage(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ProgressReporter::~ProgressReporter()
|
||||||
|
{
|
||||||
|
delete fMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ProgressReporter::Reset()
|
||||||
|
{
|
||||||
|
fBytesRead = 0;
|
||||||
|
fItemsCopied = 0;
|
||||||
|
fTimeRead = 0;
|
||||||
|
|
||||||
|
fBytesWritten = 0;
|
||||||
|
fTimeWritten = 0;
|
||||||
|
|
||||||
|
fBytesToCopy = 0;
|
||||||
|
fItemsToCopy = 0;
|
||||||
|
|
||||||
|
if (fMessage) {
|
||||||
|
BMessage message(*fMessage);
|
||||||
|
message.AddString("status", "Collecting copy information.");
|
||||||
|
fMessenger.SendMessage(&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ProgressReporter::AddItems(uint64 count, off_t bytes)
|
||||||
|
{
|
||||||
|
// TODO ...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ProgressReporter::StartTimer()
|
||||||
|
{
|
||||||
|
// TODO ...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ProgressReporter::ItemsCopied(uint64 items, off_t bytes, const char* itemName,
|
||||||
|
const char* targetFolder)
|
||||||
|
{
|
||||||
|
// TODO ...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ProgressReporter::_UpdateProgress(const char* itemName,
|
||||||
|
const char* targetFolder)
|
||||||
|
{
|
||||||
|
if (fMessage != NULL) {
|
||||||
|
BMessage message(*fMessage);
|
||||||
|
float progress = 100.0 * fBytesRead / fBytesToCopy;
|
||||||
|
message.AddFloat("progress", progress);
|
||||||
|
message.AddInt32("current", fItemsCopied);
|
||||||
|
message.AddInt32("maximum", fItemsToCopy);
|
||||||
|
message.AddString("item", itemName);
|
||||||
|
message.AddString("folder", targetFolder);
|
||||||
|
fMessenger.SendMessage(&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Stephan Aßmus <[email protected]>
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef PROGRESS_REPORTER_H
|
||||||
|
#define PROGRESS_REPORTER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Messenger.h>
|
||||||
|
|
||||||
|
|
||||||
|
class ProgressReporter {
|
||||||
|
public:
|
||||||
|
ProgressReporter(const BMessenger& messenger,
|
||||||
|
BMessage* message);
|
||||||
|
virtual ~ProgressReporter();
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
void AddItems(uint64 count, off_t bytes);
|
||||||
|
|
||||||
|
void StartTimer();
|
||||||
|
|
||||||
|
void ItemsCopied(uint64 items, off_t bytes,
|
||||||
|
const char* itemName,
|
||||||
|
const char* targetFolder);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _UpdateProgress(const char* itemName,
|
||||||
|
const char* targetFolder);
|
||||||
|
|
||||||
|
private:
|
||||||
|
off_t fBytesRead;
|
||||||
|
uint64 fItemsCopied;
|
||||||
|
bigtime_t fTimeRead;
|
||||||
|
|
||||||
|
off_t fBytesWritten;
|
||||||
|
bigtime_t fTimeWritten;
|
||||||
|
|
||||||
|
off_t fBytesToCopy;
|
||||||
|
uint64 fItemsToCopy;
|
||||||
|
|
||||||
|
BMessenger fMessenger;
|
||||||
|
BMessage* fMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PROGRESS_REPORTER_H
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2009, Stephan Aßmus <[email protected]>
|
* Copyright 2009, Stephan Aßmus <[email protected]>
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -26,20 +26,20 @@
|
|||||||
using std::nothrow;
|
using std::nothrow;
|
||||||
|
|
||||||
|
|
||||||
UnzipEngine::UnzipEngine(const BMessenger& messenger, BMessage* message)
|
UnzipEngine::UnzipEngine(const BMessenger& messenger, BMessage* message,
|
||||||
|
sem_id cancelSemaphore)
|
||||||
:
|
:
|
||||||
fPackage(""),
|
fPackage(""),
|
||||||
|
fRetrievingListing(false),
|
||||||
|
|
||||||
fBytesToUncompress(0),
|
fBytesToUncompress(0),
|
||||||
fBytesUncompressed(0),
|
fBytesUncompressed(0),
|
||||||
fItemsToUncompress(0),
|
fItemsToUncompress(0),
|
||||||
fItemsUncompressed(0),
|
fItemsUncompressed(0),
|
||||||
|
|
||||||
fCurrentTargetFolder(NULL),
|
|
||||||
fCurrentItem(NULL),
|
|
||||||
|
|
||||||
fMessenger(messenger),
|
fMessenger(messenger),
|
||||||
fMessage(message)
|
fMessage(message),
|
||||||
|
fCancelSemaphore(cancelSemaphore)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,16 +51,22 @@ UnzipEngine::~UnzipEngine()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
UnzipEngine::SetTo(const char* pathToPackage)
|
UnzipEngine::SetTo(const char* pathToPackage, const char* destinationFolder)
|
||||||
{
|
{
|
||||||
fPackage = pathToPackage;
|
fPackage = pathToPackage;
|
||||||
|
fDestinationFolder = destinationFolder;
|
||||||
|
|
||||||
|
fEntrySizeMap.Clear();
|
||||||
|
|
||||||
|
fBytesToUncompress = 0;
|
||||||
|
fBytesUncompressed = 0;
|
||||||
|
fItemsToUncompress = 0;
|
||||||
|
fItemsUncompressed = 0;
|
||||||
|
|
||||||
BPrivate::BCommandPipe commandPipe;
|
BPrivate::BCommandPipe commandPipe;
|
||||||
status_t ret = commandPipe.AddArg("unzip");
|
status_t ret = commandPipe.AddArg("unzip");
|
||||||
if (ret == B_OK)
|
if (ret == B_OK)
|
||||||
ret = commandPipe.AddArg("-Z");
|
ret = commandPipe.AddArg("-l");
|
||||||
if (ret == B_OK)
|
|
||||||
ret = commandPipe.AddArg("-t");
|
|
||||||
if (ret == B_OK)
|
if (ret == B_OK)
|
||||||
ret = commandPipe.AddArg(fPackage.String());
|
ret = commandPipe.AddArg(fPackage.String());
|
||||||
if (ret != B_OK)
|
if (ret != B_OK)
|
||||||
@@ -72,30 +78,19 @@ UnzipEngine::SetTo(const char* pathToPackage)
|
|||||||
if (unzipThread < 0)
|
if (unzipThread < 0)
|
||||||
return (status_t)unzipThread;
|
return (status_t)unzipThread;
|
||||||
|
|
||||||
BString result = commandPipe.ReadLines(stdOutAndErrPipe);
|
fRetrievingListing = true;
|
||||||
static const char* kListingFormat = "%llu files, %llu bytes uncompressed, "
|
ret = commandPipe.ReadLines(stdOutAndErrPipe, this);
|
||||||
"%llu bytes compressed: %f%%";
|
fRetrievingListing = false;
|
||||||
|
|
||||||
uint64 bytesCompressed;
|
printf("%llu items in %llu bytes\n", fItemsToUncompress,
|
||||||
float compresssionRatio;
|
|
||||||
if (sscanf(result.String(), kListingFormat, &fItemsToUncompress,
|
|
||||||
&fBytesToUncompress, &bytesCompressed, &compresssionRatio) != 4) {
|
|
||||||
fBytesToUncompress = 0;
|
|
||||||
fItemsToUncompress = 0;
|
|
||||||
fprintf(stderr, "error reading command output: %s\n", result.String());
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s: %llu items in %llu bytes\n", pathToPackage, fItemsToUncompress,
|
|
||||||
fBytesToUncompress);
|
fBytesToUncompress);
|
||||||
|
|
||||||
return B_OK;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
UnzipEngine::UnzipPackage(const char* destinationFolder,
|
UnzipEngine::UnzipPackage()
|
||||||
sem_id cancelSemaphore)
|
|
||||||
{
|
{
|
||||||
if (fItemsToUncompress == 0)
|
if (fItemsToUncompress == 0)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
@@ -115,7 +110,7 @@ UnzipEngine::UnzipPackage(const char* destinationFolder,
|
|||||||
if (ret == B_OK)
|
if (ret == B_OK)
|
||||||
ret = commandPipe.AddArg("-d");
|
ret = commandPipe.AddArg("-d");
|
||||||
if (ret == B_OK)
|
if (ret == B_OK)
|
||||||
ret = commandPipe.AddArg(destinationFolder);
|
ret = commandPipe.AddArg(fDestinationFolder.String());
|
||||||
if (ret == B_OK)
|
if (ret == B_OK)
|
||||||
ret = commandPipe.AddArg("-x");
|
ret = commandPipe.AddArg("-x");
|
||||||
if (ret == B_OK)
|
if (ret == B_OK)
|
||||||
@@ -129,87 +124,139 @@ UnzipEngine::UnzipPackage(const char* destinationFolder,
|
|||||||
if (unzipThread < 0)
|
if (unzipThread < 0)
|
||||||
return (status_t)unzipThread;
|
return (status_t)unzipThread;
|
||||||
|
|
||||||
return _ReadFromPipe(stdOutAndErrPipe, commandPipe, cancelSemaphore);
|
return commandPipe.ReadLines(stdOutAndErrPipe, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
status_t
|
bool
|
||||||
UnzipEngine::_ReadFromPipe(FILE* stdOutAndErrPipe,
|
UnzipEngine::IsCanceled()
|
||||||
BPrivate::BCommandPipe& commandPipe, sem_id cancelSemaphore)
|
|
||||||
{
|
{
|
||||||
class LineReader : public BPrivate::BCommandPipe::LineReader {
|
if (fCancelSemaphore < 0)
|
||||||
public:
|
return false;
|
||||||
LineReader(sem_id cancelSemaphore, off_t bytesToUncompress,
|
|
||||||
uint64 itemsToUncompress, BMessenger& messenger,
|
|
||||||
const BMessage* message)
|
|
||||||
:
|
|
||||||
fCancelSemaphore(cancelSemaphore),
|
|
||||||
|
|
||||||
fBytesToUncompress(itemsToUncompress),
|
SemaphoreLocker locker(fCancelSemaphore);
|
||||||
fBytesUncompressed(0),
|
return !locker.IsLocked();
|
||||||
fItemsToUncompress(itemsToUncompress),
|
}
|
||||||
fItemsUncompressed(0),
|
|
||||||
|
|
||||||
fMessenger(messenger),
|
|
||||||
fMessage(message)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool IsCanceled()
|
status_t
|
||||||
{
|
UnzipEngine::ReadLine(const BString& line)
|
||||||
if (fCancelSemaphore < 0)
|
{
|
||||||
return false;
|
if (fRetrievingListing)
|
||||||
|
return _ReadLineListing(line);
|
||||||
|
else
|
||||||
|
return _ReadLineExtract(line);
|
||||||
|
}
|
||||||
|
|
||||||
SemaphoreLocker locker(fCancelSemaphore);
|
|
||||||
return !locker.IsLocked();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual status_t ReadLine(const BString& line)
|
status_t
|
||||||
{
|
UnzipEngine::_ReadLineListing(const BString& line)
|
||||||
char item[1024];
|
{
|
||||||
char linkTarget[256];
|
// static const char* kListingFormat = "%llu files, %llu bytes uncompressed, "
|
||||||
const char* kInflatingFormat = " inflating: %s\n";
|
// "%llu bytes compressed: %f%%";
|
||||||
const char* kLinkingFormat = " linking: %s -> %s\n";
|
//
|
||||||
if (sscanf(line.String(), kInflatingFormat, &item) == 1
|
// uint64 bytesCompressed;
|
||||||
|| sscanf(line.String(), kLinkingFormat, &item,
|
// float compresssionRatio;
|
||||||
&linkTarget) == 2) {
|
// if (sscanf(line.String(), kListingFormat, &fItemsToUncompress,
|
||||||
BString itemPath(item);
|
// &fBytesToUncompress, &bytesCompressed, &compresssionRatio) != 4) {
|
||||||
int pos = itemPath.FindLast('/');
|
// fBytesToUncompress = 0;
|
||||||
BString itemName = itemPath.String() + pos + 1;
|
// fItemsToUncompress = 0;
|
||||||
itemPath.Truncate(pos);
|
// fprintf(stderr, "error reading command output: %s\n", line.String());
|
||||||
printf("extracted %s to %s\n", itemName.String(),
|
// return B_ERROR;
|
||||||
itemPath.String());
|
// }
|
||||||
} else {
|
|
||||||
printf("ignored: %s", line.String());
|
static const char* kListingFormat = "%llu %s %s %s\n";
|
||||||
|
|
||||||
|
const char* string = line.String();
|
||||||
|
while (string[0] == ' ')
|
||||||
|
string++;
|
||||||
|
|
||||||
|
uint64 bytes;
|
||||||
|
char date[16];
|
||||||
|
char time[16];
|
||||||
|
char path[1024];
|
||||||
|
if (sscanf(string, kListingFormat, &bytes, &date, &time, &path) == 4) {
|
||||||
|
fBytesToUncompress += bytes;
|
||||||
|
|
||||||
|
BString itemPath(path);
|
||||||
|
BString itemName(path);
|
||||||
|
int leafPos = itemPath.FindLast('/');
|
||||||
|
if (leafPos >= 0)
|
||||||
|
itemName = itemPath.String() + leafPos + 1;
|
||||||
|
|
||||||
|
// We check if the target folder exists and don't increment
|
||||||
|
// the item count in that case. Unzip won't report on folders that did
|
||||||
|
// not need to be created. This may mess up our current item count.
|
||||||
|
uint32 itemCount = 1;
|
||||||
|
if (bytes == 0 && itemName.Length() == 0) {
|
||||||
|
// a folder?
|
||||||
|
BPath destination(fDestinationFolder.String());
|
||||||
|
if (destination.Append(itemPath.String()) == B_OK) {
|
||||||
|
BEntry test(destination.Path());
|
||||||
|
if (test.Exists() && test.IsDirectory()) {
|
||||||
|
printf("ignoring %s\n", itemPath.String());
|
||||||
|
itemCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
fItemsToUncompress += itemCount;
|
||||||
sem_id fCancelSemaphore;
|
|
||||||
|
|
||||||
off_t fBytesToUncompress;
|
printf("item %s with %llu bytes to %s\n", itemName.String(),
|
||||||
off_t fBytesUncompressed;
|
bytes, itemPath.String());
|
||||||
uint64 fItemsToUncompress;
|
|
||||||
uint64 fItemsUncompressed;
|
|
||||||
|
|
||||||
BMessenger& fMessenger;
|
fEntrySizeMap.Put(itemName.String(), bytes);
|
||||||
const BMessage* fMessage;
|
} else {
|
||||||
};
|
// printf("listing not understood: %s", string);
|
||||||
|
}
|
||||||
|
|
||||||
LineReader lineReader(cancelSemaphore, fBytesToUncompress,
|
return B_OK;
|
||||||
fItemsToUncompress, fMessenger, fMessage);
|
}
|
||||||
|
|
||||||
return commandPipe.ReadLines(stdOutAndErrPipe, &lineReader);
|
|
||||||
|
status_t
|
||||||
|
UnzipEngine::_ReadLineExtract(const BString& line)
|
||||||
|
{
|
||||||
|
char item[1024];
|
||||||
|
char linkTarget[256];
|
||||||
|
const char* kCreatingFormat = " creating: %s\n";
|
||||||
|
const char* kInflatingFormat = " inflating: %s\n";
|
||||||
|
const char* kLinkingFormat = " linking: %s -> %s\n";
|
||||||
|
if (sscanf(line.String(), kCreatingFormat, &item) == 1
|
||||||
|
|| sscanf(line.String(), kInflatingFormat, &item) == 1
|
||||||
|
|| sscanf(line.String(), kLinkingFormat, &item,
|
||||||
|
&linkTarget) == 2) {
|
||||||
|
|
||||||
|
fItemsUncompressed++;
|
||||||
|
|
||||||
|
BString itemPath(item);
|
||||||
|
int pos = itemPath.FindLast('/');
|
||||||
|
BString itemName = itemPath.String() + pos + 1;
|
||||||
|
itemPath.Truncate(pos);
|
||||||
|
|
||||||
|
off_t bytes = 0;
|
||||||
|
if (fEntrySizeMap.ContainsKey(itemName.String())) {
|
||||||
|
bytes = fEntrySizeMap.Get(itemName.String());
|
||||||
|
fBytesUncompressed += bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%llu extracted %s to %s (%llu)\n", fItemsUncompressed,
|
||||||
|
itemName.String(), itemPath.String(), bytes);
|
||||||
|
|
||||||
|
_UpdateProgress(itemName.String(), itemPath.String());
|
||||||
|
} else {
|
||||||
|
// printf("ignored: %s", line.String());
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
UnzipEngine::_UpdateProgress()
|
UnzipEngine::_UpdateProgress(const char* item, const char* targetFolder)
|
||||||
{
|
{
|
||||||
if (fMessage != NULL) {
|
if (fMessage != NULL) {
|
||||||
BMessage message(*fMessage);
|
BMessage message(*fMessage);
|
||||||
@@ -217,8 +264,8 @@ UnzipEngine::_UpdateProgress()
|
|||||||
message.AddFloat("progress", progress);
|
message.AddFloat("progress", progress);
|
||||||
message.AddInt32("current", fItemsUncompressed);
|
message.AddInt32("current", fItemsUncompressed);
|
||||||
message.AddInt32("maximum", fItemsToUncompress);
|
message.AddInt32("maximum", fItemsToUncompress);
|
||||||
message.AddString("item", fCurrentItem);
|
message.AddString("item", item);
|
||||||
message.AddString("folder", fCurrentTargetFolder);
|
message.AddString("folder", targetFolder);
|
||||||
fMessenger.SendMessage(&message);
|
fMessenger.SendMessage(&message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,43 +11,60 @@
|
|||||||
#include <Messenger.h>
|
#include <Messenger.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
namespace BPrivate {
|
#include "CommandPipe.h"
|
||||||
class BCommandPipe;
|
#include "HashMap.h"
|
||||||
}
|
#include "HashString.h"
|
||||||
|
|
||||||
class BMessage;
|
class BMessage;
|
||||||
class BMessenger;
|
class BMessenger;
|
||||||
|
|
||||||
|
|
||||||
class UnzipEngine {
|
class UnzipEngine : private BCommandPipe::LineReader {
|
||||||
public:
|
public:
|
||||||
UnzipEngine(const BMessenger& messenger,
|
UnzipEngine(const BMessenger& messenger,
|
||||||
BMessage* message);
|
BMessage* message,
|
||||||
|
sem_id cancelSemaphore = -1);
|
||||||
virtual ~UnzipEngine();
|
virtual ~UnzipEngine();
|
||||||
|
|
||||||
status_t SetTo(const char* pathToPackage);
|
status_t SetTo(const char* pathToPackage,
|
||||||
|
const char* destinationFolder);
|
||||||
|
|
||||||
status_t UnzipPackage(const char* destinationFolder,
|
inline off_t BytesToUncompress() const
|
||||||
sem_id cancelSemaphore = -1);
|
{ return fBytesToUncompress; }
|
||||||
|
inline uint64 ItemsToUncompress() const
|
||||||
|
{ return fItemsToUncompress; }
|
||||||
|
|
||||||
|
status_t UnzipPackage();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _ReadFromPipe(FILE* stdOutAndErrPipe,
|
// BCommandPipe::LineReader
|
||||||
BPrivate::BCommandPipe& commandPipe,
|
friend class BCommandPipe;
|
||||||
sem_id cancelSemaphore);
|
|
||||||
void _UpdateProgress();
|
virtual bool IsCanceled();
|
||||||
|
virtual status_t ReadLine(const BString& line);
|
||||||
|
|
||||||
|
status_t _ReadLineListing(const BString& line);
|
||||||
|
status_t _ReadLineExtract(const BString& line);
|
||||||
|
|
||||||
|
void _UpdateProgress(const char* item,
|
||||||
|
const char* targetFolder);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BString fPackage;
|
BString fPackage;
|
||||||
|
BString fDestinationFolder;
|
||||||
|
bool fRetrievingListing;
|
||||||
|
|
||||||
|
typedef HashMap<HashString, off_t> EntrySizeMap;
|
||||||
|
EntrySizeMap fEntrySizeMap;
|
||||||
|
|
||||||
off_t fBytesToUncompress;
|
off_t fBytesToUncompress;
|
||||||
off_t fBytesUncompressed;
|
off_t fBytesUncompressed;
|
||||||
uint64 fItemsToUncompress;
|
uint64 fItemsToUncompress;
|
||||||
uint64 fItemsUncompressed;
|
uint64 fItemsUncompressed;
|
||||||
|
|
||||||
const char* fCurrentTargetFolder;
|
|
||||||
const char* fCurrentItem;
|
|
||||||
|
|
||||||
BMessenger fMessenger;
|
BMessenger fMessenger;
|
||||||
BMessage* fMessage;
|
BMessage* fMessage;
|
||||||
|
sem_id fCancelSemaphore;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "InstallerWindow.h"
|
#include "InstallerWindow.h"
|
||||||
#include "PackageViews.h"
|
#include "PackageViews.h"
|
||||||
#include "PartitionMenuItem.h"
|
#include "PartitionMenuItem.h"
|
||||||
|
#include "UnzipEngine.h"
|
||||||
|
|
||||||
|
|
||||||
//#define COPY_TRACE
|
//#define COPY_TRACE
|
||||||
@@ -390,6 +391,8 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu)
|
|||||||
"version.",
|
"version.",
|
||||||
"Install Anyway", "Cancel", 0,
|
"Install Anyway", "Cancel", 0,
|
||||||
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
|
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
|
||||||
|
// TODO: Would be cool to offer the option here to clean additional
|
||||||
|
// folders at the user's choice (like /boot/common and /boot/develop).
|
||||||
err = B_CANCELED;
|
err = B_CANCELED;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -436,6 +439,38 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// extract zip packages
|
||||||
|
// TODO: Put those in the optional packages list view
|
||||||
|
// TODO: Implement mechanism to handle dependencies between these
|
||||||
|
// packages. (Selecting one will auto-select others.)
|
||||||
|
{
|
||||||
|
BPath pkgRootDir(srcDirectory.Path(), PACKAGES_DIRECTORY);
|
||||||
|
BDirectory directory(pkgRootDir.Path());
|
||||||
|
BEntry entry;
|
||||||
|
while (directory.GetNextEntry(&entry) == B_OK) {
|
||||||
|
char name[B_FILE_NAME_LENGTH];
|
||||||
|
if (entry.GetName(name) != B_OK)
|
||||||
|
continue;
|
||||||
|
int nameLength = strlen(name);
|
||||||
|
if (nameLength <= 0)
|
||||||
|
continue;
|
||||||
|
char* nameExtension = name + nameLength - 4;
|
||||||
|
printf("inspecting %s (%s)\n", name, nameExtension);
|
||||||
|
if (strcasecmp(nameExtension, ".zip") != 0)
|
||||||
|
continue;
|
||||||
|
printf("found .zip package: %s\n", name);
|
||||||
|
|
||||||
|
UnzipEngine unzipEngine(messenger, new BMessage(MSG_STATUS_MESSAGE),
|
||||||
|
fCancelSemaphore);
|
||||||
|
BPath path;
|
||||||
|
entry.GetPath(&path);
|
||||||
|
unzipEngine.SetTo(path.Path(), targetDirectory.Path());
|
||||||
|
unzipEngine.UnzipPackage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_LaunchFinishScript(targetDirectory);
|
_LaunchFinishScript(targetDirectory);
|
||||||
|
|
||||||
BMessenger(fWindow).SendMessage(MSG_INSTALL_FINISHED);
|
BMessenger(fWindow).SendMessage(MSG_INSTALL_FINISHED);
|
||||||
|
|||||||
Reference in New Issue
Block a user