dn_common.c
Go to the documentation of this file.
00001 
00025 #include "stdint.h"
00026 #include <stdlib.h>
00027 #include <string.h>
00028 
00029 #if defined(_USE_WIN_API)
00030 #include <windows.h>
00031 #elif defined(_USE_LINUX_API)
00032 #include <float.h>
00033 #include <limits.h>
00034 #include <locale.h>
00035 #include <errno.h>
00036 #ifndef _wcsicmp
00037 #define _wcsicmp wcscasecmp
00038 #endif
00039 #ifndef __USE_XOPEN
00040 #define __USE_XOPEN
00041 #endif
00042 #endif
00043 
00044 #include "dn_common.h"
00045 
00050 #define _LEN_VARIANT2BSTR (500)
00051 
00052 #ifndef _OLEAUTO_H_
00053 
00060 BSTR
00061 SysAllocString(const wchar_t *sz)
00062 {
00063   if (sz == NULL)
00064     return NULL;
00065 
00066   return SysAllocStringLen(sz, wcslen(sz));
00067 }
00068 
00076 BSTR
00077 SysAllocStringLen(const wchar_t *pch, uint16_t cch)
00078 {
00079   uint16_t minlen;
00080   BSTR bstr = NULL;
00081 
00082   minlen = sizeof(wchar_t) * (cch + 1);
00083   bstr = (BSTR) malloc(minlen);
00084 
00085   if (bstr != NULL) {
00086     memset(bstr, 0, minlen);
00087 
00088     if (pch != NULL) {
00089       minlen = wcslen(pch);
00090       minlen = (cch < minlen ? cch : minlen);
00091       memcpy(bstr, pch, sizeof(wchar_t) * minlen);
00092     }
00093   }
00094 
00095   return bstr;
00096 }
00097 
00103 void
00104 SysFreeString(BSTR bstr)
00105 {
00106   if (bstr != NULL) {
00107     free(bstr);
00108     bstr = NULL;
00109   }
00110 }
00111 
00117 uint16_t
00118 SysStringLen(BSTR bstr)
00119 {
00120   uint16_t len = 0;
00121 
00122   if (bstr != NULL) {
00123     len = wcslen(bstr);
00124   }
00125 
00126   return len;
00127 }
00128 
00137 SAFEARRAY*
00138 SafeArrayCreateVector(uint16_t vt, int32_t lLbound, uint32_t cElements)
00139 {
00140   int sz;
00141   SAFEARRAY* psa = NULL;
00142 
00143   psa = (SAFEARRAY*) malloc(sizeof(SAFEARRAY));
00144 
00145   if (psa != NULL) {
00146     memset(psa, 0, sizeof(SAFEARRAY));
00147 
00148     psa->cDims = 1;
00149     psa->vt = vt;
00150     psa->rgsabound[0].lLbound = lLbound;
00151     psa->rgsabound[0].cElements = cElements;
00152 
00153     if (cElements > 0) {
00154       switch (vt) {
00155         case VT_UI1:
00156           sz = 1;
00157           break;
00158         case VT_I2:
00159         case VT_UI2:
00160         case VT_BOOL:
00161           sz = 2;
00162           break;
00163         case VT_I4:
00164         case VT_UI4:
00165         case VT_R4:
00166           sz = 4;
00167           break;
00168         case VT_I8:
00169         case VT_UI8:
00170         case VT_R8:
00171         case VT_CY:
00172           sz = 8;
00173           break;
00174         case VT_DATE:
00175           sz = sizeof(DATE);
00176           break;
00177         case VT_BSTR:
00178           sz = sizeof(BSTR);
00179           break;
00180         case VT_VARIANT:
00181           sz = sizeof(VARIANT);
00182           break;
00183         default:
00184           free(psa);
00185           psa = NULL;
00186           goto exit_proc;
00187       }
00188 
00189       psa->cbElements = sz;
00190       psa->pvData = malloc(cElements * sz);
00191 
00192       if (psa->pvData == NULL) {
00193         free(psa);
00194         psa = NULL;
00195         goto exit_proc;
00196       }
00197 
00198       memset(psa->pvData, 0, cElements * sz);
00199     }
00200   }
00201 
00202 exit_proc:
00203   return psa;
00204 }
00205 
00211 HRESULT
00212 SafeArrayDestroy(SAFEARRAY *psa)
00213 {
00214   int32_t i;
00215 
00216   if (psa != NULL) {
00217     if (psa->pvData != NULL) {
00218       switch (psa->vt) {
00219         case VT_BSTR:
00220           for (i = 0; i < psa->rgsabound[0].cElements; i++) {
00221             SysFreeString(*((BSTR*) psa->pvData + i));
00222           }
00223           break;
00224         case VT_VARIANT:
00225           for (i = 0; i < psa->rgsabound[0].cElements; i++) {
00226             VariantClear(((VARIANT*) psa->pvData + i));
00227           }
00228           break;
00229         default:
00230           free(psa->pvData);
00231           break;
00232       }
00233       psa->pvData = NULL;
00234     }
00235     free(psa);
00236     psa = NULL;
00237   }
00238 
00239   return S_OK;
00240 }
00241 
00247 uint16_t
00248 SafeArrayGetDim(SAFEARRAY *psa)
00249 {
00250   if (psa == NULL)
00251     return 0;
00252 
00253   return psa->cDims;
00254 }
00255 
00261 uint32_t
00262 SafeArrayGetElemsize(SAFEARRAY *psa)
00263 {
00264   if (psa == NULL)
00265     return 0;
00266 
00267   return psa->cbElements;
00268 }
00269 
00277 HRESULT
00278 SafeArrayGetLBound(SAFEARRAY *psa, uint16_t nDim, int32_t *plLbound)
00279 {
00280   if (psa == NULL || plLbound == NULL)
00281     return E_INVALIDARG;
00282   if (nDim <= 0 || psa->cDims < nDim)
00283     return DISP_E_BADINDEX;
00284 
00285   *plLbound = psa->rgsabound[nDim - 1].lLbound;
00286 
00287   return S_OK;
00288 }
00289 
00297 HRESULT
00298 SafeArrayGetUBound(SAFEARRAY *psa, uint16_t nDim, int32_t *plUbound)
00299 {
00300   if (psa == NULL || plUbound == NULL)
00301     return E_INVALIDARG;
00302   if (nDim <= 0 || psa->cDims < nDim)
00303     return DISP_E_BADINDEX;
00304 
00305   *plUbound = (psa->rgsabound[nDim - 1].cElements
00306       + psa->rgsabound[nDim - 1].lLbound - 1);
00307 
00308   return S_OK;
00309 }
00310 
00317 HRESULT
00318 SafeArrayGetVartype(SAFEARRAY *psa, uint16_t *pvt)
00319 {
00320   if (psa == NULL || pvt == NULL)
00321     return E_INVALIDARG;
00322 
00323   *pvt = psa->vt;
00324 
00325   return S_OK;
00326 }
00327 
00335 HRESULT
00336 SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
00337 {
00338   if (psa == NULL || ppvData == NULL)
00339     return E_INVALIDARG;
00340 
00341   *ppvData = psa->pvData;
00342 
00343   return S_OK;
00344 }
00345 
00352 HRESULT
00353 SafeArrayUnaccessData(SAFEARRAY *psa)
00354 {
00355   if (psa == NULL)
00356     return E_INVALIDARG;
00357 
00358   return S_OK;
00359 }
00360 
00367 void
00368 VariantInit(VARIANT *pvarg)
00369 {
00370   if (pvarg != NULL) {
00371     memset(pvarg, 0, sizeof(VARIANT));
00372   }
00373 }
00374 
00381 void
00382 VariantClear(VARIANT *pvarg)
00383 {
00384   if (pvarg != NULL) {
00385     if (pvarg->vt & VT_ARRAY) {
00386       if (pvarg->parray != NULL) {
00387         SafeArrayDestroy(pvarg->parray);
00388         pvarg->parray = NULL;
00389       }
00390     }
00391     else if (pvarg->vt == VT_BSTR) {
00392       if (pvarg->bstrVal != NULL) {
00393         SysFreeString(pvarg->bstrVal);
00394         pvarg->bstrVal = NULL;
00395       }
00396     }
00397     memset(pvarg, 0, sizeof(VARIANT));
00398   }
00399 }
00400 
00401 #if (_DN_USE_VARIANT_API)
00402 
00408 HRESULT
00409 VariantCopy(VARIANT *pvargDest, const VARIANT *pvargSrc)
00410 {
00411   if ((pvargDest == NULL) || (pvargSrc == NULL)) {
00412     return E_INVALIDARG;
00413   }
00414 
00415   if (pvargDest == pvargSrc) {
00416     return S_OK;
00417   }
00418 
00419   VariantClear(pvargDest);
00420 
00421   if (pvargSrc->vt & VT_ARRAY) {
00422     int32_t i, lLbound = 0;
00423     uint32_t cbElements = 0, cElements;
00424 
00425     lLbound = pvargSrc->parray->rgsabound[0].lLbound;
00426     cElements = pvargSrc->parray->rgsabound[0].cElements;
00427     cbElements = pvargSrc->parray->cbElements;
00428 
00429     switch (pvargSrc->vt ^ VT_ARRAY) {
00430       case VT_I2:
00431       case VT_I4:
00432       case VT_I8:
00433       case VT_R4:
00434       case VT_R8:
00435       case VT_CY:
00436       case VT_DATE:
00437       case VT_BOOL:
00438       case VT_UI1:
00439       case VT_UI2:
00440       case VT_UI4:
00441       case VT_UI8:
00442         pvargDest->vt = pvargSrc->vt;
00443         pvargDest->parray = SafeArrayCreateVector(pvargSrc->vt ^ VT_ARRAY,
00444             lLbound, cElements);
00445         memcpy(pvargDest->parray->pvData, pvargSrc->parray->pvData,
00446             cbElements * cElements);
00447         break;
00448       case VT_BSTR:
00449         pvargDest->vt = pvargSrc->vt;
00450         pvargDest->parray = SafeArrayCreateVector(VT_BSTR, lLbound, cElements);
00451         for (i = 0; i < cElements; i++) {
00452           *((BSTR*) pvargDest->parray->pvData + i) = SysAllocString(
00453               *((BSTR*) pvargSrc->parray->pvData + i));
00454         }
00455         break;
00456       case VT_VARIANT:
00457         pvargDest->vt = pvargSrc->vt;
00458         pvargDest->parray = SafeArrayCreateVector(VT_VARIANT, lLbound,
00459             cElements);
00460         for (i = 0; i < cElements; i++) {
00461           VariantCopy(((VARIANT*) pvargDest->parray->pvData + i),
00462               ((VARIANT*) pvargSrc->parray->pvData + i));
00463         }
00464         break;
00465       default:
00466         return DISP_E_BADVARTYPE;
00467     }
00468   } else {
00469     switch (pvargSrc->vt) {
00470       case VT_EMPTY:
00471       case VT_NULL:
00472       case VT_I2:
00473       case VT_I4:
00474       case VT_I8:
00475       case VT_R4:
00476       case VT_R8:
00477       case VT_CY:
00478       case VT_DATE:
00479       case VT_ERROR:
00480       case VT_BOOL:
00481       case VT_UI1:
00482       case VT_UI2:
00483       case VT_UI4:
00484       case VT_UI8:
00485         memcpy(pvargDest, pvargSrc, sizeof(VARIANT));
00486         break;
00487       case VT_BSTR:
00488         pvargDest->vt = VT_BSTR;
00489         pvargDest->bstrVal = SysAllocString(pvargSrc->bstrVal);
00490         break;
00491       default:
00492         return DISP_E_BADVARTYPE;
00493     }
00494   }
00495 
00496   return S_OK;
00497 }
00498 
00505 static HRESULT
00506 Variant2Bstr(BSTR *pbstr, VARIANT *pvarg)
00507 {
00508   HRESULT hr = S_OK;
00509   char chStr[_LEN_VARIANT2BSTR];
00510   wchar_t wchStr[_LEN_VARIANT2BSTR];
00511   struct tm *tmVal;
00512 
00513   switch (pvarg->vt) {
00514     case VT_I2:
00515       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%d", pvarg->iVal);
00516       break;
00517     case VT_I4:
00518       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%ld", pvarg->lVal);
00519       break;
00520     case VT_I8:
00521       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%lld", pvarg->llVal);
00522       break;
00523     case VT_R4:
00524       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%.7G", pvarg->fltVal);
00525       break;
00526     case VT_R8:
00527       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%.15G", pvarg->dblVal);
00528       break;
00529     case VT_CY:
00530       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%lld", pvarg->cyVal.int64);
00531       break;
00532     case VT_DATE:
00533       tmVal = gmtime(&pvarg->date);
00534       strftime(chStr, _LEN_VARIANT2BSTR, FORMAT_DATE2BSTR, tmVal);
00535       mbstowcs(wchStr, chStr, _LEN_VARIANT2BSTR);
00536       break;
00537     case VT_BOOL:
00538       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%d", pvarg->boolVal);
00539       break;
00540     case VT_UI1:
00541       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%u", pvarg->bVal);
00542       break;
00543     case VT_UI2:
00544       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%u", pvarg->uiVal);
00545       break;
00546     case VT_UI4:
00547       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%lu", pvarg->ulVal);
00548       break;
00549     case VT_UI8:
00550       swprintf(wchStr, _LEN_VARIANT2BSTR, L"%llu", pvarg->ullVal);
00551       break;
00552     default:
00553       hr = DISP_E_BADVARTYPE;
00554       break;
00555   }
00556 
00557   if(SUCCEEDED(hr)) {
00558     *pbstr = SysAllocString(wchStr);
00559   }
00560 
00561   return hr;
00562 }
00563 
00570 static HRESULT
00571 Bstr2Variant(VARIANT *pvarg, int16_t vt, BSTR bstr)
00572 {
00573   HRESULT hr = S_OK;
00574   int flag = 0, len;
00575   char *chRet, *chStr = NULL;
00576   wchar_t *wchRet;
00577   struct tm tmVal;
00578   VARIANT vntTmp;
00579 
00580   if(*bstr == L'\0') {
00581     return DISP_E_TYPEMISMATCH;
00582   }
00583 
00584   VariantInit(&vntTmp);
00585 
00586   if (pvarg->bstrVal == bstr) {
00587     flag = 1;
00588   }
00589 
00590   switch (vt) {
00591     case VT_EMPTY:
00592     case VT_NULL:
00593       break;
00594     case VT_ERROR:
00595       hr = DISP_E_TYPEMISMATCH;
00596       break;
00597     case VT_I2:
00598     case VT_I4:
00599     case VT_BOOL:
00600       errno = 0;
00601       vntTmp.lVal = (int32_t) wcstol(bstr, &wchRet, 0);
00602       if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
00603         hr = DISP_E_TYPEMISMATCH;
00604       }
00605       else if (errno == ERANGE) {
00606         hr = DISP_E_OVERFLOW;
00607       }
00608       else if ((vt == VT_I2) || (vt == VT_BOOL)) {
00609         vntTmp.vt = VT_I4;
00610         hr = VariantChangeType(&vntTmp, &vntTmp, 0, vt);
00611       }
00612       break;
00613     case VT_I8:
00614       errno = 0;
00615       vntTmp.llVal = (int64_t) wcstoll(bstr, &wchRet, 0);
00616       if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
00617         hr = DISP_E_TYPEMISMATCH;
00618       }
00619       else if (errno == ERANGE) {
00620         hr = DISP_E_OVERFLOW;
00621       }
00622       break;
00623     case VT_R4:
00624       errno = 0;
00625       vntTmp.fltVal = wcstof(bstr, &wchRet);
00626       if ((wchRet == NULL) || (*wchRet != L'\0')) {
00627         hr = DISP_E_TYPEMISMATCH;
00628       }
00629       else if (errno == ERANGE) {
00630         hr = DISP_E_OVERFLOW;
00631       }
00632       break;
00633     case VT_R8:
00634       errno = 0;
00635       vntTmp.dblVal = wcstod(bstr, &wchRet);
00636       if ((wchRet == NULL) || (*wchRet != L'\0')) {
00637         hr = DISP_E_TYPEMISMATCH;
00638       }
00639       else if (errno == ERANGE) {
00640         hr = DISP_E_OVERFLOW;
00641       }
00642       break;
00643     case VT_CY:
00644       errno = 0;
00645       vntTmp.cyVal.int64 = (int64_t) wcstoll(bstr, &wchRet, 0);
00646       if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
00647         hr = DISP_E_TYPEMISMATCH;
00648       }
00649       else if (errno == ERANGE) {
00650         hr = DISP_E_OVERFLOW;
00651       }
00652       break;
00653     case VT_UI1:
00654     case VT_UI2:
00655     case VT_UI4:
00656       errno = 0;
00657       vntTmp.ulVal = (uint32_t) wcstoul(bstr, &wchRet, 0);
00658       if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
00659         hr = DISP_E_TYPEMISMATCH;
00660       }
00661       else if (errno == ERANGE) {
00662         hr = DISP_E_OVERFLOW;
00663       }
00664       else if ((vt == VT_UI1) || (vt == VT_UI2)) {
00665         vntTmp.vt = VT_UI4;
00666         hr = VariantChangeType(&vntTmp, &vntTmp, 0, vt);
00667       }
00668       else if (*bstr == L'-') {
00669         hr = DISP_E_OVERFLOW;
00670       }
00671       break;
00672     case VT_UI8:
00673       errno = 0;
00674       vntTmp.ullVal = (uint64_t) wcstoull(bstr, &wchRet, 0);
00675       if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
00676         hr = DISP_E_TYPEMISMATCH;
00677       }
00678       else if (errno == ERANGE) {
00679         hr = DISP_E_OVERFLOW;
00680       }
00681       else if (*bstr == L'-') {
00682         hr = DISP_E_OVERFLOW;
00683       }
00684       break;
00685     case VT_DATE:
00686       len = wcstombs(NULL, bstr, 0) + 1;
00687       if(len <= 0) {
00688         hr = DISP_E_TYPEMISMATCH;
00689         break;
00690       }
00691 
00692       chStr = (char *) malloc(len);
00693       if(chStr == NULL) {
00694         hr = E_OUTOFMEMORY;
00695         break;
00696       }
00697 
00698       wcstombs(chStr, bstr, len);
00699       memset(&tmVal, 0, sizeof(struct tm));
00700       chRet = strptime(chStr, FORMAT_DATE2BSTR, &tmVal);
00701       if ((chRet == NULL) || (*chRet != '\0')) {
00702         hr = DISP_E_TYPEMISMATCH;
00703       } else {
00704         vntTmp.date = mktime(&tmVal);
00705       }
00706       free(chStr);
00707       break;
00708     default:
00709       hr = DISP_E_BADVARTYPE;
00710       break;
00711   }
00712   errno = 0;
00713 
00714   if (SUCCEEDED(hr)) {
00715     *pvarg = vntTmp;
00716     if (flag) {
00717       SysFreeString(bstr);
00718     }
00719   }
00720 
00721   VariantClear(&vntTmp);
00722 
00723   return hr;
00724 }
00725 
00735 HRESULT
00736 VariantChangeType(VARIANT *pvargDest, VARIANT *pvarSrc, uint16_t wFlags,
00737     uint16_t vt)
00738 {
00739   HRESULT hr = S_OK;
00740 
00741   if ((pvargDest == NULL) || (pvarSrc == NULL)) {
00742     return E_INVALIDARG;
00743   }
00744 
00745   if (pvargDest != pvarSrc) {
00746     VariantClear(pvargDest);
00747     if (vt == pvarSrc->vt) {
00748       return VariantCopy(pvargDest, pvarSrc);
00749     }
00750   } else {
00751     if (vt == pvarSrc->vt) {
00752       return S_OK;
00753     }
00754   }
00755 
00756 #define CheckOverflow(typeDst, typeSrc) \
00757   ((sizeof(typeDst) < sizeof(typeSrc)) \
00758       || (pvarSrc->vt == VT_R4) \
00759       || (pvarSrc->vt == VT_R8))
00760 
00761 #define IsUnsigned \
00762   ((pvarSrc->vt == VT_UI1) \
00763       || (pvarSrc->vt == VT_UI2) \
00764       || (pvarSrc->vt == VT_UI4) \
00765       || (pvarSrc->vt == VT_UI8))
00766 
00767 #define SubChangeType(type, val, chk) \
00768   switch (vt) { \
00769     case VT_EMPTY: \
00770     case VT_NULL: \
00771       memset(pvargDest, 0, sizeof(VARIANT)); \
00772       break; \
00773     case VT_ERROR: \
00774       return DISP_E_TYPEMISMATCH; \
00775       break; \
00776     case VT_I2: \
00777       if(chk) { if(CheckOverflow(int16_t, type) \
00778           && ((!IsUnsigned && ((val) < (type)SHRT_MIN)) \
00779               || ((type)SHRT_MAX < (val)))) { \
00780         return DISP_E_OVERFLOW; \
00781       } } \
00782       pvargDest->iVal = (int16_t)(val); \
00783       break; \
00784     case VT_I4: \
00785       if(chk) { if(CheckOverflow(int32_t, type) \
00786           && ((!IsUnsigned && ((val) < (type)LONG_MIN)) \
00787               || ((type)LONG_MAX < (val)))) { \
00788         return DISP_E_OVERFLOW; \
00789       } } \
00790       pvargDest->lVal = (int32_t)(val); \
00791       break; \
00792     case VT_I8: \
00793       if(chk) { if(CheckOverflow(int64_t, type) \
00794           && ((!IsUnsigned && ((val) < (type)LLONG_MIN)) \
00795               || ((type)LLONG_MAX < (val)))) { \
00796         return DISP_E_OVERFLOW; \
00797       } } \
00798       pvargDest->llVal = (int64_t)(val); \
00799       break; \
00800     case VT_R4: \
00801       if(chk) { if((pvarSrc->vt == VT_R8) \
00802           && (((val) < (double)-FLT_MAX) \
00803               || ((double)FLT_MAX < (val)))) { \
00804         return DISP_E_OVERFLOW; \
00805       } } \
00806       pvargDest->fltVal = (float)(val); \
00807       break; \
00808     case VT_R8: \
00809       pvargDest->dblVal = (double)(val); \
00810       break; \
00811     case VT_CY: \
00812       if(chk) { if(CheckOverflow(int64_t, type) \
00813           && ((!IsUnsigned && ((val) < (type)LLONG_MIN)) \
00814               || ((type)LLONG_MAX < (val)))) { \
00815         return DISP_E_OVERFLOW; \
00816       } } \
00817       pvargDest->cyVal.int64 = (int64_t)(val); \
00818       break; \
00819     case VT_DATE: \
00820       pvargDest->date = (DATE)(val); \
00821       break; \
00822     case VT_BSTR: \
00823       hr = Variant2Bstr(&pvargDest->bstrVal, pvarSrc); \
00824       break;\
00825     case VT_BOOL: \
00826       pvargDest->boolVal = ((val) ? VARIANT_TRUE : VARIANT_FALSE); \
00827       break; \
00828     case VT_UI1: \
00829       if(chk) { if(((val) < (type)0) || \
00830           (CheckOverflow(uint8_t, type) && ((type)USHRT_MAX < (val)))) { \
00831         return DISP_E_OVERFLOW; \
00832       } } \
00833       pvargDest->bVal = (uint8_t)(val); \
00834       break; \
00835     case VT_UI2: \
00836       if(chk) { if(((pvarSrc->vt != VT_I2) && ((val) < (type)0)) || \
00837           (CheckOverflow(uint16_t, type) && ((type)USHRT_MAX < (val)))) { \
00838         return DISP_E_OVERFLOW; \
00839       } } \
00840       pvargDest->uiVal = (uint16_t)(val); \
00841       break; \
00842     case VT_UI4: \
00843       if(chk) { if(((pvarSrc->vt != VT_I4) && ((val) < (type)0)) || \
00844           (CheckOverflow(uint32_t, type) && ((type)ULONG_MAX < (val)))) { \
00845         return DISP_E_OVERFLOW; \
00846       } } \
00847       pvargDest->ulVal = (uint32_t)(val); \
00848       break; \
00849     case VT_UI8: \
00850       if(chk) { if(((pvarSrc->vt != VT_I8) && ((val) < (type)0)) || \
00851           (CheckOverflow(uint64_t, type) && ((type)ULLONG_MAX < (val)))) { \
00852         return DISP_E_OVERFLOW; \
00853       } } \
00854       pvargDest->ullVal = (uint64_t)(val); \
00855       break; \
00856     default: \
00857       return DISP_E_BADVARTYPE; \
00858   }
00859 
00860   switch (pvarSrc->vt) {
00861     case VT_EMPTY:
00862       switch (vt) {
00863         case VT_BSTR:
00864           pvargDest->bstrVal = SysAllocString(L"");
00865           break;
00866         case VT_ERROR:
00867           return DISP_E_TYPEMISMATCH;
00868         default:
00869           memset(pvargDest, 0, sizeof(VARIANT));
00870           break;
00871       }
00872       break;
00873     case VT_NULL:
00874     case VT_ERROR:
00875       return DISP_E_TYPEMISMATCH;
00876     case VT_I2:
00877       SubChangeType(int16_t, pvarSrc->iVal, 1);
00878       break;
00879     case VT_I4:
00880       SubChangeType(int32_t, pvarSrc->lVal, 1);
00881       break;
00882     case VT_I8:
00883       SubChangeType(int64_t, pvarSrc->llVal, 1);
00884       break;
00885     case VT_R4:
00886       SubChangeType(float, pvarSrc->fltVal, 1);
00887       break;
00888     case VT_R8:
00889       SubChangeType(double, pvarSrc->dblVal, 1);
00890       break;
00891     case VT_CY:
00892       SubChangeType(int64_t, pvarSrc->cyVal.int64, 1);
00893       break;
00894     case VT_DATE:
00895       SubChangeType(DATE, pvarSrc->date, 1);
00896       break;
00897     case VT_BSTR:
00898       hr = Bstr2Variant(pvargDest, vt, pvarSrc->bstrVal);
00899       break;
00900     case VT_BOOL:
00901       SubChangeType(VARIANT_BOOL, pvarSrc->boolVal, 0);
00902       break;
00903     case VT_UI1:
00904       SubChangeType(uint8_t, pvarSrc->bVal, 1);
00905       break;
00906     case VT_UI2:
00907       SubChangeType(uint16_t, pvarSrc->uiVal, 1);
00908       break;
00909     case VT_UI4:
00910       SubChangeType(uint32_t, pvarSrc->ulVal, 1);
00911       break;
00912     case VT_UI8:
00913       SubChangeType(uint64_t, pvarSrc->ullVal, 1);
00914       break;
00915     default:
00916       return DISP_E_BADVARTYPE;
00917   }
00918 
00919   if (SUCCEEDED(hr)) {
00920     pvargDest->vt = vt;
00921   }
00922 
00923   return hr;
00924 }
00925 #endif /* _DN_USE_VARIANT_API */
00926 #endif /* _OLEAUTO_H_ */
00927 
00928 #if (_DN_USE_VARIANT_API)
00929 
00937 uint32_t
00938 ChangeVarType(VARIANT varSrc, uint16_t vt, void *pDest, uint32_t dwSize)
00939 {
00940   HRESULT hr = S_OK;
00941   uint32_t dwRet, dwCnt = 0;
00942   VARIANT vntTmp;
00943 
00944   if ((pDest == NULL) || (dwSize == 0)) {
00945     return 0;
00946   }
00947 
00948   VariantInit(&vntTmp);
00949 
00950   if (varSrc.vt & VT_ARRAY) {
00951     int32_t i, lMax =
00952         (int32_t) varSrc.parray->rgsabound[0].cElements;
00953     void *pVal, *pPos = pDest;
00954 
00955     SafeArrayAccessData(varSrc.parray, &pVal);
00956     for (i = 0; i < lMax; i++) {
00957       VariantClear(&vntTmp);
00958       switch (varSrc.vt ^ VT_ARRAY) {
00959         case VT_I2:
00960           vntTmp.vt = VT_I2;
00961           vntTmp.iVal = *((int16_t *) pVal + i);
00962           break;
00963         case VT_I4:
00964           vntTmp.vt = VT_I4;
00965           vntTmp.lVal = *((int32_t *) pVal + i);
00966           break;
00967         case VT_I8:
00968           vntTmp.vt = VT_I8;
00969           vntTmp.llVal = *((int64_t *) pVal + i);
00970           break;
00971         case VT_R4:
00972           vntTmp.vt = VT_R4;
00973           vntTmp.fltVal = *((float *) pVal + i);
00974           break;
00975         case VT_R8:
00976           vntTmp.vt = VT_R8;
00977           vntTmp.dblVal = *((double *) pVal + i);
00978           break;
00979         case VT_CY:
00980           vntTmp.vt = VT_CY;
00981           vntTmp.cyVal = *((CY *) pVal + i);
00982           break;
00983         case VT_DATE:
00984           vntTmp.vt = VT_DATE;
00985           vntTmp.date = *((DATE *) pVal + i);
00986           break;
00987         case VT_BSTR:
00988           vntTmp.vt = VT_BSTR;
00989           vntTmp.bstrVal = SysAllocString(*((BSTR *) pVal + i));
00990           break;
00991         case VT_BOOL:
00992           vntTmp.vt = VT_BOOL;
00993           vntTmp.boolVal = *((VARIANT_BOOL *) pVal + i);
00994           break;
00995         case VT_VARIANT:
00996           VariantCopy(&vntTmp, (VARIANT *) pVal + i);
00997           break;
00998         case VT_UI1:
00999           vntTmp.vt = VT_UI1;
01000           vntTmp.bVal = *((uint8_t *) pVal + i);
01001           break;
01002         case VT_UI2:
01003           vntTmp.vt = VT_UI2;
01004           vntTmp.uiVal = *((uint16_t *) pVal + i);
01005           break;
01006         case VT_UI4:
01007           vntTmp.vt = VT_UI4;
01008           vntTmp.ulVal = *((uint32_t *) pVal + i);
01009           break;
01010         case VT_UI8:
01011           vntTmp.vt = VT_UI8;
01012           vntTmp.ullVal = *((uint64_t *) pVal + i);
01013           break;
01014         default:
01015           hr = E_INVALIDARG;
01016           break;
01017       }
01018 
01019       if (FAILED(hr)) {
01020         break;
01021       }
01022 
01023       if (vt != VT_VARIANT) {
01024         if (vntTmp.vt & VT_ARRAY) {
01025           break;
01026         }
01027 
01028         dwRet = ChangeVarType(vntTmp, vt, pPos, 1);
01029         if (dwRet == 0) {
01030           break;
01031         }
01032       } else {
01033         hr = VariantCopy((VARIANT*) pPos, &vntTmp);
01034         if (FAILED(hr)) {
01035           break;
01036         }
01037         dwRet = 1;
01038       }
01039 
01040       dwCnt += dwRet;
01041       pPos = ((char *) pPos + varSrc.parray->cbElements);
01042 
01043       if (dwCnt >= dwSize) {
01044         break;
01045       }
01046     }
01047     SafeArrayUnaccessData(varSrc.parray);
01048   } else {
01049     VariantCopy(&vntTmp, &varSrc);
01050     if (vt != VT_VARIANT) {
01051       hr = VariantChangeType(&vntTmp, &vntTmp, 0, vt);
01052       if (FAILED(hr)) {
01053         dwCnt = 0;
01054         goto exit_proc;
01055       }
01056     }
01057 
01058     dwCnt = 1;
01059     switch (vt) {
01060       case VT_I2:
01061         *(int16_t *) pDest = vntTmp.iVal;
01062         break;
01063       case VT_I4:
01064         *(int32_t *) pDest = vntTmp.lVal;
01065         break;
01066       case VT_I8:
01067         *(int64_t *) pDest = vntTmp.llVal;
01068         break;
01069       case VT_R4:
01070         *(float *) pDest = vntTmp.fltVal;
01071         break;
01072       case VT_R8:
01073         *(double *) pDest = vntTmp.dblVal;
01074         break;
01075       case VT_CY:
01076         *(CY *) pDest = vntTmp.cyVal;
01077         break;
01078       case VT_DATE:
01079         *(DATE *) pDest = vntTmp.date;
01080         break;
01081       case VT_BSTR:
01082         *(BSTR *) pDest = SysAllocString(vntTmp.bstrVal);
01083         break;
01084       case VT_BOOL:
01085         *(VARIANT_BOOL *) pDest = vntTmp.boolVal ? VARIANT_TRUE : VARIANT_FALSE;
01086         break;
01087       case VT_VARIANT:
01088         VariantCopy((VARIANT *) pDest, &vntTmp);
01089         break;
01090       case VT_UI1:
01091         *(uint8_t *) pDest = vntTmp.bVal;
01092         break;
01093       case VT_UI2:
01094         *(uint16_t *) pDest = vntTmp.uiVal;
01095         break;
01096       case VT_UI4:
01097         *(uint32_t *) pDest = vntTmp.ulVal;
01098         break;
01099       case VT_UI8:
01100         *(uint64_t *) pDest = vntTmp.ullVal;
01101         break;
01102       default:
01103         dwCnt = 0;
01104         break;
01105     }
01106   }
01107 
01108 exit_proc:
01109   VariantClear(&vntTmp);
01110 
01111   return dwCnt;
01112 }
01113 
01122 HRESULT
01123 GetOptionValue(BSTR bstrSrc, BSTR bstrKey, uint16_t vt, VARIANT *pvarDest)
01124 {
01125   HRESULT hr = S_OK;
01126   int iLevelCount = 0, bGetTitle = 0;
01127   long lTitleTerm;
01128   uint16_t i, uiLenTarget = 0, uiLenOptTitle = 0, uiLenOneOpt = 0;
01129   wchar_t *wchTmp, *wchPos, wchStart = -1, wchEnd = -1;
01130   BSTR bstrTmp, bstrTarget, bstrOptTitle, bstrOneOpt;
01131   VARIANT vntTmp;
01132 
01133   if ((bstrKey == NULL) || (pvarDest == NULL)) {
01134     return E_INVALIDARG;
01135   }
01136 
01137   if (bstrSrc != NULL) {
01138     bstrTarget = SysAllocString(bstrSrc);
01139   } else {
01140     bstrTarget = SysAllocString(L"");
01141   }
01142 
01143   bstrOptTitle = SysAllocString(L"");
01144   bstrOneOpt = SysAllocString(L"");
01145 
01146   uiLenTarget = SysStringLen(bstrTarget);
01147   wchTmp = bstrTarget;
01148 
01149   for (i = 0; i <= uiLenTarget; i++, wchTmp++) {
01150     /* Sets the beginning and ending character for nest */
01151     if (!iLevelCount) {
01152       switch (*wchTmp) {
01153         case L'(':
01154         case L')':
01155           wchStart = L'(';
01156           wchEnd = L')';
01157           break;
01158         case L'[':
01159         case L']':
01160           wchStart = L'[';
01161           wchEnd = L']';
01162           break;
01163         case L'{':
01164         case L'}':
01165           wchStart = L'{';
01166           wchEnd = L'}';
01167           break;
01168         case L'<':
01169         case L'>':
01170           wchStart = L'<';
01171           wchEnd = L'>';
01172           break;
01173         default:
01174           break;
01175       }
01176     }
01177 
01178     /* Sets the nest level */
01179     if (*wchTmp == wchStart) {
01180       iLevelCount++;
01181       if (iLevelCount == 1) {
01182         memcpy(wchTmp, wchTmp + 1, sizeof(wchar_t) * (uiLenTarget - i));
01183         uiLenTarget--;
01184         i--;
01185         wchTmp--;
01186         continue;
01187       }
01188     }
01189     else if (*wchTmp == wchEnd) {
01190       iLevelCount--;
01191 
01192       if (iLevelCount < 0) {
01193         hr = E_FAIL;
01194         goto exit_proc;
01195       }
01196 
01197       if (!iLevelCount) {
01198         memcpy(wchTmp, wchTmp + 1, sizeof(wchar_t) * (uiLenTarget - i));
01199         uiLenTarget--;
01200         i--;
01201         wchTmp--;
01202         continue;
01203       }
01204     }
01205 
01206     /* Gets the option name */
01207     if (!iLevelCount) {
01208       if (*wchTmp == L'=') {
01209         if (bGetTitle) {
01210           hr = E_FAIL;
01211           goto exit_proc;
01212         }
01213 
01214         if (uiLenOptTitle > 0) {
01215           SysFreeString(bstrOptTitle);
01216           bstrOptTitle = SysAllocStringLen(wchTmp - uiLenOptTitle,
01217               uiLenOptTitle);
01218           uiLenOptTitle = 0;
01219         }
01220 
01221         bGetTitle = 1;
01222         continue;
01223       }
01224 
01225       if (*wchTmp == L',' || *wchTmp == L'\0') {
01226         if (uiLenOneOpt > 0) {
01227           SysFreeString(bstrOneOpt);
01228           bstrOneOpt = SysAllocStringLen(wchTmp - uiLenOneOpt,
01229               uiLenOneOpt);
01230           uiLenOneOpt = 0;
01231         }
01232 
01233         bstrTmp = bstrOptTitle;
01234         wchPos = bstrTmp;
01235         while (wchPos[0] == L' ') {
01236           wchPos++;
01237         }
01238 
01239         lTitleTerm = wcslen(wchPos) - 1;
01240         while (wchPos[lTitleTerm] == L' ') {
01241           wchPos[lTitleTerm] = L'\0';
01242           lTitleTerm--;
01243         }
01244 
01245         bstrOptTitle = SysAllocString(wchPos);
01246         SysFreeString(bstrTmp);
01247 
01248         if (!_wcsicmp(bstrOptTitle, bstrKey)) {
01249           if (!SysStringLen(bstrOneOpt)) {
01250             if (vt == VT_BOOL) {
01251               pvarDest->vt = VT_BOOL;
01252               pvarDest->boolVal = VARIANT_TRUE;
01253             } else {
01254               VariantClear(pvarDest);
01255             }
01256             hr = S_OK;
01257             goto exit_proc;
01258           }
01259           break;
01260         }
01261 
01262         if (*wchTmp == L',') {
01263           SysFreeString(bstrOptTitle);
01264           bstrOptTitle = SysAllocString(L"");
01265           uiLenOptTitle = 0;
01266 
01267           SysFreeString(bstrOneOpt);
01268           bstrOneOpt = SysAllocString(L"");
01269           uiLenOneOpt = 0;
01270 
01271           bGetTitle = 0;
01272           continue;
01273         } else {
01274           VariantClear(pvarDest);
01275           hr = S_OK;
01276           goto exit_proc;
01277         }
01278       }
01279     }
01280 
01281     if (bGetTitle) {
01282       uiLenOneOpt++;
01283     } else {
01284       uiLenOptTitle++;
01285     }
01286   }
01287 
01288   if (iLevelCount != 0) {
01289     hr = E_FAIL;
01290     goto exit_proc;
01291   }
01292 
01293   bstrTmp = bstrOneOpt;
01294   wchPos = bstrTmp;
01295   while (wchPos[0] == L' ') {
01296     wchPos++;
01297   }
01298 
01299   lTitleTerm = wcslen(wchPos) - 1;
01300   while (wchPos[lTitleTerm] == L' ') {
01301     wchPos[lTitleTerm] = L'\0';
01302     lTitleTerm--;
01303   }
01304 
01305   bstrOneOpt = SysAllocString(wchPos);
01306   SysFreeString(bstrTmp);
01307 
01308   vntTmp.vt = VT_BSTR;
01309   vntTmp.bstrVal = bstrOneOpt;
01310 
01311   hr = VariantChangeType(pvarDest, &vntTmp, 0, vt);
01312 
01313   exit_proc: SysFreeString(bstrTarget);
01314   SysFreeString(bstrOptTitle);
01315   SysFreeString(bstrOneOpt);
01316 
01317   return hr;
01318 }
01319 #endif /* _DN_USE_VARIANT_API */
01320 
01321 #if (_DN_USE_BSTR_API)
01322 
01327 wchar_t*
01328 ConvertMultiByte2WideChar(const char* chSrc)
01329 {
01330   wchar_t* chDest = NULL;
01331 
01332   if(chSrc != NULL) {
01333 #ifdef _USE_WIN_API
01334     int iLen = MultiByteToWideChar(CP_ACP, 0, chSrc, -1, NULL, 0);
01335     if(iLen > 0) {
01336       chDest = (wchar_t*)malloc(sizeof(wchar_t)*iLen);
01337       if(chDest == NULL) return NULL;
01338       MultiByteToWideChar(CP_ACP, 0, chSrc, -1, chDest, iLen);
01339     }
01340 #else
01341     char* locale = setlocale(LC_ALL, setlocale(LC_CTYPE, ""));
01342     int iLen = mbstowcs(NULL, chSrc, 0) + 1;
01343     if(iLen > 0) {
01344       chDest = (wchar_t*)malloc(sizeof(wchar_t)*iLen);
01345       if(chDest == NULL) return NULL;
01346       mbstowcs(chDest, chSrc, iLen);
01347     }
01348     setlocale(LC_ALL, locale);
01349 #endif
01350   }
01351 
01352   return chDest;  
01353 }
01354 
01360 char*
01361 ConvertWideChar2MultiByte(const wchar_t* chSrc)
01362 {
01363   char* chDest = NULL;
01364 
01365   if(chSrc != NULL) {
01366 #ifdef _USE_WIN_API
01367     int iLen = WideCharToMultiByte(CP_ACP, 0, chSrc, -1, NULL, 0, NULL, NULL);
01368     if(iLen > 0) {
01369       chDest = (char*)malloc(iLen);
01370       if(chDest == NULL) return NULL;
01371       WideCharToMultiByte(CP_ACP, 0, chSrc, -1, chDest, iLen, NULL, NULL);
01372     }
01373 #else
01374     char* locale = setlocale(LC_ALL, setlocale(LC_CTYPE, ""));
01375     int iLen = wcstombs(NULL, chSrc, 0) + 1;
01376     if(iLen > 0) {
01377       chDest = (char*)malloc(iLen);
01378       if(chDest == NULL) return NULL;
01379       wcstombs(chDest, chSrc, iLen);
01380     }
01381     setlocale(LC_ALL, locale);
01382 #endif
01383   }
01384 
01385   return chDest;
01386 }
01387 #endif /* _DN_USE_BSTR_API */


bcap_core
Author(s): DENSO WAVE INCORPORATED
autogenerated on Thu Jun 6 2019 21:00:02