00001 00025 #include "stdint.h" 00026 #include <stdio.h> 00027 #include <stdlib.h> 00028 #include <string.h> 00029 00030 #if defined(_USE_WIN_API) 00031 #include <windows.h> 00032 #endif 00033 00034 #include "dn_common.h" 00035 #include "rac_string.h" 00036 00043 static int 00044 SplitRacStr(const char* chSrc, char** chSplit) 00045 { 00046 int iCnt = 1, iBracket = 0; 00047 char* chPos; 00048 00049 *chSplit = (char*)malloc(strlen(chSrc) + 1); 00050 if(*chSplit == NULL) return -1; 00051 00052 strcpy(*chSplit, chSrc); 00053 chPos = *chSplit; 00054 00055 while(*chPos != '\0') { 00056 switch(*chPos) { 00057 case '(': 00058 iBracket++; 00059 break; 00060 case ')': 00061 iBracket--; 00062 if(iBracket < 0) { 00063 free(*chSplit); 00064 return -1; 00065 } 00066 break; 00067 case ',': 00068 if(iBracket == 0) { 00069 *chPos = '\0'; 00070 iCnt++; 00071 } 00072 break; 00073 default: 00074 break; 00075 } 00076 00077 chPos++; 00078 } 00079 00080 if(iBracket != 0) { 00081 free(*chSplit); 00082 return -1; 00083 } 00084 00085 return iCnt; 00086 } 00087 00095 HRESULT 00096 ConvertRacStr2Variant(uint16_t vt, const char* chSrc, VARIANT* pvargDest) 00097 { 00098 HRESULT hr = S_OK; 00099 int i, iCnt; 00100 char *chSplit, *chPos, *chTmp, *chNext; 00101 wchar_t *wchTmp; 00102 VARIANT vntTmp; 00103 void *parray; 00104 00105 if((chSrc == NULL) || (pvargDest == NULL)) { 00106 return E_INVALIDARG; 00107 } 00108 00109 if(vt != VT_BSTR) { 00110 iCnt = SplitRacStr(chSrc, &chSplit); 00111 if(iCnt < 0) { 00112 return E_INVALIDARG; 00113 } 00114 } else { 00115 iCnt = 1; 00116 chSplit = (char*)malloc(strlen(chSrc) + 1); 00117 if(chSplit == NULL) return E_OUTOFMEMORY; 00118 strcpy(chSplit, chSrc); 00119 } 00120 00121 VariantInit(&vntTmp); 00122 VariantClear(pvargDest); 00123 00124 if(vt == (VT_VARIANT | VT_ARRAY)) { 00125 pvargDest->vt = VT_VARIANT | VT_ARRAY; 00126 pvargDest->parray = SafeArrayCreateVector(VT_VARIANT, 0, iCnt); 00127 SafeArrayAccessData(pvargDest->parray, &parray); 00128 for(i = 0, chPos = chSplit; 00129 (i < iCnt) && SUCCEEDED(hr); 00130 i++) 00131 { 00132 chNext = chPos + strlen(chPos) + 1; 00133 00134 chTmp = strchr(chPos, '('); 00135 if(chTmp == NULL) { hr = E_INVALIDARG; break; } 00136 00137 *chTmp = '\0'; 00138 if(strspn(chPos, " ") != (chTmp - chPos)) { 00139 hr = E_INVALIDARG; 00140 break; 00141 } 00142 00143 chPos = chTmp + 1; 00144 00145 chTmp = strrchr(chPos, ')'); 00146 if(chTmp == NULL) { hr = E_INVALIDARG; break; } 00147 00148 *chTmp = '\0'; 00149 if(*(chTmp + 1) != '\0') { 00150 if(strspn(chTmp + 1, " ") != strlen(chTmp + 1)) { 00151 hr = E_INVALIDARG; 00152 break; 00153 } 00154 } 00155 00156 chTmp = strchr(chPos, ','); 00157 if(chTmp == NULL) { hr = E_INVALIDARG; break; } 00158 00159 *chTmp = '\0'; 00160 if(strspn(chPos, " 0123456789") != (chTmp - chPos)) { 00161 hr = E_INVALIDARG; 00162 break; 00163 } 00164 00165 VariantInit((VARIANT*)parray + i); 00166 hr = ConvertRacStr2Variant(atoi(chPos), chTmp + 1, (VARIANT*)parray + i); 00167 00168 chPos = chNext; 00169 } 00170 SafeArrayUnaccessData(pvargDest->parray); 00171 } 00172 else if(vt & VT_ARRAY) { 00173 pvargDest->vt = vt; 00174 pvargDest->parray = SafeArrayCreateVector(vt ^ VT_ARRAY, 0, iCnt); 00175 SafeArrayAccessData(pvargDest->parray, &parray); 00176 for(i = 0, chPos = chSplit; 00177 (i < iCnt) && SUCCEEDED(hr); 00178 i++, chPos += strlen(chPos) + 1) 00179 { 00180 wchTmp = ConvertMultiByte2WideChar(chPos); 00181 if(wchTmp == NULL) { hr = E_OUTOFMEMORY; break; } 00182 00183 if(vt == (VT_BSTR | VT_ARRAY)) { 00184 *((BSTR*)parray + i) = SysAllocString(wchTmp); 00185 } else { 00186 vntTmp.vt = VT_BSTR; 00187 vntTmp.bstrVal = SysAllocString(wchTmp); 00188 hr = VariantChangeType(&vntTmp, &vntTmp, 0, vt ^ VT_ARRAY); 00189 if(SUCCEEDED(hr)) { 00190 memcpy((char*)parray + i * pvargDest->parray->cbElements, 00191 &vntTmp.iVal, pvargDest->parray->cbElements); 00192 } 00193 } 00194 VariantClear(&vntTmp); 00195 free(wchTmp); 00196 } 00197 SafeArrayUnaccessData(pvargDest->parray); 00198 } 00199 else { 00200 if(iCnt > 1) { 00201 hr = E_INVALIDARG; 00202 } else { 00203 wchTmp = ConvertMultiByte2WideChar(chSplit); 00204 if(wchTmp == NULL) { hr = E_OUTOFMEMORY; } 00205 else { 00206 vntTmp.vt = VT_BSTR; 00207 vntTmp.bstrVal = SysAllocString(wchTmp); 00208 hr = VariantChangeType(pvargDest, &vntTmp, 0, vt); 00209 VariantClear(&vntTmp); 00210 free(wchTmp); 00211 } 00212 } 00213 } 00214 00215 VariantClear(&vntTmp); 00216 free(chSplit); 00217 00218 return hr; 00219 } 00220 00227 HRESULT 00228 ConvertVariant2RacStr(VARIANT varSrc, char** chDest) 00229 { 00230 HRESULT hr = S_OK; 00231 00232 if(chDest == NULL) { 00233 return E_INVALIDARG; 00234 } 00235 00236 *chDest = NULL; 00237 00238 if(varSrc.vt == (VT_VARIANT | VT_ARRAY)) { 00239 int32_t i, lbnd, ubnd, cnt; 00240 uint32_t len = 0; 00241 char chTmp[10], *chPoint; 00242 VARIANT *pvarTmp; 00243 00244 SafeArrayGetLBound(varSrc.parray, 1, &lbnd); 00245 SafeArrayGetUBound(varSrc.parray, 1, &ubnd); 00246 cnt = ubnd - lbnd + 1; 00247 00248 SafeArrayAccessData(varSrc.parray, (void**)&pvarTmp); 00249 for(i = 0; i < cnt; i++) { 00250 hr = ConvertVariant2RacStr(pvarTmp[i], &chPoint); 00251 if(FAILED(hr)) { if(*chDest != NULL) { free(*chDest); } break; } 00252 00253 len += sprintf(chTmp, "%d,", pvarTmp[i].vt); 00254 len += strlen(chPoint) + ((i == cnt - 1) ? 3 : 4); 00255 *chDest = (char*)realloc(*chDest, len); 00256 if(*chDest == NULL) { hr = E_OUTOFMEMORY; free(chPoint); break; } 00257 00258 if(i == 0) *chDest[0] = '\0'; 00259 00260 strcat(*chDest, "("); 00261 strcat(*chDest, chTmp); 00262 strcat(*chDest, chPoint); 00263 strcat(*chDest, (i == cnt - 1) ? ")" : "),"); 00264 00265 free(chPoint); 00266 } 00267 SafeArrayUnaccessData(varSrc.parray); 00268 } 00269 else if(varSrc.vt & VT_ARRAY) { 00270 int32_t i, lbnd, ubnd, cnt; 00271 uint32_t len = 0; 00272 char *chPoint; 00273 void *parray; 00274 VARIANT *pvarTmp; 00275 00276 SafeArrayGetLBound(varSrc.parray, 1, &lbnd); 00277 SafeArrayGetUBound(varSrc.parray, 1, &ubnd); 00278 cnt = ubnd - lbnd + 1; 00279 00280 SafeArrayAccessData(varSrc.parray, &parray); 00281 if(varSrc.vt == (VT_BSTR | VT_ARRAY)) { 00282 for(i = 0; i < cnt; i++) { 00283 chPoint = ConvertWideChar2MultiByte(*((BSTR*)parray + i)); 00284 if(chPoint == NULL) { hr = E_OUTOFMEMORY; break; } 00285 00286 len += strlen(chPoint) + ((i == cnt - 1) ? 1 : 2); 00287 *chDest = (char*)realloc(*chDest, len); 00288 if(*chDest == NULL) { hr = E_OUTOFMEMORY; free(chPoint); break; } 00289 00290 if(i == 0) *chDest[0] = '\0'; 00291 00292 strcat(*chDest, chPoint); 00293 strcat(*chDest, (i == cnt - 1) ? "" : ","); 00294 00295 free(chPoint); 00296 } 00297 } else { 00298 pvarTmp = (VARIANT*)malloc(sizeof(VARIANT) * cnt); 00299 if(pvarTmp == NULL) { hr = E_OUTOFMEMORY; } 00300 else { 00301 memset(pvarTmp, 0, sizeof(VARIANT) * cnt); 00302 for(i = 0; i < cnt; i++) { 00303 pvarTmp[i].vt = varSrc.vt ^ VT_ARRAY; 00304 memcpy(&pvarTmp[i].iVal, (char*)parray + i * varSrc.parray->cbElements, 00305 varSrc.parray->cbElements); 00306 hr = VariantChangeType(&pvarTmp[i], &pvarTmp[i], 0, VT_BSTR); 00307 if(FAILED(hr)) break; 00308 } 00309 00310 if(SUCCEEDED(hr)) { 00311 for(i = 0; i < cnt; i++) { 00312 chPoint = ConvertWideChar2MultiByte(pvarTmp[i].bstrVal); 00313 if(chPoint == NULL) { hr = E_OUTOFMEMORY; break; } 00314 00315 len += strlen(chPoint) + ((i == cnt - 1) ? 1 : 2); 00316 *chDest = (char*)realloc(*chDest, len); 00317 if(*chDest == NULL) { hr = E_OUTOFMEMORY; free(chPoint); break; } 00318 00319 if(i == 0) *chDest[0] = '\0'; 00320 00321 strcat(*chDest, chPoint); 00322 strcat(*chDest, (i == cnt - 1) ? "" : ","); 00323 00324 free(chPoint); 00325 } 00326 } 00327 00328 for(i = 0; i < cnt; i++) { 00329 VariantClear(&pvarTmp[i]); 00330 } 00331 free(pvarTmp); 00332 } 00333 } 00334 SafeArrayUnaccessData(varSrc.parray); 00335 } 00336 else { 00337 VARIANT varTmp; 00338 VariantInit(&varTmp); 00339 hr = VariantChangeType(&varTmp, &varSrc, 0, VT_BSTR); 00340 if(SUCCEEDED(hr)) { 00341 *chDest = ConvertWideChar2MultiByte(varTmp.bstrVal); 00342 if(*chDest == NULL) hr = E_OUTOFMEMORY; 00343 } 00344 VariantClear(&varTmp); 00345 } 00346 00347 return hr; 00348 }