VirtualBox

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

Last change on this file since 14948 was 14948, checked in by vboxsync, 16 years ago

Removed white space at EOL.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.6 KB
Line 
1/** @file
2 *
3 * VirtualBox collection templates
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
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 RT_OS_WINDOWS
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 RT_OS_WINDOWS
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
209 void init (const List &l)
210 {
211 // create a copy of the list
212 vec = Vector (l.begin(), l.end());
213 }
214
215 template <class Key>
216 void init (const std::map <Key, CollItem> &m)
217 {
218 // create a copy of the map
219 for (typename std::map <Key, CollItem>::const_iterator it = m.begin();
220 it != m.end(); ++ it)
221 vec.push_back (it->second);
222 }
223
224 STDMETHOD(COMGETTER(Count)) (ULONG *count)
225 {
226 if (!count)
227 return E_POINTER;
228 *count = (ULONG) vec.size();
229 return S_OK;
230 }
231
232 STDMETHOD(GetItemAt) (ULONG index, ICollItem **item)
233 {
234 if (!item)
235 return E_POINTER;
236 *item = NULL;
237 if (index >= vec.size())
238 return this->setError (E_INVALIDARG, VirtualBoxBase::translate (
239 "ReadonlyIfaceVector", "The specified index is out of range"));
240 return vec [index].queryInterfaceTo (item);
241 }
242
243 STDMETHOD(Enumerate) (IEnum **enumerator)
244 {
245 if (!enumerator)
246 return E_POINTER;
247 *enumerator = NULL;
248 ComObjPtr <Enum> enumObj;
249 HRESULT rc = enumObj.createObject();
250 if (SUCCEEDED (rc))
251 {
252 enumObj->init ((IColl *) this, vec);
253 rc = enumObj.queryInterfaceTo (enumerator);
254 }
255 return rc;
256 }
257
258 // for VirtualBoxSupportErrorInfoImpl
259 inline static const wchar_t *getComponentName() {
260 return ComponentClass::getComponentName();
261 }
262
263protected:
264
265 Vector vec;
266};
267
268/**
269 * This macro declares an enumerator class and a collection class that stores
270 * elements of the given class @a itemcls that implements the given
271 * interface @a iface
272 *
273 * The the @a itemcls class must be either a ComObjPtr or a ComPtr template
274 * instantiation with the argument being a class that implements the @a iface
275 * interface.
276 *
277 * The namespace of the collection class remains opened after
278 * this macro is expanded (i.e. no closing brace with semicolon), which
279 * allows to declare extra collection class members. This namespace
280 * must be closed by the COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END macro.
281 *
282 * For example, given |ComObjPtr <OSomeItem>|, |ISomeItem|| and |OSomeItem|
283 * arguments, this macro will generate the following code:
284 *
285 * <code>
286 * class OSomeItemEnumerator : public
287 * IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComObjPtr <OSomeItem>,
288 * OSomeItemEnumerator>
289 * {...};
290 * class SomeItemCollection : public
291 * ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComObjPtr <OSomeItem>,
292 * OSomeItemEnumerator, OSomeItemCollection>
293 * {...};
294 * </code>
295 *
296 * i.e. it assumes that ISomeItemEnumerator, ISomeItem and ISomeItemCollection
297 * are existing interfaces, and OSomeItem implements the ISomeItem interface.
298 * It also assumes, that std::list passed to SomeItemCollection::init()
299 * stores objects of the @a itemcls class (|ComObjPtr <OSomeItem>| in the
300 * example above).
301 *
302 * See descriptions of the above IfaceVectorEnumerator and
303 * ReadonlyIfaceVector templates for more info.
304 *
305 * The generated class also inherits the VirtualBoxSupportTranslation template,
306 * providing the support for translation of string constants within class
307 * members.
308 *
309 * The macro is best to be placed in the header after SomeItem class
310 * declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END macro must
311 * follow all extra member declarations of the collection class, or right
312 * after this macro if the collection doesn't have extra members.
313 *
314 * @param itemcls Either ComObjPtr or ComPtr for the class that implements
315 * the given interface of items to be stored in the
316 * collection
317 * @param iface Interface of items implemented by the @a itemcls class
318 * @param prefix Prefix to apply to generated enumerator and collection
319 * names.
320 */
321#define COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN(itemcls, iface, prefix) \
322 class prefix##Enumerator \
323 : public IfaceVectorEnumerator \
324 <iface##Enumerator, iface, itemcls, prefix##Enumerator> \
325 , public VirtualBoxSupportTranslation <prefix##Enumerator> \
326 { \
327 NS_DECL_ISUPPORTS \
328 public: static const wchar_t *getComponentName() { \
329 return WSTR_LITERAL (prefix) L"Enumerator"; \
330 } \
331 }; \
332 class prefix##Collection \
333 : public ReadonlyIfaceVector \
334 <iface##Collection, iface, iface##Enumerator, itemcls, prefix##Enumerator, \
335 prefix##Collection> \
336 , public VirtualBoxSupportTranslation <prefix##Collection> \
337 { \
338 NS_DECL_ISUPPORTS \
339 public: static const wchar_t *getComponentName() { \
340 return WSTR_LITERAL (prefix) L"Collection"; \
341 }
342
343/**
344 * This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN
345 * and must be always used to finalize the collection declaration started
346 * by that macro.
347 *
348 * Currently the macro just expands to the closing brace with semicolon,
349 * but this might change in the future.
350 */
351#define COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END(itemcls, iface, prefix) \
352 };
353
354/**
355 * This is a "shortcut" macro, for convenience. It expands exactly to:
356 * <code>
357 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN(itemcls, iface, prefix)
358 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END(itemcls, iface, prefix)
359 * </code>
360 */
361#define COM_DECL_READONLY_ENUM_AND_COLLECTION_EX(itemcls, iface, prefix) \
362 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (itemcls, iface, prefix) \
363 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (itemcls, iface, prefix)
364
365/**
366 * This macro declares an enumerator class and a collection class for the
367 * given item class @a c.
368 *
369 * It's a convenience macro that deduces all arguments to the
370 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN macro from a single @a c
371 * class name argument. Given a class named |SomeItem|, this macro is
372 * equivalent to
373 * <code>
374 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComObjPtr <SomeItem>, ISomeItem, SomeItem)
375 * </code>
376 * and will generate the following code:
377 * <code>
378 * class OSomeItemEnumerator : public
379 * IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComObjPtr <SomeItem>,
380 * SomeItemEnumerator>
381 * {...};
382 * class SomeItemCollection : public
383 * ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComObjPtr <SomeItem>,
384 * SomeItemEnumerator, SomeItemCollection>
385 * {...};
386 * </code>
387 *
388 * See COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN for the detailed
389 * description.
390 *
391 * The macro is best to be placed in the header after SomeItem class
392 * declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_END macro must follow
393 * all extra member declarations of the collection class, or right after this
394 * macro if the collection doesn't have extra members.
395 *
396 * @param c Component class implementing the interface of items to be stored
397 * in the collection
398 */
399#define COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c) \
400 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComObjPtr <c>, I##c, c)
401
402/**
403 * This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN
404 * and must be always used to finalize the collection declaration started
405 * by that macro.
406 *
407 * This is a "shortcut" macro that expands exactly to:
408 * <code>
409 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComObjPtr <c>, I##c, c)
410 * </code>
411 */
412#define COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c) \
413 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComObjPtr <c>, I##c, c)
414
415/**
416 * This is a "shortcut" macro, for convenience. It expands exactly to:
417 * <code>
418 * COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c)
419 * COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c)
420 * </code>
421 */
422#define COM_DECL_READONLY_ENUM_AND_COLLECTION(c) \
423 COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c) \
424 COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c)
425
426/**
427 * This macro declares an enumerator class and a collection class for the
428 * given item interface @a iface prefixed with the given @a prefix.
429 *
430 * It's a convenience macro that deduces all arguments to the
431 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN macro from the two given
432 * @a iface and @a prefix arguments. Given an interface named |ISomeItem|,
433 * and a prefix SomeItem this macro is equivalent to
434 * <code>
435 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComPtr <ISomeItem>, ISomeItem, SomeItem)
436 * </code>
437 * and will generate the following code:
438 * <code>
439 * class OSomeItemEnumerator : public
440 * IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComPtr <ISomeItem>,
441 * SomeItemEnumerator>
442 * {...};
443 * class SomeItemCollection : public
444 * ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComPtr <ISomeItem>,
445 * SomeItemEnumerator, SomeItemCollection>
446 * {...};
447 * </code>
448 *
449 * See COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN for the detailed
450 * description.
451 *
452 * The macro is best to be placed in the header after SomeItem class
453 * declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END macro must follow
454 * all extra member declarations of the collection class, or right after this
455 * macro if the collection doesn't have extra members.
456 *
457 * @param prefix Prefix prepended to the generated collection and
458 * enumerator classes
459 * @param iface Interface class
460 */
461#define COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN(prefix, iface) \
462 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComPtr <iface>, iface, prefix)
463
464/**
465 * This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN
466 * and must be always used to finalize the collection declaration started
467 * by that macro.
468 *
469 * This is a "shortcut" macro that expands exactly to:
470 * <code>
471 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComObjPtr <c>, I##c, c)
472 * </code>
473 */
474#define COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END(prefix, iface) \
475 COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComPtr <iface>, iface, prefix)
476
477/**
478 * This is a "shortcut" macro, for convenience. It expands exactly to:
479 * <code>
480 * COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN(c)
481 * COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END(c)
482 * </code>
483 */
484#define COM_DECL_READONLY_ENUM_AND_COLLECTION_AS(prefix, iface) \
485 COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN (prefix, iface) \
486 COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END (prefix, iface)
487
488#ifdef RT_OS_WINDOWS
489
490#define COM_IMPL_READONLY_ENUM_AND_COLLECTION_EX(itemcls, iface, prefix)
491#define COM_IMPL_READONLY_ENUM_AND_COLLECTION(c)
492#define COM_IMPL_READONLY_ENUM_AND_COLLECTION_AS(prefix, iface)
493
494#else // !RT_OS_WINDOWS
495
496/**
497 * This macro defines nsISupports implementations (i.e. QueryInterface(),
498 * AddRef() and Release()) for the enumerator and collection classes
499 * declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION_EX,
500 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN and
501 * COM_DECL_READONLY_ENUM_AND_COLLECTION_EX macros.
502 *
503 * See COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN for the detailed
504 * description.
505 *
506 * The macro should be placed in one of the source files.
507 *
508 * @note
509 * this macro is XPCOM-specific and not necessary for MS COM,
510 * so expands to nothing on Win32.
511 *
512 * @param itemcls Either ComObjPtr or ComPtr for the class that implements
513 * the given interface of items to be stored in the
514 * collection
515 * @param iface Interface of items implemented by the @a itemcls class
516 * @param prefix Prefix to apply to generated enumerator and collection
517 * names.
518 */
519#define COM_IMPL_READONLY_ENUM_AND_COLLECTION_EX(itemcls, iface, prefix) \
520 NS_DECL_CLASSINFO(prefix##Collection) \
521 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(prefix##Collection, iface##Collection) \
522 NS_DECL_CLASSINFO(prefix##Enumerator) \
523 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(prefix##Enumerator, iface##Enumerator)
524
525/**
526 * This macro defines nsISupports implementations (i.e. QueryInterface(),
527 * AddRef() and Release()) for the enumerator and collection classes
528 * declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION,
529 * COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN and
530 * COM_DECL_READONLY_ENUM_AND_COLLECTION_END macros.
531 *
532 * See COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN for the detailed
533 * description.
534 *
535 * The macro should be placed in one of the source files.
536 *
537 * @note
538 * this macro is XPCOM-specific and not necessary for MS COM,
539 * so expands to nothing on Win32.
540 *
541 * @param c Component class implementing the interface of items to be stored
542 * in the collection
543 */
544#define COM_IMPL_READONLY_ENUM_AND_COLLECTION(c) \
545 COM_IMPL_READONLY_ENUM_AND_COLLECTION_EX (0, I##c, c)
546
547/**
548 * This macro defines nsISupports implementations (i.e. QueryInterface(),
549 * AddRef() and Release()) for the enumerator and collection classes
550 * declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION_AS,
551 * COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN and
552 * COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END macros.
553 *
554 * See COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN for the detailed
555 * description.
556 *
557 * The macro should be placed in one of the source files.
558 *
559 * @note
560 * this macro is XPCOM-specific and not necessary for MS COM,
561 * so expands to nothing on Win32.
562 *
563 * @param prefix Prefix prepended to the generated collection and
564 * enumerator classes
565 * @param iface Interface class
566 */
567#define COM_IMPL_READONLY_ENUM_AND_COLLECTION_AS(prefix, iface) \
568 COM_IMPL_READONLY_ENUM_AND_COLLECTION_EX (0, iface, prefix)
569
570#endif // !RT_OS_WINDOWS
571
572#endif // ____H_COLLECTION
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use