OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
autosym.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectComponents
3// Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// OLE Automation Server Implementation, except TServedObject (in typelib.cpp)
7//----------------------------------------------------------------------------
8#include <ocf/pch.h>
9
10#include <ocf/appdesc.h>
11#include <ocf/ocreg.h>
12#include <ocf/occtrl.h>
13
14namespace ocf {
15
16using namespace owl;
17
18TAutoType TAutoVoid ::ClassInfo = {atVoid};
19TAutoType TAutoByte ::ClassInfo = {atByte};
20TAutoType TAutoShort ::ClassInfo = {atShort};
21TAutoType TAutoLong ::ClassInfo = {atLong};
22TAutoType TAutoFloat ::ClassInfo = {atFloat};
23TAutoType TAutoDouble ::ClassInfo = {atDouble};
24TAutoType TAutoCurrency ::ClassInfo = {atCurrency};
25TAutoType TAutoDate ::ClassInfo = {atDatetime};
26TAutoType TAutoString ::ClassInfo = {atString};
27TAutoType TAutoBool ::ClassInfo = {atBool};
28TAutoType TAutoUnknown ::ClassInfo = {atUnknown};
29TAutoType TAutoDispatch ::ClassInfo = {atObject};
30TAutoType TAutoVariant ::ClassInfo = {atVariant};
31TAutoType TAutoSafeArray ::ClassInfo = {atSafeArray};
32TAutoType TAutoShortRef ::ClassInfo = {atByRef|atShort};
33TAutoType TAutoLongRef ::ClassInfo = {atByRef|atLong};
34TAutoType TAutoFloatRef ::ClassInfo = {atByRef|atFloat};
35TAutoType TAutoDoubleRef ::ClassInfo = {atByRef|atDouble};
37TAutoType TAutoDateRef ::ClassInfo = {atByRef|atDatetime};
38TAutoType TAutoStringRef ::ClassInfo = {atByRef|atString};
39TAutoType TAutoVariantRef ::ClassInfo = {atByRef|atVariant};
40TAutoType TAutoBoolRef ::ClassInfo = {atByRef|atBool};
41TAutoType TAutoByteRef ::ClassInfo = {atByRef|atByte};
42
43
44_OCFFUNC(void) SendObituary(const void * obj, const std::type_info& typeInfo)
45{
47 if (appDesc)
48 appDesc->InvalidateObject(ocf::MostDerived(obj, typeInfo));
49}
50//----------------------------------------------------------------------------
51// TAutoClass implementation
52//
53
54TAutoClass::TClassList TAutoClass::ClassList = {0,0,0};// MUST BE MODULE GLOBAL
55
57 const std::type_info& typeInfo, TAggregator aggregator)
58 : Table(table), ClassSymbol(classSymbol), TypeInfo(typeInfo),
59 Aggregator(aggregator), AutoIds (TRUE)
60{
62 NextClass = ClassList.List;
63 ClassList.List = this;
64 ClassList.Count++;
65}
66
67TAutoClass::~TAutoClass() // do we really need to support dynamic AutoClass?
68{
69 for (TAutoClass** link = &ClassList.List; *link != 0; link = &(*link)->NextClass)
70 if (*link == this) {
71 *link = NextClass;
72 break;
73 }
74}
75
77{
79 if (!CommandCount) {
80 for (sym = Table; !sym->IsTerminator(); sym++) {
81 int attr = sym->GetFlags();
82 if (attr & asAnyCommand) {
84 if (attr & asOleType) {
85 if ((attr & asGetSet) == asGetSet)
87 else
89 }
90 } else if (sym->TestFlag(asClass)) {
91 TAutoClass* cls = sym->GetClass();
92 if (!sym->SymCount)
93 sym->SymCount = cls->CountCommands();
94 CommandCount += cls->CommandCount;
95 VariableCount += cls->VariableCount;
96 FunctionCount += cls->FunctionCount;
97 }
98 }
99 }
100 return CommandCount;
101}
102
104{
106 long cmdId;
107 if ((id <= 0) || !(AutoIds)) {
108 // reserved dispatch ID if negative or zero or AutoIDs is false
109 for (sym = Table; !sym->IsTerminator(); sym++) {
110 if (sym->TestFlag(asAnyCommand) && sym->DispId == id)
111 return sym;
112
113 if (sym->TestFlag(asClass)) {
114 ObjectPtr adjObj = sym->Convert(obj); // this pointer adjustment
115 TAutoSymbol* fsym = sym->GetClass()->FindId(id, adjObj);
116 if (fsym) {
117 obj = adjObj;
118 return fsym;
119 }
120 }
121 }
122 } else {
123 for (cmdId = 0, sym = Table; !sym->IsTerminator(); sym++) {
124 if (sym->TestFlag(asClass)) {
125 if (!sym->SymCount)
126 sym->SymCount = sym->GetClass()->CountCommands();
127 if (cmdId + sym->SymCount >= id) { // symbol in nested class
128 obj = sym->Convert(obj);
129 return sym->GetClass()->FindId(id-cmdId, obj);
130 }
131 cmdId += sym->SymCount;
132 }
133 else if (sym->TestFlag(asAnyCommand)) {
134 cmdId++;
135 if (cmdId == id) {
136 if (sym->DispId == -1)
137 return sym;
138 else
139 break;
140 }
141 }
142 }
143 }
144 return 0;
145}
146
148{
150 int funcCount = 0;
151 long cmdId = retId;
152 for (sym = Table; !sym->IsTerminator(); sym++) {
153 int attr = sym->GetFlags();
154 if (attr & asAnyCommand) {
155 cmdId++;
156 if ((attr & asOleType) != 0 && (attr & asGetSet) != asGetSet) {
157 if (funcCount++ == (int)index) {
158 retId = (sym->DispId == -1L) ? cmdId : sym->DispId;
159 return sym;
160 }
161 }
162 } else if (sym->TestFlag(asClass)) {
163 TAutoClass* cls = sym->GetClass();
164 if (!sym->SymCount)
165 sym->SymCount = cls->CountCommands();
166 if (funcCount + cls->FunctionCount > (int)index) {
167 retId = int(cmdId);
168 return cls->FindFunction(index - funcCount, retId);
169 }
170 funcCount += cls->FunctionCount;
171 cmdId += cls->CommandCount;
172 }
173 }
174 return 0; // should never happen unless caller overruns total count
175}
176
178{
180 int varCount = 0;
181 long cmdId = retId;
182 for (sym = Table; !sym->IsTerminator(); sym++) {
183 int attr = sym->GetFlags();
184 if (attr & asAnyCommand) {
185 cmdId++;
186 if ((attr & asGetSet) == asGetSet) {
187 if (varCount++ == (int)index) {
188 retId = (sym->DispId == -1L) ? cmdId : sym->DispId;
189 return sym;
190 }
191 }
192 } else if (sym->TestFlag(asClass)) {
193 TAutoClass* cls = sym->GetClass();
194 if (!sym->SymCount)
195 sym->SymCount = cls->CountCommands();
196 if (varCount + cls->VariableCount > (int)index){
197 retId = int(cmdId);
198 return cls->FindVariable(index - varCount, retId);
199 }
200 varCount += cls->VariableCount;
201 cmdId += cls->CommandCount;
202 }
203 }
204 return 0; // should never happen unless caller overruns total count
205}
206
208{
209 short count = 0;
210 TAutoSymbol* arg = &sym;
211 while ((++arg)->TestFlag(asArgument))
212 count++;
213 return count;
214}
215
217 long & retid)
218{
219 long cmdId = 0;
220 for (TAutoSymbol* sym = Table; !sym->IsTerminator(); sym++) {
221 if (sym->TestFlag(asAnyCommand))
222 cmdId++;
223 if (sym->TestFlag(symflags) && sym->Name.Compare(name, lang) == 0) {
224 retid = sym->DispId == -1 ? cmdId : sym->DispId;
225 return sym;
226 }
227 else if (sym->TestFlag(asClass)) {
228 TAutoClass* cls = sym->GetClass();
229 if (!sym->SymCount)
230 sym->SymCount = cls->CountCommands();
231 long id;
232 TAutoSymbol* found = cls->Lookup(name, lang, symflags, id);
233 if (found) {
234 retid = id > 0 ? id + (long)cmdId : id;
235 return found;
236 }
237 cmdId += sym->SymCount;
238 }
239 }
240 return 0;
241}
242
244 TAutoSymbol* sym, long & retid)
245{
247
248 for (int i = 0; (++sym)->TestFlag(asArgument); ++i)
249 if (sym->Name.Compare(name, lang) == 0) {
250 retid = (long)i;
251 return sym;
252 }
253 return 0;
254}
255
257 TUnknown& owner, int attr,
259{
260 TAutoCommand* cmdobj = 0;
261 TAutoIterator* iterator = 0;
262 try {
263 if (args.Symbol->IsIterator()) {
264 iterator = args.Symbol->BuildIter(obj, creator, owner, args.LangId);
265 iterator->SetSymbol(args.Symbol);
266 iterator->Init();
267 *retval = (IUnknown*)*iterator; // remains until RefCnt->0
268 } else {
269 cmdobj = args.Symbol->Build(obj, attr, args);
270 cmdobj->SetSymbol(args.Symbol);
271 if (args.ArgCount>0 && !cmdobj->Validate()) {// no validate for prop get
272 delete cmdobj;
274 }
275 cmdobj->Invoke();
276 if ((args.ErrorCode = cmdobj->Report()) != 0) {
277 args.ErrorMsg = TAutoCommand::LookupError(args.ErrorCode);
278 if (!args.ErrorMsg && args.Symbol) // if no error message available
279 args.ErrorMsg = args.Symbol->Name.Translate(args.LangId);
280 delete cmdobj;
282 }
283 if (retval) {
284 cmdobj->Return(*retval);
285 if (args.Symbol->IsEnum())
286 args.Symbol->GetEnum()->Convert(*retval, args.LangId);
288 if (retval->GetObjDesc(objDesc)) {
289 if (!objDesc.Object) // null pointer returned from function
290 // there are three choices for behavior here:
291 // 1. Allow a dead object to be returned, fail when passed back
292 // 2. Fail now, however this prevents testing for null pointer
293 // 3. Return an empty variant, causing script to fail when used
294 *retval = TAutoVoid(); // return an empty value if no object
295 else
296 *retval = creator.CreateDispatch(objDesc);
297 }
298 }
299 delete cmdobj;
300 }
301 }
302 catch(TXAuto& xobj) {
303 delete cmdobj;
304 delete iterator;
305 return xobj.ErrorCode;
306 }
307 return TXAuto::xNoError;
308}
309
310TAutoClass::TExtLink::TExtLink(TClassList* list, HINSTANCE module)
311 : Classes(list), Module(module), Next(0)
312{
313 for (Prev = &ClassList.Link; *Prev; Prev = &(*Prev)->Next)
314 ; // link to end of list
315}
316
317TAutoClass::TExtLink::~TExtLink()
318{
319 *Prev = Next;
320 if (Next)
321 Next->Prev = Prev;
322}
323
324//
325//
326//
327int
328TAutoClass::TClassList::CountAutoClasses()
329{
330 int count = Count;
331 for (TExtLink* link = Link; link; link = link->Next)
332 count += link->Classes->CountAutoClasses();
333 return count;
334}
335
336//
337//
338//
339TAutoClass::TAutoClassRef*
340TAutoClass::TClassList::MergeAutoClasses(TAutoClass::TAutoClassRef* array)
341{
342 for (TAutoClass* cls = List; cls; cls = cls->NextClass, array++)
343 array->Class = cls;
344 for (TExtLink* link = Link; link; link = link->Next)
345 array = link->Classes->MergeAutoClasses(array);
346 return array;
347}
348
349// ----------------------------------------------------------------------
350// Helper routines
351//
352
353//
354//
355TAutoCommand*
357{
358 TServedObject& owner = *args.Owner;
359
360 // if the automation object is not in control of the app, execute a no-op
361 //
362 if (owner.Destruct == TObjectDescriptor::Quiet)
363 return new TAutoCommand(0);
364
365 // if registered as the active object, free it to release OLE's refcnt
366 //
367 if (owner.Creator.GetAppDesc().IsActiveObject(&owner))
368 owner.Creator.GetAppDesc().UnregisterObject();
369
370 // disconnect automation from app to prevent further access
371 //
372 owner.Object = 0;
373 owner.RootObject = 0;
374
375 // build command object for destructor, will either delete or PostQuitMsg
376 //
377 return owner.Class->GetDestructor()(obj, owner.Destruct);
378}
379
380#if defined(BI_COMP_BORLANDC)
381} // OCF namespace
382//
383// Temporary defines for using std::type_info with dynamic cast
384//
385void* __cdecl __DynamicCast(void* object, void* vtable,
386 void* srctyp, void* dsttyp,
387 int reference = 0);
388struct tpid {int s; short m; short n; int VptrOffs; int Flags;}; // partial
389namespace ocf {
390#endif
391//
392//
393const void*
394DynamicCast(const void* obj, const std::type_info& src, const std::type_info& dst)
395{
396#if defined(__clang__) // TODO: This needs review!
397 return __DynamicCast((void*)obj, 0, (void*)&src, (void*)&dst, 0);
398#elif defined(BI_COMP_BORLANDC)
399 int vtblOff;
400 if (!obj)
401 return obj;
402 else if ((vtblOff = src.tpp->VptrOffs) == -1)
403 return src==dst ? obj : 0;
404 else
405 return __DynamicCast(const_cast<void *>(obj),
406 *(void **)((char*)obj+vtblOff), src.tpp,dst.tpp);
407#else
408 return __RTDynamicCast((void*)obj,0,(void*)&src,(void*)&dst,0);
409#endif //BI_COMP_BORLANDC
410}
411
412
413//
414//
415const void *
416MostDerived(const void * obj, const std::type_info& src)
417{
418#if defined(BI_COMP_BORLANDC) && !defined(__clang__) // TODO: This needs review for Clang!
419 int vtblOff;
420 if (!obj || (vtblOff = src.tpp->VptrOffs) == -1)
421 return obj;
422 else
423 return __DynamicCast(const_cast<void *>(obj),
424 *(void **)((char*)obj+vtblOff), src.tpp, 0);
425#else
426 return obj;
427#endif
428}
429
430
431//____________________________________________________________________________
432//
433// TAutoCommand implementation - inlined to allow definition of _AUTOCLASS
434//____________________________________________________________________________
435
438
439} // OCF namespace
440
441//==============================================================================
442
443
TAppDescriptor - OLE application descriptor definitions.
#define PRECONDITION(condition)
Definition checks.h:227
short CommandCount
command count including bases, 0 if uncounted
Definition autodefs.h:179
TAutoSymbol * Lookup(TCHAR *name, owl::TLangId lang, short symFlags, long &id)
Definition autosym.cpp:216
bool AutoIds
generate ID's automatically if true (default)
Definition autodefs.h:182
TAutoSymbol * FindVariable(unsigned index, MEMBERID &retId)
Definition autosym.cpp:177
friend struct TExtLink
access to ClassList
Definition autodefs.h:210
TXAuto::TError Dispatch(ObjectPtr obj, TAutoCreator &creator, TUnknown &owner, int attr, TAutoStack &args, TAutoVal *retval)
Definition autosym.cpp:256
TAutoClass(TAutoSymbol *table, TAutoSymbol *classSymbol, const std::type_info &typeInfo, TAggregator aggregator=0)
Definition autosym.cpp:56
friend struct TClassList
access to TAutoClassRef
Definition autodefs.h:211
short CountCommands()
Definition autosym.cpp:76
TAutoSymbol * Table
pointer to array of symbol entries
Definition autodefs.h:183
short VariableCount
number of symbols exposed as typelib variables
Definition autodefs.h:181
TAutoSymbol * FindFunction(unsigned index, MEMBERID &retId)
Definition autosym.cpp:147
TAutoSymbol * LookupArg(TCHAR *name, owl::TLangId lang, TAutoSymbol *cmd, long &retid)
Definition autosym.cpp:243
TAutoSymbol * FindId(long id, ObjectPtr &objptr)
Definition autosym.cpp:103
short FunctionCount
number of symbols exposed as typelib functions
Definition autodefs.h:180
short GetArgCount(TAutoSymbol &sym)
Definition autosym.cpp:207
Automation abstract base class for command objects.
Definition autodefs.h:846
static LPCTSTR LookupError(long errCode)
Definition autodefs.h:1827
LPCTSTR(* TErrorMsgHook)(long errCode)
Definition autodefs.h:863
bool(* TCommandHook)(TAutoCommand &cmdObj)
Definition autodefs.h:866
Object responsible for creating automation COM object.
Definition autodefs.h:924
automation collection iterator
Definition autodefs.h:1186
void SetSymbol(TAutoSymbol *sym)
Definition autodefs.h:1904
virtual void Init()=0
Automation argument stack abstraction.
Definition autodefs.h:813
Automation data element (same data as OLE/BASIC VARIANT)
Definition autodefs.h:526
OLE object exposed for automated access of internal object.
Definition autodefs.h:972
Standard implementation of a controlling IUnknown for an object, to be inherited with other COM inter...
Definition oleutil.h:264
Automation exception object.
Definition autodefs.h:115
@ xValidateFailure
Definition autodefs.h:126
Include for OC, gets common headers when precompiled headers are enabled.
Object Component Framework (COM encapsulation)
Definition appdesc.h:22
IUnknown &(* TAggregator)(ObjectPtr obj, TUnknown &inner)
Definition autodefs.h:102
void * ObjectPtr
Definition autodefs.h:84
const void * MostDerived(const void *obj, const std::type_info &src)
Definition autosym.cpp:416
const owl::uint16 atAutoClass
Definition autodefs.h:347
const owl::uint16 atSafeArray
Definition autodefs.h:344
@ asClass
extension to another class symbol table
Definition autodefs.h:307
@ asGetSet
can get or set property(...GET + ...SET)
Definition autodefs.h:304
@ asOleType
method or property exposed for OLE
Definition autodefs.h:299
@ asAnyCommand
any command: method, property get/set, build
Definition autodefs.h:298
@ asArgument
property returning an object
Definition autodefs.h:308
const void * DynamicCast(const void *obj, const std::type_info &src, const std::type_info &dst)
Definition autosym.cpp:394
TAutoCommand * AutoQuitBuild(ObjectPtr obj, int attr, TAutoStack &args)
Definition autosym.cpp:356
const owl::uint16 atByRef
Definition autodefs.h:345
TAppDescriptor * GetAppDescriptor()
Definition appdesc.h:203
@ atLong
Definition autodefs.h:326
@ atObject
Definition autodefs.h:332
@ atString
Definition autodefs.h:331
@ atByte
Definition autodefs.h:337
@ atVoid
Definition autodefs.h:323
@ atDatetime
Definition autodefs.h:330
@ atCurrency
Definition autodefs.h:329
@ atUnknown
Definition autodefs.h:336
@ atBool
Definition autodefs.h:334
@ atDouble
Definition autodefs.h:328
@ atVariant
Definition autodefs.h:335
@ atFloat
Definition autodefs.h:327
@ atShort
Definition autodefs.h:325
void SendObituary(const void *obj, const std::type_info &typeInfo)
Definition autosym.cpp:44
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
owl::uint16 TLangId
Holds a language ID, a predefined number that represents a base language and dialect.
Definition lclstrng.h:26
TModule * Module
Definition global.cpp:34
Definition of TOcControl class - Proxy object representing a control in.
#define _OCFFUNC(p)
Definition defs.h:47
#define _OCFDATA(p)
Definition defs.h:46
OLE Registration definitions.
static TAutoType ClassInfo
Definition autodefs.h:280
Symbol table element.
Definition autodefs.h:404
owl::uint16 Type
Definition autodefs.h:144
@ Quiet
behavior when an automation helper is freed
Definition autodefs.h:472