1//------------------------------------------------------------------------------
2//	Copyright (c) 2001-2005, Haiku
3//
4//	Permission is hereby granted, free of charge, to any person obtaining a
5//	copy of this software and associated documentation files (the "Software"),
6//	to deal in the Software without restriction, including without limitation
7//	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8//	and/or sell copies of the Software, and to permit persons to whom the
9//	Software is furnished to do so, subject to the following conditions:
10//
11//	The above copyright notice and this permission notice shall be included in
12//	all copies or substantial portions of the Software.
13//
14//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19//	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20//	DEALINGS IN THE SOFTWARE.
21//
22//	File Name:		AppInfoList.cpp
23//	Author:			Ingo Weinhold (bonefish@users.sf.net)
24//	Description:	A helper class for TRoster. A list of RosterAppInfos.
25//------------------------------------------------------------------------------
26
27#include <algorithm>
28
29#include <strings.h>
30
31#include "AppInfoList.h"
32#include "RosterAppInfo.h"
33
34/*!
35	\class AppInfoList
36	\brief A list of RosterAppInfos.
37
38	Features adding/removing of RosterAppInfos and method for finding
39	infos by signature, team ID, entry_ref or token.
40	The method It() returns an iterator, an instance of the basic
41	AppInfoList::Iterator class.
42*/
43
44
45// constructor
46/*!	\brief Creates an empty list.
47*/
48AppInfoList::AppInfoList()
49		   : fInfos()
50{
51}
52
53// destructor
54/*!	\brief Frees all resources associated with this object.
55
56	The RosterAppInfos the list contains are deleted.
57*/
58AppInfoList::~AppInfoList()
59{
60	// delete all infos
61	MakeEmpty(true);
62}
63
64// AddInfo
65/*!	\brief Adds a RosterAppInfos to the list.
66	\param info The RosterAppInfo to be added
67	\return \c true on success, false if \a info is \c NULL or there's not
68			enough memory for this operation.
69*/
70bool
71AppInfoList::AddInfo(RosterAppInfo *info)
72{
73	bool result = false;
74	if (info)
75		result = fInfos.AddItem(info);
76	return result;
77}
78
79// RemoveInfo
80/*!	\brief Removes a RosterAppInfos from the list.
81	\param info The RosterAppInfo to be removed
82	\return \c true on success, false if \a info was not in the list.
83*/
84bool
85AppInfoList::RemoveInfo(RosterAppInfo *info)
86{
87	return fInfos.RemoveItem(info);
88}
89
90// MakeEmpty
91/*!	\brief Removes all RosterAppInfos from the list.
92*/
93void
94AppInfoList::MakeEmpty(bool deleteInfos)
95{
96	if (deleteInfos) {
97		for (int32 i = 0; RosterAppInfo *info = InfoAt(i); i++)
98			delete info;
99	}
100
101	fInfos.MakeEmpty();
102}
103
104// InfoFor
105/*!	\brief Returns the RosterAppInfo with the supplied signature.
106
107	If the list contains more than one RosterAppInfo with the given signature,
108	it is undefined, which one is returned.
109
110	\param signature The signature
111	\return A RosterAppInfo with the supplied signature, or \c NULL, if
112			\a signature is \c NULL or the list doesn't contain an info with
113			this signature.
114*/
115RosterAppInfo *
116AppInfoList::InfoFor(const char *signature) const
117{
118	return InfoAt(IndexOf(signature));
119}
120
121// InfoFor
122/*!	\brief Returns the RosterAppInfo with the supplied team ID.
123	\param team The team ID
124	\return A RosterAppInfo with the supplied team ID, or \c NULL, if the list
125			doesn't contain an info with this team ID.
126*/
127RosterAppInfo *
128AppInfoList::InfoFor(team_id team) const
129{
130	return InfoAt(IndexOf(team));
131}
132
133// InfoFor
134/*!	\brief Returns the RosterAppInfo with the supplied entry_ref.
135
136	If the list contains more than one RosterAppInfo with the given entry_ref,
137	it is undefined, which one is returned.
138
139	\param ref The entry_ref
140	\return A RosterAppInfo with the supplied entry_ref, or \c NULL, if
141			\a ref is \c NULL or the list doesn't contain an info with
142			this entry_ref.
143*/
144RosterAppInfo *
145AppInfoList::InfoFor(const entry_ref *ref) const
146{
147	return InfoAt(IndexOf(ref));
148}
149
150// InfoForToken
151/*!	\brief Returns the RosterAppInfo with the supplied token.
152
153	If the list contains more than one RosterAppInfo with the given token,
154	it is undefined, which one is returned.
155
156	\param token The token
157	\return A RosterAppInfo with the supplied token, or \c NULL, if the list
158			doesn't contain an info with the token.
159*/
160RosterAppInfo *
161AppInfoList::InfoForToken(uint32 token) const
162{
163	return InfoAt(IndexOfToken(token));
164}
165
166// CountInfos
167/*!	\brief Returns the number of RosterAppInfos this list contains.
168	\return The number of RosterAppInfos this list contains.
169*/
170int32
171AppInfoList::CountInfos() const
172{
173	return fInfos.CountItems();
174}
175
176// It
177/*!	\brief Returns a list iterator.
178	\return A list iterator.
179*/
180AppInfoList::Iterator
181AppInfoList::It()
182{
183	return Iterator(this, 0);
184}
185
186// Sort
187/*!	\brief Sorts the infos in ascending order according to the given compare
188		   function.
189	\param lessFunc The compare function (less than) to be used.
190*/
191void
192AppInfoList::Sort(
193	bool (*lessFunc)(const RosterAppInfo *, const RosterAppInfo *))
194{
195	int32 count = CountInfos();
196	if (count > 1) {
197		RosterAppInfo **infos = (RosterAppInfo **)fInfos.Items();
198		std::sort(infos, infos + count, lessFunc);
199	}
200}
201
202// RemoveInfo
203/*!	\brief Removes a RosterAppInfo at a given index.
204	\param index The index of the info to be removed
205	\return A pointer to the removed RosterAppInfo, or \c NULL, if the index
206			is out of range.
207*/
208RosterAppInfo *
209AppInfoList::RemoveInfo(int32 index)
210{
211	return (RosterAppInfo*)fInfos.RemoveItem(index);
212}
213
214// InfoAt
215/*!	\brief Returns a RosterAppInfo at a given index.
216	\param index The index of the info to be returned
217	\return A pointer to the RosterAppInfo, or \c NULL, if the index
218			is out of range.
219*/
220RosterAppInfo *
221AppInfoList::InfoAt(int32 index) const
222{
223	return (RosterAppInfo*)fInfos.ItemAt(index);
224}
225
226// IndexOf
227/*!	\brief Returns the list index of the supplied RosterAppInfo.
228	\param info The RosterAppInfo in question
229	\return The index of the supplied info, or -1, if \a info is \c NULL or not
230			contained in the list.
231*/
232int32
233AppInfoList::IndexOf(RosterAppInfo *info) const
234{
235	return fInfos.IndexOf(info);
236}
237
238// IndexOf
239/*!	\brief Returns the list index of a RosterAppInfo with the supplied
240		   signature.
241
242	If the list contains more than one RosterAppInfo with the given signature,
243	it is undefined, which one is returned.
244
245	\param signature The signature
246	\return The index of the found RosterAppInfo, or -1, if \a signature is
247			\c NULL or the list doesn't contain an info with this signature.
248*/
249int32
250AppInfoList::IndexOf(const char *signature) const
251{
252	if (signature) {
253		for (int32 i = 0; RosterAppInfo *info = InfoAt(i); i++) {
254			if (!strcasecmp(info->signature, signature))
255				return i;
256		}
257	}
258	return -1;
259}
260
261// IndexOf
262/*!	\brief Returns the list index of a RosterAppInfo with the supplied
263		   team ID.
264
265	\param team The team ID
266	\return The index of the found RosterAppInfo, or -1, if the list doesn't
267			contain an info with this team ID.
268*/
269int32
270AppInfoList::IndexOf(team_id team) const
271{
272	for (int32 i = 0; RosterAppInfo *info = InfoAt(i); i++) {
273		if (info->team == team)
274			return i;
275	}
276	return -1;
277}
278
279// IndexOf
280/*!	\brief Returns the list index of a RosterAppInfo with the supplied
281		   entry_ref.
282
283	If the list contains more than one RosterAppInfo with the given entry_ref,
284	it is undefined, which one is returned.
285
286	\param ref The entry_ref
287	\return The index of the found RosterAppInfo, or -1, if \a ref is
288			\c NULL or the list doesn't contain an info with this entry_ref.
289*/
290int32
291AppInfoList::IndexOf(const entry_ref *ref) const
292{
293	if (ref) {
294		// Dereference symlink if needed
295		BEntry entry(ref, true);
296		entry_ref realRef;
297		if (entry.GetRef(&realRef) != B_OK)
298			realRef = *ref;
299
300		for (int32 i = 0; RosterAppInfo *info = InfoAt(i); i++) {
301			if (info->ref == realRef)
302				return i;
303		}
304	}
305	return -1;
306}
307
308// IndexOfToken
309/*!	\brief Returns the list index of a RosterAppInfo with the supplied
310		   token.
311
312	\param token The token
313	\return The index of the found RosterAppInfo, or -1, if the list doesn't
314			contain an info with this token.
315*/
316int32
317AppInfoList::IndexOfToken(uint32 token) const
318{
319	for (int32 i = 0; RosterAppInfo *info = InfoAt(i); i++) {
320		if (info->token == token)
321			return i;
322	}
323	return -1;
324}
325
326