GME
13
|
00001 00002 #ifndef MGA_COMMONSTL_H 00003 #define MGA_COMMONSTL_H 00004 00005 #include <vector> 00006 #include <string> 00007 #include <hash_map> 00008 00009 #ifndef MGA_COMMONSMART_H 00010 #include "CommonSmart.h" 00011 #endif 00012 00013 // --------------------------- string 00014 00015 // we use "const string &" for [in] and "string &" for [in, out] 00016 00017 // these THROW exceptions 00018 00019 /* needed for MS STL 00020 inline void CopyTo(const std::string::const_iterator i, int l, BSTR * b){} 00021 inline void CopyTo(const std::string::const_iterator i, int l, VARIANT *v){} 00022 inline void CopyTo(const std::string::const_iterator i, int l, CComBstrObj &a){} 00023 inline void CopyTo(const std::string::const_iterator i, int l, CComVariant &a){} 00024 inline void CopyTo(BSTR b, std::string::iterator i, int l) {} 00025 inline void CopyTo(VARIANT &v, std::string::iterator i, int l) {} 00026 */ 00027 inline void CopyTo(const std::string &s, BSTR *b) { CopyTo( s.c_str(), s.length(), b); } 00028 inline void CopyTo(const std::string &s, VARIANT *v) { CopyTo(s.c_str(), s.length(), v); } 00029 inline void CopyTo(const std::string &s, CComBstrObj &a) { CopyTo(s.c_str(), s.length(), a); } 00030 inline void CopyTo(const std::string &s, CComVariant &a) { CopyTo(s.c_str(), s.length(), a); } 00031 00032 inline void CopyTo(BSTR b, std::string &s) 00033 { 00034 int l = GetCharLength(b); 00035 char *tmp = (char*)malloc(l); 00036 if (tmp == NULL) 00037 COMTHROW(E_OUTOFMEMORY); 00038 CopyTo(b, tmp, l); 00039 s.assign(tmp, l); 00040 free(tmp); 00041 } 00042 00043 inline void CopyTo(VARIANT &v, std::string &s) 00044 { 00045 int l = GetCharLength(v); 00046 char *tmp = (char*)malloc(l); 00047 if (tmp == NULL) 00048 COMTHROW(E_OUTOFMEMORY); 00049 CopyTo(v, tmp, l); 00050 s.assign(tmp, l); 00051 free(tmp); 00052 } 00053 00054 void vFormat(std::string &s, const char *format, va_list args); 00055 void vFormat(std::wstring &s, const wchar_t *format, va_list args); 00056 00057 inline void Format(std::string &s, const char *format, ...) 00058 { 00059 va_list args; 00060 va_start(args, format); 00061 00062 vFormat(s, format, args); 00063 } 00064 00065 inline void Format(std::wstring &s, const wchar_t *format, ...) 00066 { 00067 va_list args; 00068 va_start(args, format); 00069 00070 vFormat(s, format, args); 00071 } 00072 00073 typedef wchar_t* bstr_iterator; 00074 typedef const wchar_t* bstr_const_iterator; 00075 00076 inline bstr_const_iterator begin(BSTR p) { return reinterpret_cast<wchar_t*>(p); } 00077 inline bstr_const_iterator end(BSTR p) { return reinterpret_cast<wchar_t*>(p) ? (reinterpret_cast<wchar_t*>(p) + SysStringLen(p)) : 0; } 00078 00079 inline void CopyTo(bstr_const_iterator i, bstr_const_iterator e, CComBstrObj &b) 00080 { 00081 ASSERT( i <= e ); 00082 BSTR tmpb = SysAllocStringLen(i, e - i); 00083 if (tmpb == NULL) 00084 COMTHROW(E_OUTOFMEMORY); 00085 00086 b.Attach(tmpb); 00087 } 00088 00089 // --------------------------- bindata 00090 00091 typedef std::vector<unsigned char> bindata; 00092 00093 inline void CopyTo(const bindata &b, VARIANT *p) 00094 { 00095 if(b.empty()) 00096 { 00097 unsigned char* pnull=NULL; 00098 CopyTo(pnull,pnull, p); 00099 } 00100 else 00101 { 00102 CopyTo(&b[0], (&b[0]) + b.size(), p); 00103 } 00104 } 00105 inline void CopyTo(const bindata &b, CComVariant &a) { CopyTo(&b[0], (&b[0]) + b.size(), a); } 00106 00107 inline void CopyTo(VARIANT &v, bindata &b) 00108 { 00109 if( v.vt == (VT_I4 | VT_ARRAY) ) 00110 { 00111 b.resize(sizeof(long) * GetArrayLength(v)); 00112 CopyTo(v, (long*)&b[0], (long*)((&b[0]) + b.size()) ); 00113 } 00114 else 00115 { 00116 if(GetArrayLength(v)==0) 00117 { 00118 b.clear(); 00119 } 00120 else 00121 { 00122 b.resize(GetArrayLength(v)); 00123 CopyTo(v, &b[0], (&b[0]) + b.size()); 00124 } 00125 } 00126 } 00127 00128 inline void MoveTo(SAFEARRAY *p, std::vector<CComBstrObj> &bstrobjs) 00129 { 00130 ASSERT( p != NULL ); 00131 00132 bstrobjs.resize(GetArrayLength(p)); 00133 MoveTo(p, &bstrobjs[0], (&bstrobjs[0]) + bstrobjs.size()); 00134 } 00135 00136 inline void MoveTo(std::vector<CComBstrObj> &bstrobjs, SAFEARRAY **p) 00137 { 00138 ASSERT( p != NULL && *p == NULL ); 00139 00140 MoveTo(&bstrobjs[0], (&bstrobjs[0]) + bstrobjs.size(), p); 00141 } 00142 00143 inline void CopyTo(const std::vector<CComBstrObj> &bstrobjs, SAFEARRAY **p) 00144 { 00145 ASSERT( p != NULL && *p == NULL ); 00146 00147 CopyTo(&bstrobjs[0], (&bstrobjs[0]) + bstrobjs.size(), p); 00148 } 00149 00150 inline void CopyTo(const std::vector<GUID> &guids, SAFEARRAY **p) 00151 { 00152 ASSERT( p != NULL && *p == NULL ); 00153 00154 if(guids.empty()) 00155 { 00156 GUID* pnull=NULL; 00157 CopyTo(pnull,pnull,p); 00158 } 00159 else 00160 { 00161 CopyTo(&guids[0], (&guids[0]) + guids.size(), p); 00162 } 00163 } 00164 00165 // --------------------------- STL function objects 00166 00167 template <class T> 00168 struct ptr_compare : public stdext::hash_compare<T> 00169 { 00170 size_t operator()(const T* p) const { return (size_t) p; } 00171 bool operator()(const T *a, const T *b) const { return a < b; } 00172 00173 // both hashing and comparing must be implemented here 00174 }; 00175 00176 // --------------------------- Iterator 00177 00178 #ifdef _DEBUG 00179 00180 template<class CONTAINER> 00181 inline bool IsValidIterator(const CONTAINER &container, typename CONTAINER::const_iterator i) 00182 { 00183 CONTAINER::const_iterator b = container.begin(); 00184 CONTAINER::const_iterator e = container.end(); 00185 00186 while( b != e ) 00187 { 00188 if( b == i ) 00189 return true; 00190 ++b; 00191 } 00192 00193 return false; 00194 } 00195 00196 #endif 00197 00198 template<class CONTAINER> 00199 inline int limited_size(const CONTAINER &container, int limit) 00200 { 00201 ASSERT( limit >= 1 ); 00202 int counter = limit; 00203 00204 CONTAINER::const_iterator i = container.begin(); 00205 CONTAINER::const_iterator e = container.end(); 00206 while( i != e && --counter > 0 ) 00207 ++i; 00208 00209 ASSERT( ( (int) container.size() < limit ? (int) container.size() : limit) == (limit - counter) ); 00210 return limit - counter; 00211 } 00212 00213 // --------------------------- Collection 00214 00215 template<class INTERFACE> 00216 class CComObjPtrVector : public std::vector< CComObjPtr<INTERFACE> > 00217 { 00218 }; 00219 00220 template<class ELEM> 00221 void CopyTo( TYPENAME_ELEM2COLL(ELEM) *p, std::vector< CComObjPtr<ELEM> > &q) 00222 { 00223 ASSERT( p != NULL ); 00224 ASSERT( &q != NULL ); 00225 00226 q.clear(); 00227 00228 long count = 0; 00229 COMTHROW( p->get_Count(&count) ); 00230 ASSERT( count >= 0 ); 00231 00232 if(count > 0) 00233 { 00234 //q.insert(q.begin(), count, CComObjPtr<ELEM>()); 00235 q.resize(count); 00236 00237 COMTHROW( p->GetAll(count, (ELEM**)&q[0]) ); 00238 } 00239 } 00240 00241 template<class ELEM> 00242 class PutOutCollObj; // forward declaration for the template class 00243 00244 00245 // this template function will be befriended with the PutOutCollObj class, in VS.NET 2003 sucha friend needs to be declared before the class declaration 00246 template<class ELEM> 00247 PutOutCollObj<ELEM> PutOut( std::vector< CComObjPtr<ELEM> > & coll_vector); 00248 00249 00250 template<class ELEM> 00251 class PutOutCollObj 00252 { 00253 public: 00254 typedef ELEM elem_interface; 00255 typedef TYPENAME_ELEM2COLL(ELEM) coll_interface; 00256 00257 typedef std::vector< CComObjPtr<elem_interface> > vector_type; 00258 00259 operator coll_interface** () { return PutOut(coll_ptr); } 00260 00261 ~PutOutCollObj() 00262 { 00263 // we need this because COM methods might 00264 // not fill in the [out] parameter 00265 00266 if( coll_ptr != NULL ) 00267 CopyTo(coll_ptr, coll_vector); 00268 } 00269 00270 private: 00271 PutOutCollObj(vector_type &v) : coll_vector(v) { } 00272 00273 friend PutOutCollObj<ELEM> PutOut<ELEM>( std::vector< CComObjPtr<ELEM> > &coll_vector); 00274 00275 // to prevent misuse 00276 PutOutCollObj(); 00277 PutOutCollObj(const PutOutCollObj<ELEM> &a); 00278 00279 public: 00280 CComObjPtr<coll_interface> coll_ptr; 00281 vector_type &coll_vector; 00282 }; 00283 00284 // this template function (friend of PutOutCollObj) needs to be forward declared! 00285 template<class ELEM> 00286 PutOutCollObj<ELEM> PutOut( std::vector< CComObjPtr<ELEM> > & coll_vector) 00287 { 00288 return PutOutCollObj<ELEM>( coll_vector); 00289 } 00290 00291 #endif//MGA_COMMONSTL_H