1/*
2 * Copyright 2013-2014, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <EntryOperationEngineBase.h>
8
9#include <Directory.h>
10#include <Entry.h>
11#include <Path.h>
12
13
14namespace BPrivate {
15
16
17BEntryOperationEngineBase::Entry::Entry(const char* path)
18	:
19	fDirectory(NULL),
20	fPath(path),
21	fEntry(NULL),
22	fEntryRef(NULL),
23	fDirectoryRef(NULL)
24{
25}
26
27
28BEntryOperationEngineBase::Entry::Entry(const BDirectory& directory,
29	const char* path)
30	:
31	fDirectory(&directory),
32	fPath(path),
33	fEntry(NULL),
34	fEntryRef(NULL),
35	fDirectoryRef(NULL)
36{
37}
38
39
40BEntryOperationEngineBase::Entry::Entry(const BEntry& entry)
41	:
42	fDirectory(NULL),
43	fPath(NULL),
44	fEntry(&entry),
45	fEntryRef(NULL),
46	fDirectoryRef(NULL)
47{
48}
49
50
51BEntryOperationEngineBase::Entry::Entry(const entry_ref& entryRef)
52	:
53	fDirectory(NULL),
54	fPath(NULL),
55	fEntry(NULL),
56	fEntryRef(&entryRef),
57	fDirectoryRef(NULL)
58{
59}
60
61
62BEntryOperationEngineBase::Entry::Entry(const node_ref& directoryRef,
63	const char* path)
64	:
65	fDirectory(NULL),
66	fPath(path),
67	fEntry(NULL),
68	fEntryRef(NULL),
69	fDirectoryRef(&directoryRef)
70{
71}
72
73
74BEntryOperationEngineBase::Entry::~Entry()
75{
76}
77
78
79status_t
80BEntryOperationEngineBase::Entry::GetPath(BPath& buffer, const char*& _path)
81	const
82{
83	status_t error = B_OK;
84
85	if (fEntry != NULL) {
86		error = buffer.SetTo(fEntry);
87	} else if (fDirectory != NULL) {
88		error = buffer.SetTo(fDirectory, fPath);
89	} else if (fEntryRef != NULL) {
90		error = buffer.SetTo(fEntryRef);
91	} else if (fDirectoryRef != NULL) {
92		BDirectory directory;
93		error = directory.SetTo(fDirectoryRef);
94		if (error == B_OK)
95			error = buffer.SetTo(&directory, fPath);
96	} else if (fPath != NULL) {
97		_path = fPath;
98		return B_OK;
99	}
100
101	if (error != B_OK)
102		return error;
103
104	_path = buffer.Path();
105	return B_OK;
106}
107
108
109BString
110BEntryOperationEngineBase::Entry::Path() const
111{
112	BPath pathBuffer;
113	const char* path;
114	if (GetPath(pathBuffer, path) == B_OK)
115		return BString(path);
116	return BString();
117}
118
119
120status_t
121BEntryOperationEngineBase::Entry::GetPathOrName(BString& _path) const
122{
123	_path.Truncate(0);
124
125	BPath buffer;
126	const char* path;
127	status_t error = GetPath(buffer, path);
128	if (error == B_NO_MEMORY)
129		return error;
130
131	if (error == B_OK) {
132		_path = path;
133	} else if (fEntry != NULL) {
134		// GetPath() apparently failed, so just return the entry name.
135		_path = fEntry->Name();
136	} else if (fDirectory != NULL || fDirectoryRef != NULL) {
137		if (fPath != NULL && fPath[0] == '/') {
138			// absolute path -- just return it
139			_path = fPath;
140		} else {
141			// get the directory path
142			BEntry entry;
143			if (fDirectory != NULL) {
144				error = fDirectory->GetEntry(&entry);
145			} else {
146				BDirectory directory;
147				error = directory.SetTo(fDirectoryRef);
148				if (error == B_OK)
149					error = directory.GetEntry(&entry);
150			}
151
152			if (error != B_OK || (error = entry.GetPath(&buffer)) != B_OK)
153				return error;
154
155			_path = buffer.Path();
156
157			// If we additionally have a relative path, append it.
158			if (!_path.IsEmpty() && fPath != NULL) {
159				int32 length = _path.Length();
160				_path << '/' << fPath;
161				if (_path.Length() < length + 2)
162					return B_NO_MEMORY;
163			}
164		}
165	} else if (fEntryRef != NULL) {
166		// Getting the actual path apparently failed, so just return the entry
167		// name.
168		_path = fEntryRef->name;
169	} else if (fPath != NULL)
170		_path = fPath;
171
172	return _path.IsEmpty() ? B_NO_MEMORY : B_OK;
173}
174
175
176BString
177BEntryOperationEngineBase::Entry::PathOrName() const
178{
179	BString path;
180	return GetPathOrName(path) == B_OK ? path : BString();
181}
182
183
184} // namespace BPrivate
185