GME  13
CommonSmart.cpp
Go to the documentation of this file.
00001 
00002 #include "stdafx.h"
00003 #include "CommonSmart.h"
00004 
00005 // --------------------------- CComBstrObj
00006 
00007 int CComBstrObj::Compare(BSTR q) const
00008 {
00009         unsigned int pl = p ? SysStringLen(p) : 0;
00010         unsigned int ql = q ? SysStringLen(q) : 0;
00011 
00012         if( pl != ql )
00013                 return pl - ql;
00014         if (pl == NULL && ql == NULL)
00015                 return 0;
00016 
00017         return wcsncmp(p, q, pl);
00018 }
00019 
00020 void CopyTo(const char *p, int len, BSTR *b, UINT codepage)
00021 {
00022         ASSERT( len >= 0 );
00023         ASSERT( b != NULL );
00024 
00025         if(*b)
00026         {
00027                 SysFreeString(*b);
00028                 *b = NULL;
00029         }
00030 
00031         if( len <= 0 )
00032                 return;
00033 
00034         int blen = MultiByteToWideChar(codepage, 0, p, len, NULL, 0);
00035 
00036         if( blen <= 0 )
00037                 HR_THROW(E_CONVERSION);
00038 
00039         *b = SysAllocStringLen(NULL, blen);
00040         if( *b == NULL )
00041                 HR_THROW(E_OUTOFMEMORY);
00042 
00043         int tlen = MultiByteToWideChar(codepage, 0, p, len, *b, blen);
00044 
00045         if( tlen <= 0 )
00046                 HR_THROW(E_CONVERSION);
00047         
00048         ASSERT( tlen == blen );
00049 
00050         (*b)[blen] = L'\0';
00051 }
00052 
00053 int GetCharLength(const OLECHAR *p, int olelen, UINT codepage)
00054 {
00055         ASSERT( olelen >= -1 );
00056 
00057         if( olelen == 0 )
00058                 return 0;
00059 
00060         int charlen = WideCharToMultiByte(codepage, 0, p, olelen,
00061                 NULL, 0, NULL, NULL);
00062 
00063         // zero if failed
00064         ASSERT( charlen > 0 );
00065 
00066         return charlen;
00067 }
00068 
00069 void CopyTo(const OLECHAR *p, int olelen, char *s, int charlen, UINT codepage)
00070 {
00071         ASSERT( olelen >= -1 && charlen >= 0 );
00072         ASSERT( charlen == 0 || p != NULL );
00073 
00074         if( charlen <= 0 )
00075                 return;
00076 
00077         int len = WideCharToMultiByte(codepage, 0, p, olelen, 
00078                 s, charlen, NULL, NULL);
00079 
00080         // zero if failed
00081         ASSERT( len > 0 );
00082 
00083         ASSERT( len == charlen );
00084 }               
00085 
00086 void CopyTo(const OLECHAR *p, GUID &guid)
00087 {
00088         ASSERT( p != NULL );
00089 
00090         if( FAILED(IIDFromString(const_cast<OLECHAR*>(p), static_cast<IID*>(&guid))) )
00091                 HR_THROW(E_CONVERSION);
00092 }
00093 
00094 void CopyTo(const GUID &guid, BSTR *p)
00095 {
00096         ASSERT( p != NULL );
00097 
00098         OLECHAR *q = NULL;
00099 
00100         if( FAILED(StringFromIID(static_cast<IID>(guid), &q)) )
00101                 HR_THROW(E_CONVERSION);
00102 
00103         if(*p != NULL)
00104                 SysFreeString(*p);
00105         
00106         *p = SysAllocString(q);
00107         CoTaskMemFree(q);
00108         if (*p == NULL)
00109                 HR_THROW(E_OUTOFMEMORY);
00110 }
00111 
00112 // --------------------------- CComSafeArray
00113 
00114 void CopyTo(const CComBstrObj *start, const CComBstrObj *end, SAFEARRAY **p)
00115 {
00116         ASSERT( p != NULL && *p == NULL );
00117         ASSERT( start <= end );
00118 
00119         *p = SafeArrayCreateVector(VT_BSTR, 1, end - start);
00120         if( *p == NULL )
00121                 HR_THROW(E_OUTOFMEMORY);
00122 
00123         try
00124         {
00125                 BSTR *q = NULL;
00126 
00127                 COMTHROW( SafeArrayAccessData(*p, (void**)&q) );
00128                 ASSERT( q != NULL );
00129 
00130                 while( start < end )
00131                 {
00132                         CopyTo(*start, q);
00133 
00134                         ++q;
00135                         ++start;
00136                 }
00137 
00138                 COMTHROW( SafeArrayUnaccessData(*p) );
00139         }
00140         catch(hresult_exception &)
00141         {
00142                 SafeArrayDestroy(*p);
00143                 *p = NULL;
00144 
00145                 throw;
00146         }
00147 }
00148 
00149 void MoveTo(CComBstrObj *start, CComBstrObj *end, SAFEARRAY **p)
00150 {
00151         ASSERT( p != NULL && *p == NULL );
00152         ASSERT( start <= end );
00153 
00154         *p = SafeArrayCreateVector(VT_BSTR, 1, end - start);
00155         if( *p == NULL )
00156                 HR_THROW(E_OUTOFMEMORY);
00157 
00158         try
00159         {
00160                 BSTR *q = NULL;
00161 
00162                 COMTHROW( SafeArrayAccessData(*p, (void**)&q) );
00163                 ASSERT( q != NULL );
00164 
00165                 while( start < end )
00166                 {
00167                         MoveTo(*start, q);
00168 
00169                         ++q;
00170                         ++start;
00171                 }
00172 
00173                 COMTHROW( SafeArrayUnaccessData(*p) );
00174         }
00175         catch(hresult_exception &)
00176         {
00177                 SafeArrayDestroy(*p);
00178                 *p = NULL;
00179 
00180                 throw;
00181         }
00182 }
00183 
00184 void CopyTo(const unsigned char *start, const unsigned char *end, SAFEARRAY **p)
00185 {
00186         ASSERT( p != NULL && *p == NULL );
00187         ASSERT( start <= end );
00188 
00189         *p = SafeArrayCreateVector(VT_UI1, 1, end - start);
00190         if( *p == NULL )
00191                 HR_THROW(E_OUTOFMEMORY);
00192 
00193         try
00194         {
00195                 unsigned char *q = NULL;
00196 
00197                 COMTHROW( SafeArrayAccessData(*p, (void**)&q) );
00198                 ASSERT( q != NULL );
00199 
00200                 // FIXME: how about memcpy?
00201                 while( start < end )
00202                 {
00203                         *q = *start;
00204 
00205                         ++q;
00206                         ++start;
00207                 }
00208 
00209                 COMTHROW( SafeArrayUnaccessData(*p) );
00210         }
00211         catch(hresult_exception &)
00212         {
00213                 SafeArrayDestroy(*p);
00214                 *p = NULL;
00215 
00216                 throw;
00217         }
00218 }
00219 
00220 void CopyTo(const long *start, const long *end, SAFEARRAY **p)
00221 {
00222         ASSERT( p != NULL && *p == NULL );
00223         ASSERT( start <= end );
00224 
00225         *p = SafeArrayCreateVector(VT_I4, 1, end - start);
00226         if( *p == NULL )
00227                 HR_THROW(E_OUTOFMEMORY);
00228 
00229         try
00230         {
00231                 long *q = NULL;
00232 
00233                 COMTHROW( SafeArrayAccessData(*p, (void**)&q) );
00234                 ASSERT( q != NULL );
00235 
00236                 while( start < end )
00237                 {
00238                         *q = *start;
00239 
00240                         ++q;
00241                         ++start;
00242                 }
00243 
00244                 COMTHROW( SafeArrayUnaccessData(*p) );
00245         }
00246         catch(hresult_exception &)
00247         {
00248                 SafeArrayDestroy(*p);
00249                 *p = NULL;
00250 
00251                 throw;
00252         }
00253 }
00254 
00255 void CopyTo(const GUID *start, const GUID *end, SAFEARRAY **p)
00256 {
00257         ASSERT( p != NULL && *p == NULL );
00258         ASSERT( start <= end );
00259 
00260         SAFEARRAYBOUND bounds[2];
00261         bounds[0].cElements = end - start;
00262         bounds[0].lLbound = 1;
00263         bounds[1].cElements = sizeof(GUID);
00264         bounds[1].lLbound = 0;
00265 
00266         *p = SafeArrayCreate(VT_UI1, 2, bounds);
00267         if( *p == NULL )
00268                 HR_THROW(E_OUTOFMEMORY);
00269 
00270         try
00271         {
00272                 GUID *q = NULL;
00273 
00274                 COMTHROW( SafeArrayAccessData(*p, (void**)&q) );
00275                 ASSERT( q != NULL );
00276 
00277                 while( start < end )
00278                 {
00279                         *q = *start;
00280 
00281                         ++q;
00282                         ++start;
00283                 }
00284 
00285                 COMTHROW( SafeArrayUnaccessData(*p) );
00286         }
00287         catch(hresult_exception &)
00288         {
00289                 SafeArrayDestroy(*p);
00290                 *p = NULL;
00291 
00292                 throw;
00293         }
00294 }
00295 
00296 long GetArrayLength(SAFEARRAY *p)
00297 {
00298         ASSERT( p != NULL );
00299 
00300         if( !(p->cDims == 1 || p->cDims == 2) )
00301                 HR_THROW(E_INVALIDARG);
00302 
00303         ASSERT( p->rgsabound[0].cElements >= 0 );
00304         return p->rgsabound[0].cElements;
00305 }
00306 
00307 void GetArrayStart(SAFEARRAY *p, CComBstrObj *&start)
00308 {
00309         ASSERT( p != NULL );
00310 
00311         if( (p->fFeatures & FADF_BSTR) != FADF_BSTR )
00312                 HR_THROW(E_INVALIDARG);
00313 
00314         start = (CComBstrObj*)p->pvData;
00315 }
00316 
00317 void GetArrayStart(SAFEARRAY *p, long *&start)
00318 {
00319         ASSERT( p != NULL );
00320 
00321         if( p->cbElements != 4 )
00322                 HR_THROW(E_INVALIDARG);
00323 
00324         start = (long*)p->pvData;
00325 }
00326 
00327 void GetArrayStart(SAFEARRAY *p, unsigned char *&start)
00328 {
00329         ASSERT( p != NULL );
00330 
00331         if( p->cbElements != 1 )
00332                 HR_THROW(E_INVALIDARG);
00333 
00334         start = (unsigned char*)p->pvData;
00335 }
00336 
00337 void GetArrayStart(SAFEARRAY *p, GUID *&start)
00338 {
00339         ASSERT( p != NULL );
00340 
00341         if( p->cbElements != 1 || p->cDims != 2 || p->rgsabound[1].cElements != sizeof(GUID) )
00342                 HR_THROW(E_INVALIDARG);
00343 
00344         start = (GUID*)p->pvData;
00345 }
00346 
00347 void CopyTo(SAFEARRAY *p, CComBstrObj *start, CComBstrObj *end)
00348 {
00349         ASSERT( p != NULL );
00350         ASSERT( start <= end );
00351 
00352         ASSERT( (p->fFeatures & FADF_BSTR) == FADF_BSTR );
00353 
00354         BSTR *q = NULL;
00355 
00356         COMTHROW( SafeArrayAccessData(p, (void**)&q) );
00357         ASSERT( q != NULL );
00358 
00359         try
00360         {
00361                 ASSERT( GetArrayLength(p) == (end - start) );
00362 
00363                 while( start < end )
00364                 {
00365                         CopyTo(*q, *start);
00366 
00367                         ++q;
00368                         ++start;
00369                 }
00370         }
00371         catch(hresult_exception &)
00372         {
00373                 SafeArrayUnaccessData(p);
00374                 throw;
00375         }
00376 
00377         COMTHROW( SafeArrayUnaccessData(p) );
00378 }
00379 
00380 void MoveTo(SAFEARRAY *p, CComBstrObj *start, CComBstrObj *end)
00381 {
00382         ASSERT( p != NULL );
00383         ASSERT( start <= end );
00384 
00385         ASSERT( (p->fFeatures & FADF_BSTR) == FADF_BSTR );
00386 
00387         BSTR *q = NULL;
00388 
00389         COMTHROW( SafeArrayAccessData(p, (void**)&q) );
00390         ASSERT( q != NULL );
00391 
00392         try
00393         {
00394                 ASSERT( GetArrayLength(p) == (end - start) );
00395 
00396                 while( start < end )
00397                 {
00398                         MoveTo(q, *start);
00399 
00400                         ++q;
00401                         ++start;
00402                 }
00403         }
00404         catch(hresult_exception &)
00405         {
00406                 SafeArrayUnaccessData(p);
00407                 throw;
00408         }
00409 
00410         COMTHROW( SafeArrayUnaccessData(p) );
00411 }
00412 
00413 void CopyTo(SAFEARRAY *p, unsigned char *start, unsigned char *end)
00414 {
00415         ASSERT( p != NULL );
00416         ASSERT( start <= end );
00417 
00418         ASSERT( p->cbElements == 1 );
00419 
00420         const unsigned char *q = NULL;
00421 
00422         COMTHROW( SafeArrayAccessData(p, (void**)&q) );
00423         ASSERT( q != NULL );
00424 
00425         ASSERT( GetArrayLength(p) == (end - start) );
00426         memcpy( start, q, (end - start) * sizeof(unsigned char) );
00427 
00428         COMTHROW( SafeArrayUnaccessData(p) );
00429 }
00430 
00431 void CopyTo(SAFEARRAY *p, long *start, long *end)
00432 {
00433         ASSERT( p != NULL );
00434         ASSERT( start <= end );
00435 
00436         ASSERT( p->cbElements == 4 );
00437 
00438         const long *q = NULL;
00439 
00440         COMTHROW( SafeArrayAccessData(p, (void**)&q) );
00441         ASSERT( q != NULL );
00442 
00443         ASSERT( GetArrayLength(p) == (end - start) );
00444         memcpy( start, q, (end - start) * sizeof(long) );
00445 
00446         COMTHROW( SafeArrayUnaccessData(p) );
00447 }
00448 
00449 void CopyTo(SAFEARRAY *p, GUID *start, GUID *end)
00450 {
00451         ASSERT( p != NULL );
00452         ASSERT( start <= end );
00453 
00454         ASSERT( p->cbElements == 1 );
00455 
00456         const GUID *q = NULL;
00457 
00458         COMTHROW( SafeArrayAccessData(p, (void**)&q) );
00459         ASSERT( q != NULL );
00460 
00461         ASSERT( GetArrayLength(p) == (end - start) );
00462         memcpy( start, q, (end - start) * sizeof(GUID) );
00463 
00464         COMTHROW( SafeArrayUnaccessData(p) );
00465 }
00466 
00467 // --------------------------- CComVariant
00468 
00469 void CopyTo(unsigned char a, VARIANT *v)
00470 {
00471         ASSERT( v != NULL );
00472 
00473         if( v->vt != VT_UI1 )
00474         {
00475                 if( v->vt != VT_EMPTY )
00476                         COMTHROW( VariantClear(v) );
00477 
00478                 v->vt = VT_UI1;
00479         }
00480         v->bVal = a;
00481 }
00482 
00483 void CopyTo(short a, VARIANT *v)
00484 {
00485         ASSERT( v != NULL );
00486 
00487         if( v->vt != VT_I2 )
00488         {
00489                 if( v->vt != VT_EMPTY )
00490                         COMTHROW( VariantClear(v) );
00491 
00492                 v->vt = VT_I2;
00493         }
00494         v->iVal = a;
00495 }
00496 
00497 void CopyTo(long a, VARIANT *v)
00498 {
00499         ASSERT( v != NULL );
00500 
00501         if( v->vt != VT_I4 )
00502         {
00503                 if( v->vt != VT_EMPTY )
00504                         COMTHROW( VariantClear(v) );
00505 
00506                 v->vt = VT_I4;
00507         }
00508         v->lVal = a;
00509 }
00510 
00511 void CopyTo(double a, VARIANT *v)
00512 {
00513         ASSERT( v != NULL );
00514 
00515         if( v->vt != VT_R8 )
00516         {
00517                 if( v->vt != VT_EMPTY )
00518                         COMTHROW( VariantClear(v) );
00519 
00520                 v->vt = VT_R8;
00521         }
00522         v->dblVal = a;
00523 }
00524 
00525 void CopyTo(BSTR b, VARIANT *v)
00526 {
00527         ASSERT( v != NULL );
00528 
00529         if( v->vt != VT_EMPTY )
00530                 COMTHROW( VariantClear(v) );
00531 
00532         v->bstrVal = SysAllocStringLen(b, SysStringLen(b));
00533         v->vt = VT_BSTR;
00534         if (v->bstrVal == NULL && b != NULL)
00535         {
00536                 v->vt = VT_EMPTY;
00537                 COMTHROW(E_OUTOFMEMORY);
00538         }
00539 }
00540 
00541 void CopyTo(IDispatch *p, VARIANT *v)
00542 {
00543         ASSERT( v != NULL );
00544 
00545         if( v->vt != VT_EMPTY )
00546                 COMTHROW( VariantClear(v) );
00547 
00548         v->pdispVal = p;
00549         if(p) p->AddRef();
00550         v->vt = VT_DISPATCH;
00551 }
00552 
00553 void MoveTo(IDispatch **p, VARIANT *v)
00554 {
00555         ASSERT( p != NULL );
00556         ASSERT( v != NULL );
00557 
00558         if( v->vt != VT_EMPTY )
00559                 COMTHROW( VariantClear(v) );
00560 
00561         v->pdispVal = *p;
00562         *p = NULL;
00563         v->vt = VT_DISPATCH;
00564 }
00565 
00566 void CopyTo(const VARIANT &v, unsigned char &a)
00567 {
00568         if( v.vt == VT_UI1 )
00569                 a = v.bVal;
00570         else if( v.vt == VT_EMPTY )
00571                 a = 0;
00572         else
00573         {
00574                 CComVariant w;
00575                 COMTHROW( w.ChangeType(VT_UI1, &v) );
00576                 ASSERT( w.vt == VT_UI1 );
00577                 a = w.bVal;
00578         }
00579 }
00580 
00581 void CopyTo(const VARIANT &v, short &a)
00582 {
00583         if( v.vt == VT_I2 )
00584                 a = v.iVal;
00585         else if( v.vt == VT_EMPTY )
00586                 a = 0;
00587         else
00588         {
00589                 CComVariant w;
00590                 COMTHROW( w.ChangeType(VT_I2, &v) );
00591                 ASSERT( w.vt == VT_I2 );
00592                 a = w.iVal;
00593         }
00594 }
00595 
00596 void CopyTo(const VARIANT &v, long &a)
00597 {
00598         if( v.vt == VT_I4 )
00599                 a = v.lVal;
00600         else if( v.vt == VT_EMPTY )
00601                 a = 0;
00602         else
00603         {
00604                 CComVariant w;
00605                 COMTHROW( w.ChangeType(VT_I4, &v) );
00606                 ASSERT( w.vt == VT_I4 );
00607                 a = w.lVal;
00608         }
00609 }
00610 
00611 void CopyTo(const VARIANT &v, double &a)
00612 {
00613         if( v.vt == VT_R8 )
00614                 a = v.dblVal;
00615         else if( v.vt == VT_EMPTY )
00616                 a = 0.0;
00617         else
00618         {
00619                 CComVariant w;
00620                 COMTHROW( w.ChangeType(VT_R8, &v) );
00621                 ASSERT( w.vt == VT_R8 );
00622                 a = w.dblVal;
00623         }
00624 }
00625 
00626 void CopyTo(const VARIANT &v, BSTR *a)
00627 {
00628         ASSERT( a != NULL );
00629 
00630         if( *a != NULL )
00631         {
00632                 SysFreeString(*a);
00633                 *a = NULL;
00634         }
00635 
00636         if( v.vt == VT_BSTR )
00637         {
00638                 *a = SysAllocStringLen(v.bstrVal, SysStringLen(v.bstrVal));
00639                 if (*a == NULL && v.bstrVal != NULL)
00640                         COMTHROW(E_OUTOFMEMORY);
00641         }
00642         else if( v.vt != VT_EMPTY )
00643         {
00644                 CComVariant w;
00645                 COMTHROW( w.ChangeType(VT_BSTR, &v) );
00646                 ASSERT( w.vt == VT_BSTR );
00647 
00648                 *a = w.bstrVal;
00649                 w.vt = VT_EMPTY;
00650         }
00651 }
00652 
00653 void CopyTo(const char *p, int len, VARIANT *v)
00654 {
00655         ASSERT( v != NULL );
00656 
00657         if( v->vt != VT_EMPTY )
00658                 COMTHROW( VariantClear(v) );
00659 
00660         v->bstrVal = NULL;
00661         CopyTo(p, len, &v->bstrVal);
00662         v->vt = VT_BSTR;
00663 }
00664 
00665 int GetCharLength(VARIANT &v)
00666 {
00667         if( v.vt == VT_EMPTY )
00668                 return 0;
00669         else if( v.vt == VT_DISPATCH )
00670         {
00671                 // VB passes strings as VT_DISPATCH
00672                 COMTHROW( VariantChangeType(&v, &v, 0, VT_BSTR) );
00673                 ASSERT( v.vt == VT_BSTR );
00674         }
00675 
00676         if( v.vt == VT_BSTR )
00677                 return GetCharLength(v.bstrVal);
00678 
00679         HR_THROW(E_INVALIDARG);
00680 }
00681 
00682 void CopyTo(const VARIANT &v, char *s, int charlen)
00683 {
00684         if( v.vt == VT_EMPTY )
00685         {
00686                 ASSERT( charlen == 0 );
00687                 return;
00688         }
00689         
00690         ASSERT( v.vt == VT_BSTR );
00691         CopyTo(v.bstrVal, s, charlen);
00692 }
00693 
00694 long GetArrayLength(const VARIANT &v)
00695 {
00696         if( (v.vt & VT_ARRAY) == VT_ARRAY )
00697                 return GetArrayLength(v.parray);
00698         else if( v.vt == VT_EMPTY )
00699                 return 0;
00700 
00701         HR_THROW(E_INVALIDARG);
00702 }
00703 
00704 void GetArrayStart(const VARIANT &v, CComBstrObj *&start)
00705 {
00706         if( (v.vt & VT_ARRAY) != VT_ARRAY )
00707                 HR_THROW(E_INVALIDARG);
00708 
00709         GetArrayStart(v.parray, start);
00710 }
00711 
00712 void GetArrayStart(const VARIANT &v, unsigned char *&start)
00713 {
00714         if( (v.vt & VT_ARRAY) != VT_ARRAY )
00715                 HR_THROW(E_INVALIDARG);
00716 
00717         GetArrayStart(v.parray, start);
00718 }
00719 
00720 void GetArrayStart(const VARIANT &v, long *&start)
00721 {
00722         if( (v.vt & VT_ARRAY) != VT_ARRAY )
00723                 HR_THROW(E_INVALIDARG);
00724 
00725         GetArrayStart(v.parray, start);
00726 }
00727 
00728 void CopyTo(const CComBstrObj *start, const CComBstrObj *end, VARIANT *v)
00729 {
00730         ASSERT( v != NULL );
00731 
00732         if( v->vt != VT_EMPTY )
00733                 COMTHROW( VariantClear(v) );
00734 
00735         v->parray = NULL;
00736         CopyTo(start, end, &v->parray);
00737         v->vt = VT_BSTR | VT_ARRAY;
00738 }
00739 
00740 void MoveTo(CComBstrObj *start, CComBstrObj *end, VARIANT *v)
00741 {
00742         ASSERT( v != NULL );
00743 
00744         if( v->vt != VT_EMPTY )
00745                 COMTHROW( VariantClear(v) );
00746 
00747         v->parray = NULL;
00748         MoveTo(start, end, &v->parray);
00749         v->vt = VT_BSTR | VT_ARRAY;
00750 }
00751 
00752 void CopyTo(const unsigned char *start, const unsigned char *end, VARIANT *v)
00753 {
00754         ASSERT( v != NULL );
00755 
00756         if( v->vt != VT_EMPTY )
00757                 COMTHROW( VariantClear(v) );
00758 
00759         v->parray = NULL;
00760         CopyTo(start, end, &v->parray);
00761         v->vt = VT_UI1 | VT_ARRAY;
00762 }
00763 
00764 void CopyTo(const long *start, const long *end, VARIANT *v)
00765 {
00766         ASSERT( v != NULL );
00767 
00768         if( v->vt != VT_EMPTY )
00769                 COMTHROW( VariantClear(v) );
00770 
00771         v->parray = NULL;
00772         CopyTo(start, end, &v->parray);
00773         v->vt = VT_I4 | VT_ARRAY;
00774 }
00775 
00776 void CopyTo(const VARIANT &v, CComBstrObj *start, CComBstrObj *end)
00777 {
00778         ASSERT( start <= end );
00779 
00780         if( v.vt == VT_EMPTY && start == end )
00781                 return;
00782 
00783         if( v.vt != (VT_BSTR | VT_ARRAY) )
00784                 HR_THROW(E_INVALIDARG);
00785 
00786         CopyTo(v.parray, start, end);
00787 }
00788 
00789 void MoveTo(VARIANT *v, CComBstrObj *start, CComBstrObj *end)
00790 {
00791         ASSERT( v != NULL );
00792         ASSERT( start <= end );
00793 
00794         if( v->vt == VT_EMPTY && start == end )
00795                 return;
00796 
00797         if( v->vt != (VT_BSTR | VT_ARRAY) )
00798                 HR_THROW(E_INVALIDARG);
00799 
00800         MoveTo(v->parray, start, end);
00801         COMTHROW( VariantClear(v) );
00802 }
00803 
00804 void CopyTo(const VARIANT &v, unsigned char *start, unsigned char *end)
00805 {
00806         ASSERT( start <= end );
00807 
00808         if( v.vt == VT_EMPTY && start == end )
00809                 return;
00810 
00811         if( v.vt != (VT_UI1 | VT_ARRAY) )
00812                 HR_THROW(E_INVALIDARG);
00813 
00814         CopyTo(v.parray, start, end);
00815 }
00816 
00817 void CopyTo(const VARIANT &v, long *start, long *end)
00818 {
00819         ASSERT( start <= end );
00820 
00821         if( v.vt == VT_EMPTY && start == end )
00822                 return;
00823 
00824         if( v.vt != (VT_I4 | VT_ARRAY) )
00825                 HR_THROW(E_INVALIDARG);
00826 
00827         CopyTo(v.parray, start, end);
00828 }
00829 
00830 void CopyTo(const VARIANT &v, GUID &guid)
00831 {
00832         if( v.vt != (VT_UI1 | VT_ARRAY) || GetArrayLength(v) != sizeof(GUID) )
00833                 HR_THROW(E_CONVERSION);
00834         
00835         CopyTo(v, (unsigned char*)&guid, (unsigned char*)(&guid+1));
00836 }
00837 
00838 // --------------------------- COM Helper functions
00839 
00840 bool IsEqualObject(IUnknown *p, IUnknown *q)
00841 {
00842         if( p == q )
00843                 return true;
00844         else if( p == NULL || q == NULL )
00845                 return false;
00846 
00847         CComObjPtr<IUnknown> a;
00848         CComObjPtr<IUnknown> b;
00849         COMTHROW( p->QueryInterface(IID_IUnknown, (void**)PutOut(a)) );
00850         COMTHROW( q->QueryInterface(IID_IUnknown, (void**)PutOut(b)) );
00851 
00852         return a == b;
00853 }
00854