OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
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