PageRenderTime 43ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/trunk/source/Tools/JLevelViewer/class.h

#
C Header | 904 lines | 743 code | 108 blank | 53 comment | 98 complexity | 4bbb7c9235f2cb46e31abf7831d055e9 MD5 | raw file
  1. //////////////////////////////////////////////////////////////////////////
  2. //
  3. // PROJECT:
  4. // FILE: class.h - base class object model definitions
  5. // AUTHOR: Vladimir Gumenuk
  6. // CREATED: 14-Aug-2004
  7. //
  8. // MODIFIED: 5-Jul-2005 added IClassEnum, IClassCollection
  9. //
  10. //////////////////////////////////////////////////////////////////////////
  11. #ifndef __class_h__
  12. #define __class_h__
  13. #pragma warning(disable:4311) // 'type cast' : pointer truncation from 'void *' to 'uint
  14. #pragma warning(disable:4312) // 'type cast' : conversion from 'uint' to 'IClassUnknown *' of greater size
  15. #pragma warning(disable:4267) // '=' : conversion from 'size_t' to 'dword', possible loss of data
  16. #include <assert.h>
  17. #include <string.h>
  18. #include <memory.h>
  19. #define interface struct
  20. //////////////////////////////////////////////////////////////////////////
  21. // typedefs
  22. typedef unsigned char byte;
  23. typedef byte* lpbyte;
  24. typedef unsigned int uint;
  25. typedef unsigned short word;
  26. typedef unsigned long dword;
  27. typedef unsigned long ulong;
  28. typedef float real;
  29. typedef double vtime;
  30. typedef char* lpstr;
  31. typedef const char* lpcstr;
  32. typedef unsigned short wchar;
  33. typedef wchar* lpwstr;
  34. typedef const lpwstr lpcwstr;
  35. #ifdef CLS_UNICODE
  36. typedef wchar tchar;
  37. typedef lpwstr lptstr;
  38. typedef lpcwstr lpctstr;
  39. #else // ANSI
  40. typedef char tchar;
  41. typedef lpstr lptstr;
  42. typedef lpcstr lpctstr;
  43. #endif // CLS_UNICODE
  44. typedef lptstr bstr; // special string
  45. typedef uint ciid; // class interface id
  46. typedef int vresult; // virtual method result
  47. // this class id reserved for IClassUnknown interface
  48. #define CID_IClassUnknown 0x00000001
  49. // this class id reserved for IClassEnum interface
  50. #define CID_IClassEnum 0x00000002
  51. // this class id reserved for IClassCollection interface
  52. #define CID_IClassCollection 0x00000003
  53. // this class id reserved for IClassStream
  54. #define CID_IClassStream 0x00000004
  55. #define VIRTUAL =0
  56. #define DEFFN(n) virtual vresult n
  57. #define DEFFN_(r,n) virtual r n
  58. #define STDEFFN(n) virtual vresult __stdcall n
  59. #define STDEFFN_(r,n) virtual r __stdcall n
  60. //////////////////////////////////////////////////////////////////////////
  61. // Base class for all com classes
  62. class IClassUnknown
  63. {
  64. public:
  65. virtual bool QueryClass( ciid iid, void **ppv ) = 0;
  66. virtual uint AddRef() = 0;
  67. virtual uint Release() = 0;
  68. };
  69. //////////////////////////////////////////////////////////////////////////
  70. // enumerator
  71. class IClassEnum : public IClassUnknown
  72. {
  73. public:
  74. virtual void Reset() = 0;
  75. virtual bool get_Next( IClassUnknown **ppv ) = 0;
  76. };
  77. //////////////////////////////////////////////////////////////////////////
  78. // collection
  79. class IClassCollection : public IClassUnknown
  80. {
  81. public:
  82. virtual uint get_Count() = 0;
  83. virtual bool get_Item( uint idx, IClassUnknown **ppv ) = 0;
  84. virtual bool get_Enum( IClassEnum **ppv ) = 0;
  85. };
  86. //////////////////////////////////////////////////////////////////////////
  87. // Stream
  88. class IClassStream : public IClassUnknown
  89. {
  90. public:
  91. // returns the current size of the stream
  92. virtual dword get_Size() = 0;
  93. // Reads the requested size from stream, returns the number of bytes,
  94. // that were actually read. Advance stream pointer
  95. virtual dword Read( void *pBuf, dword Size ) = 0;
  96. // Writes the specified number of bytes to stram, returns the number of bytes,
  97. // that were actually written
  98. virtual dword Write( void *pBuf, dword Size ) = 0;
  99. // Changes the position of the internal pointer, returns the new position
  100. virtual dword Seek( long Offset ) = 0;
  101. };
  102. //////////////////////////////////////////////////////////////////////////
  103. // base templates
  104. #define NOVTABLE __declspec(novtable)
  105. // compiler dependent
  106. #define cls_packing 8
  107. #define classoffset(base, derived) ((uint)(static_cast<base*>((derived*)cls_packing))-cls_packing)
  108. typedef struct
  109. {
  110. ciid iid;
  111. uint offset;
  112. } vtbl_entry_t;
  113. inline bool _QueryClass( void *pThis, const vtbl_entry_t *pClasses, ciid iid, void **ppOut ) {
  114. if( pClasses->iid == 1 /*CID_IClassUnknown*/ ) {
  115. IClassUnknown *p = (IClassUnknown*)((uint)pThis + pClasses->offset);
  116. *ppOut = p;
  117. return true;
  118. }
  119. while( pClasses->iid != 0 ) {
  120. if( pClasses->iid == iid ) {
  121. IClassUnknown *p = (IClassUnknown*)((uint)pThis + pClasses->offset);
  122. *ppOut = p;
  123. return true;
  124. }
  125. pClasses++;
  126. }
  127. return false;
  128. };
  129. #define BEGIN_CLASS_MAP(c) \
  130. public: \
  131. typedef c _MapClass; \
  132. bool _QueryClassInternal( ciid iid, void **ppv ) { \
  133. return _QueryClass( this, _get_classes(), iid, ppv ); } \
  134. const static vtbl_entry_t * __stdcall _get_classes() { \
  135. static const vtbl_entry_t _classes[] = {
  136. #define CLASS_ENTRY(i) \
  137. { CID_##i, classoffset(i,_MapClass) },
  138. #define END_CLASS_MAP() \
  139. { 0, 0 } }; return _classes; } \
  140. virtual bool QueryClass( ciid iid, void **ppv ) = 0; \
  141. virtual uint AddRef() = 0; \
  142. virtual uint Release() = 0; \
  143. class CClassObjectRoot
  144. {
  145. public:
  146. void SetVoid( void *lpVoid ) { ; }
  147. bool FinalConstruct() { return true; } // with declaration specificator novtable impossible call virtual functions
  148. void FinalRelease() { ; } // from constructor,this should help...
  149. };
  150. //////////////////////////////////////////////////////////////////////////
  151. // last object in hierarchy
  152. template<class T>
  153. class CClassCreator : public T
  154. {
  155. typedef T _clsBase;
  156. uint m_cRef;
  157. public:
  158. CClassCreator() { m_cRef = 0; }
  159. virtual ~CClassCreator() { assert( m_cRef == 0 ); }
  160. bool QueryClass( ciid iid, void **ppv ) {
  161. if( ppv && _QueryClassInternal( iid, ppv ) ) {
  162. AddRef();
  163. return true;
  164. }
  165. return false;
  166. }
  167. uint AddRef() { return ++m_cRef; }
  168. uint Release() {
  169. if( --m_cRef == 0 ) {
  170. FinalRelease();
  171. delete this;
  172. return 0;
  173. }
  174. return m_cRef;
  175. }
  176. static bool _create( CClassCreator<T> **ppv ) {
  177. if( !ppv ) return false;
  178. CClassCreator<T> *p = new CClassCreator<T>();
  179. if( !p )
  180. return false;
  181. p->SetVoid( 0 );
  182. if( !p->FinalConstruct() ) {
  183. delete p;
  184. return false;
  185. }
  186. *ppv = p;
  187. return true;
  188. }
  189. static bool _create_vp( void *lpVoid, CClassCreator<T> **ppv ) {
  190. if( !ppv ) return false;
  191. CClassCreator<T> *p = new CClassCreator<T>();
  192. if( !p )
  193. return false;
  194. p->SetVoid( lpVoid );
  195. if( !p->FinalConstruct() ) {
  196. delete p;
  197. return false;
  198. }
  199. *ppv = p;
  200. return true;
  201. }
  202. };
  203. //////////////////////////////////////////////////////////////////////////
  204. // Helpers
  205. //////////////////////////////////////////////////////////////////////////
  206. template <class T>
  207. class _NoAddRefReleasePtr : public T
  208. {
  209. private:
  210. virtual uint AddRef() = 0;
  211. virtual uint Release() = 0;
  212. };
  213. inline IClassUnknown* ClassPtrAssign( IClassUnknown** pp, IClassUnknown* lp ) {
  214. if( lp != 0 )
  215. lp->AddRef();
  216. if( *pp )
  217. ( *pp )->Release();
  218. *pp = lp;
  219. return lp;
  220. }
  221. template <class T>
  222. class CSafePtr
  223. {
  224. public:
  225. typedef T _PtrClass;
  226. T* p;
  227. CSafePtr() {
  228. p=0;
  229. }
  230. CSafePtr( T* lp ) {
  231. if( (p = lp) != 0 )
  232. p->AddRef();
  233. }
  234. CSafePtr( const CSafePtr<T>& lp ) {
  235. if( (p = lp.p) != 0 )
  236. p->AddRef();
  237. }
  238. ~CSafePtr() {
  239. if( p )
  240. p->Release();
  241. }
  242. void Release() {
  243. IClassUnknown* pTemp = p;
  244. if( pTemp ) {
  245. p = 0;
  246. pTemp->Release();
  247. }
  248. }
  249. inline operator T*() const {
  250. return (T*)p;
  251. }
  252. inline T& operator*() const { assert(p!=0);
  253. return *p;
  254. }
  255. inline T** operator&() { assert(p==0);
  256. return &p;
  257. }
  258. inline _NoAddRefReleasePtr<T>* operator->() const { assert(p!=0);
  259. return (_NoAddRefReleasePtr<T>*)p;
  260. }
  261. inline T* operator=( T* lp ) {
  262. return (T*)ClassPtrAssign( (IClassUnknown**)&p, lp );
  263. }
  264. inline T* operator=( const CSafePtr<T>& lp ) {
  265. return (T*)ClassPtrAssign( (IClassUnknown**)&p, lp.p );
  266. }
  267. inline bool operator!() const {
  268. return (p == 0);
  269. }
  270. inline bool operator< ( T* pT ) const {
  271. return p < pT;
  272. }
  273. inline bool operator==( T* pT ) const {
  274. return p == pT;
  275. }
  276. inline void Attach(T* p2) {
  277. if( p )
  278. p->Release();
  279. p = p2;
  280. }
  281. inline T* Detach() {
  282. T* pt = p;
  283. p = 0;
  284. return pt;
  285. }
  286. bool CopyTo( T** ppT ) {
  287. assert(ppT != 0);
  288. if( ppT == 0 )
  289. return false;
  290. *ppT = p;
  291. if( p )
  292. p->AddRef();
  293. return true;
  294. }
  295. };
  296. //////////////////////////////////////////////////////////////////////////
  297. // safe memory buffer
  298. template <class T>
  299. class CMemPtr
  300. {
  301. public:
  302. CMemPtr() { p = 0; cb = 0; }
  303. CMemPtr( dword dwSize ) { Alloc( dwSize ); }
  304. ~CMemPtr() { if( p ) delete[] p; }
  305. bool Alloc( dword dwSize, bool bZero = false ) {
  306. if( dwSize ) {
  307. cb = dwSize;
  308. p = new T[cb];
  309. if( p ) {
  310. if( bZero ) {
  311. dword dwByteLen = cb * sizeof(T);
  312. lpbyte pBuffer = (lpbyte)p;
  313. for( register dword i = 0; i < dwByteLen; i++ ) p[i] = 0;
  314. }
  315. return true;
  316. }
  317. }
  318. return false;
  319. }
  320. inline void Free() { if( p ) { delete[] p; p = 0; cb = 0; } }
  321. inline dword Size() const { return cb; }
  322. inline operator T() const {
  323. return p;
  324. }
  325. inline operator T*() const {
  326. return &p[0];
  327. }
  328. inline T* operator& () {
  329. return p;
  330. }
  331. inline T operator[] ( dword dwIndex ) const {
  332. return p[dwIndex];
  333. }
  334. T *p;
  335. dword cb;
  336. };
  337. //////////////////////////////////////////////////////////////////////////
  338. template<class T>
  339. class CClassPtrArray
  340. {
  341. typedef T* LPT;
  342. LPT *m_pT;
  343. uint m_iCount;
  344. uint m_iAllocated;
  345. public:
  346. CClassPtrArray() {
  347. m_pT = 0; m_iCount = 0; m_iAllocated = 0;
  348. }
  349. ~CClassPtrArray() {
  350. Clear();
  351. }
  352. inline uint GetSize() {
  353. return m_iCount;
  354. }
  355. void Clear() {
  356. if( m_pT ) {
  357. for( uint i = 0; i < m_iCount; i++ ) {
  358. m_pT[i]->Release();
  359. }
  360. delete[] m_pT;
  361. m_pT = 0; m_iCount = 0; m_iAllocated = 0;
  362. }
  363. }
  364. void Add( T* t ) {
  365. if( m_iCount == m_iAllocated ) {
  366. uint iNewAllocSize = (m_iAllocated == 0) ? 1 : ( m_iCount * 2 );
  367. m_iAllocated = iNewAllocSize;
  368. LPT *p = new LPT[ iNewAllocSize ];
  369. for( uint i = 0; i < m_iCount; i++ )
  370. p[i] = m_pT[i];
  371. if( m_pT )
  372. delete[] m_pT;
  373. m_pT = p;
  374. }
  375. m_pT[m_iCount] = t;
  376. m_pT[m_iCount]->AddRef();
  377. m_iCount++;
  378. }
  379. void Remove( uint idx ) {
  380. if( idx < m_iCount ) {
  381. m_pT[idx]->Release();
  382. m_pT[idx] = 0;
  383. uint i = idx + 1;
  384. while( idx < m_iCount ) {
  385. m_pT[idx++] = m_pT[i++];
  386. }
  387. m_iCount--;
  388. }
  389. }
  390. inline T*& operator[] ( uint index ) const {
  391. return m_pT[index];
  392. }
  393. CClassPtrArray<T>& operator= ( const CClassPtrArray<T>& a ) {
  394. Clear();
  395. if( a.m_pT && a.m_iCount ) {
  396. m_iAllocated = a.m_iAllocated;
  397. m_iCount = a.m_iCount;
  398. m_pT = new LPT[ m_iAllocated ];
  399. for( uint i = 0; i < m_iCount; i++ ) {
  400. m_pT[i] = a.m_pT[i];
  401. m_pT[i]->AddRef();
  402. }
  403. }
  404. return *this;
  405. }
  406. };
  407. //////////////////////////////////////////////////////////////////////////
  408. //
  409. #define GROWLEN 4
  410. class CDynamicClsUnkArray
  411. {
  412. public:
  413. CDynamicClsUnkArray() {
  414. m_nSize = 0;
  415. m_ppUnk = NULL;
  416. }
  417. ~CDynamicClsUnkArray() {
  418. if( m_nSize > 1 )
  419. free( m_ppUnk );
  420. }
  421. DWORD Add( IClassUnknown *pUnk ) {
  422. IClassUnknown** pp = NULL;
  423. if( m_nSize == 0 ) {// no connections
  424. m_pUnk = pUnk;
  425. m_nSize = 1;
  426. return (DWORD)m_pUnk;
  427. } else if ( m_nSize == 1 ) {
  428. //create array
  429. pp = (IClassUnknown**)malloc(sizeof(IClassUnknown*)*GROWLEN);
  430. if (pp == NULL)
  431. return 0;
  432. memset(pp, 0, sizeof(IClassUnknown*)*GROWLEN);
  433. *pp = m_pUnk;
  434. m_ppUnk = pp;
  435. m_nSize = GROWLEN;
  436. }
  437. for( pp = begin(); pp<end(); pp++ ) {
  438. if( *pp == NULL ) {
  439. *pp = pUnk;
  440. return (DWORD)pUnk;
  441. }
  442. }
  443. int nAlloc = m_nSize*2;
  444. pp = (IClassUnknown**)realloc( m_ppUnk, sizeof(IClassUnknown*)*nAlloc );
  445. if( pp == NULL )
  446. return 0;
  447. m_ppUnk = pp;
  448. memset( &m_ppUnk[m_nSize], 0, sizeof(IClassUnknown*)*m_nSize );
  449. m_ppUnk[m_nSize] = pUnk;
  450. m_nSize = nAlloc;
  451. return (DWORD)pUnk;
  452. }
  453. BOOL Remove( DWORD dwCookie ) {
  454. IClassUnknown** pp;
  455. if( dwCookie == NULL || m_nSize == 0 )
  456. return FALSE;
  457. if( m_nSize == 1 ) {
  458. if( (DWORD)m_pUnk == dwCookie ) {
  459. m_nSize = 0;
  460. return TRUE;
  461. }
  462. return FALSE;
  463. }
  464. for( pp = begin(); pp < end(); pp++ ) {
  465. if( (DWORD)*pp == dwCookie ) {
  466. *pp = NULL;
  467. return TRUE;
  468. }
  469. }
  470. return FALSE;
  471. }
  472. static DWORD GetCookie( IClassUnknown **pp ) {
  473. return (DWORD)*pp;
  474. }
  475. static IClassUnknown * GetClsUnknown( DWORD dwCookie ) {
  476. return (IClassUnknown*)dwCookie;
  477. }
  478. IClassUnknown** begin() {
  479. return ( m_nSize < 2 ) ? &m_pUnk : m_ppUnk;
  480. }
  481. IClassUnknown** end() {
  482. return ( m_nSize < 2 ) ? (&m_pUnk)+m_nSize : &m_ppUnk[m_nSize];
  483. }
  484. IClassUnknown* GetAt( uint nIndex ) {
  485. if( nIndex < 0 || nIndex >= m_nSize )
  486. return NULL;
  487. return (m_nSize < 2) ? m_pUnk : m_ppUnk[nIndex];
  488. }
  489. uint GetSize() const { return m_nSize; }
  490. void clear() {
  491. if( m_nSize > 1 )
  492. free( m_ppUnk );
  493. m_nSize = 0;
  494. }
  495. protected:
  496. union {
  497. IClassUnknown** m_ppUnk;
  498. IClassUnknown* m_pUnk;
  499. };
  500. uint m_nSize;
  501. };
  502. //////////////////////////////////////////////////////////////////////////
  503. // IClassStream
  504. template<class T>
  505. class CClassStreamImpl : public T
  506. {
  507. protected:
  508. dword m_dwAllocated;
  509. dword m_dwDataSize;
  510. lpbyte m_pBuffer;
  511. dword m_dwPos;
  512. public:
  513. CClassStreamImpl() {
  514. m_dwAllocated = 0; m_dwDataSize = 0; m_pBuffer = 0; m_dwPos = 0;
  515. }
  516. virtual ~CClassStreamImpl() {
  517. if( m_pBuffer )
  518. free( m_pBuffer );
  519. }
  520. virtual dword get_Size() {
  521. return m_dwDataSize;
  522. }
  523. virtual dword Read( void *pBuf, dword Size ) {
  524. dword dwToRead = 0;
  525. if( pBuf && Size && m_pBuffer ) {
  526. dwToRead = Size;
  527. if( m_dwPos + Size > m_dwDataSize )
  528. dwToRead = m_dwPos + Size - m_dwDataSize;
  529. memcpy( pBuf, &m_pBuffer[m_dwPos], dwToRead );
  530. m_dwPos += dwToRead;
  531. }
  532. return dwToRead;
  533. }
  534. virtual dword Write( void *pBuf, dword Size ) {
  535. dword dwWritten = 0;
  536. if( m_dwAllocated - m_dwPos < Size ) {
  537. dword dwNewAllocSize = ( Size * 2 ) + m_dwAllocated;
  538. m_dwAllocated = dwNewAllocSize;
  539. m_pBuffer = (lpbyte)realloc( m_pBuffer, m_dwAllocated );
  540. }
  541. if( m_pBuffer && pBuf && Size ) {
  542. memcpy( &m_pBuffer[m_dwPos], pBuf, Size );
  543. m_dwPos += Size;
  544. dwWritten = Size;
  545. }
  546. return dwWritten;
  547. }
  548. virtual dword Seek( long Offset ) {
  549. if( Offset ) {
  550. dword dwMove = ABS( Offset );
  551. if( Offset < 0 ) {
  552. m_dwPos = ( m_dwPos < dwMove ) ? 0 : m_dwPos - dwMove;
  553. } else {
  554. m_dwPos = ( m_dwSize < dwMove ) ? m_dwSize : m_dwPos + dwMove;
  555. }
  556. }
  557. return m_dwPos;
  558. }
  559. };
  560. //////////////////////////////////////////////////////////////////////////
  561. // Variant
  562. enum VariantType
  563. {
  564. VAR_EMPTY = 0,
  565. VAR_CHAR,
  566. VAR_BYTE,
  567. VAR_SHORT,
  568. VAR_WORD,
  569. VAR_INTEGER,
  570. VAR_UINT,
  571. VAR_LONG,
  572. VAR_DWORD,
  573. VAR_FLOAT,
  574. VAR_DOUBLE,
  575. VAR_TIME,
  576. VAR_BSTRING,
  577. VAR_BIN,
  578. VAR_CLSUNKNOWN
  579. };
  580. typedef struct _Variant
  581. {
  582. VariantType vt;
  583. union
  584. {
  585. char cVal;
  586. byte bVal;
  587. short sVal;
  588. word wVal;
  589. int iVal;
  590. uint uiVal;
  591. long lVal;
  592. dword dwVal;
  593. float fVal;
  594. double dVal;
  595. vtime tVal;
  596. bstr strVal;
  597. lpbyte binVal;
  598. IClassUnknown *punkVal;
  599. };
  600. dword dwSize;
  601. } Variant;
  602. //////////////////////////////////////////////////////////////////////////
  603. // variant api
  604. inline void variant_init( Variant *pv ) {
  605. pv->vt = VAR_EMPTY;
  606. pv->dwVal = 0;
  607. pv->dwSize = 0;
  608. }
  609. inline void variant_clear( Variant *pv ) {
  610. switch( pv->vt ) {
  611. case VAR_EMPTY: break;
  612. case VAR_CHAR:
  613. case VAR_BYTE:
  614. case VAR_SHORT:
  615. case VAR_WORD:
  616. case VAR_INTEGER:
  617. case VAR_UINT:
  618. case VAR_LONG:
  619. case VAR_DWORD:
  620. pv->dwVal = 0;
  621. break;
  622. case VAR_FLOAT:
  623. pv->fVal = 0.0f;
  624. break;
  625. case VAR_DOUBLE:
  626. pv->dVal = 0.0;
  627. break;
  628. case VAR_TIME:
  629. pv->tVal = 0.0;
  630. break;
  631. case VAR_BSTRING:
  632. delete[] pv->strVal;
  633. break;
  634. case VAR_BIN:
  635. delete[] pv->binVal;
  636. break;
  637. case VAR_CLSUNKNOWN:
  638. pv->punkVal->Release();
  639. pv->punkVal = 0;
  640. break;
  641. }
  642. pv->vt = VAR_EMPTY;
  643. pv->dwSize = 0;
  644. }
  645. inline bool variant_copy( Variant *pDst, Variant *pSrc ) {
  646. if( pDst->vt != VAR_EMPTY )
  647. return false;
  648. pDst->dwSize = pSrc->dwSize;
  649. switch( pSrc->vt ) {
  650. case VAR_EMPTY: break;
  651. case VAR_CHAR: pDst->cVal = pSrc->cVal; break;
  652. case VAR_BYTE: pDst->bVal = pSrc->bVal; break;
  653. case VAR_SHORT: pDst->sVal = pSrc->sVal; break;
  654. case VAR_WORD: pDst->wVal = pSrc->wVal; break;
  655. case VAR_INTEGER: pDst->iVal = pSrc->iVal; break;
  656. case VAR_UINT: pDst->uiVal = pSrc->uiVal; break;
  657. case VAR_LONG: pDst->lVal = pSrc->lVal; break;
  658. case VAR_DWORD: pDst->dwVal = pSrc->dwVal; break;
  659. case VAR_FLOAT: pDst->fVal = pSrc->fVal; break;
  660. case VAR_DOUBLE: pDst->dVal = pSrc->dVal; break;
  661. case VAR_TIME: pDst->tVal = pSrc->tVal; break;
  662. case VAR_BSTRING:
  663. {
  664. if( !pSrc->dwSize )
  665. return false;
  666. pDst->strVal = new char[pSrc->dwSize+1];
  667. if( !pDst->strVal )
  668. return false;
  669. char *d = pDst->strVal;
  670. char *s = pSrc->strVal;
  671. while( *d++ = *s++ ) ;
  672. *d = 0;
  673. pDst->dwSize = pSrc->dwSize;
  674. }
  675. break;
  676. case VAR_BIN:
  677. {
  678. if( !pSrc->dwSize )
  679. return false;
  680. pDst->binVal = new byte[pSrc->dwSize];
  681. if( !pDst->binVal )
  682. return false;
  683. for( dword i = 0; i < pSrc->dwSize; i++ )
  684. pDst->binVal[i] = pSrc->binVal[i];
  685. pDst->dwSize = pSrc->dwSize;
  686. }
  687. break;
  688. case VAR_CLSUNKNOWN:
  689. if( !pSrc->punkVal )
  690. return false;
  691. pDst->punkVal = pSrc->punkVal;
  692. pDst->punkVal->AddRef();
  693. break;
  694. }
  695. pDst->vt = pSrc->vt;
  696. return true;
  697. }
  698. //////////////////////////////////////////////////////////////////////////
  699. // CVariant
  700. class CVariant : public Variant
  701. {
  702. public:
  703. CVariant() { variant_init( this ); }
  704. ~CVariant() { variant_clear( this ); }
  705. CVariant( char c ) {
  706. vt = VAR_CHAR;
  707. cVal = c;
  708. dwSize = sizeof(char);
  709. }
  710. CVariant( byte b ) {
  711. vt = VAR_BYTE;
  712. bVal = b;
  713. dwSize = sizeof(byte);
  714. }
  715. CVariant( short s ) {
  716. vt = VAR_SHORT;
  717. sVal = s;
  718. dwSize = sizeof(short);
  719. }
  720. CVariant( word w ) {
  721. vt = VAR_WORD;
  722. wVal = w;
  723. dwSize = sizeof(word);
  724. }
  725. CVariant( int i ) {
  726. vt = VAR_INTEGER;
  727. iVal = i;
  728. dwSize = sizeof(int);
  729. }
  730. CVariant( uint u ) {
  731. vt = VAR_UINT;
  732. uiVal = u;
  733. dwSize = sizeof(uint);
  734. }
  735. CVariant( long l ) {
  736. vt = VAR_LONG;
  737. lVal = l;
  738. dwSize = sizeof(long);
  739. }
  740. CVariant( dword dw ) {
  741. vt = VAR_DWORD;
  742. dwVal = dw;
  743. dwSize = sizeof(dword);
  744. }
  745. CVariant( float f ) {
  746. vt = VAR_FLOAT;
  747. fVal = f;
  748. dwSize = sizeof(float);
  749. }
  750. CVariant( double d ) {
  751. vt = VAR_DOUBLE;
  752. dVal = d;
  753. dwSize = sizeof(double);
  754. }
  755. CVariant( lpcstr str ) {
  756. assert( str );
  757. vt = VAR_BSTRING;
  758. dwSize = strlen( str );
  759. strVal = new char[ dwSize + 1 ];
  760. char *d = strVal;
  761. const char *s = str;
  762. while( *d++ = *s++ ) ;
  763. *d = 0;
  764. }
  765. CVariant( lpbyte pbin, dword dwSize ) {
  766. assert( pbin );
  767. assert( dwSize != 0 );
  768. vt = VAR_BIN;
  769. dwSize = dwSize;
  770. binVal = new byte[ dwSize ];
  771. for( dword i = 0; i < dwSize; i++ )
  772. binVal[i] = pbin[i];
  773. }
  774. CVariant( IClassUnknown *punk ) {
  775. assert( punk );
  776. vt = VAR_CLSUNKNOWN;
  777. punkVal = punk;
  778. punkVal->AddRef();
  779. }
  780. CVariant( const Variant& v ) {
  781. variant_init( this );
  782. Variant *pv = const_cast<Variant*>( &v );
  783. variant_copy( this, pv );
  784. }
  785. CVariant& operator= ( const CVariant& v ) {
  786. variant_clear( this );
  787. CVariant *pv = const_cast<CVariant*>( &v );
  788. variant_copy( this, pv );
  789. return (*this);
  790. }
  791. void clear() {
  792. variant_clear( this );
  793. }
  794. };
  795. //////////////////////////////////////////////////////////////////////////
  796. #endif // __class_h__