COM.m
上传用户:shenzhenrh
上传日期:2013-05-12
资源大小:2904k
文件大小:11k
源码类别:

信息检索与抽取

开发平台:

Unix_Linux

  1. #import "COM.h"
  2. #import <defobj/directory.h>
  3. #import <defobj/COMProxy.h>
  4. // mframe_build_signature
  5. #ifdef GNUSTEP
  6. #include <Foundation/NSMethodSignature.h>
  7. #include <mframe.h>
  8. #else
  9. #ifdef USE_MFRAME
  10. #include <objc/mframe.h>
  11. #endif
  12. #endif
  13. #import "internal.h" // objc_type_for_fcall_type
  14. #include <misc.h> // strdup
  15. static COMEnv *comEnv = 0;
  16. void
  17. initCOM (COMEnv *env)
  18. {
  19.   comEnv = env;
  20. }
  21. BOOL
  22. COM_init_p ()
  23. {
  24.   return comEnv != 0;
  25. }
  26. const char *
  27. COM_copy_string (const char *str)
  28. {
  29.   return comEnv->COMcopyString (str);
  30. }
  31. const char *
  32. COM_class_name (COMobject cObj)
  33. {
  34.   return SSTRDUP (comEnv->COMgetName (cObj));
  35. }
  36. const char *
  37. COM_get_class_name (COMclass cClass)
  38. {
  39.   return SSTRDUP (comEnv->COMgetComponentName (cClass));
  40. }
  41. COMclass
  42. COM_get_class (COMobject cObj)
  43. {
  44.   if (comEnv)
  45.     return comEnv->COMgetClass (cObj);
  46.   return NULL;
  47. }
  48. COMclass
  49. COM_find_class (const char *className)
  50. {
  51.   if (comEnv)
  52.     return comEnv->COMfindComponent (className);
  53.   return NULL;
  54. }
  55. BOOL
  56. COM_selector_is_javascript (COMselector cSel)
  57. {
  58.   return comEnv->selectorIsJavaScript (cSel);
  59. }
  60. BOOL
  61. COM_selector_is_boolean_return (COMselector cSel)
  62. {
  63.   return comEnv->selectorIsBooleanReturn (cSel);
  64. }
  65. COMselector
  66. COM_selector_create (COMmethod cMethod)
  67. {
  68.   return comEnv->selectorCreate (cMethod);
  69. }
  70. COMmethod
  71. COM_selector_method (COMselector cSel)
  72. {
  73.   return comEnv->selectorMethod (cSel);
  74. }
  75. void *
  76. COM_create_params (unsigned size)
  77. {
  78.   return comEnv->COMcreateParams (size);
  79. }
  80. void
  81. COM_set_arg (void *params, unsigned pos, val_t *val)
  82. {
  83.   comEnv->COMsetArg (params, pos, val);
  84. }
  85. void
  86. COM_set_return (void *params, unsigned pos, val_t *val)
  87. {
  88.   comEnv->COMsetReturn (params, pos, val);
  89. }
  90. void
  91. COM_free_params (void *params)
  92. {
  93.   comEnv->COMfreeParams (params);
  94. }
  95. BOOL
  96. COM_is_javascript (COMobject cObj)
  97. {
  98.   return cObj ? comEnv->isJavaScript (cObj) : NO;
  99. }
  100. void *
  101. JS_create_params (unsigned size)
  102. {
  103.   return comEnv->JScreateParams (size);
  104. }
  105. void
  106. JS_set_arg (void *params, unsigned pos, val_t *val)
  107. {
  108.   comEnv->JSsetArg (params, pos, val);
  109. }
  110. void
  111. JS_set_return (void *params, unsigned pos, val_t *val)
  112. {
  113.   comEnv->JSsetReturn (params, pos, val);
  114. }
  115. void
  116. JS_free_params (void *params)
  117. {
  118.   comEnv->JSfreeParams (params);
  119. }
  120. void
  121. COM_collect_variables (COMclass cClass, COM_collect_variable_func_t variableFunc)
  122. {
  123.   comEnv->collectMethods (cClass, variableFunc, NULL);
  124. }
  125. void
  126. COM_collect_methods (COMclass cClass, COM_collect_method_func_t methodFunc)
  127. {
  128.   comEnv->collectMethods (cClass, NULL, methodFunc);
  129. }
  130. void
  131. JS_collect_variables (COMobject cObj, JS_collect_func_t variableFunc)
  132. {
  133.   comEnv->collectJSProperties (cObj, variableFunc, NULL);
  134. }
  135. void
  136. JS_collect_methods (COMobject cObj, JS_collect_func_t methodFunc)
  137. {
  138.   comEnv->collectJSProperties (cObj, NULL, methodFunc);
  139. }
  140. BOOL
  141. JS_probe_variable (COMobject cObj, const char *variableName, val_t *ret)
  142. {
  143.   return comEnv->JSprobeVariable (cObj, variableName, ret);
  144. }
  145. void
  146. JS_set_variable (COMobject cObj, const char *variableName, val_t *val)
  147. {
  148.   comEnv->JSsetVariable (cObj, variableName, val);
  149. }
  150. void
  151. JS_method_invoke (COMobject cObj, const char *methodName, void *params)
  152. {
  153.   comEnv->JSmethodInvoke (cObj, methodName, params);
  154. }
  155. unsigned
  156. JS_method_arg_count (COMobject cObj, const char *methodName)
  157. {
  158.   return comEnv->JSmethodArgCount (cObj, methodName);
  159. }
  160. const char *
  161. COM_method_name (COMmethod cMethod)
  162. {
  163.   return comEnv->COMmethodName (cMethod);
  164. }
  165. fcall_type_t
  166. COM_method_param_fcall_type (COMmethod cMethod, unsigned index)
  167. {
  168.   return comEnv->COMmethodParamFcallType (cMethod, index);
  169. }
  170. void
  171. COM_method_set_return (COMmethod cMethod, void *params, void *value)
  172. {
  173.   comEnv->COMmethodSetReturn (cMethod, params, value);
  174. }
  175. void
  176. COM_method_invoke (COMobject cObj, COMmethod cMethod, void *params)
  177. {
  178.   comEnv->COMmethodInvoke (cObj, cMethod, params);
  179. }
  180. COMobject 
  181. swarm_directory_objc_find_object_COM (id oObject)
  182. {
  183.   ObjectEntry *entry = swarm_directory_objc_find_object (oObject);
  184.   
  185.   if (entry)
  186.     {
  187.       if (entry->type == foreign_COM)
  188.         return entry->foreignObject.COM;
  189.     }
  190.   return NULL;
  191. }
  192. COMselector
  193. swarm_directory_objc_find_selector_COM (SEL sel)
  194. {
  195.   SelectorEntry *entry = swarm_directory_objc_find_selector (sel);
  196.   if (entry)
  197.     {
  198.       if (entry->type == foreign_COM)
  199.         return comEnv->selectorQuery (entry->foreignObject.COM);
  200.     }
  201.   return NULL;
  202. }
  203. static COMclass
  204. find_wrapper_class_COM (Class oClass)
  205. {
  206.   if (comEnv)
  207.     {
  208.       const char *name = language_independent_class_name_for_objc_class (oClass);
  209.       COMclass cClass = comEnv->COMfindComponent (name);
  210.       
  211.       FREECLASSNAME (name);
  212.       return cClass;
  213.     }
  214.   return NULL;
  215. }
  216. COMclass
  217. swarm_directory_objc_find_class_COM (Class oClass)
  218. {
  219.   if (swarmDirectory) // for find_wrapper_class_COM
  220.     {
  221.       COMclass cClass = (COMclass) SD_COM_FIND_OBJECT_COM ((id) oClass);
  222.       
  223.       if (!cClass)
  224.         {
  225.           cClass = find_wrapper_class_COM (oClass);
  226.           if (cClass)
  227.             cClass = SD_COM_ADD_CLASS_COM (cClass, oClass);
  228.         }
  229.       return cClass;
  230.     }
  231.   else
  232.     return NULL;
  233. }
  234. COMobject
  235. swarm_directory_objc_ensure_object_COM (id oObject)
  236. {
  237.   COMobject cObject;
  238.   if (!oObject)
  239.     return 0;
  240.   
  241.   if (!(cObject = SD_COM_FIND_OBJECT_COM (oObject)))
  242.     {
  243.       Class oClass = getClass (oObject);
  244.       COMclass cClass = SD_COM_FIND_CLASS_COM (oClass);
  245.       
  246.       cObject = comEnv->COMnormalize (comEnv->COMcreateComponent (cClass));
  247.       return swarm_directory_COM_add_object_COM (cObject, oObject);
  248.     }
  249.   return cObject;
  250. }
  251. COMobject
  252. swarm_directory_update_phase_COM (Object_s *oObject)
  253. {
  254.   Class oClass = getClass (oObject);
  255.   COMclass cClass = SD_COM_FIND_CLASS_COM (oClass);
  256.   COMobject cLastObj = SD_COM_FIND_OBJECT_COM (oObject);
  257.   COMobject cNewObj = comEnv->COMcreateComponent (cClass);
  258.   COMobject cDirObj = cDirObj = comEnv->COMnormalize (cNewObj);
  259.   ObjectEntry *entry;
  260.   avl_delete (swarmDirectory->COM_tree, COM_FIND_OBJECT_ENTRY (cLastObj));
  261.   avl_probe (swarmDirectory->COM_tree, COM_OBJECT_ENTRY (cDirObj, oObject));
  262.   entry = oObject->foreignEntry;
  263.   entry->foreignObject.COM = (COMOBJECT) cDirObj;
  264.   return cNewObj;
  265. }
  266. static ObjectEntry *
  267. swarm_directory_COM_find (COMobject cObject)
  268. {
  269.   cObject = comEnv->COMnormalize (cObject);
  270.   return (cObject
  271.           ? avl_find (swarmDirectory->COM_tree,
  272.                       COM_FIND_OBJECT_ENTRY (cObject))
  273.           : nil);
  274. }
  275. id
  276. swarm_directory_COM_find_object_objc (COMobject cObject)
  277. {
  278.   if (!cObject)
  279.     return nil;
  280.   else
  281.     {
  282.       ObjectEntry *result = swarm_directory_COM_find (cObject);
  283.       return (result
  284.               ? result->object
  285.               : nil);
  286.     }
  287. }
  288. static ObjectEntry *
  289. swarm_directory_COM_find_class (COMclass cClass)
  290. {
  291.   return (cClass
  292.           ? avl_find (swarmDirectory->COM_tree,
  293.                       COM_FIND_OBJECT_ENTRY (cClass))
  294.           : nil);
  295. }
  296. id
  297. swarm_directory_COM_find_class_objc (COMclass cClass)
  298. {
  299.   if (!cClass)
  300.     return nil;
  301.   else
  302.     {
  303.       ObjectEntry *result = swarm_directory_COM_find_class (cClass);
  304.       return (result
  305.               ? result->object
  306.               : nil);
  307.     }
  308. }
  309. id
  310. swarm_directory_COM_ensure_object_objc (COMobject cObject)
  311. {
  312.   if (!cObject)
  313.     return nil;
  314.   else
  315.     {
  316.       ObjectEntry *result;
  317.       result = swarm_directory_COM_find (cObject);
  318.       return (result
  319.               ? result->object
  320.               : SD_COM_ADD_OBJECT_OBJC (comEnv->COMnormalize (cObject),
  321.                                         [COMProxy create: globalZone]));
  322.     }
  323. }
  324. SEL
  325. swarm_directory_COM_ensure_selector (COMselector cSel)
  326. {
  327.   SEL sel = NULL;
  328.   if (!cSel)
  329.     sel = NULL;
  330.   else if (!(sel = (SEL) SD_COM_FIND_OBJECT_OBJC (cSel)))
  331.     {
  332.       unsigned argCount = comEnv->selectorArgCount (cSel);
  333.       const char *name = comEnv->selectorName (cSel);
  334.       {
  335.         unsigned ti;
  336.         char signatureBuf[(argCount + 3) * 3 + 1], *p = signatureBuf;
  337.         
  338.         void add_type (fcall_type_t type)
  339.           {
  340.             const char *objcType = objc_type_for_fcall_type (type);
  341.             p = stpcpy (p, objcType);
  342.             *p++ = '0';
  343.             *p = '';
  344.             [globalZone free: (void *) objcType];
  345.           }
  346.         if (comEnv->selectorIsVoidReturn (cSel))
  347.           add_type (fcall_type_void);
  348.         else
  349.           add_type (comEnv->selectorArgFcallType (cSel, argCount));
  350.         add_type (fcall_type_object);
  351.         add_type (fcall_type_selector);
  352.         for (ti = 0; ti < argCount; ti++)
  353.           add_type (comEnv->selectorArgFcallType (cSel, ti));
  354.         sel = sel_get_any_typed_uid (name);
  355.         {
  356.           BOOL needSelector = NO;
  357.           
  358.           if (sel)
  359.             {
  360.               if (!sel_get_typed_uid (name, signatureBuf))
  361.                 {
  362. #if 1
  363.                   raiseEvent (WarningMessage,
  364.                               "Method `%s' type (%s) differs from Swarm "
  365.                               "method's type (%s)n",
  366.                             name, signatureBuf, sel->sel_types);
  367. #endif
  368.                   needSelector = YES;
  369.                 }
  370.               
  371.             }
  372.           else
  373.             needSelector = YES;
  374.           
  375.           if (needSelector)
  376.             {
  377.               const char *type =
  378.                 mframe_build_signature (signatureBuf, NULL, NULL, NULL);
  379.               
  380.               sel = sel_register_typed_name (name, type);
  381.             }
  382.         }
  383.       }
  384.       SD_COM_ADD_SELECTOR (cSel, sel);
  385.       // Does GetName return a malloced pointer?
  386.       // SFREEBLOCK (name); 
  387.     }
  388.   return sel;
  389. }
  390. Class
  391. swarm_directory_COM_ensure_class_objc (COMclass cClass)
  392. {
  393.   Class objcClass;
  394.   if (!(objcClass = SD_COM_FIND_CLASS_OBJC (cClass)))
  395.     {
  396.       const char *className = COM_get_class_name (cClass);
  397.       if (strncmp (className, "swarm", 5) == 0)
  398.         className += 5;
  399.       
  400.       objcClass = objc_class_for_class_name (className);
  401.       
  402.       if (objcClass == nil)
  403.         objcClass = [COMProxy create: globalZone];
  404.       (void) SD_COM_ADD_CLASS_COM (cClass, objcClass);
  405.     }
  406.   return objcClass;
  407. }
  408. static ObjectEntry *
  409. add (COMobject cObject, Object_s *oObject)
  410. {
  411.   ObjectEntry *entry = COM_OBJECT_ENTRY (cObject, oObject);
  412.   oObject->foreignEntry = entry;
  413.   avl_probe (swarmDirectory->COM_tree, entry);
  414.   return entry;
  415. }
  416. COMclass
  417. swarm_directory_COM_add_class_COM (COMclass cClass, Class oClass)
  418. {
  419.   ObjectEntry *entry = COM_OBJECT_ENTRY (cClass, oClass);
  420.   
  421.   avl_probe (swarmDirectory->class_tree, entry);
  422.   avl_probe (swarmDirectory->COM_tree, entry);
  423.   return cClass;
  424. }
  425. COMobject
  426. swarm_directory_COM_add_object_COM (COMobject cObject, id oObject)
  427. {
  428.   return add (cObject, oObject)->foreignObject.COM;
  429. }
  430. id
  431. swarm_directory_COM_add_object_objc (COMobject cObject, id oObject)
  432. {
  433.   return add (cObject, oObject)->object;
  434. }
  435. void
  436. swarm_directory_COM_add_selector (COMselector cSel, SEL oSel)
  437. {
  438.   SelectorEntry *entry = COM_SELECTOR_ENTRY (cSel, oSel);
  439.   avl_probe (swarmDirectory->selector_tree, entry);
  440.   avl_probe (swarmDirectory->COM_tree, entry);
  441. }