dn_common.c
Go to the documentation of this file.
1 
25 #include "stdint.h"
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #if defined(_USE_WIN_API)
30 #include <windows.h>
31 #elif defined(_USE_LINUX_API)
32 #include <float.h>
33 #include <limits.h>
34 #include <locale.h>
35 #include <errno.h>
36 #ifndef _wcsicmp
37 #define _wcsicmp wcscasecmp
38 #endif
39 #ifndef __USE_XOPEN
40 #define __USE_XOPEN
41 #endif
42 #endif
43 
44 #include "dn_common.h"
45 
50 #define _LEN_VARIANT2BSTR (500)
51 
52 #ifndef _OLEAUTO_H_
53 
60 BSTR
61 SysAllocString(const wchar_t *sz)
62 {
63  if (sz == NULL)
64  return NULL;
65 
66  return SysAllocStringLen(sz, wcslen(sz));
67 }
68 
76 BSTR
77 SysAllocStringLen(const wchar_t *pch, uint16_t cch)
78 {
79  uint16_t minlen;
80  BSTR bstr = NULL;
81 
82  minlen = sizeof(wchar_t) * (cch + 1);
83  bstr = (BSTR) malloc(minlen);
84 
85  if (bstr != NULL) {
86  memset(bstr, 0, minlen);
87 
88  if (pch != NULL) {
89  minlen = wcslen(pch);
90  minlen = (cch < minlen ? cch : minlen);
91  memcpy(bstr, pch, sizeof(wchar_t) * minlen);
92  }
93  }
94 
95  return bstr;
96 }
97 
103 void
105 {
106  if (bstr != NULL) {
107  free(bstr);
108  bstr = NULL;
109  }
110 }
111 
117 uint16_t
119 {
120  uint16_t len = 0;
121 
122  if (bstr != NULL) {
123  len = wcslen(bstr);
124  }
125 
126  return len;
127 }
128 
137 SAFEARRAY*
139 {
140  int sz;
141  SAFEARRAY* psa = NULL;
142 
143  psa = (SAFEARRAY*) malloc(sizeof(SAFEARRAY));
144 
145  if (psa != NULL) {
146  memset(psa, 0, sizeof(SAFEARRAY));
147 
148  psa->cDims = 1;
149  psa->vt = vt;
150  psa->rgsabound[0].lLbound = lLbound;
151  psa->rgsabound[0].cElements = cElements;
152 
153  if (cElements > 0) {
154  switch (vt) {
155  case VT_UI1:
156  sz = 1;
157  break;
158  case VT_I2:
159  case VT_UI2:
160  case VT_BOOL:
161  sz = 2;
162  break;
163  case VT_I4:
164  case VT_UI4:
165  case VT_R4:
166  sz = 4;
167  break;
168  case VT_I8:
169  case VT_UI8:
170  case VT_R8:
171  case VT_CY:
172  sz = 8;
173  break;
174  case VT_DATE:
175  sz = sizeof(DATE);
176  break;
177  case VT_BSTR:
178  sz = sizeof(BSTR);
179  break;
180  case VT_VARIANT:
181  sz = sizeof(VARIANT);
182  break;
183  default:
184  free(psa);
185  psa = NULL;
186  goto exit_proc;
187  }
188 
189  psa->cbElements = sz;
190  psa->pvData = malloc(cElements * sz);
191 
192  if (psa->pvData == NULL) {
193  free(psa);
194  psa = NULL;
195  goto exit_proc;
196  }
197 
198  memset(psa->pvData, 0, cElements * sz);
199  }
200  }
201 
202 exit_proc:
203  return psa;
204 }
205 
211 HRESULT
213 {
214  int32_t i;
215 
216  if (psa != NULL) {
217  if (psa->pvData != NULL) {
218  switch (psa->vt) {
219  case VT_BSTR:
220  for (i = 0; i < psa->rgsabound[0].cElements; i++) {
221  SysFreeString(*((BSTR*) psa->pvData + i));
222  }
223  break;
224  case VT_VARIANT:
225  for (i = 0; i < psa->rgsabound[0].cElements; i++) {
226  VariantClear(((VARIANT*) psa->pvData + i));
227  }
228  break;
229  default:
230  free(psa->pvData);
231  break;
232  }
233  psa->pvData = NULL;
234  }
235  free(psa);
236  psa = NULL;
237  }
238 
239  return S_OK;
240 }
241 
247 uint16_t
249 {
250  if (psa == NULL)
251  return 0;
252 
253  return psa->cDims;
254 }
255 
261 uint32_t
263 {
264  if (psa == NULL)
265  return 0;
266 
267  return psa->cbElements;
268 }
269 
277 HRESULT
279 {
280  if (psa == NULL || plLbound == NULL)
281  return E_INVALIDARG;
282  if (nDim <= 0 || psa->cDims < nDim)
283  return DISP_E_BADINDEX;
284 
285  *plLbound = psa->rgsabound[nDim - 1].lLbound;
286 
287  return S_OK;
288 }
289 
297 HRESULT
299 {
300  if (psa == NULL || plUbound == NULL)
301  return E_INVALIDARG;
302  if (nDim <= 0 || psa->cDims < nDim)
303  return DISP_E_BADINDEX;
304 
305  *plUbound = (psa->rgsabound[nDim - 1].cElements
306  + psa->rgsabound[nDim - 1].lLbound - 1);
307 
308  return S_OK;
309 }
310 
317 HRESULT
319 {
320  if (psa == NULL || pvt == NULL)
321  return E_INVALIDARG;
322 
323  *pvt = psa->vt;
324 
325  return S_OK;
326 }
327 
335 HRESULT
336 SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
337 {
338  if (psa == NULL || ppvData == NULL)
339  return E_INVALIDARG;
340 
341  *ppvData = psa->pvData;
342 
343  return S_OK;
344 }
345 
352 HRESULT
354 {
355  if (psa == NULL)
356  return E_INVALIDARG;
357 
358  return S_OK;
359 }
360 
367 void
369 {
370  if (pvarg != NULL) {
371  memset(pvarg, 0, sizeof(VARIANT));
372  }
373 }
374 
381 void
383 {
384  if (pvarg != NULL) {
385  if (pvarg->vt & VT_ARRAY) {
386  if (pvarg->parray != NULL) {
387  SafeArrayDestroy(pvarg->parray);
388  pvarg->parray = NULL;
389  }
390  }
391  else if (pvarg->vt == VT_BSTR) {
392  if (pvarg->bstrVal != NULL) {
393  SysFreeString(pvarg->bstrVal);
394  pvarg->bstrVal = NULL;
395  }
396  }
397  memset(pvarg, 0, sizeof(VARIANT));
398  }
399 }
400 
401 #if (_DN_USE_VARIANT_API)
402 
408 HRESULT
409 VariantCopy(VARIANT *pvargDest, const VARIANT *pvargSrc)
410 {
411  if ((pvargDest == NULL) || (pvargSrc == NULL)) {
412  return E_INVALIDARG;
413  }
414 
415  if (pvargDest == pvargSrc) {
416  return S_OK;
417  }
418 
419  VariantClear(pvargDest);
420 
421  if (pvargSrc->vt & VT_ARRAY) {
422  int32_t i, lLbound = 0;
423  uint32_t cbElements = 0, cElements;
424 
425  lLbound = pvargSrc->parray->rgsabound[0].lLbound;
426  cElements = pvargSrc->parray->rgsabound[0].cElements;
427  cbElements = pvargSrc->parray->cbElements;
428 
429  switch (pvargSrc->vt ^ VT_ARRAY) {
430  case VT_I2:
431  case VT_I4:
432  case VT_I8:
433  case VT_R4:
434  case VT_R8:
435  case VT_CY:
436  case VT_DATE:
437  case VT_BOOL:
438  case VT_UI1:
439  case VT_UI2:
440  case VT_UI4:
441  case VT_UI8:
442  pvargDest->vt = pvargSrc->vt;
443  pvargDest->parray = SafeArrayCreateVector(pvargSrc->vt ^ VT_ARRAY,
444  lLbound, cElements);
445  memcpy(pvargDest->parray->pvData, pvargSrc->parray->pvData,
446  cbElements * cElements);
447  break;
448  case VT_BSTR:
449  pvargDest->vt = pvargSrc->vt;
450  pvargDest->parray = SafeArrayCreateVector(VT_BSTR, lLbound, cElements);
451  for (i = 0; i < cElements; i++) {
452  *((BSTR*) pvargDest->parray->pvData + i) = SysAllocString(
453  *((BSTR*) pvargSrc->parray->pvData + i));
454  }
455  break;
456  case VT_VARIANT:
457  pvargDest->vt = pvargSrc->vt;
458  pvargDest->parray = SafeArrayCreateVector(VT_VARIANT, lLbound,
459  cElements);
460  for (i = 0; i < cElements; i++) {
461  VariantCopy(((VARIANT*) pvargDest->parray->pvData + i),
462  ((VARIANT*) pvargSrc->parray->pvData + i));
463  }
464  break;
465  default:
466  return DISP_E_BADVARTYPE;
467  }
468  } else {
469  switch (pvargSrc->vt) {
470  case VT_EMPTY:
471  case VT_NULL:
472  case VT_I2:
473  case VT_I4:
474  case VT_I8:
475  case VT_R4:
476  case VT_R8:
477  case VT_CY:
478  case VT_DATE:
479  case VT_ERROR:
480  case VT_BOOL:
481  case VT_UI1:
482  case VT_UI2:
483  case VT_UI4:
484  case VT_UI8:
485  memcpy(pvargDest, pvargSrc, sizeof(VARIANT));
486  break;
487  case VT_BSTR:
488  pvargDest->vt = VT_BSTR;
489  pvargDest->bstrVal = SysAllocString(pvargSrc->bstrVal);
490  break;
491  default:
492  return DISP_E_BADVARTYPE;
493  }
494  }
495 
496  return S_OK;
497 }
498 
505 static HRESULT
506 Variant2Bstr(BSTR *pbstr, VARIANT *pvarg)
507 {
508  HRESULT hr = S_OK;
509  char chStr[_LEN_VARIANT2BSTR];
510  wchar_t wchStr[_LEN_VARIANT2BSTR];
511  struct tm *tmVal;
512 
513  switch (pvarg->vt) {
514  case VT_I2:
515  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%d", pvarg->iVal);
516  break;
517  case VT_I4:
518  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%ld", pvarg->lVal);
519  break;
520  case VT_I8:
521  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%lld", pvarg->llVal);
522  break;
523  case VT_R4:
524  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%.7G", pvarg->fltVal);
525  break;
526  case VT_R8:
527  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%.15G", pvarg->dblVal);
528  break;
529  case VT_CY:
530  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%lld", pvarg->cyVal.int64);
531  break;
532  case VT_DATE:
533  tmVal = gmtime(&pvarg->date);
534  strftime(chStr, _LEN_VARIANT2BSTR, FORMAT_DATE2BSTR, tmVal);
535  mbstowcs(wchStr, chStr, _LEN_VARIANT2BSTR);
536  break;
537  case VT_BOOL:
538  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%d", pvarg->boolVal);
539  break;
540  case VT_UI1:
541  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%u", pvarg->bVal);
542  break;
543  case VT_UI2:
544  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%u", pvarg->uiVal);
545  break;
546  case VT_UI4:
547  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%lu", pvarg->ulVal);
548  break;
549  case VT_UI8:
550  swprintf(wchStr, _LEN_VARIANT2BSTR, L"%llu", pvarg->ullVal);
551  break;
552  default:
553  hr = DISP_E_BADVARTYPE;
554  break;
555  }
556 
557  if(SUCCEEDED(hr)) {
558  *pbstr = SysAllocString(wchStr);
559  }
560 
561  return hr;
562 }
563 
570 static HRESULT
571 Bstr2Variant(VARIANT *pvarg, int16_t vt, BSTR bstr)
572 {
573  HRESULT hr = S_OK;
574  int flag = 0, len;
575  char *chRet, *chStr = NULL;
576  wchar_t *wchRet;
577  struct tm tmVal;
578  VARIANT vntTmp;
579 
580  if(*bstr == L'\0') {
581  return DISP_E_TYPEMISMATCH;
582  }
583 
584  VariantInit(&vntTmp);
585 
586  if (pvarg->bstrVal == bstr) {
587  flag = 1;
588  }
589 
590  switch (vt) {
591  case VT_EMPTY:
592  case VT_NULL:
593  break;
594  case VT_ERROR:
595  hr = DISP_E_TYPEMISMATCH;
596  break;
597  case VT_I2:
598  case VT_I4:
599  case VT_BOOL:
600  errno = 0;
601  vntTmp.lVal = (int32_t) wcstol(bstr, &wchRet, 0);
602  if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
603  hr = DISP_E_TYPEMISMATCH;
604  }
605  else if (errno == ERANGE) {
606  hr = DISP_E_OVERFLOW;
607  }
608  else if ((vt == VT_I2) || (vt == VT_BOOL)) {
609  vntTmp.vt = VT_I4;
610  hr = VariantChangeType(&vntTmp, &vntTmp, 0, vt);
611  }
612  break;
613  case VT_I8:
614  errno = 0;
615  vntTmp.llVal = (int64_t) wcstoll(bstr, &wchRet, 0);
616  if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
617  hr = DISP_E_TYPEMISMATCH;
618  }
619  else if (errno == ERANGE) {
620  hr = DISP_E_OVERFLOW;
621  }
622  break;
623  case VT_R4:
624  errno = 0;
625  vntTmp.fltVal = wcstof(bstr, &wchRet);
626  if ((wchRet == NULL) || (*wchRet != L'\0')) {
627  hr = DISP_E_TYPEMISMATCH;
628  }
629  else if (errno == ERANGE) {
630  hr = DISP_E_OVERFLOW;
631  }
632  break;
633  case VT_R8:
634  errno = 0;
635  vntTmp.dblVal = wcstod(bstr, &wchRet);
636  if ((wchRet == NULL) || (*wchRet != L'\0')) {
637  hr = DISP_E_TYPEMISMATCH;
638  }
639  else if (errno == ERANGE) {
640  hr = DISP_E_OVERFLOW;
641  }
642  break;
643  case VT_CY:
644  errno = 0;
645  vntTmp.cyVal.int64 = (int64_t) wcstoll(bstr, &wchRet, 0);
646  if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
647  hr = DISP_E_TYPEMISMATCH;
648  }
649  else if (errno == ERANGE) {
650  hr = DISP_E_OVERFLOW;
651  }
652  break;
653  case VT_UI1:
654  case VT_UI2:
655  case VT_UI4:
656  errno = 0;
657  vntTmp.ulVal = (uint32_t) wcstoul(bstr, &wchRet, 0);
658  if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
659  hr = DISP_E_TYPEMISMATCH;
660  }
661  else if (errno == ERANGE) {
662  hr = DISP_E_OVERFLOW;
663  }
664  else if ((vt == VT_UI1) || (vt == VT_UI2)) {
665  vntTmp.vt = VT_UI4;
666  hr = VariantChangeType(&vntTmp, &vntTmp, 0, vt);
667  }
668  else if (*bstr == L'-') {
669  hr = DISP_E_OVERFLOW;
670  }
671  break;
672  case VT_UI8:
673  errno = 0;
674  vntTmp.ullVal = (uint64_t) wcstoull(bstr, &wchRet, 0);
675  if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
676  hr = DISP_E_TYPEMISMATCH;
677  }
678  else if (errno == ERANGE) {
679  hr = DISP_E_OVERFLOW;
680  }
681  else if (*bstr == L'-') {
682  hr = DISP_E_OVERFLOW;
683  }
684  break;
685  case VT_DATE:
686  len = wcstombs(NULL, bstr, 0) + 1;
687  if(len <= 0) {
688  hr = DISP_E_TYPEMISMATCH;
689  break;
690  }
691 
692  chStr = (char *) malloc(len);
693  if(chStr == NULL) {
694  hr = E_OUTOFMEMORY;
695  break;
696  }
697 
698  wcstombs(chStr, bstr, len);
699  memset(&tmVal, 0, sizeof(struct tm));
700  chRet = strptime(chStr, FORMAT_DATE2BSTR, &tmVal);
701  if ((chRet == NULL) || (*chRet != '\0')) {
702  hr = DISP_E_TYPEMISMATCH;
703  } else {
704  vntTmp.date = mktime(&tmVal);
705  }
706  free(chStr);
707  break;
708  default:
709  hr = DISP_E_BADVARTYPE;
710  break;
711  }
712  errno = 0;
713 
714  if (SUCCEEDED(hr)) {
715  *pvarg = vntTmp;
716  if (flag) {
717  SysFreeString(bstr);
718  }
719  }
720 
721  VariantClear(&vntTmp);
722 
723  return hr;
724 }
725 
735 HRESULT
736 VariantChangeType(VARIANT *pvargDest, VARIANT *pvarSrc, uint16_t wFlags,
737  uint16_t vt)
738 {
739  HRESULT hr = S_OK;
740 
741  if ((pvargDest == NULL) || (pvarSrc == NULL)) {
742  return E_INVALIDARG;
743  }
744 
745  if (pvargDest != pvarSrc) {
746  VariantClear(pvargDest);
747  if (vt == pvarSrc->vt) {
748  return VariantCopy(pvargDest, pvarSrc);
749  }
750  } else {
751  if (vt == pvarSrc->vt) {
752  return S_OK;
753  }
754  }
755 
756 #define CheckOverflow(typeDst, typeSrc) \
757  ((sizeof(typeDst) < sizeof(typeSrc)) \
758  || (pvarSrc->vt == VT_R4) \
759  || (pvarSrc->vt == VT_R8))
760 
761 #define IsUnsigned \
762  ((pvarSrc->vt == VT_UI1) \
763  || (pvarSrc->vt == VT_UI2) \
764  || (pvarSrc->vt == VT_UI4) \
765  || (pvarSrc->vt == VT_UI8))
766 
767 #define SubChangeType(type, val, chk) \
768  switch (vt) { \
769  case VT_EMPTY: \
770  case VT_NULL: \
771  memset(pvargDest, 0, sizeof(VARIANT)); \
772  break; \
773  case VT_ERROR: \
774  return DISP_E_TYPEMISMATCH; \
775  break; \
776  case VT_I2: \
777  if(chk) { if(CheckOverflow(int16_t, type) \
778  && ((!IsUnsigned && ((val) < (type)SHRT_MIN)) \
779  || ((type)SHRT_MAX < (val)))) { \
780  return DISP_E_OVERFLOW; \
781  } } \
782  pvargDest->iVal = (int16_t)(val); \
783  break; \
784  case VT_I4: \
785  if(chk) { if(CheckOverflow(int32_t, type) \
786  && ((!IsUnsigned && ((val) < (type)LONG_MIN)) \
787  || ((type)LONG_MAX < (val)))) { \
788  return DISP_E_OVERFLOW; \
789  } } \
790  pvargDest->lVal = (int32_t)(val); \
791  break; \
792  case VT_I8: \
793  if(chk) { if(CheckOverflow(int64_t, type) \
794  && ((!IsUnsigned && ((val) < (type)LLONG_MIN)) \
795  || ((type)LLONG_MAX < (val)))) { \
796  return DISP_E_OVERFLOW; \
797  } } \
798  pvargDest->llVal = (int64_t)(val); \
799  break; \
800  case VT_R4: \
801  if(chk) { if((pvarSrc->vt == VT_R8) \
802  && (((val) < (double)-FLT_MAX) \
803  || ((double)FLT_MAX < (val)))) { \
804  return DISP_E_OVERFLOW; \
805  } } \
806  pvargDest->fltVal = (float)(val); \
807  break; \
808  case VT_R8: \
809  pvargDest->dblVal = (double)(val); \
810  break; \
811  case VT_CY: \
812  if(chk) { if(CheckOverflow(int64_t, type) \
813  && ((!IsUnsigned && ((val) < (type)LLONG_MIN)) \
814  || ((type)LLONG_MAX < (val)))) { \
815  return DISP_E_OVERFLOW; \
816  } } \
817  pvargDest->cyVal.int64 = (int64_t)(val); \
818  break; \
819  case VT_DATE: \
820  pvargDest->date = (DATE)(val); \
821  break; \
822  case VT_BSTR: \
823  hr = Variant2Bstr(&pvargDest->bstrVal, pvarSrc); \
824  break;\
825  case VT_BOOL: \
826  pvargDest->boolVal = ((val) ? VARIANT_TRUE : VARIANT_FALSE); \
827  break; \
828  case VT_UI1: \
829  if(chk) { if(((val) < (type)0) || \
830  (CheckOverflow(uint8_t, type) && ((type)USHRT_MAX < (val)))) { \
831  return DISP_E_OVERFLOW; \
832  } } \
833  pvargDest->bVal = (uint8_t)(val); \
834  break; \
835  case VT_UI2: \
836  if(chk) { if(((pvarSrc->vt != VT_I2) && ((val) < (type)0)) || \
837  (CheckOverflow(uint16_t, type) && ((type)USHRT_MAX < (val)))) { \
838  return DISP_E_OVERFLOW; \
839  } } \
840  pvargDest->uiVal = (uint16_t)(val); \
841  break; \
842  case VT_UI4: \
843  if(chk) { if(((pvarSrc->vt != VT_I4) && ((val) < (type)0)) || \
844  (CheckOverflow(uint32_t, type) && ((type)ULONG_MAX < (val)))) { \
845  return DISP_E_OVERFLOW; \
846  } } \
847  pvargDest->ulVal = (uint32_t)(val); \
848  break; \
849  case VT_UI8: \
850  if(chk) { if(((pvarSrc->vt != VT_I8) && ((val) < (type)0)) || \
851  (CheckOverflow(uint64_t, type) && ((type)ULLONG_MAX < (val)))) { \
852  return DISP_E_OVERFLOW; \
853  } } \
854  pvargDest->ullVal = (uint64_t)(val); \
855  break; \
856  default: \
857  return DISP_E_BADVARTYPE; \
858  }
859 
860  switch (pvarSrc->vt) {
861  case VT_EMPTY:
862  switch (vt) {
863  case VT_BSTR:
864  pvargDest->bstrVal = SysAllocString(L"");
865  break;
866  case VT_ERROR:
867  return DISP_E_TYPEMISMATCH;
868  default:
869  memset(pvargDest, 0, sizeof(VARIANT));
870  break;
871  }
872  break;
873  case VT_NULL:
874  case VT_ERROR:
875  return DISP_E_TYPEMISMATCH;
876  case VT_I2:
877  SubChangeType(int16_t, pvarSrc->iVal, 1);
878  break;
879  case VT_I4:
880  SubChangeType(int32_t, pvarSrc->lVal, 1);
881  break;
882  case VT_I8:
883  SubChangeType(int64_t, pvarSrc->llVal, 1);
884  break;
885  case VT_R4:
886  SubChangeType(float, pvarSrc->fltVal, 1);
887  break;
888  case VT_R8:
889  SubChangeType(double, pvarSrc->dblVal, 1);
890  break;
891  case VT_CY:
892  SubChangeType(int64_t, pvarSrc->cyVal.int64, 1);
893  break;
894  case VT_DATE:
895  SubChangeType(DATE, pvarSrc->date, 1);
896  break;
897  case VT_BSTR:
898  hr = Bstr2Variant(pvargDest, vt, pvarSrc->bstrVal);
899  break;
900  case VT_BOOL:
901  SubChangeType(VARIANT_BOOL, pvarSrc->boolVal, 0);
902  break;
903  case VT_UI1:
904  SubChangeType(uint8_t, pvarSrc->bVal, 1);
905  break;
906  case VT_UI2:
907  SubChangeType(uint16_t, pvarSrc->uiVal, 1);
908  break;
909  case VT_UI4:
910  SubChangeType(uint32_t, pvarSrc->ulVal, 1);
911  break;
912  case VT_UI8:
913  SubChangeType(uint64_t, pvarSrc->ullVal, 1);
914  break;
915  default:
916  return DISP_E_BADVARTYPE;
917  }
918 
919  if (SUCCEEDED(hr)) {
920  pvargDest->vt = vt;
921  }
922 
923  return hr;
924 }
925 #endif /* _DN_USE_VARIANT_API */
926 #endif /* _OLEAUTO_H_ */
927 
928 #if (_DN_USE_VARIANT_API)
929 
937 uint32_t
938 ChangeVarType(VARIANT varSrc, uint16_t vt, void *pDest, uint32_t dwSize)
939 {
940  HRESULT hr = S_OK;
941  uint32_t dwRet, dwCnt = 0;
942  VARIANT vntTmp;
943 
944  if ((pDest == NULL) || (dwSize == 0)) {
945  return 0;
946  }
947 
948  VariantInit(&vntTmp);
949 
950  if (varSrc.vt & VT_ARRAY) {
951  int32_t i, lMax =
952  (int32_t) varSrc.parray->rgsabound[0].cElements;
953  void *pVal, *pPos = pDest;
954 
955  SafeArrayAccessData(varSrc.parray, &pVal);
956  for (i = 0; i < lMax; i++) {
957  VariantClear(&vntTmp);
958  switch (varSrc.vt ^ VT_ARRAY) {
959  case VT_I2:
960  vntTmp.vt = VT_I2;
961  vntTmp.iVal = *((int16_t *) pVal + i);
962  break;
963  case VT_I4:
964  vntTmp.vt = VT_I4;
965  vntTmp.lVal = *((int32_t *) pVal + i);
966  break;
967  case VT_I8:
968  vntTmp.vt = VT_I8;
969  vntTmp.llVal = *((int64_t *) pVal + i);
970  break;
971  case VT_R4:
972  vntTmp.vt = VT_R4;
973  vntTmp.fltVal = *((float *) pVal + i);
974  break;
975  case VT_R8:
976  vntTmp.vt = VT_R8;
977  vntTmp.dblVal = *((double *) pVal + i);
978  break;
979  case VT_CY:
980  vntTmp.vt = VT_CY;
981  vntTmp.cyVal = *((CY *) pVal + i);
982  break;
983  case VT_DATE:
984  vntTmp.vt = VT_DATE;
985  vntTmp.date = *((DATE *) pVal + i);
986  break;
987  case VT_BSTR:
988  vntTmp.vt = VT_BSTR;
989  vntTmp.bstrVal = SysAllocString(*((BSTR *) pVal + i));
990  break;
991  case VT_BOOL:
992  vntTmp.vt = VT_BOOL;
993  vntTmp.boolVal = *((VARIANT_BOOL *) pVal + i);
994  break;
995  case VT_VARIANT:
996  VariantCopy(&vntTmp, (VARIANT *) pVal + i);
997  break;
998  case VT_UI1:
999  vntTmp.vt = VT_UI1;
1000  vntTmp.bVal = *((uint8_t *) pVal + i);
1001  break;
1002  case VT_UI2:
1003  vntTmp.vt = VT_UI2;
1004  vntTmp.uiVal = *((uint16_t *) pVal + i);
1005  break;
1006  case VT_UI4:
1007  vntTmp.vt = VT_UI4;
1008  vntTmp.ulVal = *((uint32_t *) pVal + i);
1009  break;
1010  case VT_UI8:
1011  vntTmp.vt = VT_UI8;
1012  vntTmp.ullVal = *((uint64_t *) pVal + i);
1013  break;
1014  default:
1015  hr = E_INVALIDARG;
1016  break;
1017  }
1018 
1019  if (FAILED(hr)) {
1020  break;
1021  }
1022 
1023  if (vt != VT_VARIANT) {
1024  if (vntTmp.vt & VT_ARRAY) {
1025  break;
1026  }
1027 
1028  dwRet = ChangeVarType(vntTmp, vt, pPos, 1);
1029  if (dwRet == 0) {
1030  break;
1031  }
1032  } else {
1033  hr = VariantCopy((VARIANT*) pPos, &vntTmp);
1034  if (FAILED(hr)) {
1035  break;
1036  }
1037  dwRet = 1;
1038  }
1039 
1040  dwCnt += dwRet;
1041  pPos = ((char *) pPos + varSrc.parray->cbElements);
1042 
1043  if (dwCnt >= dwSize) {
1044  break;
1045  }
1046  }
1047  SafeArrayUnaccessData(varSrc.parray);
1048  } else {
1049  VariantCopy(&vntTmp, &varSrc);
1050  if (vt != VT_VARIANT) {
1051  hr = VariantChangeType(&vntTmp, &vntTmp, 0, vt);
1052  if (FAILED(hr)) {
1053  dwCnt = 0;
1054  goto exit_proc;
1055  }
1056  }
1057 
1058  dwCnt = 1;
1059  switch (vt) {
1060  case VT_I2:
1061  *(int16_t *) pDest = vntTmp.iVal;
1062  break;
1063  case VT_I4:
1064  *(int32_t *) pDest = vntTmp.lVal;
1065  break;
1066  case VT_I8:
1067  *(int64_t *) pDest = vntTmp.llVal;
1068  break;
1069  case VT_R4:
1070  *(float *) pDest = vntTmp.fltVal;
1071  break;
1072  case VT_R8:
1073  *(double *) pDest = vntTmp.dblVal;
1074  break;
1075  case VT_CY:
1076  *(CY *) pDest = vntTmp.cyVal;
1077  break;
1078  case VT_DATE:
1079  *(DATE *) pDest = vntTmp.date;
1080  break;
1081  case VT_BSTR:
1082  *(BSTR *) pDest = SysAllocString(vntTmp.bstrVal);
1083  break;
1084  case VT_BOOL:
1085  *(VARIANT_BOOL *) pDest = vntTmp.boolVal ? VARIANT_TRUE : VARIANT_FALSE;
1086  break;
1087  case VT_VARIANT:
1088  VariantCopy((VARIANT *) pDest, &vntTmp);
1089  break;
1090  case VT_UI1:
1091  *(uint8_t *) pDest = vntTmp.bVal;
1092  break;
1093  case VT_UI2:
1094  *(uint16_t *) pDest = vntTmp.uiVal;
1095  break;
1096  case VT_UI4:
1097  *(uint32_t *) pDest = vntTmp.ulVal;
1098  break;
1099  case VT_UI8:
1100  *(uint64_t *) pDest = vntTmp.ullVal;
1101  break;
1102  default:
1103  dwCnt = 0;
1104  break;
1105  }
1106  }
1107 
1108 exit_proc:
1109  VariantClear(&vntTmp);
1110 
1111  return dwCnt;
1112 }
1113 
1122 HRESULT
1123 GetOptionValue(BSTR bstrSrc, BSTR bstrKey, uint16_t vt, VARIANT *pvarDest)
1124 {
1125  HRESULT hr = S_OK;
1126  int iLevelCount = 0, bGetTitle = 0;
1127  long lTitleTerm;
1128  uint16_t i, uiLenTarget = 0, uiLenOptTitle = 0, uiLenOneOpt = 0;
1129  wchar_t *wchTmp, *wchPos, wchStart = -1, wchEnd = -1;
1130  BSTR bstrTmp, bstrTarget, bstrOptTitle, bstrOneOpt;
1131  VARIANT vntTmp;
1132 
1133  if ((bstrKey == NULL) || (pvarDest == NULL)) {
1134  return E_INVALIDARG;
1135  }
1136 
1137  if (bstrSrc != NULL) {
1138  bstrTarget = SysAllocString(bstrSrc);
1139  } else {
1140  bstrTarget = SysAllocString(L"");
1141  }
1142 
1143  bstrOptTitle = SysAllocString(L"");
1144  bstrOneOpt = SysAllocString(L"");
1145 
1146  uiLenTarget = SysStringLen(bstrTarget);
1147  wchTmp = bstrTarget;
1148 
1149  for (i = 0; i <= uiLenTarget; i++, wchTmp++) {
1150  /* Sets the beginning and ending character for nest */
1151  if (!iLevelCount) {
1152  switch (*wchTmp) {
1153  case L'(':
1154  case L')':
1155  wchStart = L'(';
1156  wchEnd = L')';
1157  break;
1158  case L'[':
1159  case L']':
1160  wchStart = L'[';
1161  wchEnd = L']';
1162  break;
1163  case L'{':
1164  case L'}':
1165  wchStart = L'{';
1166  wchEnd = L'}';
1167  break;
1168  case L'<':
1169  case L'>':
1170  wchStart = L'<';
1171  wchEnd = L'>';
1172  break;
1173  default:
1174  break;
1175  }
1176  }
1177 
1178  /* Sets the nest level */
1179  if (*wchTmp == wchStart) {
1180  iLevelCount++;
1181  if (iLevelCount == 1) {
1182  memcpy(wchTmp, wchTmp + 1, sizeof(wchar_t) * (uiLenTarget - i));
1183  uiLenTarget--;
1184  i--;
1185  wchTmp--;
1186  continue;
1187  }
1188  }
1189  else if (*wchTmp == wchEnd) {
1190  iLevelCount--;
1191 
1192  if (iLevelCount < 0) {
1193  hr = E_FAIL;
1194  goto exit_proc;
1195  }
1196 
1197  if (!iLevelCount) {
1198  memcpy(wchTmp, wchTmp + 1, sizeof(wchar_t) * (uiLenTarget - i));
1199  uiLenTarget--;
1200  i--;
1201  wchTmp--;
1202  continue;
1203  }
1204  }
1205 
1206  /* Gets the option name */
1207  if (!iLevelCount) {
1208  if (*wchTmp == L'=') {
1209  if (bGetTitle) {
1210  hr = E_FAIL;
1211  goto exit_proc;
1212  }
1213 
1214  if (uiLenOptTitle > 0) {
1215  SysFreeString(bstrOptTitle);
1216  bstrOptTitle = SysAllocStringLen(wchTmp - uiLenOptTitle,
1217  uiLenOptTitle);
1218  uiLenOptTitle = 0;
1219  }
1220 
1221  bGetTitle = 1;
1222  continue;
1223  }
1224 
1225  if (*wchTmp == L',' || *wchTmp == L'\0') {
1226  if (uiLenOneOpt > 0) {
1227  SysFreeString(bstrOneOpt);
1228  bstrOneOpt = SysAllocStringLen(wchTmp - uiLenOneOpt,
1229  uiLenOneOpt);
1230  uiLenOneOpt = 0;
1231  }
1232 
1233  bstrTmp = bstrOptTitle;
1234  wchPos = bstrTmp;
1235  while (wchPos[0] == L' ') {
1236  wchPos++;
1237  }
1238 
1239  lTitleTerm = wcslen(wchPos) - 1;
1240  while (wchPos[lTitleTerm] == L' ') {
1241  wchPos[lTitleTerm] = L'\0';
1242  lTitleTerm--;
1243  }
1244 
1245  bstrOptTitle = SysAllocString(wchPos);
1246  SysFreeString(bstrTmp);
1247 
1248  if (!_wcsicmp(bstrOptTitle, bstrKey)) {
1249  if (!SysStringLen(bstrOneOpt)) {
1250  if (vt == VT_BOOL) {
1251  pvarDest->vt = VT_BOOL;
1252  pvarDest->boolVal = VARIANT_TRUE;
1253  } else {
1254  VariantClear(pvarDest);
1255  }
1256  hr = S_OK;
1257  goto exit_proc;
1258  }
1259  break;
1260  }
1261 
1262  if (*wchTmp == L',') {
1263  SysFreeString(bstrOptTitle);
1264  bstrOptTitle = SysAllocString(L"");
1265  uiLenOptTitle = 0;
1266 
1267  SysFreeString(bstrOneOpt);
1268  bstrOneOpt = SysAllocString(L"");
1269  uiLenOneOpt = 0;
1270 
1271  bGetTitle = 0;
1272  continue;
1273  } else {
1274  VariantClear(pvarDest);
1275  hr = S_OK;
1276  goto exit_proc;
1277  }
1278  }
1279  }
1280 
1281  if (bGetTitle) {
1282  uiLenOneOpt++;
1283  } else {
1284  uiLenOptTitle++;
1285  }
1286  }
1287 
1288  if (iLevelCount != 0) {
1289  hr = E_FAIL;
1290  goto exit_proc;
1291  }
1292 
1293  bstrTmp = bstrOneOpt;
1294  wchPos = bstrTmp;
1295  while (wchPos[0] == L' ') {
1296  wchPos++;
1297  }
1298 
1299  lTitleTerm = wcslen(wchPos) - 1;
1300  while (wchPos[lTitleTerm] == L' ') {
1301  wchPos[lTitleTerm] = L'\0';
1302  lTitleTerm--;
1303  }
1304 
1305  bstrOneOpt = SysAllocString(wchPos);
1306  SysFreeString(bstrTmp);
1307 
1308  vntTmp.vt = VT_BSTR;
1309  vntTmp.bstrVal = bstrOneOpt;
1310 
1311  hr = VariantChangeType(pvarDest, &vntTmp, 0, vt);
1312 
1313  exit_proc: SysFreeString(bstrTarget);
1314  SysFreeString(bstrOptTitle);
1315  SysFreeString(bstrOneOpt);
1316 
1317  return hr;
1318 }
1319 #endif /* _DN_USE_VARIANT_API */
1320 
1321 #if (_DN_USE_BSTR_API)
1322 
1327 wchar_t*
1328 ConvertMultiByte2WideChar(const char* chSrc)
1329 {
1330  wchar_t* chDest = NULL;
1331 
1332  if(chSrc != NULL) {
1333 #ifdef _USE_WIN_API
1334  int iLen = MultiByteToWideChar(CP_ACP, 0, chSrc, -1, NULL, 0);
1335  if(iLen > 0) {
1336  chDest = (wchar_t*)malloc(sizeof(wchar_t)*iLen);
1337  if(chDest == NULL) return NULL;
1338  MultiByteToWideChar(CP_ACP, 0, chSrc, -1, chDest, iLen);
1339  }
1340 #else
1341  char* locale = setlocale(LC_ALL, setlocale(LC_CTYPE, ""));
1342  int iLen = mbstowcs(NULL, chSrc, 0) + 1;
1343  if(iLen > 0) {
1344  chDest = (wchar_t*)malloc(sizeof(wchar_t)*iLen);
1345  if(chDest == NULL) return NULL;
1346  mbstowcs(chDest, chSrc, iLen);
1347  }
1348  setlocale(LC_ALL, locale);
1349 #endif
1350  }
1351 
1352  return chDest;
1353 }
1354 
1360 char*
1361 ConvertWideChar2MultiByte(const wchar_t* chSrc)
1362 {
1363  char* chDest = NULL;
1364 
1365  if(chSrc != NULL) {
1366 #ifdef _USE_WIN_API
1367  int iLen = WideCharToMultiByte(CP_ACP, 0, chSrc, -1, NULL, 0, NULL, NULL);
1368  if(iLen > 0) {
1369  chDest = (char*)malloc(iLen);
1370  if(chDest == NULL) return NULL;
1371  WideCharToMultiByte(CP_ACP, 0, chSrc, -1, chDest, iLen, NULL, NULL);
1372  }
1373 #else
1374  char* locale = setlocale(LC_ALL, setlocale(LC_CTYPE, ""));
1375  int iLen = wcstombs(NULL, chSrc, 0) + 1;
1376  if(iLen > 0) {
1377  chDest = (char*)malloc(iLen);
1378  if(chDest == NULL) return NULL;
1379  wcstombs(chDest, chSrc, iLen);
1380  }
1381  setlocale(LC_ALL, locale);
1382 #endif
1383  }
1384 
1385  return chDest;
1386 }
1387 #endif /* _DN_USE_BSTR_API */
uint64_t ullVal
Definition: dn_common.h:324
void SysFreeString(BSTR bstr)
Releases the memory of BSTR.
Definition: dn_common.c:104
HRESULT SafeArrayUnaccessData(SAFEARRAY *psa)
Unaccesses the SAFEARRAY.
Definition: dn_common.c:353
BSTR SysAllocStringLen(const wchar_t *pch, uint16_t cch)
Allocates and returns BSTR.
Definition: dn_common.c:77
short int16_t
Definition: stdint.h:40
VARIANT_BOOL boolVal
Definition: dn_common.h:320
unsigned uint32_t
Definition: stdint.h:43
uint16_t SafeArrayGetDim(SAFEARRAY *psa)
Gets and returns the dimension of SAFEARRAY.
Definition: dn_common.c:248
SAFEARRAY * SafeArrayCreateVector(uint16_t vt, int32_t lLbound, uint32_t cElements)
Allocates and returns SAFEARRAY.
Definition: dn_common.c:138
#define VARIANT_TRUE
TRUE for VARIANT.
Definition: dn_common.h:267
long long int64_t
Definition: stdint.h:44
uint8_t bVal
Definition: dn_common.h:321
_DN_EXP_COMMON uint32_t ChangeVarType(VARIANT varSrc, uint16_t vt, void *pDest, uint32_t dwSize)
Changes the variant to destination value with the indicated type.
#define S_OK
Succeeded.
Definition: dn_common.h:89
uint32_t cElements
Definition: dn_common.h:285
HRESULT SafeArrayGetUBound(SAFEARRAY *psa, uint16_t nDim, int32_t *plUbound)
Gets the upper bound of SAFEARRAY.
Definition: dn_common.c:298
wchar_t * BSTR
Definition: dn_common.h:239
unsigned short uint16_t
Definition: stdint.h:41
HRESULT SafeArrayGetVartype(SAFEARRAY *psa, uint16_t *pvt)
Gets the variant type of SAFEARRAY.
Definition: dn_common.c:318
int32_t lVal
Definition: dn_common.h:312
time_t DATE
Definition: dn_common.h:259
#define DISP_E_BADINDEX
Failed because the index is invalid.
Definition: dn_common.h:161
unsigned char uint8_t
Definition: stdint.h:39
BSTR bstrVal
Definition: dn_common.h:318
#define FAILED(hr)
A macro that returns TRUE/FALSE. If hr is less than zero, then returns TRUE.
Definition: dn_common.h:77
A type definition for the signed 64bit integer.
Definition: dn_common.h:245
void VariantClear(VARIANT *pvarg)
Clears the VARIANT.
Definition: dn_common.c:382
int64_t llVal
Definition: dn_common.h:313
uint16_t SysStringLen(BSTR bstr)
Gets and returns the number of characters of BSTR.
Definition: dn_common.c:118
uint32_t SafeArrayGetElemsize(SAFEARRAY *psa)
Gets and returns the size of an element.
Definition: dn_common.c:262
#define DISP_E_BADVARTYPE
Failed because bad variable type.
Definition: dn_common.h:149
#define E_INVALIDARG
Failed because some arguments are invalid.
Definition: dn_common.h:131
void * pvData
Definition: dn_common.h:298
uint32_t cbElements
Definition: dn_common.h:297
void VariantInit(VARIANT *pvarg)
Initializes the VARIANT.
Definition: dn_common.c:368
CY cyVal
Definition: dn_common.h:316
#define E_FAIL
Failed because unspecified error occurs.
Definition: dn_common.h:107
int32_t HRESULT
Definition: dn_common.h:61
unsigned long long uint64_t
Definition: stdint.h:45
BSTR SysAllocString(const wchar_t *sz)
Allocates and returns BSTR.
Definition: dn_common.c:61
uint16_t vt
Definition: dn_common.h:296
_DN_EXP_COMMON HRESULT VariantCopy(VARIANT *pvargDest, const VARIANT *pvargSrc)
Copies the source variant to destination variant.
A type definition for the array.
Definition: dn_common.h:293
#define E_OUTOFMEMORY
Failed because there is no enough memory space.
Definition: dn_common.h:125
#define DISP_E_OVERFLOW
Failed because out of range.
Definition: dn_common.h:155
SAFEARRAY * parray
Definition: dn_common.h:325
HRESULT SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Accesses the SAFEARRAY and gets the pointer of array data.
Definition: dn_common.c:336
#define _LEN_VARIANT2BSTR
A definition for the string length for converting VARIANT to BSTR.
Definition: dn_common.c:50
uint16_t uiVal
Definition: dn_common.h:322
#define SUCCEEDED(hr)
A macro that returns TRUE/FALSE. If hr is zero or more, then returns TRUE.
Definition: dn_common.h:71
int32_t lLbound
Definition: dn_common.h:286
int64_t int64
Definition: dn_common.h:252
uint16_t vt
Definition: dn_common.h:308
Common API file.
_DN_EXP_COMMON HRESULT VariantChangeType(VARIANT *pvargDest, VARIANT *pvarSrc, uint16_t wFlags, uint16_t vt)
Changes the source variant to destination variant with the indicated type.
#define FORMAT_DATE2BSTR
A definition for the format string converting DATE to BSTR.
Definition: dn_common.h:56
int16_t VARIANT_BOOL
Definition: dn_common.h:261
A type definition for the multi type variable.
Definition: dn_common.h:306
#define VARIANT_FALSE
FALSE for VARIANT.
Definition: dn_common.h:273
int int32_t
Definition: stdint.h:42
_DN_EXP_COMMON HRESULT GetOptionValue(BSTR bstrSrc, BSTR bstrKey, uint16_t vt, VARIANT *pvarDest)
Searchs the key string from source string and sets the value to the destination variant with the indi...
SAFEARRAYBOUND rgsabound[1]
Definition: dn_common.h:299
uint32_t ulVal
Definition: dn_common.h:323
HRESULT SafeArrayGetLBound(SAFEARRAY *psa, uint16_t nDim, int32_t *plLbound)
Gets the lower bound of SAFEARRAY.
Definition: dn_common.c:278
struct VARIANT VARIANT
#define DISP_E_TYPEMISMATCH
Failed because the type mismatch.
Definition: dn_common.h:143
float fltVal
Definition: dn_common.h:314
int16_t iVal
Definition: dn_common.h:311
DATE date
Definition: dn_common.h:317
uint16_t cDims
Definition: dn_common.h:295
_DN_EXP_COMMON char * ConvertWideChar2MultiByte(const wchar_t *chSrc)
Converts wide string to string.
HRESULT SafeArrayDestroy(SAFEARRAY *psa)
Releases the memory of SAFEARRAY.
Definition: dn_common.c:212
double dblVal
Definition: dn_common.h:315
_DN_EXP_COMMON wchar_t * ConvertMultiByte2WideChar(const char *chSrc)
Converts string to wide string.


bcap_core
Author(s): DENSO WAVE INCORPORATED
autogenerated on Mon Jun 10 2019 13:12:20