⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enumerator_sequence_unittest_.h

📁 新版本TR1的stl
💻 H
📖 第 1 页 / 共 2 页
字号:

// Updated: 12th March 2007

#if !defined(COMSTL_INCL_COMSTL_COLLECTIONS_HPP_ENUMERATOR_SEQUENCE)
# error This file cannot be directly included, and should only be included within comstl/collections/enumerator_sequence.hpp
#endif /* !COMSTL_INCL_COMSTL_COLLECTIONS_HPP_ENUMERATOR_SEQUENCE */

#if !defined(STLSOFT_UNITTEST)
# error This file cannot be included when not unit-testing STLSoft
#endif /* !STLSOFT_UNITTEST */

namespace unittest
{
	namespace
	{
		namespace Synesis_COM
		{
#if !defined(SYFNCOMDECL)
# define SYFNCOMDECL_WAS_NOT_DEFINED_IN_COMSTL_ENUM_SEQ_CONTEXT
# define SYFNCOMDECL	STDMETHODIMP
#endif /* !SYFNCOMDECL */

			typedef OLECHAR 		OChar;
			typedef OChar const 	*LPCOChar;
			typedef LPCOChar const	*LPCPCOChar;
			typedef size_t			Size;
			typedef void			**LPPVoid;

			SYFNCOMDECL CreateEnumStringFromArray(LPCPCOChar items, Size cItems, LPPVoid ppvEnum);

#ifndef __IEnumGUID_FWD_DEFINED__
#define __IEnumGUID_FWD_DEFINED__
			typedef interface IEnumGUID IEnumGUID;

			typedef /* [unique] */ IEnumGUID __RPC_FAR *LPENUMGUID;

			inline IID const& IID_IEnumGUID_()
			{
				static const IID IID_IEnumGUID__	=	{ 0x00537963, 0x0003, 0x0013, { 0x00, 0x01, 0x00, 0xc0, 0xdf, 0xe6, 0x4a, 0x64 } };

				return IID_IEnumGUID__;
			}

			interface IEnumGUID : public IUnknown
			{
			public:
				virtual /* [helpstring][local] */ HRESULT STDMETHODCALLTYPE Next(
					/* [in] */ ULONG celt,
					/* [length_is][size_is][out] */ GUID __RPC_FAR *rgelt,
					/* [out] */ ULONG __RPC_FAR *pceltFetched) = 0;

				virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Skip(
					/* [in] */ ULONG celt) = 0;

				virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Reset( void) = 0;

				virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Clone(
					/* [retval][ref][out] */ IEnumGUID __RPC_FAR *__RPC_FAR *ppenum) = 0;

			};
#endif	/* __IEnumGUID_FWD_DEFINED__ */

#ifndef __IEnumBSTR_FWD_DEFINED__
#define __IEnumBSTR_FWD_DEFINED__
			typedef interface IEnumBSTR IEnumBSTR;

			typedef /* [unique] */ IEnumBSTR __RPC_FAR *LPENUMBSTR;

			inline IID const& IID_IEnumBSTR_()
			{
				static const IID IID_IEnumBSTR__	=	{ 0x00537963, 0x0003, 0x001b, { 0x00, 0x01, 0x00, 0xc0, 0xdf, 0xe6, 0x4a, 0x64 } };

				return IID_IEnumBSTR__;
			}

			interface IEnumBSTR : public IUnknown
			{
			public:
				virtual /* [helpstring][local] */ HRESULT STDMETHODCALLTYPE Next(
					/* [in] */ ULONG celt,
					/* [length_is][size_is][out] */ BSTR __RPC_FAR *rgelt,
					/* [out] */ ULONG __RPC_FAR *pceltFetched) = 0;

				virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Skip(
					/* [in] */ ULONG celt) = 0;

				virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Reset( void) = 0;

				virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Clone(
					/* [retval][ref][out] */ IEnumBSTR __RPC_FAR *__RPC_FAR *ppenum) = 0;

			};

#endif	/* __IEnumBSTR_FWD_DEFINED__ */


#ifdef SYFNCOMDECL_WAS_NOT_DEFINED_IN_COMSTL_ENUM_SEQ_CONTEXT
# undef SYFNCOMDECL
#endif /* SYFNCOMDECL_WAS_NOT_DEFINED_IN_COMSTL_ENUM_SEQ_CONTEXT */

		} // namespace Synesis_COM

#if !defined(STLSOFT_COMPILER_IS_DMC)
		ss_bool_t test_comstl_enumerator_sequence_recls_COM(unittest_reporter *r)
		{
			ss_bool_t				bSuccess	=	true;

			STLSOFT_SUPPRESS_UNUSED(recls_COM::IID_IFileEntry_);
			STLSOFT_SUPPRESS_UNUSED(recls_COM::IID_IEnumFileEntry_);
			STLSOFT_SUPPRESS_UNUSED(recls_COM::IID_ISearchCollection_);
			STLSOFT_SUPPRESS_UNUSED(recls_COM::IID_IDirectoryPartsCollection_);
			STLSOFT_SUPPRESS_UNUSED(recls_COM::IID_IFileSearch_);

			if(::GetVersion() & 0x80000000)
			{
				r->report(	"Windows 9x system detected. Although comstl::enumerator_sequence and recls both\n"
							"  work on these systems, I've not been bother to write the even-more-verbose \n"
							"  client-code to effect unit-tests on these systems. Hence, the test is skipped", -1, NULL);
			}
			else
			{
				r->report("Loading recls COM server ...", -1, NULL);

				recls_COM::IFileSearch_ *pfs;
				HRESULT 				hr			=	::CoCreateInstance( recls_COM::CLSID_FileSearch_
																		,	NULL
																		,	CLSCTX_ALL
																		,	recls_COM::IID_IFileSearch_
																		,	reinterpret_cast<void**>(&pfs));

				if(FAILED(hr))
				{
					r->report("Cannot load recls.COM server, so skipping this test", -1, NULL);
				}
				else
				{
					using namespace recls_COM;

					// Find the windows directory
					WCHAR		szWindowsDir[1 + _MAX_PATH];
					const WCHAR szPattern[] =	L"*.exe";

					if(0 == ::GetWindowsDirectoryW(&szWindowsDir[0], STLSOFT_NUM_ELEMENTS(szWindowsDir)))
					{
						lstrcpyW(&szWindowsDir[0], L".");
					}

					LPUNKNOWN	punkColl;

					hr = pfs->Search(	::SysAllocString(szWindowsDir)		// Memory-leak here, but we don't care since UT only
									,	::SysAllocString(szPattern) 		// Memory-leak here, but we don't care since UT only
									,	RECLS_F_FILES_ | RECLS_F_RECURSIVE_
									,	&punkColl);

					if(FAILED(hr))
					{
						r->report("IFileSearch::Search() failed", __LINE__);
						bSuccess = false;
					}
					else
					{
						ISearchCollection_	*pSrchColl;

						hr = punkColl->QueryInterface(IID_ISearchCollection_, reinterpret_cast<void**>(&pSrchColl));

						if(FAILED(hr))
						{
							r->report("Object returned from IFileSearch::Search() did not support IID_ISearchCollection", __LINE__);
							bSuccess = false;
						}
						else
						{
							LPUNKNOWN	punkEnum;

							hr = pSrchColl->get__NewEnum(&punkEnum);

							if(FAILED(hr))
							{
								r->report("Collection could not return item enumerator", __LINE__);
								bSuccess = false;
							}
							else
							{
								typedef enumerator_sequence<IEnumFileEntry_
														,	IFileEntry_*
														,	interface_policy<IFileEntry_>
														>			enumerator_t;

								IEnumFileEntry_ *penFile;

								hr = punkEnum->QueryInterface(IID_IEnumFileEntry_, reinterpret_cast<void**>(&penFile));

								if(FAILED(hr))
								{
									r->report("Object returned from IFileSearch::Search() did not support IEnumFileEntry", __LINE__);
									bSuccess = false;
								}
								else
								{
									enumerator_t			en(penFile, false); // Eat the reference

// For some reason, calling begin() *in this context* causes an ICE for VC++ (pre 7.1), so we skip it
#if !defined(STLSOFT_COMPILER_IS_MSVC) || \
	_MSC_VER >= 1310
									r->report(	"Enumerating all .exe in Windows Directory. This may take some time. Check"
												" the debug window for progress ... [Use w32dblog from"
												" http://synesis.com.au/systools.html]", -1, NULL);

									enumerator_t::iterator	b	=	en.begin();
									enumerator_t::iterator	e	=	en.end();

									for(; b != e; ++b)
									{
										BSTR	bstrPath;
										HRESULT hr2 =	(*b)->get_Path(&bstrPath);

										if(FAILED(hr2))
										{
										}
										else
										{
											ss_size_t				cchPath(::SysStringLen(bstrPath));
											auto_buffer<OLECHAR>	buff(cchPath + 1 + 1);

											::lstrcpyW(&buff[0], bstrPath);
											buff[cchPath] = L'\n';
											buff[cchPath + 1] = L'\0';

											::OutputDebugStringW(buff.data());

											::SysFreeString(bstrPath);
										}

									}
#endif /* 0 */
								}

								punkEnum->Release();
							}

							pSrchColl->Release();
						}

						punkColl->Release();
					}

					pfs->Release();
				}
			}

			return bSuccess;
		}
#endif /* compiler */

#if !defined(STLSOFT_COMPILER_IS_COMO) // dl_call gives como an ICE
		ss_bool_t test_comstl_enumerator_sequence_MMCOMBSC_IEnumString(HINSTANCE hinst, unittest_reporter *r)
		{
			using namespace Synesis_COM;

			static const LPCOChar	strings[]	=
			{
					L"string-1"
				,	L"string-2"
				,	L"string-3"
			};
			ss_bool_t				bSuccess	=	true;
			LPUNKNOWN				punkEnum	=	NULL;
			HRESULT 				hr			=	winstl::dl_call<HRESULT>(hinst, winstl::fn_desc<STLSOFT_STDCALL_VALUE>(MAKEINTRESOURCE(144)), strings, STLSOFT_NUM_ELEMENTS(strings), reinterpret_cast<void**>(&punkEnum));

			if(FAILED(hr))
			{
				r->report("Failed to create string enumerator from Synesis COM server");
				bSuccess = false;
			}
			else
			{
				typedef enumerator_sequence<IEnumString
										,	LPOLESTR
										,	LPOLESTR_policy
										>			enumerator_t;

				{ for(cs_size_t q = 0; q < enumerator_t::retrievalQuanta; ++q)
				{
					LPENUMSTRING	lpenStr;

					hr = punkEnum->QueryInterface(IID_IEnumString, reinterpret_cast<void**>(&lpenStr));

					if(FAILED(hr))
					{
						r->report("Failed to retrieve required enumerator interface from enumerator object", __LINE__);
						bSuccess = false;
					}
					else
					{
						enumerator_t			en(lpenStr, false, q); // Eat the reference
						char					msg[101];

						::sprintf(&msg[0], "Enumerating strings using IEnumString; quanta=%u", q);

						r->report(msg, -1, NULL);

						enumerator_t::iterator	b	=	en.begin();
						enumerator_t::iterator	e	=	en.end();

						{ for(size_t i = 0; i < STLSOFT_NUM_ELEMENTS(strings); ++i)
						{
							if(en.end() == b)
							{
								r->report("Enumerator sequence contains the wrong number of elements", __LINE__);
								bSuccess = false;
							}
							else
							{
								if(0 != ::wcscmp(*b, strings[i]))
								{
									r->report("Enumerator sequence element contains the wrong value", __LINE__);
									bSuccess = false;
								}

								++b;
							}
						}}

						if(en.end() != b)
						{
							r->report("Enumerator sequence contains the wrong number of elements", __LINE__);
							bSuccess = false;
						}
					}
				}}

				punkEnum->Release();
			}

			return bSuccess;
		}

		ss_bool_t test_comstl_enumerator_sequence_MMCOMBSC_IEnumGUID(HINSTANCE hinst, unittest_reporter *r)
		{
			using namespace Synesis_COM;

			GUID		guids[14];

			guids[0]	=	IID_IUnknown;
			guids[1]	=	IID_IClassFactory;
			guids[2]	=	IID_IMarshal;
			guids[3]	=	IID_IMalloc;
			guids[4]	=	IID_IMallocSpy;
			guids[5]	=	IID_IStdMarshalInfo;
			guids[6]	=	IID_IExternalConnection;
			guids[7]	=	/* IID_IMultiQI; */IID_IEnumUnknown;
			guids[8]	=	IID_IEnumUnknown;
			guids[9]	=	IID_IBindCtx;
			guids[10]	=	IID_IEnumMoniker;
			guids[11]	=	IID_IRunnableObject;
			guids[12]	=	IID_IRunningObjectTable;
			guids[13]	=	IID_IPersist;

			ss_bool_t	bSuccess	=	true;
			LPUNKNOWN	punkEnum	=	NULL;
			HRESULT 	hr			=	winstl::dl_call<HRESULT>(hinst, winstl::fn_desc<STLSOFT_STDCALL_VALUE>(MAKEINTRESOURCE(146)), guids, STLSOFT_NUM_ELEMENTS(guids), reinterpret_cast<void**>(&punkEnum));

			if(FAILED(hr))
			{
				r->report("Failed to create GUID enumerator from Synesis COM server");
				bSuccess = false;
			}
			else
			{
				// 1. input_cloning_policy
				{
					r->report("input_cloning_policy", -1, NULL);

					typedef enumerator_sequence<IEnumGUID
											,	GUID
											,	GUID_policy
											,	GUID
											,	input_cloning_policy<IEnumGUID>
											,	10
											>			enumerator_t;

					{ for(cs_size_t q = 0; q < enumerator_t::retrievalQuanta; ++q)
					{
						LPENUMGUID	  lpenStr;

						hr = punkEnum->QueryInterface(IID_IEnumGUID_(), reinterpret_cast<void**>(&lpenStr));

						if(FAILED(hr))
						{
							r->report("Failed to retrieve required enumerator interface from enumerator object", __LINE__);
							bSuccess = false;
						}
						else
						{
							enumerator_t			en(lpenStr, false, q); // Eat the reference
							char					msg[101];

							::sprintf(&msg[0], "Enumerating GUIDs using IEnumGUID; quanta=%u", q);

							r->report(msg, -1, NULL);

							enumerator_t::iterator	b	=	en.begin();
							enumerator_t::iterator	e	=	en.end();

							{ for(size_t i = 0; i < STLSOFT_NUM_ELEMENTS(guids); ++i)
							{
								if(en.end() == b)
								{
									r->report("Enumerator sequence contains the wrong number of elements", __LINE__);
									bSuccess = false;
								}
								else
								{
									if(*b != guids[i])
									{
										r->report("Enumerator sequence element contains the wrong value", __LINE__);
										bSuccess = false;
									}

									++b;
								}
							}}

							if(en.end() != b)
							{
								r->report("Enumerator sequence contains the wrong number of elements", __LINE__);
								bSuccess = false;
							}
						}
					}}
				}

				// 2. input_cloning_policy with copying
				{
					r->report("input_cloning_policy with copying", -1, NULL);

					typedef enumerator_sequence<IEnumGUID
											,	GUID
											,	GUID_policy
											,	GUID
											,	input_cloning_policy<IEnumGUID>
											,	10
											>			enumerator_t;

					{ for(cs_size_t q = 0; q < enumerator_t::retrievalQuanta; ++q)
					{
						LPENUMGUID	  lpenStr;

						hr = punkEnum->QueryInterface(IID_IEnumGUID_(), reinterpret_cast<void**>(&lpenStr));

						if(FAILED(hr))
						{
							r->report("Failed to retrieve required enumerator interface from enumerator object", __LINE__);
							bSuccess = false;
						}
						else
						{
							enumerator_t			en(lpenStr, false, q); // Eat the reference
							char					msg[101];

							::sprintf(&msg[0], "Enumerating GUIDs using IEnumGUID; quanta=%u", q);

							r->report(msg, -1, NULL);

							enumerator_t::iterator	b	=	en.begin();
							enumerator_t::iterator	e	=	en.end();

							{ for(size_t i = 0; i < STLSOFT_NUM_ELEMENTS(guids); ++i)
							{
								enumerator_t::iterator	b2	=	b;

								b = b2;

								if(en.end() == b)
								{
									r->report("Enumerator sequence contains the wrong number of elements", __LINE__);
									bSuccess = false;
								}
								else
								{
									if(*b != guids[i])
									{
										r->report("Enumerator sequence element contains the wrong value", __LINE__);
										bSuccess = false;
									}

									b2	=	b;
									++b2;
									b	=	b2;
								}
							}}

							if(en.end() != b)
							{
								r->report("Enumerator sequence contains the wrong number of elements", __LINE__);
								bSuccess = false;
							}
						}
					}}
				}

				// 3. cloneable_cloning_policy
				{
					r->report("cloneable_cloning_policy", -1, NULL);

					typedef enumerator_sequence<IEnumGUID
											,	GUID
											,	GUID_policy
											,	GUID
											,	cloneable_cloning_policy<IEnumGUID>
											,	10
											>			enumerator_t;

					{ for(cs_size_t q = 0; q < enumerator_t::retrievalQuanta; ++q)
					{
						LPENUMGUID	  lpenStr;

						hr = punkEnum->QueryInterface(IID_IEnumGUID_(), reinterpret_cast<void**>(&lpenStr));

						if(FAILED(hr))
						{
							r->report("Failed to retrieve required enumerator interface from enumerator object", __LINE__);
							bSuccess = false;
						}
						else
						{
							enumerator_t			en(lpenStr, false, q); // Eat the reference
							char					msg[101];

							::sprintf(&msg[0], "Enumerating GUIDs using IEnumGUID; quanta=%u", q);

							r->report(msg, -1, NULL);

							enumerator_t::iterator	b	=	en.begin();
							enumerator_t::iterator	e	=	en.end();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -