1/*
2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <PathFinder.h>
8
9#include <AutoDeleter.h>
10#include <FindDirectory.h>
11#include <Path.h>
12#include <StringList.h>
13
14
15// NOTE: The package kit specific part of BPathFinder (BResolvableExpression
16// constructor and SetTo()) is implemented in the package kit.
17
18
19BPathFinder::BPathFinder(const void* codePointer, const char* dependency)
20{
21	_SetTo(codePointer, NULL, dependency);
22}
23
24
25BPathFinder::BPathFinder(const char* path, const char* dependency)
26{
27	_SetTo(NULL, path, dependency);
28}
29
30
31BPathFinder::BPathFinder(const entry_ref& ref, const char* dependency)
32{
33	SetTo(ref, dependency);
34}
35
36
37status_t
38BPathFinder::SetTo(const void* codePointer, const char* dependency)
39{
40	return _SetTo(codePointer, NULL, dependency);
41}
42
43
44status_t
45BPathFinder::SetTo(const char* path, const char* dependency)
46{
47	return _SetTo(NULL, path, dependency);
48}
49
50
51status_t
52BPathFinder::SetTo(const entry_ref& ref, const char* dependency)
53{
54	BPath path;
55	fInitStatus = path.SetTo(&ref);
56	if (fInitStatus != B_OK)
57		return fInitStatus;
58
59	return _SetTo(NULL, path.Path(), dependency);
60}
61
62
63status_t
64BPathFinder::FindPath(const char* architecture,
65	path_base_directory baseDirectory, const char* subPath, uint32 flags,
66	BPath& _path)
67{
68	_path.Unset();
69
70	if (fInitStatus != B_OK)
71		return fInitStatus;
72
73	const char* dependency = fDependency.IsEmpty()
74		? NULL : fDependency.String();
75
76	char pathBuffer[B_PATH_NAME_LENGTH];
77	status_t error;
78
79	if (!fPath.IsEmpty()) {
80		error = find_path_for_path_etc(fPath, dependency, architecture,
81			baseDirectory, subPath, flags, pathBuffer, sizeof(pathBuffer));
82	} else {
83		error = find_path_etc(fCodePointer, dependency, architecture,
84			baseDirectory, subPath, flags, pathBuffer, sizeof(pathBuffer));
85	}
86
87	if (error != B_OK)
88		return error;
89
90	return _path.SetTo(pathBuffer);
91}
92
93
94status_t
95BPathFinder::FindPath(path_base_directory baseDirectory, const char* subPath,
96	uint32 flags, BPath& _path)
97{
98	return FindPath(NULL, baseDirectory, subPath, flags, _path);
99}
100
101
102status_t
103BPathFinder::FindPath(path_base_directory baseDirectory, const char* subPath,
104	BPath& _path)
105{
106	return FindPath(NULL, baseDirectory, subPath, 0, _path);
107}
108
109
110status_t
111BPathFinder::FindPath(path_base_directory baseDirectory, BPath& _path)
112{
113	return FindPath(NULL, baseDirectory, NULL, 0, _path);
114}
115
116
117/*static*/ status_t
118BPathFinder::FindPaths(const char* architecture,
119	path_base_directory baseDirectory, const char* subPath, uint32 flags,
120	BStringList& _paths)
121{
122	_paths.MakeEmpty();
123
124	// get the paths
125	char** pathArray;
126	size_t pathCount;
127	status_t error = find_paths_etc(architecture, baseDirectory, subPath, flags,
128		&pathArray, &pathCount);
129	if (error != B_OK)
130		return error;
131
132	MemoryDeleter pathArrayDeleter(pathArray);
133
134	// add them to BStringList
135	for (size_t i = 0; i < pathCount; i++) {
136		BString path(pathArray[i]);
137		if (path.IsEmpty() || !_paths.Add(path)) {
138			_paths.MakeEmpty();
139			return B_NO_MEMORY;
140		}
141	}
142
143	return B_OK;
144}
145
146
147/*static*/ status_t
148BPathFinder::FindPaths(path_base_directory baseDirectory, const char* subPath,
149	uint32 flags, BStringList& _paths)
150{
151	return FindPaths(NULL, baseDirectory, subPath, flags, _paths);
152}
153
154
155/*static*/ status_t
156BPathFinder::FindPaths(path_base_directory baseDirectory, const char* subPath,
157	BStringList& _paths)
158{
159	return FindPaths(NULL, baseDirectory, subPath, 0, _paths);
160}
161
162
163/*static*/ status_t
164BPathFinder::FindPaths(path_base_directory baseDirectory, BStringList& _paths)
165{
166	return FindPaths(NULL, baseDirectory, NULL, 0, _paths);
167}
168
169
170status_t
171BPathFinder::_SetTo(const void* codePointer, const char* path,
172	const char* dependency)
173{
174	fCodePointer = codePointer;
175	fPath = path;
176	fDependency = dependency;
177
178	if ((path != NULL && path[0] != '\0' && fPath.IsEmpty())
179		|| (dependency != NULL && dependency[0] != '\0'
180			&& fDependency.IsEmpty())) {
181		fInitStatus = B_NO_MEMORY;
182	} else
183		fInitStatus = B_OK;
184
185	return fInitStatus;
186}
187