DumontEXE 0.0.1
typelib.cpp
00001 
00002 #include <QDebug>
00003 
00004 #include "TypeLib.h"
00005 
00006 #include <oaidl.h>
00007 #include "VariantHelper.h"
00008 
00009 void TypeLib::init(void)
00010 {
00011   typeLib_       = 0;
00012   nofTypeInfos_  = 0;
00013   curTypeInfo_   =-1;
00014   curITypeInfo_  = 0;
00015   curTypeAttr_   = 0;
00016   curFunc_       = -1;
00017   curVar_        = 0;
00018   curFuncParam_  = 0;
00019   funcNames_     = 0;
00020   curVarDesc_    = 0;
00021   curFuncDesc_   = 0;
00022 }  
00023 
00024 void TypeLib::init( ITypeInfo * i_typeInfo )
00025 {
00026   if( i_typeInfo )
00027   {
00028     init();
00029     UINT index = 0;
00030     i_typeInfo -> GetContainingTypeLib( &typeLib_, &index );
00031     qDebug( "typelib index %d %p %p", index, typeLib_, i_typeInfo );
00032     if( typeLib_ )
00033     {
00034       nofTypeInfos_ = typeLib_ -> GetTypeInfoCount();
00035     }
00036   }
00037 }  
00038 
00039 
00040 TypeLib::TypeLib()
00041 {
00042   init();
00043 }
00044 
00045 TypeLib::TypeLib( IDispatch * i_dispatch )
00046 {
00047   if( i_dispatch )
00048   {
00049     UINT typeInfoCount = 0;
00050     i_dispatch -> GetTypeInfoCount( &typeInfoCount );
00051 
00052     qDebug( "TypeLib typeInfoCount %d", typeInfoCount );
00053 
00054     if( typeInfoCount )
00055     {
00056       ITypeInfo * ppTInfo = NULL;
00057   
00058       i_dispatch -> GetTypeInfo( 0, 0, &ppTInfo );
00059   
00060       init( ppTInfo );
00061     }
00062   }
00063 }
00064 
00065 TypeLib::TypeLib( ITypeLib * i_typeLib )
00066 {
00067   init();
00068   typeLib_ = i_typeLib;
00069   nofTypeInfos_ = typeLib_->GetTypeInfoCount();
00070 }
00071 
00072 TypeLib::TypeLib( ITypeInfo * i_typeInfo )
00073 {
00074   init( i_typeInfo );
00075 }
00076 
00077 void TypeLib::dump(void)
00078 {
00079   qDebug( "Lib Documentation %s",  QString::fromStdString(LibDocumentation()).toAscii().data() );
00080 
00081   int nofTypeInfos = NofTypeInfos();
00082 
00083   qDebug( "Nof Type Infos: %d", nofTypeInfos );
00084   
00085   while( NextTypeInfo() )
00086   {
00087     curITypeInfo_ -> GetTypeAttr(&curTypeAttr_);
00088 
00089     std::string type_doc = TypeDocumentation(); 
00090 
00091     qDebug( " " );
00092     qDebug( "%s", QString::fromStdString(type_doc).toAscii().data() );
00093     qDebug( "----------------------------" );
00094 
00095     if( IsTypeEnum     () )  qDebug( "  Interface: Enum"      ); 
00096     if( IsTypeRecord   () )  qDebug( "  Interface: Record"    ); 
00097     if( IsTypeModule   () )  qDebug( "  Interface: Module"    ); 
00098     if( IsTypeInterface() )  qDebug( "  Interface: Interface" ); 
00099     if( IsTypeDispatch () )  qDebug( "  Interface: Dispatch"  ); 
00100     if( IsTypeCoClass  () )  qDebug( "  Interface: CoClass"   ); 
00101     if( IsTypeAlias    () )  qDebug( "  Interface: Alias"     ); 
00102     if( IsTypeUnion    () )  qDebug( "  Interface: Union"     ); 
00103     if( IsTypeMax      () )  qDebug( "  Interface: Max"       ); 
00104 
00105     int nofFunctions=NofFunctions();
00106     int nofVariables=NofVariables();
00107 
00108     qDebug( "  functions: %d", nofFunctions );
00109     qDebug( "  variables: %d", nofVariables );
00110 
00111     while( NextFunction() )
00112     {
00113       qDebug( "  Function     : %s %lx", QString::fromStdString(FunctionName()).toAscii().data(), curFuncDesc_->memid );
00114 
00115       qDebug( "    returns    : %s", QString::fromStdString(ReturnType()).toAscii().data() );
00116 
00117       if (HasFunctionTypeFlag(TypeLib::FDEFAULT      )) qDebug( "    flags      : FDEFAULT "      );
00118       if (HasFunctionTypeFlag(TypeLib::FSOURCE       )) qDebug( "    flags      : FSOURCE "       );
00119       if (HasFunctionTypeFlag(TypeLib::FRESTRICTED   )) qDebug( "    flags      : FRESTRICTED "   );
00120       if (HasFunctionTypeFlag(TypeLib::FDEFAULTVTABLE)) qDebug( "    flags      : FDEFAULTVTABLE ");
00121 
00122       TypeLib::INVOKEKIND ik = InvokeKind();
00123       switch (ik) {
00124         case TypeLib::func: 
00125           qDebug( "    invoke kind: function");
00126           break;
00127         case TypeLib::put: 
00128           qDebug( "    invoke kind: put");
00129           break;
00130         case TypeLib::get: 
00131           qDebug( "    invoke kind: get");
00132           break;
00133         case TypeLib::putref: 
00134           qDebug( "    invoke kind: put ref");
00135           break;
00136         default:
00137           qDebug( "    invoke kind: ???");
00138       }
00139 
00140       qDebug( "    params     : %d", NofParameters()         );
00141       qDebug( "    params opt : %d", NofOptionalParameters() );
00142 
00143       while (NextParameter()) {
00144         qDebug( "    Parameter  : " );
00145         if (ParameterIsIn         ()) qDebug(  " type =  in"    );
00146         if (ParameterIsOut        ()) qDebug(  " type =  out"   );
00147         if (ParameterIsFLCID      ()) qDebug(  " type =  flcid" );
00148         if (ParameterIsReturnValue()) qDebug(  " type =  ret"   );
00149         if (ParameterIsOptional   ()) qDebug(  " type =  opt"   );
00150         if (ParameterHasDefault   ()) qDebug(  " type =  def"   );
00151         if (ParameterHasCustumData()) qDebug(  " type =  cust"  );
00152       }
00153     }
00154 
00155     while (NextVariable()) {
00156       qDebug( "  Variable : %s", QString::fromStdString(VariableName()).toAscii().data() );
00157       qDebug( "      Type : %s", QString::fromStdString(VariableType()).toAscii().data() );
00158       TypeLib::VARIABLEKIND vk = VariableKind();
00159       switch (vk) {
00160         case TypeLib::instance: qDebug( " (instance)" ); break;
00161         case TypeLib::static_ : qDebug( " (static)"   ); break;
00162         case TypeLib::const_  : qDebug( " (const %s)",
00163              QString::fromStdString(ConstValue()).toAscii().data() );            break;
00164         case TypeLib::dispatch: qDebug( " (dispatch)"  ); break;
00165         default:
00166           qDebug( "    variable kind: unknown" );
00167       }
00168     }
00169   }
00170   
00171 }  
00172 
00173 #define QS(x) QString::fromStdString(x).toAscii.data()
00174 
00175 bool TypeLib::Open(std::string const& type_lib_file) 
00176 {
00177   ::OleInitialize(0);
00178   std::wstring ws_type_lib_file = s2ws(type_lib_file);
00179   HRESULT hr = ::LoadTypeLib(ws_type_lib_file.c_str(), &typeLib_);
00180 
00181   if (hr != S_OK) {
00182     qDebug( "Error with LoadTypeLibrary" );
00183 
00184     return false;
00185   }
00186   nofTypeInfos_ = typeLib_->GetTypeInfoCount();
00187   return true;
00188 }
00189 
00190 bool TypeLib::NextTypeInfo() {
00191   curTypeInfo_++;
00192 
00193   curFunc_     = -1;
00194   curVar_      = -1;
00195 
00196   if (curTypeInfo_ >= nofTypeInfos_) return false;
00197 
00198   // TODO: warum curTypeAttr_
00199   if (curTypeAttr_ && curITypeInfo_) 
00200   {
00201     curITypeInfo_ -> ReleaseTypeAttr(curTypeAttr_);
00202   }
00203 
00204   if (typeLib_) 
00205   {
00206     HRESULT hr=typeLib_-> GetTypeInfo(curTypeInfo_, &curITypeInfo_);
00207     if (hr == S_OK) 
00208     {
00209       curITypeInfo_ -> GetTypeAttr(&curTypeAttr_);
00210 
00211       return true;
00212     }
00213   }
00214 
00215   return false;
00216 }
00217 
00218 bool TypeLib::IsTypeEnum() {
00219   return IsTypeKind(TKIND_ENUM);
00220 }
00221 bool TypeLib::IsTypeRecord() {
00222   return IsTypeKind(TKIND_RECORD);
00223 }
00224 bool TypeLib::IsTypeModule() {
00225   return IsTypeKind(TKIND_MODULE);
00226 }
00227 bool TypeLib::IsTypeInterface() {
00228   return IsTypeKind(TKIND_INTERFACE);
00229 }
00230 bool TypeLib::IsTypeDispatch() {
00231   return IsTypeKind(TKIND_DISPATCH);
00232 }
00233 bool TypeLib::IsTypeCoClass() {
00234   return IsTypeKind(TKIND_COCLASS);
00235 }
00236 bool TypeLib::IsTypeAlias() {
00237   return IsTypeKind(TKIND_ALIAS);
00238 }
00239 bool TypeLib::IsTypeUnion() {
00240   return IsTypeKind(TKIND_UNION);
00241 }
00242 bool TypeLib::IsTypeMax() {
00243   return IsTypeKind(TKIND_MAX);
00244 }
00245 bool TypeLib::IsTypeKind(int i) {
00246 
00247   TYPEKIND tk = TKIND_MAX;
00248   if( curTypeAttr_ )
00249     tk = curTypeAttr_->typekind;
00250 
00251   return i == tk;
00252 }
00253 
00254 std::string TypeLib::LibDocumentation()
00255 {
00256   if (! typeLib_ ) return "No Type Library open!";
00257 
00258   BSTR name;
00259   BSTR doc;
00260   unsigned long ctx;
00261   
00262   HRESULT hr = typeLib_->GetDocumentation(
00263     -1,
00264     &name,
00265     &doc,
00266     &ctx,
00267     0  // Help File
00268     );
00269 
00270   if (hr != S_OK) {
00271     return "";
00272   }
00273   
00274   std::string sName = ws2s(name);
00275   std::string sDoc;
00276   if (doc) {
00277     sDoc = ws2s(doc);
00278   }
00279   
00280   ::SysFreeString(name);
00281   ::SysFreeString(doc );
00282   
00283   return sName + ": " + sDoc;
00284 }
00285 
00286 std::string TypeLib::TypeDocumentation() {
00287   return TypeDocumentation_(curITypeInfo_);
00288 }
00289 
00290 std::string TypeLib::TypeDocumentation_(ITypeInfo* i) {
00291   BSTR name;
00292   unsigned long ctx;
00293   
00294   HRESULT hr = i->GetDocumentation(
00295     MEMBERID_NIL, //idx,
00296     &name,
00297     0,//&doc,
00298     &ctx,
00299     0  // Help File
00300     );
00301 
00302   if (hr != S_OK) {
00303     return "";
00304   }
00305   
00306   std::string sName = ws2s(name);
00307   
00308   ::SysFreeString(name);
00309   return sName;
00310 }
00311 
00312 TypeLib::INVOKEKIND TypeLib::InvokeKind() {
00313   return static_cast<INVOKEKIND>(curFuncDesc_->invkind);
00314 }
00315 
00316 TypeLib::VARIABLEKIND TypeLib::VariableKind() {
00317   return static_cast<VARIABLEKIND>(curVarDesc_->varkind);
00318 }
00319 
00320 bool TypeLib::NextFunction() 
00321 {
00322   if( !curTypeAttr_ ) return( false );
00323 
00324   ReleaseFuncNames();
00325 
00326   curFunc_ ++;
00327   curFuncParam_= -1;
00328 
00329   if (curFunc_ >= curTypeAttr_->cFuncs) return false;
00330 
00331   if (curFuncDesc_) {
00332     curITypeInfo_->ReleaseFuncDesc(curFuncDesc_);
00333   }
00334 
00335   HRESULT hr = curITypeInfo_-> GetFuncDesc(curFunc_, &curFuncDesc_);
00336   GetFuncNames();
00337 
00338   if (hr != S_OK) {
00339     return false;
00340   }
00341 
00342   // Is that correct? What is actually a IMPLTYPEFLAG?
00343   curITypeInfo_ -> GetImplTypeFlags (curFunc_, &curImplTypeFlags_);
00344 
00345   return true;
00346 }
00347 
00348 bool TypeLib::HasFunctionTypeFlag(TYPEFLAG tf) {
00349   return curImplTypeFlags_ & static_cast<int>(tf);
00350 }
00351 
00352 std::string TypeLib::ConstValue() {
00353   if (VariableKind() != const_) {
00354     return "VariableKind must be const_";
00355   }
00356   //VARIANT v=*(curVarDesc_->lpvarValue);
00357   variant v=*(curVarDesc_->lpvarValue);
00358 
00359   return v.ValueAsString();
00360 }
00361 
00362 std::string TypeLib::UserdefinedType(HREFTYPE hrt) {
00363   std::string tp="";
00364 
00365   ITypeInfo* itpi;
00366   curITypeInfo_ -> GetRefTypeInfo(hrt, &itpi);
00367   std::string ref_type = TypeDocumentation_(itpi);
00368   tp += ref_type;
00369 
00370   return tp;
00371 }
00372 
00373 std::string TypeLib::Type(ELEMDESC const& ed) {
00374   TYPEDESC td = ed.tdesc;
00375 
00376   std::string tp = TypeAsString(td.vt);
00377 
00378   if (td.vt==VT_PTR) {
00379     TYPEDESC ptr_td = *(td.lptdesc);
00380     tp += " (";
00381     tp += TypeAsString(ptr_td.vt);
00382     if (ptr_td.vt == VT_USERDEFINED) {
00383       tp += " (";
00384       HREFTYPE hrt = ptr_td.hreftype;
00385       tp += UserdefinedType(hrt);
00386       tp += ")";
00387     }
00388     tp += ")";
00389   }
00390   else if (td.vt == VT_USERDEFINED) {
00391     tp += " (";
00392     tp += UserdefinedType(td.hreftype);
00393     tp += ")";
00394   }
00395   else if (td.vt == VT_SAFEARRAY) {
00396     // TODO
00397   }
00398 
00399   return tp;
00400 }
00401 
00402 std::string TypeLib::ParameterType() {
00403 
00404   ELEMDESC ed;
00405   if( curFuncDesc_ )
00406     ed = curFuncDesc_->lprgelemdescParam[curFuncParam_];
00407 
00408   return Type(ed);
00409 }
00410 
00411 std::string TypeLib::VariableType() {
00412 
00413   ELEMDESC ed;
00414   if( curVarDesc_ )
00415     ed = curVarDesc_->elemdescVar;
00416 
00417   return Type(ed);
00418 }
00419 
00420 std::string TypeLib::ReturnType() {
00421   ELEMDESC ed ;
00422   if( curFuncDesc_ )
00423     ed = curFuncDesc_->elemdescFunc;
00424 
00425   return Type(ed);
00426 }
00427 
00428 bool TypeLib::NextVariable() {
00429   curVar_ ++;
00430 
00431   if( !curTypeAttr_ ) return(false);
00432   
00433   // TODO: curVar_->cVars accessed through NofVariables().
00434   if (curVar_ >= curTypeAttr_->cVars) return false;
00435 
00436   if (curVarDesc_) {
00437     curITypeInfo_->ReleaseVarDesc(curVarDesc_);
00438   }
00439 
00440   HRESULT hr = curITypeInfo_->GetVarDesc(curVar_, &curVarDesc_);
00441 
00442   if (hr != S_OK) {
00443     return false;
00444   }
00445 
00446   return true;
00447 }
00448 
00449 bool TypeLib::NextParameter() {
00450 
00451   qDebug( "curFuncParam_ %u", curFuncParam_ );
00452 
00453   curFuncParam_ ++;
00454   if( !curFuncParam_ ) return(false);
00455   
00456   if (curFuncParam_ >= NofParameters()) return false;
00457 
00458   return true;
00459 }
00460 
00461 std::string TypeLib::VariableName() {
00462   BSTR varName;
00463 
00464   unsigned int dummy;
00465 
00466   HRESULT hr = curITypeInfo_->GetNames(curVarDesc_->memid, &varName, 1, &dummy);
00467 
00468   if (hr!= S_OK) {
00469     return "GetNames failed";
00470   }
00471 
00472   std::string ret = ws2s(varName);
00473 
00474   ::SysFreeString(varName);
00475 
00476   return ret;
00477 }
00478 
00479 std::string TypeLib::ParameterName() {
00480   if (1+curFuncParam_ >= static_cast<int>(nofFuncNames_)) return "<nameless>";
00481 
00482   BSTR paramName = funcNames_[1+curFuncParam_];
00483 
00484   std::string ret = ws2s(paramName);
00485 
00486   return ret;
00487 }
00488 
00489 // http://doc.ddart.net/msdn/header/include/oaidl.h.html
00490 //  return ParameterIsHasX(PARAMFLAG_NONE);
00491 bool TypeLib::ParameterIsIn() {
00492   return ParameterIsHasX(PARAMFLAG_FIN);
00493 }
00494 bool TypeLib::ParameterIsOut() {
00495   return ParameterIsHasX(PARAMFLAG_FOUT);
00496 }
00497 bool TypeLib::ParameterIsFLCID() {
00498   return ParameterIsHasX(PARAMFLAG_FLCID);
00499 }
00500 bool TypeLib::ParameterIsReturnValue() {
00501   return ParameterIsHasX(PARAMFLAG_FRETVAL);
00502 }
00503 bool TypeLib::ParameterIsOptional() {
00504   return ParameterIsHasX(PARAMFLAG_FOPT);
00505 }
00506 bool TypeLib::ParameterHasDefault() {
00507   return ParameterIsHasX(PARAMFLAG_FHASDEFAULT);
00508 }
00509 bool TypeLib::ParameterHasCustumData() {
00510   return ParameterIsHasX(0x40 /*PARAMFLAG_FHASCUSTDATA*/);
00511 }
00512 bool TypeLib::ParameterIsHasX(int flag) {
00513   ELEMDESC e = curFuncDesc_->lprgelemdescParam[curFuncParam_];
00514   return e.paramdesc.wParamFlags & flag;
00515 }
00516 
00517 void TypeLib::ReleaseFuncNames() 
00518 {
00519   if( funcNames_ )
00520   {
00521     for (int i=0;i<static_cast<int>(nofFuncNames_); i++) {
00522       ::SysFreeString(funcNames_[i]);
00523     }
00524 
00525     delete [] funcNames_;
00526     funcNames_=0;
00527   }
00528 }
00529 
00530 void TypeLib::GetFuncNames() 
00531 {
00532   unsigned int nof_names = 1 + NofParameters();
00533 
00534   funcNames_ = new BSTR[nof_names];
00535 
00536   HRESULT hr = curITypeInfo_->GetNames(curFuncDesc_->memid, funcNames_, nof_names, &nofFuncNames_);
00537 
00538   if (hr!= S_OK) {
00539   }
00540 }
00541 
00542 std::string TypeLib::FunctionName() {
00543   BSTR funcName = funcNames_[0];
00544 
00545   std::string ret = ws2s(funcName);
00546 
00547   return ret;
00548 }
00549 
00550 int TypeLib::NofVariables() {
00551   if( curTypeAttr_ )
00552     return curTypeAttr_->cVars;
00553   return( 0 );
00554 }
00555 
00556 int TypeLib::NofFunctions() {
00557   if( curTypeAttr_ )
00558     return curTypeAttr_->cFuncs;
00559   return( 0 );
00560   
00561 }
00562 
00563 int TypeLib::NofTypeInfos() {
00564   return nofTypeInfos_;
00565 }
00566 
00567 short TypeLib::NofParameters() {
00568   if( curFuncDesc_ )
00569     return curFuncDesc_->cParams;
00570   return( 0 );
00571 }
00572 
00573 short TypeLib::NofOptionalParameters() {
00574   if( curFuncDesc_ )
00575     return curFuncDesc_->cParamsOpt;
00576   return( 0 );
00577   
00578 }
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties




~ ~ ~ ~ ~ ~
Source Code without Comments is like a Cranberry Garland
without the berries. Comment your Code!
 
Commence Database User Support Group Forum
http://newsgroup.showoff-db.org/
~ ~ ~ ~ ~ ~
Author: Mark Petryk
Lorimark Solutions, LLC
mark@lorimarksolutions.com