First round of cleanup:
* Renamed CopyEngine to WorkerThread, since it's used for other things than just copying. * Removed the code borrowed from Tracker. * Removed the InstallerCopyLoopControl, since the CopyEngine handles notifications and cancelling by itself now. * Renamed a few message constants. * Since we only support BFS partitions as install targets, I removed the FS type from the target menu item label. However, I am going to solve this differently. I guess all partitions should be seen in the target list, just disabled if they are not a valid target, and with a reason given too. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30600 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2005, Jérôme DUVAL. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CopyEngine_h
|
|
||||||
#define _CopyEngine_h
|
|
||||||
|
|
||||||
#include "InstallerCopyLoopControl.h"
|
|
||||||
|
|
||||||
#include <DiskDevice.h>
|
|
||||||
#include <DiskDeviceRoster.h>
|
|
||||||
#include <Looper.h>
|
|
||||||
#include <Messenger.h>
|
|
||||||
#include <Partition.h>
|
|
||||||
#include <Volume.h>
|
|
||||||
|
|
||||||
class BLocker;
|
|
||||||
class InstallerWindow;
|
|
||||||
|
|
||||||
const uint32 ENGINE_START = 'eSRT';
|
|
||||||
|
|
||||||
class CopyEngine : public BLooper {
|
|
||||||
public:
|
|
||||||
CopyEngine(InstallerWindow *window);
|
|
||||||
void MessageReceived(BMessage *msg);
|
|
||||||
void ScanDisksPartitions(BMenu *srcMenu, BMenu *targetMenu);
|
|
||||||
void SetPackagesList(BList *list);
|
|
||||||
void SetSpaceRequired(off_t bytes) { fSpaceRequired = bytes; };
|
|
||||||
bool Cancel();
|
|
||||||
void SetLock(BLocker* lock) { fCancelLock = lock; }
|
|
||||||
void WriteBootSector(BMenu *targetMenu);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void LaunchInitScript(BPath &path);
|
|
||||||
void LaunchFinishScript(BPath &path);
|
|
||||||
void SetStatusMessage(const char *status);
|
|
||||||
void Start(BMenu *srcMenu, BMenu *targetMenu);
|
|
||||||
status_t CopyFolder(BDirectory &srcDir, BDirectory &targetDir);
|
|
||||||
|
|
||||||
InstallerWindow *fWindow;
|
|
||||||
BDiskDeviceRoster fDDRoster;
|
|
||||||
InstallerCopyLoopControl *fControl;
|
|
||||||
BList *fPackages;
|
|
||||||
off_t fSpaceRequired;
|
|
||||||
BLocker* fCancelLock;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _CopyEngine_h */
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,312 +0,0 @@
|
|||||||
/*
|
|
||||||
Open Tracker License
|
|
||||||
|
|
||||||
Terms and Conditions
|
|
||||||
|
|
||||||
Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice applies to all licensees
|
|
||||||
and shall be included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
||||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
Except as contained in this notice, the name of Be Incorporated shall not be
|
|
||||||
used in advertising or otherwise to promote the sale, use or other dealings in
|
|
||||||
this Software without prior written authorization from Be Incorporated.
|
|
||||||
|
|
||||||
Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
|
|
||||||
of Be Incorporated in the United States and other countries. Other brand product
|
|
||||||
names are registered trademarks or trademarks of their respective holders.
|
|
||||||
All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FS_UTILS_H
|
|
||||||
#define FS_UTILS_H
|
|
||||||
|
|
||||||
#include <FindDirectory.h>
|
|
||||||
#include <List.h>
|
|
||||||
#include <Point.h>
|
|
||||||
#include <StorageDefs.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Model.h"
|
|
||||||
#include "ObjectList.h"
|
|
||||||
|
|
||||||
// Note - APIs/code in FSUtils.h and FSUtils.cpp is slated for a major cleanup
|
|
||||||
// -- in other words, you will find a lot of ugly cruft in here
|
|
||||||
|
|
||||||
class BDirectory;
|
|
||||||
class BEntry;
|
|
||||||
class BList;
|
|
||||||
class BFile;
|
|
||||||
|
|
||||||
namespace BPrivate {
|
|
||||||
|
|
||||||
class BInfoWindow;
|
|
||||||
|
|
||||||
class CopyLoopControl {
|
|
||||||
// controls the copy engine; may be overriden to specify how conflicts are
|
|
||||||
// handled, etc.
|
|
||||||
// Installer has it's own subclass
|
|
||||||
public:
|
|
||||||
virtual ~CopyLoopControl();
|
|
||||||
virtual bool FileError(const char *message, const char *name, status_t error,
|
|
||||||
bool allowContinue) = 0;
|
|
||||||
// inform that a file error occurred while copying <name>
|
|
||||||
// returns true if user decided to continue
|
|
||||||
|
|
||||||
virtual void UpdateStatus(const char *name, entry_ref ref, int32 count,
|
|
||||||
bool optional = false) = 0;
|
|
||||||
|
|
||||||
virtual bool CheckUserCanceled() = 0;
|
|
||||||
// returns true if canceled
|
|
||||||
|
|
||||||
enum OverwriteMode {
|
|
||||||
kSkip, // do not replace, go to next entry
|
|
||||||
kReplace, // remove entry before copying new one
|
|
||||||
kMerge // for folders: leave existing folder, update contents leaving
|
|
||||||
// nonconflicting items
|
|
||||||
// for files: save original attributes on file.
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
|
|
||||||
const char *destName, const BDirectory *destDir, bool srcIsDir,
|
|
||||||
bool dstIsDir) = 0;
|
|
||||||
// override to always overwrite, never overwrite, let user decide,
|
|
||||||
// compare dates, etc.
|
|
||||||
|
|
||||||
virtual bool SkipEntry(const BEntry *, bool file) = 0;
|
|
||||||
// override to prevent copying of a given file or directory
|
|
||||||
|
|
||||||
virtual void ChecksumChunk(const char *block, size_t size);
|
|
||||||
// during a file copy, this is called every time a chunk of data
|
|
||||||
// is copied. Users may override to keep a running checksum.
|
|
||||||
|
|
||||||
virtual bool ChecksumFile(const entry_ref *);
|
|
||||||
// This is called when a file is finished copying. Users of this
|
|
||||||
// class may override to verify that the checksum they've been
|
|
||||||
// computing in ChecksumChunk matches. If this returns true,
|
|
||||||
// the copy will continue. If false, if will abort.
|
|
||||||
|
|
||||||
virtual bool SkipAttribute(const char *attributeName);
|
|
||||||
virtual bool PreserveAttribute(const char *attributeName);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class TrackerCopyLoopControl : public CopyLoopControl {
|
|
||||||
// this is the Tracker copy - specific version of CopyLoopControl
|
|
||||||
public:
|
|
||||||
TrackerCopyLoopControl(thread_id);
|
|
||||||
virtual ~TrackerCopyLoopControl() {}
|
|
||||||
|
|
||||||
virtual bool FileError(const char *message, const char *name, status_t error,
|
|
||||||
bool allowContinue);
|
|
||||||
// inform that a file error occurred while copying <name>
|
|
||||||
// returns true if user decided to continue
|
|
||||||
|
|
||||||
virtual void UpdateStatus(const char *name, entry_ref ref, int32 count,
|
|
||||||
bool optional = false);
|
|
||||||
|
|
||||||
virtual bool CheckUserCanceled();
|
|
||||||
// returns true if canceled
|
|
||||||
|
|
||||||
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
|
|
||||||
const char *destName, const BDirectory *destDir, bool srcIsDir,
|
|
||||||
bool dstIsDir);
|
|
||||||
|
|
||||||
virtual bool SkipEntry(const BEntry *, bool file);
|
|
||||||
// override to prevent copying of a given file or directory
|
|
||||||
|
|
||||||
virtual bool SkipAttribute(const char *attributeName);
|
|
||||||
|
|
||||||
private:
|
|
||||||
thread_id fThread;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
TrackerCopyLoopControl::TrackerCopyLoopControl(thread_id thread)
|
|
||||||
: fThread(thread)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#define B_DESKTOP_DIR_NAME "Desktop"
|
|
||||||
|
|
||||||
status_t FSCopyAttributesAndStats(BNode *, BNode *);
|
|
||||||
|
|
||||||
status_t FSCopyFile(BEntry* srcFile, StatStruct *srcStat, BDirectory* destDir,
|
|
||||||
CopyLoopControl *loopControl, BPoint *loc, bool makeOriginalName, Undo &undo);
|
|
||||||
status_t FSCopyFolder(BEntry *srcEntry, BDirectory *destDir, CopyLoopControl *loopControl,
|
|
||||||
BPoint *loc, bool makeOriginalName, Undo &undo);
|
|
||||||
void FSDuplicate(BObjectList<entry_ref> *srcList, BList *pointList);
|
|
||||||
void FSMoveToFolder(BObjectList<entry_ref> *srcList, BEntry *, uint32 moveMode,
|
|
||||||
BList *pointList = NULL);
|
|
||||||
void FSMakeOriginalName(char *name, BDirectory *destDir, const char *suffix);
|
|
||||||
bool FSIsTrashDir(const BEntry *);
|
|
||||||
bool FSIsPrintersDir(const BEntry *);
|
|
||||||
bool FSIsDeskDir(const BEntry *);
|
|
||||||
bool FSIsSystemDir(const BEntry *);
|
|
||||||
bool FSIsBeOSDir(const BEntry *);
|
|
||||||
bool FSIsHomeDir(const BEntry *);
|
|
||||||
void FSMoveToTrash(BObjectList<entry_ref> *srcList, BList *pointList = NULL,
|
|
||||||
bool async = true);
|
|
||||||
// Deprecated
|
|
||||||
|
|
||||||
void FSDeleteRefList(BObjectList<entry_ref> *, bool, bool confirm = true);
|
|
||||||
void FSDelete(entry_ref *, bool, bool confirm = true);
|
|
||||||
void FSRestoreRefList(BObjectList<entry_ref> *list, bool async);
|
|
||||||
|
|
||||||
status_t FSLaunchItem(const entry_ref *application, const BMessage *refsReceived,
|
|
||||||
bool async, bool openWithOK);
|
|
||||||
// Preferred way of launching; only pass an actual application in <application>, not
|
|
||||||
// a document; to open documents with the preferred app, pase 0 in <application> and
|
|
||||||
// stuff all the document refs into <refsReceived>
|
|
||||||
// Consider having silent mode that does not show alerts, just returns error code
|
|
||||||
|
|
||||||
status_t FSOpenWith(BMessage *listOfRefs);
|
|
||||||
// runs the Open With window; pas a list of refs
|
|
||||||
|
|
||||||
void FSEmptyTrash();
|
|
||||||
status_t FSCreateNewFolderIn(const node_ref *destDir, entry_ref *newRef,
|
|
||||||
node_ref *new_node);
|
|
||||||
void FSCreateTrashDirs();
|
|
||||||
status_t FSGetTrashDir(BDirectory *trashDir, dev_t volume);
|
|
||||||
status_t FSGetDeskDir(BDirectory *deskDir, dev_t volume);
|
|
||||||
status_t FSRecursiveCalcSize(BInfoWindow *, BDirectory *,
|
|
||||||
off_t *runningSize, int32 *fileCount, int32 *dirCount);
|
|
||||||
|
|
||||||
bool FSInTrashDir(const entry_ref *);
|
|
||||||
|
|
||||||
// doesn't need to be exported
|
|
||||||
bool FSGetPoseLocation(const BNode *node, BPoint *point);
|
|
||||||
status_t FSSetPoseLocation(BEntry *entry, BPoint point);
|
|
||||||
status_t FSSetPoseLocation(ino_t destDirInode, BNode *destNode, BPoint point);
|
|
||||||
status_t FSGetBootDeskDir(BDirectory *deskDir);
|
|
||||||
|
|
||||||
status_t FSGetOriginalPath(BEntry *entry, BPath *path);
|
|
||||||
|
|
||||||
enum ReadAttrResult {
|
|
||||||
kReadAttrFailed,
|
|
||||||
kReadAttrNativeOK,
|
|
||||||
kReadAttrForeignOK
|
|
||||||
};
|
|
||||||
|
|
||||||
ReadAttrResult ReadAttr(const BNode *, const char *hostAttrName, const char *foreignAttrName,
|
|
||||||
type_code , off_t , void *, size_t , void (*swapFunc)(void *) = 0,
|
|
||||||
bool isForeign = false);
|
|
||||||
// Endian swapping ReadAttr call; endianness is determined by trying first the
|
|
||||||
// native attribute name, then the foreign one; an endian swapping function can
|
|
||||||
// be passed, if null data won't be swapped; if <isForeign> set the foreign endianness
|
|
||||||
// will be read directly without first trying the native one
|
|
||||||
|
|
||||||
ReadAttrResult GetAttrInfo(const BNode *, const char *hostAttrName, const char *foreignAttrName,
|
|
||||||
type_code * = NULL, size_t * = NULL);
|
|
||||||
|
|
||||||
status_t FSCreateNewFolder(const entry_ref *);
|
|
||||||
status_t FSRecursiveCreateFolder(const char *path);
|
|
||||||
void FSMakeOriginalName(BString &name, const BDirectory *destDir, const char *suffix = 0);
|
|
||||||
|
|
||||||
status_t TrackerLaunch(const entry_ref *app, bool async);
|
|
||||||
status_t TrackerLaunch(const BMessage *refs, bool async, bool okToRunOpenWith = true);
|
|
||||||
status_t TrackerLaunch(const entry_ref *app, const BMessage *refs, bool async,
|
|
||||||
bool okToRunOpenWith = true);
|
|
||||||
status_t LaunchBrokenLink(const char *, const BMessage *);
|
|
||||||
|
|
||||||
status_t FSFindTrackerSettingsDir(BPath *, bool autoCreate = true);
|
|
||||||
|
|
||||||
bool FSIsDeskDir(const BEntry *, dev_t);
|
|
||||||
|
|
||||||
bool ConfirmChangeIfWellKnownDirectory(const BEntry *entry, const char *action,
|
|
||||||
bool dontAsk = false, int32 *confirmedAlready = NULL);
|
|
||||||
|
|
||||||
// Deprecated calls use newer calls above instead
|
|
||||||
void FSLaunchItem(const entry_ref *, BMessage * = NULL, int32 workspace = -1);
|
|
||||||
status_t FSLaunchItem(const entry_ref *, BMessage *,
|
|
||||||
int32 workspace, bool asynch);
|
|
||||||
void FSOpenWithDocuments(const entry_ref *executableToLaunch,
|
|
||||||
BMessage *documentEntryRefs);
|
|
||||||
status_t FSLaunchUsing(const entry_ref *ref, BMessage *listOfRefs);
|
|
||||||
|
|
||||||
|
|
||||||
// some extra directory_which values
|
|
||||||
// move these to FindDirectory.h
|
|
||||||
const uint32 B_USER_MAIL_DIRECTORY = 3500;
|
|
||||||
const uint32 B_USER_QUERIES_DIRECTORY = 3501;
|
|
||||||
const uint32 B_USER_PEOPLE_DIRECTORY = 3502;
|
|
||||||
const uint32 B_USER_DOWNLOADS_DIRECTORY = 3503;
|
|
||||||
const uint32 B_USER_DESKBAR_APPS_DIRECTORY = 3504;
|
|
||||||
const uint32 B_USER_DESKBAR_PREFERENCES_DIRECTORY = 3505;
|
|
||||||
const uint32 B_USER_DESKBAR_DEVELOP_DIRECTORY = 3506;
|
|
||||||
|
|
||||||
const int32 B_BOOT_DISK = 10000000;
|
|
||||||
// map /boot into the directory_which enum for convenience
|
|
||||||
|
|
||||||
class WellKnowEntryList {
|
|
||||||
// matches up names, id's and node_refs of well known entries in the
|
|
||||||
// system hierarchy
|
|
||||||
public:
|
|
||||||
struct WellKnownEntry {
|
|
||||||
WellKnownEntry(const node_ref *node, directory_which which, const char *name)
|
|
||||||
:
|
|
||||||
node(*node),
|
|
||||||
which(which),
|
|
||||||
name(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// mwcc needs these explicitly to use vector
|
|
||||||
WellKnownEntry(const WellKnownEntry &clone)
|
|
||||||
:
|
|
||||||
node(clone.node),
|
|
||||||
which(clone.which),
|
|
||||||
name(clone.name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
WellKnownEntry()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
node_ref node;
|
|
||||||
directory_which which;
|
|
||||||
const char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
static directory_which Match(const node_ref *);
|
|
||||||
static const WellKnownEntry *MatchEntry(const node_ref *);
|
|
||||||
static void Quit();
|
|
||||||
|
|
||||||
private:
|
|
||||||
const WellKnownEntry *MatchEntryCommon(const node_ref *);
|
|
||||||
WellKnowEntryList();
|
|
||||||
void AddOne(directory_which, const char *name);
|
|
||||||
void AddOne(directory_which, const char *path, const char *name);
|
|
||||||
void AddOne(directory_which, directory_which base, const char *extension,
|
|
||||||
const char *name);
|
|
||||||
|
|
||||||
std::vector<WellKnownEntry> entries;
|
|
||||||
static WellKnowEntryList *self;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if B_BEOS_VERSION_DANO
|
|
||||||
#undef _IMPEXP_TRACKER
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace BPrivate
|
|
||||||
|
|
||||||
using namespace BPrivate;
|
|
||||||
|
|
||||||
#endif /* FS_UTILS_H */
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2005, Jérôme Duval. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "InstallerCopyLoopControl.h"
|
|
||||||
#include "InstallerWindow.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <Alert.h>
|
|
||||||
|
|
||||||
InstallerCopyLoopControl::InstallerCopyLoopControl(InstallerWindow *window)
|
|
||||||
: fWindow(window),
|
|
||||||
fMessenger(window),
|
|
||||||
fUserCanceled(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
InstallerCopyLoopControl::FileError(const char *message, const char *name, status_t error,
|
|
||||||
bool allowContinue)
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
sprintf(buffer, message, name, strerror(error));
|
|
||||||
|
|
||||||
if (allowContinue)
|
|
||||||
return (new BAlert("", buffer, "Cancel", "OK", 0,
|
|
||||||
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0;
|
|
||||||
|
|
||||||
(new BAlert("", buffer, "Cancel", 0, 0,
|
|
||||||
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
InstallerCopyLoopControl::UpdateStatus(const char *name, entry_ref ref, int32 count,
|
|
||||||
bool optional)
|
|
||||||
{
|
|
||||||
if (name) {
|
|
||||||
BMessage msg(STATUS_MESSAGE);
|
|
||||||
BString s = "Installing ";
|
|
||||||
s << name;
|
|
||||||
msg.AddString("status", s.String());
|
|
||||||
fMessenger.SendMessage(&msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
InstallerCopyLoopControl::CheckUserCanceled()
|
|
||||||
{
|
|
||||||
return fUserCanceled;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
InstallerCopyLoopControl::OverwriteMode
|
|
||||||
InstallerCopyLoopControl::OverwriteOnConflict(const BEntry *srcEntry,
|
|
||||||
const char *destName, const BDirectory *destDir, bool srcIsDir,
|
|
||||||
bool dstIsDir)
|
|
||||||
{
|
|
||||||
if (srcIsDir && dstIsDir)
|
|
||||||
return kMerge;
|
|
||||||
else
|
|
||||||
return kReplace;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
InstallerCopyLoopControl::SkipEntry(const BEntry *, bool file)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
InstallerCopyLoopControl::ChecksumChunk(const char *block, size_t size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
InstallerCopyLoopControl::ChecksumFile(const entry_ref *ref)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
InstallerCopyLoopControl::SkipAttribute(const char *attributeName)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
InstallerCopyLoopControl::PreserveAttribute(const char *attributeName)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
InstallerCopyLoopControl::Cancel()
|
|
||||||
{
|
|
||||||
fUserCanceled = (new BAlert("",
|
|
||||||
"Are you sure you want to to stop the installation?",
|
|
||||||
"Continue", "Stop", 0,
|
|
||||||
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0;
|
|
||||||
return fUserCanceled;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
InstallerCopyLoopControl::Reset()
|
|
||||||
{
|
|
||||||
fUserCanceled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2005, Jérôme Duval. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _INSTALLERCOPYLOOPCONTROL_H
|
|
||||||
#define _INSTALLERCOPYLOOPCONTROL_H
|
|
||||||
|
|
||||||
#include "FSUndoRedo.h"
|
|
||||||
#include "FSUtils.h"
|
|
||||||
class InstallerWindow;
|
|
||||||
|
|
||||||
class InstallerCopyLoopControl : public CopyLoopControl
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InstallerCopyLoopControl(InstallerWindow *window);
|
|
||||||
virtual ~InstallerCopyLoopControl() {};
|
|
||||||
|
|
||||||
virtual bool FileError(const char *message, const char *name, status_t error,
|
|
||||||
bool allowContinue);
|
|
||||||
|
|
||||||
virtual void UpdateStatus(const char *name, entry_ref ref, int32 count,
|
|
||||||
bool optional = false);
|
|
||||||
|
|
||||||
virtual bool CheckUserCanceled();
|
|
||||||
|
|
||||||
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
|
|
||||||
const char *destName, const BDirectory *destDir, bool srcIsDir,
|
|
||||||
bool dstIsDir);
|
|
||||||
|
|
||||||
virtual bool SkipEntry(const BEntry *, bool file);
|
|
||||||
|
|
||||||
virtual void ChecksumChunk(const char *block, size_t size);
|
|
||||||
virtual bool ChecksumFile(const entry_ref *);
|
|
||||||
virtual bool SkipAttribute(const char *attributeName);
|
|
||||||
virtual bool PreserveAttribute(const char *attributeName);
|
|
||||||
bool Cancel();
|
|
||||||
void Reset();
|
|
||||||
|
|
||||||
private:
|
|
||||||
InstallerWindow *fWindow;
|
|
||||||
BMessenger fMessenger;
|
|
||||||
bool fUserCanceled;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <Button.h>
|
#include <Button.h>
|
||||||
#include <ClassInfo.h>
|
#include <ClassInfo.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
#include <GridLayoutBuilder.h>
|
#include <GridLayoutBuilder.h>
|
||||||
#include <GroupLayoutBuilder.h>
|
#include <GroupLayoutBuilder.h>
|
||||||
#include <LayoutUtils.h>
|
#include <LayoutUtils.h>
|
||||||
@@ -35,10 +36,10 @@
|
|||||||
|
|
||||||
#include "tracker_private.h"
|
#include "tracker_private.h"
|
||||||
|
|
||||||
#include "CopyEngine.h"
|
|
||||||
#include "DialogPane.h"
|
#include "DialogPane.h"
|
||||||
#include "PackageViews.h"
|
#include "PackageViews.h"
|
||||||
#include "PartitionMenuItem.h"
|
#include "PartitionMenuItem.h"
|
||||||
|
#include "WorkerThread.h"
|
||||||
|
|
||||||
|
|
||||||
#define DRIVESETUP_SIG "application/x-vnd.Haiku-DriveSetup"
|
#define DRIVESETUP_SIG "application/x-vnd.Haiku-DriveSetup"
|
||||||
@@ -209,7 +210,7 @@ InstallerWindow::InstallerWindow()
|
|||||||
fNeedsToCenterOnScreen(true),
|
fNeedsToCenterOnScreen(true),
|
||||||
fDriveSetupLaunched(false),
|
fDriveSetupLaunched(false),
|
||||||
fInstallStatus(kReadyForInstall),
|
fInstallStatus(kReadyForInstall),
|
||||||
fCopyEngine(new CopyEngine(this)),
|
fWorkerThread(new WorkerThread(this)),
|
||||||
fCopyEngineLock(NULL)
|
fCopyEngineLock(NULL)
|
||||||
{
|
{
|
||||||
LogoView* logoView = new LogoView();
|
LogoView* logoView = new LogoView();
|
||||||
@@ -265,7 +266,7 @@ InstallerWindow::InstallerWindow()
|
|||||||
"Setup partitions" B_UTF8_ELLIPSIS, new BMessage(SETUP_MESSAGE));
|
"Setup partitions" B_UTF8_ELLIPSIS, new BMessage(SETUP_MESSAGE));
|
||||||
|
|
||||||
fMakeBootableButton = new BButton("makebootable_button",
|
fMakeBootableButton = new BButton("makebootable_button",
|
||||||
"Write Boot Sector", new BMessage(kWriteBootSector));
|
"Write Boot Sector", new BMessage(MSG_WRITE_BOOT_SECTOR));
|
||||||
fMakeBootableButton->SetEnabled(false);
|
fMakeBootableButton->SetEnabled(false);
|
||||||
|
|
||||||
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
||||||
@@ -357,7 +358,7 @@ void
|
|||||||
InstallerWindow::MessageReceived(BMessage *msg)
|
InstallerWindow::MessageReceived(BMessage *msg)
|
||||||
{
|
{
|
||||||
switch (msg->what) {
|
switch (msg->what) {
|
||||||
case RESET_INSTALL:
|
case MSG_RESET:
|
||||||
delete fCopyEngineLock;
|
delete fCopyEngineLock;
|
||||||
fCopyEngineLock = NULL;
|
fCopyEngineLock = NULL;
|
||||||
|
|
||||||
@@ -383,11 +384,11 @@ InstallerWindow::MessageReceived(BMessage *msg)
|
|||||||
BList* list = new BList();
|
BList* list = new BList();
|
||||||
int32 size = 0;
|
int32 size = 0;
|
||||||
fPackagesView->GetPackagesToInstall(list, &size);
|
fPackagesView->GetPackagesToInstall(list, &size);
|
||||||
fCopyEngine->SetLock(fCopyEngineLock);
|
fWorkerThread->SetLock(fCopyEngineLock);
|
||||||
fCopyEngine->SetPackagesList(list);
|
fWorkerThread->SetPackagesList(list);
|
||||||
fCopyEngine->SetSpaceRequired(size);
|
fWorkerThread->SetSpaceRequired(size);
|
||||||
fInstallStatus = kInstalling;
|
fInstallStatus = kInstalling;
|
||||||
BMessenger(fCopyEngine).SendMessage(ENGINE_START);
|
fWorkerThread->StartInstall();
|
||||||
fBeginButton->SetLabel("Stop");
|
fBeginButton->SetLabel("Stop");
|
||||||
_DisableInterface(true);
|
_DisableInterface(true);
|
||||||
|
|
||||||
@@ -402,7 +403,7 @@ InstallerWindow::MessageReceived(BMessage *msg)
|
|||||||
case kInstalling:
|
case kInstalling:
|
||||||
{
|
{
|
||||||
_QuitCopyEngine(true);
|
_QuitCopyEngine(true);
|
||||||
// if (fCopyEngine->Cancel()) {
|
// if (fWorkerThread->Cancel()) {
|
||||||
// fInstallStatus = kCancelled;
|
// fInstallStatus = kCancelled;
|
||||||
// _SetStatusMessage("Installation cancelled.");
|
// _SetStatusMessage("Installation cancelled.");
|
||||||
// fProgressLayoutItem->SetVisible(false);
|
// fProgressLayoutItem->SetVisible(false);
|
||||||
@@ -440,7 +441,7 @@ InstallerWindow::MessageReceived(BMessage *msg)
|
|||||||
fSizeView->SetText(string);
|
fSizeView->SetText(string);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STATUS_MESSAGE:
|
case MSG_STATUS_MESSAGE:
|
||||||
{
|
{
|
||||||
// TODO: Was this supposed to prevent status messages still arriving
|
// TODO: Was this supposed to prevent status messages still arriving
|
||||||
// after the copy engine was shut down?
|
// after the copy engine was shut down?
|
||||||
@@ -472,7 +473,7 @@ InstallerWindow::MessageReceived(BMessage *msg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INSTALL_FINISHED:
|
case MSG_INSTALL_FINISHED:
|
||||||
{
|
{
|
||||||
delete fCopyEngineLock;
|
delete fCopyEngineLock;
|
||||||
fCopyEngineLock = NULL;
|
fCopyEngineLock = NULL;
|
||||||
@@ -512,8 +513,8 @@ InstallerWindow::MessageReceived(BMessage *msg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kWriteBootSector:
|
case MSG_WRITE_BOOT_SECTOR:
|
||||||
fCopyEngine->WriteBootSector(fDestMenu);
|
fWorkerThread->WriteBootSector(fDestMenu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -533,7 +534,7 @@ InstallerWindow::QuitRequested()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_QuitCopyEngine(false);
|
_QuitCopyEngine(false);
|
||||||
fCopyEngine->PostMessage(B_QUIT_REQUESTED);
|
fWorkerThread->PostMessage(B_QUIT_REQUESTED);
|
||||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -597,7 +598,7 @@ InstallerWindow::_ScanPartitions()
|
|||||||
while ((item = fDestMenu->RemoveItem((int32)0)))
|
while ((item = fDestMenu->RemoveItem((int32)0)))
|
||||||
delete item;
|
delete item;
|
||||||
|
|
||||||
fCopyEngine->ScanDisksPartitions(fSrcMenu, fDestMenu);
|
fWorkerThread->ScanDisksPartitions(fSrcMenu, fDestMenu);
|
||||||
|
|
||||||
if (fSrcMenu->ItemAt(0)) {
|
if (fSrcMenu->ItemAt(0)) {
|
||||||
_PublishPackages();
|
_PublishPackages();
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ class BMenuField;
|
|||||||
class BStatusBar;
|
class BStatusBar;
|
||||||
class BStringView;
|
class BStringView;
|
||||||
class BTextView;
|
class BTextView;
|
||||||
class CopyEngine;
|
|
||||||
class PackagesView;
|
class PackagesView;
|
||||||
|
class WorkerThread;
|
||||||
|
|
||||||
enum InstallStatus {
|
enum InstallStatus {
|
||||||
kReadyForInstall,
|
kReadyForInstall,
|
||||||
@@ -32,10 +32,10 @@ enum InstallStatus {
|
|||||||
kCancelled
|
kCancelled
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint32 STATUS_MESSAGE = 'iSTM';
|
const uint32 MSG_STATUS_MESSAGE = 'iSTM';
|
||||||
const uint32 INSTALL_FINISHED = 'iIFN';
|
const uint32 MSG_INSTALL_FINISHED = 'iIFN';
|
||||||
const uint32 RESET_INSTALL = 'iRSI';
|
const uint32 MSG_RESET = 'iRSI';
|
||||||
const uint32 kWriteBootSector = 'iWBS';
|
const uint32 MSG_WRITE_BOOT_SECTOR = 'iWBS';
|
||||||
|
|
||||||
const char PACKAGES_DIRECTORY[] = "_packages_";
|
const char PACKAGES_DIRECTORY[] = "_packages_";
|
||||||
const char VAR_DIRECTORY[] = "var";
|
const char VAR_DIRECTORY[] = "var";
|
||||||
@@ -92,7 +92,7 @@ private:
|
|||||||
bool fDriveSetupLaunched;
|
bool fDriveSetupLaunched;
|
||||||
InstallStatus fInstallStatus;
|
InstallStatus fInstallStatus;
|
||||||
|
|
||||||
CopyEngine* fCopyEngine;
|
WorkerThread* fWorkerThread;
|
||||||
BString fLastStatus;
|
BString fLastStatus;
|
||||||
BLocker* fCopyEngineLock;
|
BLocker* fCopyEngineLock;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,13 +4,11 @@ UsePrivateHeaders shared storage tracker ;
|
|||||||
SubDirHdrs [ FDirName $(HAIKU_TOP) src kits tracker ] ;
|
SubDirHdrs [ FDirName $(HAIKU_TOP) src kits tracker ] ;
|
||||||
|
|
||||||
Application Installer :
|
Application Installer :
|
||||||
CopyEngine.cpp
|
|
||||||
CopyEngine2.cpp
|
CopyEngine2.cpp
|
||||||
FSUtils.cpp
|
|
||||||
InstallerApp.cpp
|
InstallerApp.cpp
|
||||||
InstallerCopyLoopControl.cpp
|
|
||||||
InstallerWindow.cpp
|
InstallerWindow.cpp
|
||||||
PackageViews.cpp
|
PackageViews.cpp
|
||||||
PartitionMenuItem.cpp
|
PartitionMenuItem.cpp
|
||||||
|
WorkerThread.cpp
|
||||||
: be tracker translation $(TARGET_LIBSTDC++)
|
: be tracker translation $(TARGET_LIBSTDC++)
|
||||||
: Installer.rdef ;
|
: Installer.rdef ;
|
||||||
|
|||||||
@@ -178,11 +178,11 @@ PackageCheckBox::MouseMoved(BPoint point, uint32 transit,
|
|||||||
{
|
{
|
||||||
printf("%s called\n", __PRETTY_FUNCTION__);
|
printf("%s called\n", __PRETTY_FUNCTION__);
|
||||||
if (transit == B_ENTERED_VIEW) {
|
if (transit == B_ENTERED_VIEW) {
|
||||||
BMessage msg(STATUS_MESSAGE);
|
BMessage msg(MSG_STATUS_MESSAGE);
|
||||||
msg.AddString("status", fPackage->Description());
|
msg.AddString("status", fPackage->Description());
|
||||||
BMessenger(NULL, Window()).SendMessage(&msg);
|
BMessenger(NULL, Window()).SendMessage(&msg);
|
||||||
} else if (transit == B_EXITED_VIEW) {
|
} else if (transit == B_EXITED_VIEW) {
|
||||||
BMessage msg(STATUS_MESSAGE);
|
BMessage msg(MSG_STATUS_MESSAGE);
|
||||||
BMessenger(NULL, Window()).SendMessage(&msg);
|
BMessenger(NULL, Window()).SendMessage(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,798 +0,0 @@
|
|||||||
// Vector.h
|
|
||||||
//
|
|
||||||
// Copyright (c) 2003, Ingo Weinhold ([email protected])
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
|
||||||
// to deal in the Software without restriction, including without limitation
|
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
//
|
|
||||||
// Except as contained in this notice, the name of a copyright holder shall
|
|
||||||
// not be used in advertising or otherwise to promote the sale, use or other
|
|
||||||
// dealings in this Software without prior written authorization of the
|
|
||||||
// copyright holder.
|
|
||||||
|
|
||||||
#ifndef _INSTALLER_VECTOR_H
|
|
||||||
#define _INSTALLER_VECTOR_H
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <SupportDefs.h>
|
|
||||||
|
|
||||||
template<typename Value> class VectorIterator;
|
|
||||||
|
|
||||||
// for convenience
|
|
||||||
#define _VECTOR_TEMPLATE_LIST template<typename Value>
|
|
||||||
#define _VECTOR_CLASS_NAME Vector<Value>
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\class Vector
|
|
||||||
\brief A generic vector implementation.
|
|
||||||
*/
|
|
||||||
template<typename Value>
|
|
||||||
class Vector {
|
|
||||||
public:
|
|
||||||
typedef VectorIterator<Value> Iterator;
|
|
||||||
typedef VectorIterator<const Value> ConstIterator;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const size_t kDefaultChunkSize = 10;
|
|
||||||
static const size_t kMaximalChunkSize = 1024 * 1024;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Vector(size_t chunkSize = kDefaultChunkSize);
|
|
||||||
~Vector();
|
|
||||||
|
|
||||||
status_t PushFront(const Value &value);
|
|
||||||
status_t PushBack(const Value &value);
|
|
||||||
|
|
||||||
void PopFront();
|
|
||||||
void PopBack();
|
|
||||||
|
|
||||||
status_t Insert(const Value &value, int32 index);
|
|
||||||
status_t Insert(const Value &value, const Iterator &iterator);
|
|
||||||
|
|
||||||
int32 Remove(const Value &value);
|
|
||||||
Iterator Erase(int32 index);
|
|
||||||
Iterator Erase(const Iterator &iterator);
|
|
||||||
|
|
||||||
inline int32 Count() const;
|
|
||||||
inline bool IsEmpty() const;
|
|
||||||
void MakeEmpty();
|
|
||||||
|
|
||||||
inline Iterator Begin();
|
|
||||||
inline ConstIterator Begin() const;
|
|
||||||
inline Iterator End();
|
|
||||||
inline ConstIterator End() const;
|
|
||||||
inline Iterator Null();
|
|
||||||
inline ConstIterator Null() const;
|
|
||||||
inline Iterator IteratorForIndex(int32 index);
|
|
||||||
inline ConstIterator IteratorForIndex(int32 index) const;
|
|
||||||
|
|
||||||
inline const Value &ElementAt(int32 index) const;
|
|
||||||
inline Value &ElementAt(int32 index);
|
|
||||||
|
|
||||||
int32 IndexOf(const Value &value, int32 start = 0) const;
|
|
||||||
Iterator Find(const Value &value);
|
|
||||||
Iterator Find(const Value &value, const Iterator &start);
|
|
||||||
ConstIterator Find(const Value &value) const;
|
|
||||||
ConstIterator Find(const Value &value, const ConstIterator &start) const;
|
|
||||||
|
|
||||||
inline Value &operator[](int32 index);
|
|
||||||
inline const Value &operator[](int32 index) const;
|
|
||||||
|
|
||||||
// debugging
|
|
||||||
int32 GetCapacity() const { return fCapacity; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline static void _MoveItems(Value *values, int32 offset, int32 count);
|
|
||||||
bool _Resize(size_t count);
|
|
||||||
inline int32 _IteratorIndex(const Iterator &iterator) const;
|
|
||||||
inline int32 _IteratorIndex(const ConstIterator &iterator) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_t fCapacity;
|
|
||||||
size_t fChunkSize;
|
|
||||||
int32 fItemCount;
|
|
||||||
Value *fItems;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// VectorIterator
|
|
||||||
template<typename Value>
|
|
||||||
class VectorIterator {
|
|
||||||
private:
|
|
||||||
typedef VectorIterator<Value> Iterator;
|
|
||||||
|
|
||||||
public:
|
|
||||||
inline VectorIterator<Value>()
|
|
||||||
: fElement(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline VectorIterator<Value>(const Iterator &other)
|
|
||||||
: fElement(other.fElement)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Iterator &operator++()
|
|
||||||
{
|
|
||||||
if (fElement)
|
|
||||||
++fElement;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Iterator operator++(int)
|
|
||||||
{
|
|
||||||
Iterator it(*this);
|
|
||||||
++*this;
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Iterator &operator--()
|
|
||||||
{
|
|
||||||
if (fElement)
|
|
||||||
--fElement;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Iterator operator--(int)
|
|
||||||
{
|
|
||||||
Iterator it(*this);
|
|
||||||
--*this;
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Iterator &operator=(const Iterator &other)
|
|
||||||
{
|
|
||||||
fElement = other.fElement;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool operator==(const Iterator &other) const
|
|
||||||
{
|
|
||||||
return (fElement == other.fElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const Iterator &other) const
|
|
||||||
{
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Value &operator*() const
|
|
||||||
{
|
|
||||||
return *fElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Value *operator->() const
|
|
||||||
{
|
|
||||||
return fElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline operator bool() const
|
|
||||||
{
|
|
||||||
return fElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
// private
|
|
||||||
public:
|
|
||||||
inline VectorIterator<Value>(Value *element)
|
|
||||||
: fElement(element)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Value *Element() const
|
|
||||||
{
|
|
||||||
return fElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Value *fElement;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Vector
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates an empty vector.
|
|
||||||
\param chunkSize The granularity for the vector's capacity, i.e. the
|
|
||||||
minimal number of elements the capacity grows or shrinks when
|
|
||||||
necessary.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
_VECTOR_CLASS_NAME::Vector(size_t chunkSize)
|
|
||||||
: fCapacity(0),
|
|
||||||
fChunkSize(chunkSize),
|
|
||||||
fItemCount(0),
|
|
||||||
fItems(NULL)
|
|
||||||
{
|
|
||||||
if (fChunkSize == 0 || fChunkSize > kMaximalChunkSize)
|
|
||||||
fChunkSize = kDefaultChunkSize;
|
|
||||||
_Resize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Frees all resources associated with the object.
|
|
||||||
|
|
||||||
The contained elements are destroyed. Note, that, if the element
|
|
||||||
type is a pointer type, only the pointer is destroyed, not the object
|
|
||||||
it points to.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
_VECTOR_CLASS_NAME::~Vector()
|
|
||||||
{
|
|
||||||
MakeEmpty();
|
|
||||||
free(fItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushFront
|
|
||||||
/*! \brief Inserts a copy of the supplied value at the beginning of the
|
|
||||||
vector.
|
|
||||||
\param value The element to be inserted.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Insufficient memory for this operation.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
status_t
|
|
||||||
_VECTOR_CLASS_NAME::PushFront(const Value &value)
|
|
||||||
{
|
|
||||||
return Insert(value, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushBack
|
|
||||||
/*! \brief Inserts a copy of the supplied value at the end of the vector.
|
|
||||||
\param value The element to be inserted.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Insufficient memory for this operation.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
status_t
|
|
||||||
_VECTOR_CLASS_NAME::PushBack(const Value &value)
|
|
||||||
{
|
|
||||||
return Insert(value, fItemCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PopFront
|
|
||||||
/*! \brief Removes the first element of the vector.
|
|
||||||
|
|
||||||
Invocation on an empty vector is harmless.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
void
|
|
||||||
_VECTOR_CLASS_NAME::PopFront()
|
|
||||||
{
|
|
||||||
if (fItemCount > 0)
|
|
||||||
Erase(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PopBack
|
|
||||||
/*! \brief Removes the last element of the vector.
|
|
||||||
|
|
||||||
Invocation on an empty vector is harmless.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
void
|
|
||||||
_VECTOR_CLASS_NAME::PopBack()
|
|
||||||
{
|
|
||||||
if (fItemCount > 0)
|
|
||||||
Erase(fItemCount - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _MoveItems
|
|
||||||
/*! \brief Moves elements within an array.
|
|
||||||
\param items The elements to be moved.
|
|
||||||
\param offset The index to which the elements shall be moved. May be
|
|
||||||
negative.
|
|
||||||
\param count The number of elements to be moved.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
_VECTOR_CLASS_NAME::_MoveItems(Value* items, int32 offset, int32 count)
|
|
||||||
{
|
|
||||||
if (count > 0 && offset != 0)
|
|
||||||
memmove(items + offset, items, count * sizeof(Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert
|
|
||||||
/*! \brief Inserts a copy of the the supplied value at the given index.
|
|
||||||
\param value The value to be inserted.
|
|
||||||
\param index The index at which to insert the new element. It must
|
|
||||||
hold: 0 <= \a index <= Count().
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_BAD_VALUE: \a index is out of range.
|
|
||||||
- \c B_NO_MEMORY: Insufficient memory for this operation.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
status_t
|
|
||||||
_VECTOR_CLASS_NAME::Insert(const Value &value, int32 index)
|
|
||||||
{
|
|
||||||
if (index < 0 || index > fItemCount)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
if (!_Resize(fItemCount + 1))
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
_MoveItems(fItems + index, 1, fItemCount - index - 1);
|
|
||||||
new(fItems + index) Value(value);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert
|
|
||||||
/*! \brief Inserts a copy of the the supplied value at the given position.
|
|
||||||
\param value The value to be inserted.
|
|
||||||
\param iterator An iterator specifying the position at which to insert
|
|
||||||
the new element.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_BAD_VALUE: \a iterator is is invalid.
|
|
||||||
- \c B_NO_MEMORY: Insufficient memory for this operation.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
status_t
|
|
||||||
_VECTOR_CLASS_NAME::Insert(const Value &value, const Iterator &iterator)
|
|
||||||
{
|
|
||||||
int32 index = _IteratorIndex(iterator);
|
|
||||||
if (index >= 0)
|
|
||||||
return Insert(value, index);
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove
|
|
||||||
/*! \brief Removes all elements of the supplied value.
|
|
||||||
\param value The value of the elements to be removed.
|
|
||||||
\return The number of removed occurrences.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
int32
|
|
||||||
_VECTOR_CLASS_NAME::Remove(const Value &value)
|
|
||||||
{
|
|
||||||
int32 count = 0;
|
|
||||||
for (int32 i = fItemCount - 1; i >= 0; i--) {
|
|
||||||
if (ElementAt(i) == value) {
|
|
||||||
Erase(i);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase
|
|
||||||
/*! \brief Removes the element at the given index.
|
|
||||||
\param index The position of the element to be removed.
|
|
||||||
\return An iterator referring to the element now being located at index
|
|
||||||
\a index (End(), if it was the last element that has been
|
|
||||||
removed), or Null(), if \a index was out of range.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
_VECTOR_CLASS_NAME::Iterator
|
|
||||||
_VECTOR_CLASS_NAME::Erase(int32 index)
|
|
||||||
{
|
|
||||||
if (index >= 0 && index < fItemCount) {
|
|
||||||
fItems[index].~Value();
|
|
||||||
_MoveItems(fItems + index + 1, -1, fItemCount - index - 1);
|
|
||||||
_Resize(fItemCount - 1);
|
|
||||||
return Iterator(fItems + index);
|
|
||||||
}
|
|
||||||
return Null();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase
|
|
||||||
/*! \brief Removes the element at the given position.
|
|
||||||
\param iterator An iterator referring to the element to be removed.
|
|
||||||
\return An iterator referring to the element succeeding the removed
|
|
||||||
one (End(), if it was the last element that has been
|
|
||||||
removed), or Null(), if \a iterator was an invalid iterator
|
|
||||||
(in this case including End()).
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
_VECTOR_CLASS_NAME::Iterator
|
|
||||||
_VECTOR_CLASS_NAME::Erase(const Iterator &iterator)
|
|
||||||
{
|
|
||||||
int32 index = _IteratorIndex(iterator);
|
|
||||||
if (index >= 0 && index < fItemCount)
|
|
||||||
return Erase(index);
|
|
||||||
return Null();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count
|
|
||||||
/*! \brief Returns the number of elements the vector contains.
|
|
||||||
\return The number of elements the vector contains.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
int32
|
|
||||||
_VECTOR_CLASS_NAME::Count() const
|
|
||||||
{
|
|
||||||
return fItemCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsEmpty
|
|
||||||
/*! \brief Returns whether the vector is empty.
|
|
||||||
\return \c true, if the vector is empty, \c false otherwise.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
bool
|
|
||||||
_VECTOR_CLASS_NAME::IsEmpty() const
|
|
||||||
{
|
|
||||||
return (fItemCount == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeEmpty
|
|
||||||
/*! \brief Removes all elements from the vector.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
void
|
|
||||||
_VECTOR_CLASS_NAME::MakeEmpty()
|
|
||||||
{
|
|
||||||
for (int32 i = 0; i < fItemCount; i++)
|
|
||||||
fItems[i].~Value();
|
|
||||||
_Resize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Begin
|
|
||||||
/*! \brief Returns an iterator referring to the beginning of the vector.
|
|
||||||
|
|
||||||
If the vector is not empty, Begin() refers to its first element,
|
|
||||||
otherwise it is equal to End() and must not be dereferenced!
|
|
||||||
|
|
||||||
\return An iterator referring to the beginning of the vector.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
_VECTOR_CLASS_NAME::Iterator
|
|
||||||
_VECTOR_CLASS_NAME::Begin()
|
|
||||||
{
|
|
||||||
return Iterator(fItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Begin
|
|
||||||
/*! \brief Returns an iterator referring to the beginning of the vector.
|
|
||||||
|
|
||||||
If the vector is not empty, Begin() refers to its first element,
|
|
||||||
otherwise it is equal to End() and must not be dereferenced!
|
|
||||||
|
|
||||||
\return An iterator referring to the beginning of the vector.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
_VECTOR_CLASS_NAME::ConstIterator
|
|
||||||
_VECTOR_CLASS_NAME::Begin() const
|
|
||||||
{
|
|
||||||
return ConstIterator(fItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
// End
|
|
||||||
/*! \brief Returns an iterator referring to the end of the vector.
|
|
||||||
|
|
||||||
The position identified by End() is the one succeeding the last
|
|
||||||
element, i.e. it must not be dereferenced!
|
|
||||||
|
|
||||||
\return An iterator referring to the end of the vector.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
_VECTOR_CLASS_NAME::Iterator
|
|
||||||
_VECTOR_CLASS_NAME::End()
|
|
||||||
{
|
|
||||||
return Iterator(fItems + fItemCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// End
|
|
||||||
/*! \brief Returns an iterator referring to the end of the vector.
|
|
||||||
|
|
||||||
The position identified by End() is the one succeeding the last
|
|
||||||
element, i.e. it must not be dereferenced!
|
|
||||||
|
|
||||||
\return An iterator referring to the end of the vector.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
_VECTOR_CLASS_NAME::ConstIterator
|
|
||||||
_VECTOR_CLASS_NAME::End() const
|
|
||||||
{
|
|
||||||
return ConstIterator(fItems + fItemCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Null
|
|
||||||
/*! \brief Returns an invalid iterator.
|
|
||||||
|
|
||||||
Null() is used as a return value, if something went wrong. It must
|
|
||||||
neither be incremented or decremented nor dereferenced!
|
|
||||||
|
|
||||||
\return An invalid iterator.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
_VECTOR_CLASS_NAME::Iterator
|
|
||||||
_VECTOR_CLASS_NAME::Null()
|
|
||||||
{
|
|
||||||
return Iterator(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Null
|
|
||||||
/*! \brief Returns an invalid iterator.
|
|
||||||
|
|
||||||
Null() is used as a return value, if something went wrong. It must
|
|
||||||
neither be incremented or decremented nor dereferenced!
|
|
||||||
|
|
||||||
\return An invalid iterator.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
_VECTOR_CLASS_NAME::ConstIterator
|
|
||||||
_VECTOR_CLASS_NAME::Null() const
|
|
||||||
{
|
|
||||||
return ConstIterator(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// IteratorForIndex
|
|
||||||
/*! \brief Returns an iterator for a given index.
|
|
||||||
\return An iterator referring to the same element as \a index, or
|
|
||||||
End(), if \a index is out of range.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
_VECTOR_CLASS_NAME::Iterator
|
|
||||||
_VECTOR_CLASS_NAME::IteratorForIndex(int32 index)
|
|
||||||
{
|
|
||||||
if (index >= 0 && index <= fItemCount)
|
|
||||||
return Iterator(fItems + index);
|
|
||||||
return End();
|
|
||||||
}
|
|
||||||
|
|
||||||
// IteratorForIndex
|
|
||||||
/*! \brief Returns an iterator for a given index.
|
|
||||||
\return An iterator referring to the same element as \a index, or
|
|
||||||
End(), if \a index is out of range.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
_VECTOR_CLASS_NAME::ConstIterator
|
|
||||||
_VECTOR_CLASS_NAME::IteratorForIndex(int32 index) const
|
|
||||||
{
|
|
||||||
if (index >= 0 && index <= fItemCount)
|
|
||||||
return ConstIterator(fItems + index);
|
|
||||||
return End();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ElementAt
|
|
||||||
/*! \brief Returns the element at a given index.
|
|
||||||
\param index The index identifying the element to be returned.
|
|
||||||
\return The element identified by the given index.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
const Value &
|
|
||||||
_VECTOR_CLASS_NAME::ElementAt(int32 index) const
|
|
||||||
{
|
|
||||||
if (index >= 0 && index < fItemCount)
|
|
||||||
return fItems[index];
|
|
||||||
// Return the 0th element by default. Unless the allocation failed, there
|
|
||||||
// is always a 0th element -- uninitialized perhaps.
|
|
||||||
return fItems[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// ElementAt
|
|
||||||
/*! \brief Returns the element at a given index.
|
|
||||||
\param index The index identifying the element to be returned.
|
|
||||||
\return The element identified by the given index.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
Value &
|
|
||||||
_VECTOR_CLASS_NAME::ElementAt(int32 index)
|
|
||||||
{
|
|
||||||
if (index >= 0 && index < fItemCount)
|
|
||||||
return fItems[index];
|
|
||||||
// Return the 0th element by default. Unless the allocation failed, there
|
|
||||||
// is always a 0th element -- uninitialized perhaps.
|
|
||||||
return fItems[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// IndexOf
|
|
||||||
/*! \brief Returns the index of the next element with the specified value.
|
|
||||||
\param value The value of the element to be found.
|
|
||||||
\param start The index at which to be started to search for the element.
|
|
||||||
\return The index of the found element, or \c -1, if no further element
|
|
||||||
with the given value could be found or \a index is out of range.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
int32
|
|
||||||
_VECTOR_CLASS_NAME::IndexOf(const Value &value, int32 start) const
|
|
||||||
{
|
|
||||||
if (start >= 0) {
|
|
||||||
for (int32 i = start; i < fItemCount; i++) {
|
|
||||||
if (fItems[i] == value)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find
|
|
||||||
/*! \brief Returns an iterator referring to the next element with the
|
|
||||||
specified value.
|
|
||||||
\param value The value of the element to be found.
|
|
||||||
\return An iterator referring to the found element, or End(), if no
|
|
||||||
further with the given value could be found.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
_VECTOR_CLASS_NAME::Iterator
|
|
||||||
_VECTOR_CLASS_NAME::Find(const Value &value)
|
|
||||||
{
|
|
||||||
return Find(value, Begin());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find
|
|
||||||
/*! \brief Returns an iterator referring to the next element with the
|
|
||||||
specified value.
|
|
||||||
\param value The value of the element to be found.
|
|
||||||
\param start And iterator specifying where to start searching for the
|
|
||||||
element.
|
|
||||||
\return An iterator referring to the found element, or End(), if no
|
|
||||||
further with the given value could be found or \a start was
|
|
||||||
invalid.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
_VECTOR_CLASS_NAME::Iterator
|
|
||||||
_VECTOR_CLASS_NAME::Find(const Value &value, const Iterator &start)
|
|
||||||
{
|
|
||||||
int32 index = IndexOf(value, _IteratorIndex(start));
|
|
||||||
if (index >= 0)
|
|
||||||
return Iterator(fItems + index);
|
|
||||||
return End();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find
|
|
||||||
/*! \brief Returns an iterator referring to the of the next element with the
|
|
||||||
specified value.
|
|
||||||
\param value The value of the element to be found.
|
|
||||||
\return An iterator referring to the found element, or End(), if no
|
|
||||||
further with the given value could be found.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
_VECTOR_CLASS_NAME::ConstIterator
|
|
||||||
_VECTOR_CLASS_NAME::Find(const Value &value) const
|
|
||||||
{
|
|
||||||
return Find(value, Begin());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find
|
|
||||||
/*! \brief Returns an iterator referring to the of the next element with the
|
|
||||||
specified value.
|
|
||||||
\param value The value of the element to be found.
|
|
||||||
\param start And iterator specifying where to start searching for the
|
|
||||||
element.
|
|
||||||
\return An iterator referring to the found element, or End(), if no
|
|
||||||
further with the given value could be found or \a start was
|
|
||||||
invalid.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
_VECTOR_CLASS_NAME::ConstIterator
|
|
||||||
_VECTOR_CLASS_NAME::Find(const Value &value, const ConstIterator &start) const
|
|
||||||
{
|
|
||||||
int32 index = IndexOf(value, _IteratorIndex(start));
|
|
||||||
if (index >= 0)
|
|
||||||
return ConstIterator(fItems + index);
|
|
||||||
return End();
|
|
||||||
}
|
|
||||||
|
|
||||||
// []
|
|
||||||
/*! \brief Semantically equivalent to ElementAt().
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
Value &
|
|
||||||
_VECTOR_CLASS_NAME::operator[](int32 index)
|
|
||||||
{
|
|
||||||
return ElementAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// []
|
|
||||||
/*! \brief Semantically equivalent to ElementAt().
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
const Value &
|
|
||||||
_VECTOR_CLASS_NAME::operator[](int32 index) const
|
|
||||||
{
|
|
||||||
return ElementAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _Resize
|
|
||||||
/*! \brief Resizes the vector.
|
|
||||||
|
|
||||||
The internal element array will be grown or shrunk to the next multiple
|
|
||||||
of \a fChunkSize >= \a count, but no less than \a fChunkSize.
|
|
||||||
|
|
||||||
Also adjusts \a fItemCount according to the supplied \a count, but does
|
|
||||||
not invoke a destructor or constructor on any element.
|
|
||||||
|
|
||||||
\param count The number of element.
|
|
||||||
\return \c true, if everything went fine, \c false, if the memory
|
|
||||||
allocation failed.
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
bool
|
|
||||||
_VECTOR_CLASS_NAME::_Resize(size_t count)
|
|
||||||
{
|
|
||||||
bool result = true;
|
|
||||||
// calculate the new capacity
|
|
||||||
int32 newSize = count;
|
|
||||||
if (newSize <= 0)
|
|
||||||
newSize = 1;
|
|
||||||
newSize = ((newSize - 1) / fChunkSize + 1) * fChunkSize;
|
|
||||||
// resize if necessary
|
|
||||||
if ((size_t)newSize != fCapacity) {
|
|
||||||
Value* newItems = (Value*)realloc(fItems, newSize * sizeof(Value));
|
|
||||||
if (newItems) {
|
|
||||||
fItems = newItems;
|
|
||||||
fCapacity = newSize;
|
|
||||||
} else
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
if (result)
|
|
||||||
fItemCount = count;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _IteratorIndex
|
|
||||||
/*! \brief Returns index of the element the supplied iterator refers to.
|
|
||||||
\return The index of the element the supplied iterator refers to, or
|
|
||||||
\c -1, if the iterator is invalid (End() is considered valid
|
|
||||||
here, and Count() is returned).
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
int32
|
|
||||||
_VECTOR_CLASS_NAME::_IteratorIndex(const Iterator &iterator) const
|
|
||||||
{
|
|
||||||
if (iterator.Element()) {
|
|
||||||
int32 index = iterator.Element() - fItems;
|
|
||||||
if (index >= 0 && index <= fItemCount)
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _IteratorIndex
|
|
||||||
/*! \brief Returns index of the element the supplied iterator refers to.
|
|
||||||
\return The index of the element the supplied iterator refers to, or
|
|
||||||
\c -1, if the iterator is invalid (End() is considered valid
|
|
||||||
here, and Count() is returned).
|
|
||||||
*/
|
|
||||||
_VECTOR_TEMPLATE_LIST
|
|
||||||
inline
|
|
||||||
int32
|
|
||||||
_VECTOR_CLASS_NAME::_IteratorIndex(const ConstIterator &iterator) const
|
|
||||||
{
|
|
||||||
if (iterator.Element()) {
|
|
||||||
int32 index = iterator.Element() - fItems;
|
|
||||||
if (index >= 0 && index <= fItemCount)
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _INSTALLER_VECTOR_H
|
|
||||||
@@ -1,26 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2008, Jérôme DUVAL. All rights reserved.
|
* Copyright 2009, Stephan Aßmus <superstippi@gmx.de>.
|
||||||
* Distributed under the terms of the MIT License.
|
* Copyright 2005-2008, Jérôme DUVAL.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CopyEngine.h"
|
#include "WorkerThread.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
|
#include <Autolock.h>
|
||||||
|
#include <Directory.h>
|
||||||
#include <DiskDeviceVisitor.h>
|
#include <DiskDeviceVisitor.h>
|
||||||
#include <DiskDeviceTypes.h>
|
#include <DiskDeviceTypes.h>
|
||||||
#include <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
|
#include <Menu.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <Messenger.h>
|
#include <Messenger.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <VolumeRoster.h>
|
#include <VolumeRoster.h>
|
||||||
|
|
||||||
|
#include "AutoLocker.h"
|
||||||
#include "CopyEngine2.h"
|
#include "CopyEngine2.h"
|
||||||
#include "InstallerWindow.h"
|
#include "InstallerWindow.h"
|
||||||
#include "FSUndoRedo.h"
|
|
||||||
#include "FSUtils.h"
|
|
||||||
#include "PackageViews.h"
|
#include "PackageViews.h"
|
||||||
#include "PartitionMenuItem.h"
|
#include "PartitionMenuItem.h"
|
||||||
|
|
||||||
@@ -28,8 +32,8 @@
|
|||||||
//#define COPY_TRACE
|
//#define COPY_TRACE
|
||||||
#ifdef COPY_TRACE
|
#ifdef COPY_TRACE
|
||||||
#define CALLED() printf("CALLED %s\n",__PRETTY_FUNCTION__)
|
#define CALLED() printf("CALLED %s\n",__PRETTY_FUNCTION__)
|
||||||
#define ERR2(x, y...) fprintf(stderr, "CopyEngine: "x" %s\n", y, strerror(err))
|
#define ERR2(x, y...) fprintf(stderr, "WorkerThread: "x" %s\n", y, strerror(err))
|
||||||
#define ERR(x) fprintf(stderr, "CopyEngine: "x" %s\n", strerror(err))
|
#define ERR(x) fprintf(stderr, "WorkerThread: "x" %s\n", strerror(err))
|
||||||
#else
|
#else
|
||||||
#define CALLED()
|
#define CALLED()
|
||||||
#define ERR(x)
|
#define ERR(x)
|
||||||
@@ -40,6 +44,10 @@ const char BOOT_PATH[] = "/boot";
|
|||||||
|
|
||||||
extern void SizeAsString(off_t size, char *string);
|
extern void SizeAsString(off_t size, char *string);
|
||||||
|
|
||||||
|
|
||||||
|
const uint32 MSG_START_INSTALLING = 'eSRT';
|
||||||
|
|
||||||
|
|
||||||
class SourceVisitor : public BDiskDeviceVisitor
|
class SourceVisitor : public BDiskDeviceVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -63,37 +71,39 @@ class TargetVisitor : public BDiskDeviceVisitor
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
CopyEngine::CopyEngine(InstallerWindow *window)
|
// #pragma mark - WorkerThread
|
||||||
|
|
||||||
|
|
||||||
|
WorkerThread::WorkerThread(InstallerWindow *window)
|
||||||
: BLooper("copy_engine"),
|
: BLooper("copy_engine"),
|
||||||
fWindow(window),
|
fWindow(window),
|
||||||
fPackages(NULL),
|
fPackages(NULL),
|
||||||
fSpaceRequired(0)
|
fSpaceRequired(0)
|
||||||
{
|
{
|
||||||
fControl = new InstallerCopyLoopControl(window);
|
|
||||||
Run();
|
Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CopyEngine::MessageReceived(BMessage* message)
|
WorkerThread::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
case ENGINE_START:
|
case MSG_START_INSTALLING:
|
||||||
Start(fWindow->GetSourceMenu(), fWindow->GetTargetMenu());
|
_PerformInstall(fWindow->GetSourceMenu(), fWindow->GetTargetMenu());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kWriteBootSector:
|
case MSG_WRITE_BOOT_SECTOR:
|
||||||
{
|
{
|
||||||
int32 id;
|
int32 id;
|
||||||
if (message->FindInt32("id", &id) != B_OK) {
|
if (message->FindInt32("id", &id) != B_OK) {
|
||||||
SetStatusMessage("Boot sector not written because of an "
|
_SetStatusMessage("Boot sector not written because of an "
|
||||||
" internal error.");
|
" internal error.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor with Start()
|
// TODO: Refactor with _PerformInstall()
|
||||||
BPath targetDirectory;
|
BPath targetDirectory;
|
||||||
BDiskDevice device;
|
BDiskDevice device;
|
||||||
BPartition* partition;
|
BPartition* partition;
|
||||||
@@ -101,32 +111,32 @@ CopyEngine::MessageReceived(BMessage* message)
|
|||||||
if (fDDRoster.GetPartitionWithID(id, &device, &partition) == B_OK) {
|
if (fDDRoster.GetPartitionWithID(id, &device, &partition) == B_OK) {
|
||||||
if (!partition->IsMounted()) {
|
if (!partition->IsMounted()) {
|
||||||
if (partition->Mount() < B_OK) {
|
if (partition->Mount() < B_OK) {
|
||||||
SetStatusMessage("The partition can't be mounted. "
|
_SetStatusMessage("The partition can't be mounted. "
|
||||||
"Please choose a different partition.");
|
"Please choose a different partition.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (partition->GetMountPoint(&targetDirectory) != B_OK) {
|
if (partition->GetMountPoint(&targetDirectory) != B_OK) {
|
||||||
SetStatusMessage("The mount point could not be retrieve.");
|
_SetStatusMessage("The mount point could not be retrieve.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (fDDRoster.GetDeviceWithID(id, &device) == B_OK) {
|
} else if (fDDRoster.GetDeviceWithID(id, &device) == B_OK) {
|
||||||
if (!device.IsMounted()) {
|
if (!device.IsMounted()) {
|
||||||
if (device.Mount() < B_OK) {
|
if (device.Mount() < B_OK) {
|
||||||
SetStatusMessage("The disk can't be mounted. Please "
|
_SetStatusMessage("The disk can't be mounted. Please "
|
||||||
"choose a different disk.");
|
"choose a different disk.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (device.GetMountPoint(&targetDirectory) != B_OK) {
|
if (device.GetMountPoint(&targetDirectory) != B_OK) {
|
||||||
SetStatusMessage("The mount point could not be retrieve.");
|
_SetStatusMessage("The mount point could not be retrieve.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchFinishScript(targetDirectory);
|
_LaunchFinishScript(targetDirectory);
|
||||||
// TODO: Get error from executing script!
|
// TODO: Get error from executing script!
|
||||||
SetStatusMessage("Boot sector successfully written.");
|
_SetStatusMessage("Boot sector successfully written.");
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
BLooper::MessageReceived(message);
|
BLooper::MessageReceived(message);
|
||||||
@@ -134,17 +144,67 @@ CopyEngine::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CopyEngine::SetStatusMessage(const char *status)
|
WorkerThread::ScanDisksPartitions(BMenu *srcMenu, BMenu *targetMenu)
|
||||||
{
|
{
|
||||||
BMessage msg(STATUS_MESSAGE);
|
// NOTE: This is actually executed in the window thread.
|
||||||
msg.AddString("status", status);
|
BDiskDevice device;
|
||||||
BMessenger(fWindow).SendMessage(&msg);
|
BPartition *partition = NULL;
|
||||||
|
|
||||||
|
printf("\nScanDisksPartitions source partitions begin\n");
|
||||||
|
SourceVisitor srcVisitor(srcMenu);
|
||||||
|
fDDRoster.VisitEachMountedPartition(&srcVisitor, &device, &partition);
|
||||||
|
|
||||||
|
printf("\nScanDisksPartitions target partitions begin\n");
|
||||||
|
TargetVisitor targetVisitor(targetMenu);
|
||||||
|
fDDRoster.VisitEachPartition(&targetVisitor, &device, &partition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CopyEngine::LaunchInitScript(BPath &path)
|
WorkerThread::SetPackagesList(BList *list)
|
||||||
|
{
|
||||||
|
// Executed in window thread.
|
||||||
|
BAutolock _(this);
|
||||||
|
|
||||||
|
delete fPackages;
|
||||||
|
fPackages = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WorkerThread::StartInstall()
|
||||||
|
{
|
||||||
|
// Executed in window thread.
|
||||||
|
PostMessage(MSG_START_INSTALLING, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WorkerThread::WriteBootSector(BMenu* targetMenu)
|
||||||
|
{
|
||||||
|
// Executed in window thread.
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
PartitionMenuItem* item = (PartitionMenuItem*)targetMenu->FindMarked();
|
||||||
|
if (item == NULL) {
|
||||||
|
ERR("bad menu items\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage message(MSG_WRITE_BOOT_SECTOR);
|
||||||
|
message.AddInt32("id", item->ID());
|
||||||
|
PostMessage(&message, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WorkerThread::_LaunchInitScript(BPath &path)
|
||||||
{
|
{
|
||||||
BPath bootPath;
|
BPath bootPath;
|
||||||
find_directory(B_BEOS_BOOT_DIRECTORY, &bootPath);
|
find_directory(B_BEOS_BOOT_DIRECTORY, &bootPath);
|
||||||
@@ -152,13 +212,13 @@ CopyEngine::LaunchInitScript(BPath &path)
|
|||||||
command += bootPath.Path();
|
command += bootPath.Path();
|
||||||
command += "/InstallerInitScript ";
|
command += "/InstallerInitScript ";
|
||||||
command += path.Path();
|
command += path.Path();
|
||||||
SetStatusMessage("Starting Installation.");
|
_SetStatusMessage("Starting Installation.");
|
||||||
system(command.String());
|
system(command.String());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CopyEngine::LaunchFinishScript(BPath &path)
|
WorkerThread::_LaunchFinishScript(BPath &path)
|
||||||
{
|
{
|
||||||
BPath bootPath;
|
BPath bootPath;
|
||||||
find_directory(B_BEOS_BOOT_DIRECTORY, &bootPath);
|
find_directory(B_BEOS_BOOT_DIRECTORY, &bootPath);
|
||||||
@@ -166,27 +226,27 @@ CopyEngine::LaunchFinishScript(BPath &path)
|
|||||||
command += bootPath.Path();
|
command += bootPath.Path();
|
||||||
command += "/InstallerFinishScript ";
|
command += "/InstallerFinishScript ";
|
||||||
command += path.Path();
|
command += path.Path();
|
||||||
SetStatusMessage("Finishing Installation.");
|
_SetStatusMessage("Finishing Installation.");
|
||||||
system(command.String());
|
system(command.String());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
|
WorkerThread::_PerformInstall(BMenu *srcMenu, BMenu *targetMenu)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
BPath targetDirectory, srcDirectory;
|
BPath targetDirectory, srcDirectory;
|
||||||
BDirectory targetDir, srcDir;
|
BDirectory targetDir;
|
||||||
BDiskDevice device;
|
BDiskDevice device;
|
||||||
BPartition *partition;
|
BPartition *partition;
|
||||||
BVolume targetVolume;
|
BVolume targetVolume;
|
||||||
status_t err = B_OK;
|
status_t err = B_OK;
|
||||||
int32 entries = 0;
|
int32 entries = 0;
|
||||||
entry_ref testRef;
|
entry_ref testRef;
|
||||||
bigtime_t now;
|
|
||||||
|
|
||||||
fControl->Reset();
|
BMessenger messenger(fWindow);
|
||||||
|
CopyEngine2 engine(messenger, new BMessage(MSG_STATUS_MESSAGE));
|
||||||
|
|
||||||
PartitionMenuItem *targetItem = (PartitionMenuItem *)targetMenu->FindMarked();
|
PartitionMenuItem *targetItem = (PartitionMenuItem *)targetMenu->FindMarked();
|
||||||
PartitionMenuItem *srcItem = (PartitionMenuItem *)srcMenu->FindMarked();
|
PartitionMenuItem *srcItem = (PartitionMenuItem *)srcMenu->FindMarked();
|
||||||
@@ -201,7 +261,7 @@ bigtime_t now;
|
|||||||
if (fDDRoster.GetPartitionWithID(targetItem->ID(), &device, &partition) == B_OK) {
|
if (fDDRoster.GetPartitionWithID(targetItem->ID(), &device, &partition) == B_OK) {
|
||||||
if (!partition->IsMounted()) {
|
if (!partition->IsMounted()) {
|
||||||
if ((err = partition->Mount()) < B_OK) {
|
if ((err = partition->Mount()) < B_OK) {
|
||||||
SetStatusMessage("The disk can't be mounted. Please choose a "
|
_SetStatusMessage("The disk can't be mounted. Please choose a "
|
||||||
"different disk.");
|
"different disk.");
|
||||||
ERR("BPartition::Mount");
|
ERR("BPartition::Mount");
|
||||||
goto error;
|
goto error;
|
||||||
@@ -218,7 +278,7 @@ bigtime_t now;
|
|||||||
} else if (fDDRoster.GetDeviceWithID(targetItem->ID(), &device) == B_OK) {
|
} else if (fDDRoster.GetDeviceWithID(targetItem->ID(), &device) == B_OK) {
|
||||||
if (!device.IsMounted()) {
|
if (!device.IsMounted()) {
|
||||||
if ((err = device.Mount()) < B_OK) {
|
if ((err = device.Mount()) < B_OK) {
|
||||||
SetStatusMessage("The disk can't be mounted. Please choose a "
|
_SetStatusMessage("The disk can't be mounted. Please choose a "
|
||||||
"different disk.");
|
"different disk.");
|
||||||
ERR("BDiskDevice::Mount");
|
ERR("BDiskDevice::Mount");
|
||||||
goto error;
|
goto error;
|
||||||
@@ -259,7 +319,7 @@ bigtime_t now;
|
|||||||
|
|
||||||
// check not installing on itself
|
// check not installing on itself
|
||||||
if (strcmp(srcDirectory.Path(), targetDirectory.Path()) == 0) {
|
if (strcmp(srcDirectory.Path(), targetDirectory.Path()) == 0) {
|
||||||
SetStatusMessage("You can't install the contents of a disk onto "
|
_SetStatusMessage("You can't install the contents of a disk onto "
|
||||||
"itself. Please choose a different disk.");
|
"itself. Please choose a different disk.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -270,7 +330,7 @@ bigtime_t now;
|
|||||||
"current boot disk? The Installer will have to reboot your "
|
"current boot disk? The Installer will have to reboot your "
|
||||||
"machine if you proceed.", "OK", "Cancel", 0,
|
"machine if you proceed.", "OK", "Cancel", 0,
|
||||||
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
|
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
|
||||||
SetStatusMessage("Installation stopped.");
|
_SetStatusMessage("Installation stopped.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,143 +386,54 @@ bigtime_t now;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LaunchInitScript(targetDirectory);
|
_LaunchInitScript(targetDirectory);
|
||||||
|
|
||||||
// copy source volume
|
// copy source volume
|
||||||
targetDir.Rewind();
|
err = engine.CopyFolder(srcDirectory.Path(), targetDirectory.Path(),
|
||||||
srcDir.SetTo(srcDirectory.Path());
|
fCancelLock);
|
||||||
now = system_time();
|
if (err != B_OK)
|
||||||
#if 0
|
|
||||||
err = CopyFolder(srcDir, targetDir);
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
BMessenger messenger(fWindow);
|
|
||||||
CopyEngine2 engine(messenger, new BMessage(STATUS_MESSAGE));
|
|
||||||
err = engine.CopyFolder(srcDirectory.Path(), targetDirectory.Path(),
|
|
||||||
fCancelLock);
|
|
||||||
if (err != B_OK)
|
|
||||||
printf("error: %s\n", strerror(err));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
printf("copy time: %.3fs\n", (system_time() - now) / 1000000.0);
|
|
||||||
|
|
||||||
if (err != B_OK || fControl->CheckUserCanceled())
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
// copy selected packages
|
// copy selected packages
|
||||||
if (fPackages) {
|
if (fPackages) {
|
||||||
srcDirectory.Append(PACKAGES_DIRECTORY);
|
srcDirectory.Append(PACKAGES_DIRECTORY);
|
||||||
srcDir.SetTo(srcDirectory.Path());
|
|
||||||
BDirectory packageDir;
|
|
||||||
int32 count = fPackages->CountItems();
|
int32 count = fPackages->CountItems();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
Package *p = static_cast<Package*>(fPackages->ItemAt(i));
|
Package *p = static_cast<Package*>(fPackages->ItemAt(i));
|
||||||
packageDir.SetTo(&srcDir, p->Folder());
|
BPath packageDir(srcDirectory.Path(), p->Folder());
|
||||||
err = CopyFolder(packageDir, targetDir);
|
err = engine.CopyFolder(packageDir.Path(), targetDirectory.Path(),
|
||||||
if (err != B_OK || fControl->CheckUserCanceled())
|
fCancelLock);
|
||||||
|
if (err != B_OK)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchFinishScript(targetDirectory);
|
_LaunchFinishScript(targetDirectory);
|
||||||
|
|
||||||
BMessenger(fWindow).SendMessage(INSTALL_FINISHED);
|
BMessenger(fWindow).SendMessage(MSG_INSTALL_FINISHED);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
error:
|
error:
|
||||||
if (err == B_CANCELED || fControl->CheckUserCanceled())
|
BMessage statusMessage(MSG_RESET);
|
||||||
SetStatusMessage("Installation canceled.");
|
if (err == B_CANCELED)
|
||||||
ERR("Start failed");
|
_SetStatusMessage("Installation canceled.");
|
||||||
BMessenger(fWindow).SendMessage(RESET_INSTALL);
|
else
|
||||||
}
|
statusMessage.AddInt32("error", err);
|
||||||
|
ERR("_PerformInstall failed");
|
||||||
|
BMessenger(fWindow).SendMessage(&statusMessage);
|
||||||
status_t
|
|
||||||
CopyEngine::CopyFolder(BDirectory &srcDir, BDirectory &targetDir)
|
|
||||||
{
|
|
||||||
BEntry entry;
|
|
||||||
status_t err;
|
|
||||||
while (srcDir.GetNextEntry(&entry) == B_OK
|
|
||||||
&& !fControl->CheckUserCanceled()) {
|
|
||||||
StatStruct statbuf;
|
|
||||||
entry.GetStat(&statbuf);
|
|
||||||
|
|
||||||
Undo undo;
|
|
||||||
if (S_ISDIR(statbuf.st_mode)) {
|
|
||||||
char name[B_FILE_NAME_LENGTH];
|
|
||||||
if (entry.GetName(name) == B_OK
|
|
||||||
&& (strcmp(name, PACKAGES_DIRECTORY) == 0
|
|
||||||
|| strcmp(name, VAR_DIRECTORY) == 0)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
err = FSCopyFolder(&entry, &targetDir, fControl, NULL, false, undo);
|
|
||||||
} else {
|
|
||||||
err = FSCopyFile(&entry, &statbuf, &targetDir, fControl, NULL,
|
|
||||||
false, undo);
|
|
||||||
}
|
|
||||||
if (err != B_OK) {
|
|
||||||
BPath path;
|
|
||||||
entry.GetPath(&path);
|
|
||||||
ERR2("error while copying %s", path.Path());
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CopyEngine::ScanDisksPartitions(BMenu *srcMenu, BMenu *targetMenu)
|
WorkerThread::_SetStatusMessage(const char *status)
|
||||||
{
|
{
|
||||||
// NOTE: This is actually executed in the window thread.
|
BMessage msg(MSG_STATUS_MESSAGE);
|
||||||
BDiskDevice device;
|
msg.AddString("status", status);
|
||||||
BPartition *partition = NULL;
|
BMessenger(fWindow).SendMessage(&msg);
|
||||||
|
|
||||||
printf("\nScanDisksPartitions source partitions begin\n");
|
|
||||||
SourceVisitor srcVisitor(srcMenu);
|
|
||||||
fDDRoster.VisitEachMountedPartition(&srcVisitor, &device, &partition);
|
|
||||||
|
|
||||||
printf("\nScanDisksPartitions target partitions begin\n");
|
|
||||||
TargetVisitor targetVisitor(targetMenu);
|
|
||||||
fDDRoster.VisitEachPartition(&targetVisitor, &device, &partition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
// #pragma mark - SourceVisitor
|
||||||
CopyEngine::SetPackagesList(BList *list)
|
|
||||||
{
|
|
||||||
delete fPackages;
|
|
||||||
fPackages = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
CopyEngine::Cancel()
|
|
||||||
{
|
|
||||||
return fControl->Cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CopyEngine::WriteBootSector(BMenu* targetMenu)
|
|
||||||
{
|
|
||||||
// Executed in window thread.
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
PartitionMenuItem* item = (PartitionMenuItem*)targetMenu->FindMarked();
|
|
||||||
if (item == NULL) {
|
|
||||||
ERR("bad menu items\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BMessage message(kWriteBootSector);
|
|
||||||
message.AddInt32("id", item->ID());
|
|
||||||
PostMessage(&message, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
SourceVisitor::SourceVisitor(BMenu *menu)
|
SourceVisitor::SourceVisitor(BMenu *menu)
|
||||||
@@ -516,7 +487,7 @@ SourceVisitor::Visit(BPartition *partition, int32 level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark - TargetVisitor
|
||||||
|
|
||||||
|
|
||||||
TargetVisitor::TargetVisitor(BMenu *menu)
|
TargetVisitor::TargetVisitor(BMenu *menu)
|
||||||
@@ -582,10 +553,15 @@ TargetVisitor::_MakeLabel(BPartition *partition, char *label, char *menuLabel)
|
|||||||
BPath path;
|
BPath path;
|
||||||
partition->GetPath(&path);
|
partition->GetPath(&path);
|
||||||
|
|
||||||
sprintf(label, "%s - %s [%s] [%s]", partition->ContentName(),
|
// TODO: Reenable the printing of the content type once Haiku supports
|
||||||
size, partition->ContentType(), path.Path());
|
// installing to other file systems than BFS.
|
||||||
sprintf(menuLabel, "%s - %s [%s]", partition->ContentName(), size,
|
// sprintf(label, "%s - %s [%s] [%s]", partition->ContentName(),
|
||||||
partition->ContentType());
|
// size, partition->ContentType(), path.Path());
|
||||||
|
// sprintf(menuLabel, "%s - %s [%s]", partition->ContentName(), size,
|
||||||
|
// partition->ContentType());
|
||||||
|
|
||||||
|
sprintf(label, "%s - %s - %s", partition->ContentName(), size,
|
||||||
|
path.Path());
|
||||||
|
sprintf(menuLabel, "%s - %s", partition->ContentName(), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Stephan Aßmus <superstippi@gmx.de>.
|
||||||
|
* Copyright 2005, Jérôme DUVAL.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef WORKER_THREAD_H
|
||||||
|
#define WORKER_THREAD_H
|
||||||
|
|
||||||
|
#include <DiskDevice.h>
|
||||||
|
#include <DiskDeviceRoster.h>
|
||||||
|
#include <Looper.h>
|
||||||
|
#include <Messenger.h>
|
||||||
|
#include <Partition.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
|
||||||
|
class BList;
|
||||||
|
class BLocker;
|
||||||
|
class BMenu;
|
||||||
|
class InstallerWindow;
|
||||||
|
|
||||||
|
class WorkerThread : public BLooper {
|
||||||
|
public:
|
||||||
|
WorkerThread(InstallerWindow* window);
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
|
void ScanDisksPartitions(BMenu* srcMenu,
|
||||||
|
BMenu* dstMenu);
|
||||||
|
|
||||||
|
void SetPackagesList(BList* list);
|
||||||
|
void SetSpaceRequired(off_t bytes)
|
||||||
|
{ fSpaceRequired = bytes; };
|
||||||
|
|
||||||
|
bool Cancel();
|
||||||
|
void SetLock(BLocker* lock)
|
||||||
|
{ fCancelLock = lock; }
|
||||||
|
|
||||||
|
void StartInstall();
|
||||||
|
void WriteBootSector(BMenu* dstMenu);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _LaunchInitScript(BPath& path);
|
||||||
|
void _LaunchFinishScript(BPath& path);
|
||||||
|
|
||||||
|
void _PerformInstall(BMenu* srcMenu, BMenu* dstMenu);
|
||||||
|
|
||||||
|
void _SetStatusMessage(const char* status);
|
||||||
|
|
||||||
|
InstallerWindow* fWindow;
|
||||||
|
BDiskDeviceRoster fDDRoster;
|
||||||
|
BList* fPackages;
|
||||||
|
off_t fSpaceRequired;
|
||||||
|
BLocker* fCancelLock;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WORKER_THREAD_H
|
||||||
Reference in New Issue
Block a user