VirtualBox

source: vbox/trunk/src/VBox/Main/include/Collection.h@ 394

Last change on this file since 394 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.6 KB
Line 
1/** @file
2 *
3 * VirtualBox collection templates
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22#ifndef ____H_COLLECTION
23#define ____H_COLLECTION
24
25#include "VBox/com/defs.h"
26#include "VirtualBoxBase.h"
27
28#include <list>
29#include <vector>
30
31/**
32 * Template class to create a non-thread safe implementation of the
33 * enumerator over the read-only collection that stores safe interface pointers
34 * using std::vector. The enumerator is attached to an existing std::vector
35 * storing EnumItem instances, optionally making a copy.
36 *
37 * The template also inherits the VirtualBoxSupportErrorInfoImpl template and
38 * therefore provides the error info support.
39 *
40 * @param IEnum
41 * enumerator interface to implement. This interface must define
42 * HasMore (BOOL *) and GetNext (IEnumItem **).
43 * @param IEnumItem
44 * enumerator item interface. Pointers of this type are returned
45 * by GetNext().
46 * @param EnumItem
47 * actual enumerator item class. Instances of this class
48 * are stored in the std::vector passed as an argument to
49 * init(). This class must be a ComPtrBase<> template instantiation
50 * or derived from such instantiation.
51 * @param ComponentClass
52 * the only role of this class is to have the following member:
53 * |public: static const wchar_t *getComponentName()|, that returns the
54 * component name (see VirtualBoxSupportErrorInfoImpl template for more info).
55 */
56template <class IEnum, class IEnumItem, class EnumItem, class ComponentClass>
57class ATL_NO_VTABLE IfaceVectorEnumerator :
58 public VirtualBoxSupportErrorInfoImpl <IfaceVectorEnumerator <IEnum, IEnumItem,
59 EnumItem, ComponentClass>, IEnum>,
60#ifdef __WIN__
61 public CComObjectRootEx <CComSingleThreadModel>,
62#else
63 public CComObjectRootEx,
64#endif
65 public IEnum
66{
67 Q_OBJECT
68
69public:
70
71 typedef std::vector <EnumItem> Vector;
72
73 DECLARE_NOT_AGGREGATABLE(IfaceVectorEnumerator)
74
75 DECLARE_PROTECT_FINAL_CONSTRUCT()
76
77 BEGIN_COM_MAP(IfaceVectorEnumerator)
78 COM_INTERFACE_ENTRY(ISupportErrorInfo)
79 COM_INTERFACE_ENTRY(IEnum)
80 END_COM_MAP()
81
82 IfaceVectorEnumerator()
83 {
84 parent = NULL;
85 vec = NULL;
86 allocated = true;
87 }
88
89 virtual ~IfaceVectorEnumerator()
90 {
91 if (vec && allocated)
92 delete vec;
93 if (parent)
94 parent->Release();
95 }
96
97 // public initializer/uninitializer for internal purposes only
98 void init (IUnknown *p, const Vector &v, bool readonly = true)
99 {
100 parent = p;
101 if (parent)
102 parent->AddRef();
103 if (readonly)
104 vec = &v;
105 else
106 vec = new Vector (v);
107 allocated = !readonly;
108 iter = vec->begin();
109 }
110
111 STDMETHOD(HasMore) (BOOL *more)
112 {
113 if (!more)
114 return E_POINTER;
115 *more = iter != vec->end();
116 return S_OK;
117 }
118
119 STDMETHOD(GetNext) (IEnumItem **next)
120 {
121 if (!next)
122 return E_POINTER;
123 *next = NULL;
124 if (iter == vec->end())
125 return this->setError (E_UNEXPECTED, VirtualBoxBase::translate (
126 "IfaceVectorEnumerator", "No more elements"));
127 typename Vector::value_type item = *iter;
128 ++iter;
129 return item.queryInterfaceTo (next);
130 }
131
132 // for VirtualBoxSupportErrorInfoImpl
133 inline static const wchar_t *getComponentName() {
134 return ComponentClass::getComponentName();
135 }
136
137private:
138
139 IUnknown *parent;
140 const Vector *vec;
141 bool allocated;
142 typename Vector::const_iterator iter;
143};
144
145/**
146 * Template class to create a non-thread safe implementation of the
147 * read-only collection that stores interface pointers. The collection is
148 * initialized from the std::list storing CollItem instances by copying
149 * (i.e. making a snapshot of) all list items to std::vector for
150 * optimized random access.
151 *
152 * The template also inherits the VirtualBoxSupportErrorInfoImpl template and
153 * therefore provides the error info support.
154 *
155 * @param IColl
156 * collection interface to implement. This interface must define
157 * Count(ULONG *), GetItemAt (ULONG, ICollItem**) and Enumerate (IEnum **).
158 * @param ICollItem
159 * collection item interface. Pointers of this type are returned by
160 * GetItemAt().
161 * @param IEnum
162 * enumerator interface. Pointers of this type are returned by Enumerate().
163 * @param CollItem
164 * actual collection item class. Instances of this class
165 * are stored in the std::list passed as an argument to
166 * init() and in the internal std::vector. This class must be a
167 * ComPtrBase<> template instantiation or derived from such instantiation.
168 * @param Enum
169 * enumerator implementation class used to construct a new enumerator.
170 * This class must be a IfaceVectorEnumerator<> template instantiation
171 * with IEnum and IEnumItem arguments exactly the same as in this template,
172 * and with EnumItem argument exactly the same as this template's
173 * CollItem argument.
174 * @param ComponentClass
175 * the only role of this class is to have the following member:
176 * |public: static const wchar_t *getComponentName()|, that returns the
177 * component name (see VirtualBoxSupportErrorInfoImpl template for more info).
178 */
179template <class IColl, class ICollItem, class IEnum, class CollItem, class Enum,
180 class ComponentClass>
181class ATL_NO_VTABLE ReadonlyIfaceVector :
182 public VirtualBoxSupportErrorInfoImpl <ReadonlyIfaceVector <IColl, ICollItem,
183 IEnum, CollItem, Enum, ComponentClass>, IColl>,
184#ifdef __WIN__
185 public CComObjectRootEx <CComSingleThreadModel>,
186#else
187 public CComObjectRootEx,
188#endif
189 public IColl
190{
191 Q_OBJECT
192
193public:
194
195 typedef std::vector <CollItem> Vector;
196 typedef std::list <CollItem> List;
197
198 DECLARE_NOT_AGGREGATABLE(ReadonlyIfaceVector)
199
200 DECLARE_PROTECT_FINAL_CONSTRUCT()
201
202 BEGIN_COM_MAP(ReadonlyIfaceVector)
203 COM_INTERFACE_ENTRY(ISupportErrorInfo)
204 COM_INTERFACE_ENTRY(IColl)
205 END_COM_MAP()
206
207 // public initializer/uninitializer for internal purposes only
208 void init (const List &l)
209 {
210 // create a copy of the list
211 vec = Vector (l.begin(), l.end());
212 }
213
214 STDMETHOD(COMGETTER(Count)) (ULONG *count)
215 {
216 if (!count)
217 return E_POINTER;
218 *count = (ULONG) vec.size();
219 return S_OK;
220 }
221
222 STDMETHOD(GetItemAt) (ULONG index, ICollItem **item)
223 {
224 if (!item)
225 return E_POINTER;
226 *item = NULL;
227 if (index >= vec.size())
228 return this->setError (E_INVALIDARG, VirtualBoxBase::translate (
229 "ReadonlyIfaceVector", "The specified index is out of range"));
230 return vec [index].queryInterfaceTo (item);
231 }
232
233 STDMETHOD(Enumerate) (IEnum **enumerator)
234 {
235 if (!enumerator)
236 return E_POINTER;
237 *enumerator = NULL;
238 ComObjPtr <Enum> enumObj;
239 HRESULT rc = enumObj.createObject();
240 if (SUCCEEDED (rc))
241 {
242 enumObj->init ((IColl *) this, vec);
243 rc = enumObj.queryInterfaceTo (enumerator);
244 }
245 return rc;
246 }
247
248 // for VirtualBoxSupportErrorInfoImpl
249 inline static const wchar_t *getComponentName() {
250 return ComponentClass::getComponentName();
251 }
252
253protected:
254
255 Vector vec;
256};
257
258/**
259 * This macro declares an enumerator class and a collection class for the
260 * given item class. The namespace of the collection class remains opened after
261 * this macro is expanded (i.e. no closing brace with semicolon), thus allowing
262 * one to declare extra collection class members. This namespace
263 * must be closed by the COM_DECL_READONLY_ENUM_AND_COLLECTION_END macro.
264 *
265 * For example, given a 'SomeItem' argument, this macro will declare the
266 * following:
267 *
268 * <code>
269 * class SomeItemEnumerator : public
270 * IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComObjPtr <SomeItem>,
271 * SomeItemEnumerator> {...};
272 * class SomeItemCollection : public
273 * ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComObjPtr <SomeItem>,
274 * SomeItemEnumerator, SomeItemCollection> {
275 * </code>
276 *
277 * i.e. it assumes that ISomeItemEnumerator, ISomeItem and ISomeItemCollection
278 * are existing interfaces, and SomeItem implements the ISomeItem interface.
279 * It also assumes, that std::list passed to SomeItemCollection::init()
280 * stores objects of |ComObjPtr <SomeItem>| class, i.e. safe pointers around
281 * SomeItem instances.
282 *
283 * See descriptions of the above two templates for more info.
284 *
285 * The generated class also inherits the VirtualBoxSupportTranslation template,
286 * providing the support for translation of string constants within class
287 * members.
288 *
289 * The macro is best to be placed in the header after SomeItem class
290 * declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_END macro must follow
291 * all extra member declarations of the collection class, or right after this
292 * macro if the collection doesn't have extra members.
293 *
294 * @param c component class implementing the interface of items to be stored
295 * in the collection
296 */
297#define COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c) \
298 class c##Enumerator \
299 : public IfaceVectorEnumerator \
300 <I##c##Enumerator, I##c, ComObjPtr <c>, c##Enumerator> \
301 , public VirtualBoxSupportTranslation <c##Enumerator> \
302 { \
303 NS_DECL_ISUPPORTS \
304 public: static const wchar_t *getComponentName() { \
305 return WSTR_LITERAL (c) L"Enumerator"; \
306 } \
307 }; \
308 class c##Collection \
309 : public ReadonlyIfaceVector \
310 <I##c##Collection, I##c, I##c##Enumerator, ComObjPtr <c>, c##Enumerator, \
311 c##Collection> \
312 , public VirtualBoxSupportTranslation <c##Collection> \
313 { \
314 NS_DECL_ISUPPORTS \
315 public: static const wchar_t *getComponentName() { \
316 return WSTR_LITERAL (c) L"Collection"; \
317 }
318
319/**
320 * This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN
321 * and must be always used to finalize the collection declaration started
322 * by that macro.
323 *
324 * Currently the macro just expands to the closing brace with semicolon,
325 * but this might change in the future.
326 */
327#define COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c) \
328 };
329
330/**
331 * This is a "shortcut" macro, for convenience. It expands exactly to:
332 * <code>
333 * COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c)
334 * COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c)
335 * </code>
336 */
337#define COM_DECL_READONLY_ENUM_AND_COLLECTION(c) \
338 COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c) \
339 COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c)
340
341/**
342 * This macro declares an enumerator class and a collection class for the
343 * given item class and interface. The namespace of the collection class remains
344 * opened after this macro is expanded (i.e. no closing brace with semicolon),
345 * thus allowing one to declare extra collection class members. This namespace
346 * must be closed by the COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END macro.
347 *
348 * For example, given a 'SomeItem' and a 'ISomeItem' arguments, this macro will
349 * declare the following:
350 *
351 * <code>
352 * class SomeItemEnumerator_ComponentName {...};
353 * class SomeItemCollection_ComponentName {...};
354 *
355 * class SomeItemEnumerator : public
356 * IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComPtr <ISomeItem>,
357 * SomeItemEnumerator_ComponentName> {...};
358 * class SomeItemCollection : public
359 * ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComPtr <ISomeItem>,
360 * SomeItemEnumerator, SomeItemCollection_ComponentName> {...};
361 * </code>
362 *
363 * i.e. it assumes that ISomeItemEnumerator, ISomeItem and ISomeItemCollection
364 * are existing interfaces. It also assumes, that std::list passed to
365 * SomeItemCollection::init() stores objects of |ComPtr <ISomeItem>| class, i.e
366 * safe ISomeItem interface pointers.
367 *
368 * See descriptions of the above two templates for more info.
369 *
370 * The generated class also inherits the VirtualBoxSupportTranslation template,
371 * providing the support for translation of string constants within class
372 * members.
373 *
374 * The macro is best to be placed in the header after SomeItem class
375 * declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END macro must follow
376 * all extra member declarations of the collection class, or right after this
377 * macro if the collection doesn't have extra members.
378 *
379 * @param prefix the prefix prepended to the generated collection and
380 * enumerator classes
381 * @param iface interface class
382 */
383#define COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN(prefix, iface) \
384 class prefix##Enumerator \
385 : public IfaceVectorEnumerator \
386 <iface##Enumerator, iface, ComPtr <iface>, prefix##Enumerator> \
387 , public VirtualBoxSupportTranslation <prefix##Enumerator> \
388 { \
389 NS_DECL_ISUPPORTS \
390 public: static const wchar_t *getComponentName() { \
391 return WSTR_LITERAL (prefix) L"Enumerator"; \
392 } \
393 }; \
394 class prefix##Collection \
395 : public ReadonlyIfaceVector \
396 <iface##Collection, iface, iface##Enumerator, ComPtr <iface>, prefix##Enumerator, \
397 prefix##Collection> \
398 , public VirtualBoxSupportTranslation <prefix##Collection> \
399 { \
400 NS_DECL_ISUPPORTS \
401 public: static const wchar_t *getComponentName() { \
402 return WSTR_LITERAL (prefix) L"Collection"; \
403 }
404
405/**
406 * This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN
407 * and must be always used to finalize the collection declaration started
408 * by that macro.
409 *
410 * Currently the macro just expands to the closing brace with semicolon,
411 * but this might change in the future.
412 */
413#define COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END(prefix, iface) \
414 };
415
416/**
417 * This is a "shortcut" macro, for convenience. It expands exactly to:
418 * <code>
419 * COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN(c)
420 * COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END(c)
421 * </code>
422 */
423#define COM_DECL_READONLY_ENUM_AND_COLLECTION_AS(prefix, iface) \
424 COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN(prefix, iface) \
425 COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END(prefix, iface)
426
427#ifdef __WIN__
428
429#define COM_IMPL_READONLY_ENUM_AND_COLLECTION(c)
430#define COM_IMPL_READONLY_ENUM_AND_COLLECTION_AS(prefix, iface)
431#else // !__WIN__
432
433/**
434 * This macro defines nsISupports implementations (i.e. QueryInterface(),
435 * AddRef() and Release()) for the enumerator and collection classes
436 * declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION macro.
437 *
438 * The macro should be placed in one of the source files.
439 *
440 * @note
441 * this macro is XPCOM-specific and not necessary for MS COM,
442 * so expands to nothing on Win32.
443 *
444 * @param c component class implementing the item interface
445 */
446#define COM_IMPL_READONLY_ENUM_AND_COLLECTION(c) \
447 NS_DECL_CLASSINFO(c##Collection) \
448 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(c##Collection, I##c##Collection) \
449 NS_DECL_CLASSINFO(c##Enumerator) \
450 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(c##Enumerator, I##c##Enumerator)
451
452/**
453 * This macro defines nsISupports implementations (i.e. QueryInterface(),
454 * AddRef() and Release()) for the enumerator and collection classes
455 * declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION_AS macro.
456 *
457 * The macro should be placed in one of the source files.
458 *
459 * @note
460 * this macro is XPCOM-specific and not necessary for MS COM,
461 * so expands to nothing on Win32.
462 *
463 * @param prefix the prefix prepended to the generated collection and
464 * enumerator classes
465 * @param iface interface class
466 */
467#define COM_IMPL_READONLY_ENUM_AND_COLLECTION_AS(prefix, iface) \
468 NS_DECL_CLASSINFO(prefix##Collection) \
469 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(prefix##Collection, iface##Collection) \
470 NS_DECL_CLASSINFO(prefix##Enumerator) \
471 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(prefix##Enumerator, iface##Enumerator)
472
473#endif // !__WIN__
474
475#endif // ____H_COLLECTION
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette