1/*
2 * Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "PackageFileManager.h"
8
9#include <Locker.h>
10
11#include <AutoLocker.h>
12
13#include "DebugSupport.h"
14#include "Package.h"
15
16
17PackageFileManager::PackageFileManager(BLocker& lock)
18	:
19	fLock(lock),
20	fFilesByEntryRef()
21{
22}
23
24
25PackageFileManager::~PackageFileManager()
26{
27}
28
29
30status_t
31PackageFileManager::Init()
32{
33	return fFilesByEntryRef.Init();
34}
35
36
37status_t
38PackageFileManager::GetPackageFile(const entry_ref& entryRef,
39	PackageFile*& _file)
40{
41	AutoLocker<BLocker> locker(fLock);
42
43	PackageFile* file = fFilesByEntryRef.Lookup(entryRef);
44	if (file != NULL) {
45		if (file->AcquireReference() > 0) {
46			_file = file;
47			return B_OK;
48		}
49
50		// File already full dereferenced. It is about to be deleted.
51		fFilesByEntryRef.Remove(file);
52	}
53
54	file = new(std::nothrow) PackageFile;
55	if (file == NULL)
56		RETURN_ERROR(B_NO_MEMORY);
57
58	status_t error = file->Init(entryRef, this);
59	if (error != B_OK) {
60		delete file;
61		return error;
62	}
63
64	fFilesByEntryRef.Insert(file);
65
66	_file = file;
67	return B_OK;
68}
69
70
71status_t
72PackageFileManager::CreatePackage(const entry_ref& entryRef, Package*& _package)
73{
74	PackageFile* packageFile;
75	status_t error = GetPackageFile(entryRef, packageFile);
76	if (error != B_OK)
77		RETURN_ERROR(error);
78	BReference<PackageFile> packageFileReference(packageFile, true);
79
80	_package = new(std::nothrow) Package(packageFile);
81	RETURN_ERROR(_package != NULL ? B_OK : B_NO_MEMORY);
82}
83
84
85void
86PackageFileManager::PackageFileMoved(PackageFile* file,
87	const node_ref& newDirectory)
88{
89	if (newDirectory == file->DirectoryRef())
90		return;
91
92	AutoLocker<BLocker> locker(fLock);
93
94	fFilesByEntryRef.Remove(file);
95	file->SetDirectoryRef(newDirectory);
96	fFilesByEntryRef.Insert(file);
97}
98
99
100void
101PackageFileManager::RemovePackageFile(PackageFile* file)
102{
103	AutoLocker<BLocker> locker(fLock);
104
105	fFilesByEntryRef.Remove(file);
106}
107