VirtualBox

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

Last change on this file since 977 was 436, checked in by vboxsync, 18 years ago

Main: Added USBDevice to the DeviceType enum to provide USB device activity (search for USB_DEVICE_ACTIVITY in ConsoleImpl.cpp). Thanks to MS COM C++ bingings polluting the global namespace with enum values, I had to rename the USBDevice class to OUSBDevice (and to add the COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN macro for even more flexible collection declarations).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.3 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 that stores
260 * elements of the given class @a itemcls that implements the given
261 * interface @a iface
262 *
263 * The the @a itemcls class must be either a ComObjPtr or a ComPtr template
264 * instantiation with the argument being a class that implements the @a iface
265 * interface.
266 *
267 * The namespace of the collection class remains opened after
268 * this macro is expanded (i.e. no closing brace with semicolon), which
269 * allows to declare extra collection class members. This namespace
270 * must be closed by the COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END macro.
271 *
272 * For example, given |ComObjPtr <OSomeItem>|, |ISomeItem|| and |OSomeItem|
273 * arguments, this macro will generate the following code:
274 *
275 * <code>
276 * class OSomeItemEnumerator : public
277 * IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComObjPtr <OSomeItem>,
278 * OSomeItemEnumerator>
279 * {...};
280 * class SomeItemCollection : public
281 * ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComObjPtr <OSomeItem>,
282 * OSomeItemEnumerator, OSomeItemCollection>
283 * {...};
284 * </code>
285 *
286 * i.e. it assumes that ISomeItemEnumerator, ISomeItem and ISomeItemCollection
287 * are existing interfaces, and OSomeItem implements the ISomeItem interface.
288 * It also assumes, that std::list passed to SomeItemCollection::init()
289 * stores objects of the @a itemcls class (|ComObjPtr <OSomeItem>| in the
290 * example above).
291 *
292 * See descriptions of the above IfaceVectorEnumerator and
293 * ReadonlyIfaceVector templates for more info.
294 *
295 * The generated class also inherits the VirtualBoxSupportTranslation template,
296 * providing the support for translation of string constants within class
297 * members.
298 *
299 * The macro is best to be placed in the header after SomeItem class
300 * declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END macro must
301 * follow all extra member declarations of the collection class, or right
302 * after this macro if the collection doesn't have extra members.
303 *
304 * @param itemcls Either ComObjPtr or ComPtr for the class that implements
305 * the given interface of items to be stored in the
306 * collection
307 * @param iface Interface of items implemented by the @a itemcls class
308 * @param prefix Prefix to apply to generated enumerator and collection
309 * names.
310 */
311#define COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN(itemcls, iface, prefix) \
312 class prefix##Enumerator \
313 : public IfaceVectorEnumerator \
314 <iface##Enumerator, iface, itemcls, prefix##Enumerator> \
315 , public VirtualBoxSupportTranslation <prefix##Enumerator> \
316 { \
317 NS_DECL_ISUPPORTS \
318 public: static const wchar_t *getComponentName() { \
319 return WSTR_LITERAL (prefix) L"Enumerator"; \
320 } \
321 }; \
322 class prefix##Collection \
323 : public ReadonlyIfaceVector \
324 <iface##Collection, iface, iface##Enumerator, itemcls, prefix##Enumerator, \
325 prefix##Collection> \
326 , public VirtualBoxSupportTranslation <prefix##Collection> \
327 { \
328 NS_DECL_ISUPPORTS \
329 public: static const wchar_t *getComponentName() { \
330 return WSTR_LITERAL (prefix) L"Collection"; \
331 }
332
333/**
334 * This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN
335 * and must be always used to finalize the collection declaration started
336 * by that macro.
337 *
338 * Currently the macro just expands to the closing brace with semicolon,
339 * but this might change in the future.
340 */
341#define COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END(itemcls, iface, prefix) \
342 };
343
344/**
345 * This is a "shortcut" macro, for convenience. It expands exactly to:
346 * <code>
347 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN(itemcls, iface, prefix)
348 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END(itemcls, iface, prefix)
349 * </code>
350 */
351#define COM_DECL_READONLY_ENUM_AND_COLLECTION_EX(itemcls, iface, prefix) \
352 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (itemcls, iface, prefix) \
353 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (itemcls, iface, prefix)
354
355/**
356 * This macro declares an enumerator class and a collection class for the
357 * given item class @a c.
358 *
359 * It's a convenience macro that deduces all arguments to the
360 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN macro from a single @a c
361 * class name argument. Given a class named |SomeItem|, this macro is
362 * equivalent to
363 * <code>
364 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComObjPtr <SomeItem>, ISomeItem, SomeItem)
365 * </code>
366 * and will generate the following code:
367 * <code>
368 * class OSomeItemEnumerator : public
369 * IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComObjPtr <SomeItem>,
370 * SomeItemEnumerator>
371 * {...};
372 * class SomeItemCollection : public
373 * ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComObjPtr <SomeItem>,
374 * SomeItemEnumerator, SomeItemCollection>
375 * {...};
376 * </code>
377 *
378 * See COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN for the detailed
379 * description.
380 *
381 * The macro is best to be placed in the header after SomeItem class
382 * declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_END macro must follow
383 * all extra member declarations of the collection class, or right after this
384 * macro if the collection doesn't have extra members.
385 *
386 * @param c Component class implementing the interface of items to be stored
387 * in the collection
388 */
389#define COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c) \
390 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComObjPtr <c>, I##c, c)
391
392/**
393 * This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN
394 * and must be always used to finalize the collection declaration started
395 * by that macro.
396 *
397 * This is a "shortcut" macro that expands exactly to:
398 * <code>
399 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComObjPtr <c>, I##c, c)
400 * </code>
401 */
402#define COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c) \
403 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComObjPtr <c>, I##c, c)
404
405/**
406 * This is a "shortcut" macro, for convenience. It expands exactly to:
407 * <code>
408 * COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c)
409 * COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c)
410 * </code>
411 */
412#define COM_DECL_READONLY_ENUM_AND_COLLECTION(c) \
413 COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c) \
414 COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c)
415
416/**
417 * This macro declares an enumerator class and a collection class for the
418 * given item interface @a iface prefixed with the given @a prefix.
419 *
420 * It's a convenience macro that deduces all arguments to the
421 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN macro from the two given
422 * @a iface and @a prefix arguments. Given an interface named |ISomeItem|,
423 * and a prefix SomeItem this macro is equivalent to
424 * <code>
425 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComPtr <ISomeItem>, ISomeItem, SomeItem)
426 * </code>
427 * and will generate the following code:
428 * <code>
429 * class OSomeItemEnumerator : public
430 * IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComPtr <ISomeItem>,
431 * SomeItemEnumerator>
432 * {...};
433 * class SomeItemCollection : public
434 * ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComPtr <ISomeItem>,
435 * SomeItemEnumerator, SomeItemCollection>
436 * {...};
437 * </code>
438 *
439 * See COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN for the detailed
440 * description.
441 *
442 * The macro is best to be placed in the header after SomeItem class
443 * declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END macro must follow
444 * all extra member declarations of the collection class, or right after this
445 * macro if the collection doesn't have extra members.
446 *
447 * @param prefix Prefix prepended to the generated collection and
448 * enumerator classes
449 * @param iface Interface class
450 */
451#define COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN(prefix, iface) \
452 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComPtr <iface>, iface, prefix)
453
454/**
455 * This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN
456 * and must be always used to finalize the collection declaration started
457 * by that macro.
458 *
459 * This is a "shortcut" macro that expands exactly to:
460 * <code>
461 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComObjPtr <c>, I##c, c)
462 * </code>
463 */
464#define COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END(prefix, iface) \
465 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComPtr <iface>, iface, prefix)
466
467/**
468 * This is a "shortcut" macro, for convenience. It expands exactly to:
469 * <code>
470 * COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN(c)
471 * COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END(c)
472 * </code>
473 */
474#define COM_DECL_READONLY_ENUM_AND_COLLECTION_AS(prefix, iface) \
475 COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN (prefix, iface) \
476 COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END (prefix, iface)
477
478#ifdef __WIN__
479
480#define COM_IMPL_READONLY_ENUM_AND_COLLECTION_EX(itemcls, iface, prefix)
481#define COM_IMPL_READONLY_ENUM_AND_COLLECTION(c)
482#define COM_IMPL_READONLY_ENUM_AND_COLLECTION_AS(prefix, iface)
483
484#else // !__WIN__
485
486/**
487 * This macro defines nsISupports implementations (i.e. QueryInterface(),
488 * AddRef() and Release()) for the enumerator and collection classes
489 * declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION_EX,
490 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN and
491 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX macros.
492 *
493 * See COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN for the detailed
494 * description.
495 *
496 * The macro should be placed in one of the source files.
497 *
498 * @note
499 * this macro is XPCOM-specific and not necessary for MS COM,
500 * so expands to nothing on Win32.
501 *
502 * @param itemcls Either ComObjPtr or ComPtr for the class that implements
503 * the given interface of items to be stored in the
504 * collection
505 * @param iface Interface of items implemented by the @a itemcls class
506 * @param prefix Prefix to apply to generated enumerator and collection
507 * names.
508 */
509#define COM_IMPL_READONLY_ENUM_AND_COLLECTION_EX(itemcls, iface, prefix) \
510 NS_DECL_CLASSINFO(prefix##Collection) \
511 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(prefix##Collection, iface##Collection) \
512 NS_DECL_CLASSINFO(prefix##Enumerator) \
513 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(prefix##Enumerator, iface##Enumerator)
514
515/**
516 * This macro defines nsISupports implementations (i.e. QueryInterface(),
517 * AddRef() and Release()) for the enumerator and collection classes
518 * declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION,
519 * COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN and
520 * COM_DECL_READONLY_ENUM_AND_COLLECTION_END macros.
521 *
522 * See COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN for the detailed
523 * description.
524 *
525 * The macro should be placed in one of the source files.
526 *
527 * @note
528 * this macro is XPCOM-specific and not necessary for MS COM,
529 * so expands to nothing on Win32.
530 *
531 * @param c Component class implementing the interface of items to be stored
532 * in the collection
533 */
534#define COM_IMPL_READONLY_ENUM_AND_COLLECTION(c) \
535 COM_IMPL_READONLY_ENUM_AND_COLLECTION_EX (0, I##c, c)
536
537/**
538 * This macro defines nsISupports implementations (i.e. QueryInterface(),
539 * AddRef() and Release()) for the enumerator and collection classes
540 * declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION_AS,
541 * COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN and
542 * COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END macros.
543 *
544 * See COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN for the detailed
545 * description.
546 *
547 * The macro should be placed in one of the source files.
548 *
549 * @note
550 * this macro is XPCOM-specific and not necessary for MS COM,
551 * so expands to nothing on Win32.
552 *
553 * @param prefix Prefix prepended to the generated collection and
554 * enumerator classes
555 * @param iface Interface class
556 */
557#define COM_IMPL_READONLY_ENUM_AND_COLLECTION_AS(prefix, iface) \
558 COM_IMPL_READONLY_ENUM_AND_COLLECTION_EX (0, iface, prefix)
559
560#endif // !__WIN__
561
562#endif // ____H_COLLECTION
Note: See TracBrowser for help on using the repository browser.

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