home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 11.ddi / OWLSRC.PAK / APPDICT.CPP next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  6.7 KB  |  273 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   source\owl\appdict.cpp
  4. //   Implementation of class TAppDictionary, a dictionary of
  5. //   associations between task handles and TApplication pointers.
  6. //   Used to support GetApplicationObject().
  7. //----------------------------------------------------------------------------
  8. #include <owl\owlpch.h>
  9. #include <owl\owldefs.h>
  10. #include <owl\applicat.h>
  11. #if defined(__DLL__)
  12.   #include <dos.h>
  13.   #include <string.h>
  14. #endif
  15.  
  16. //
  17. // Dictionary class used to associate Pids (hTasks) with running Owl apps when
  18. // Owl is in a DLL. 32bit only needs this when running win32s since
  19. // per-instance data is not available.
  20. //
  21. #if defined(__DLL__)
  22.  
  23. const int DefDictionarySize      = 10;
  24. const int DefDictionaryIncrement = 10;
  25.  
  26. #if !defined(__WIN32__)
  27.   inline unsigned GetCurrentProcessId() {return (unsigned)GetCurrentTask();}
  28. #endif
  29.  
  30. //
  31. //  class TAppDictionaryEntry
  32. //  ----- -------------------
  33. //
  34. class TAppDictionaryEntry {
  35.   public:
  36.     unsigned       Pid;
  37.     TApplication*  Application;
  38. };
  39.  
  40. //
  41. //  class TAppDictionary
  42. //  ----- --------------
  43. //
  44. class TAppDictionary {
  45.   public:
  46.     TAppDictionary(int initialCount = DefDictionarySize);
  47.  
  48.    ~TAppDictionary();
  49.     
  50.     static TAppDictionaryEntry*  AllocTable(int count);
  51.     static void                  FreeTable(TAppDictionaryEntry* table);
  52.  
  53.     TAppDictionaryEntry*  GrowTable(int increment = DefDictionaryIncrement);
  54.     void                  Add(unsigned pid, TApplication*);
  55.     void                  Delete(unsigned pid);
  56.     TApplication*         LookupApp(unsigned pid);
  57.  
  58.   private:
  59.     int                   NumEntries;
  60.     TAppDictionaryEntry*  Table;
  61. };
  62.  
  63. //
  64. // Dictionary implementation
  65. //
  66. TAppDictionary::TAppDictionary(int initialCount)
  67. {
  68.   if (initialCount != 0)
  69.     Table = AllocTable(initialCount);
  70.  
  71.   NumEntries = Table ? initialCount : 0;
  72. }
  73.  
  74. TAppDictionary::~TAppDictionary()
  75. {
  76.   if (NumEntries != 0 && Table)
  77.     FreeTable(Table);
  78. }
  79.  
  80. //
  81. // Allocate the table from the local heap so that this DLL always owns it.
  82. //
  83. TAppDictionaryEntry*
  84. TAppDictionary::AllocTable(int count)
  85. {
  86.   return (TAppDictionaryEntry*)LocalLock(
  87.            LocalAlloc(LMEM_ZEROINIT, count * sizeof(TAppDictionaryEntry))
  88.          );
  89. }
  90.  
  91. void
  92. TAppDictionary::FreeTable(TAppDictionaryEntry* table)
  93. {
  94. #if defined(__WIN32__)
  95.   HLOCAL  hMem = LocalHandle(table);
  96. #else
  97.   HLOCAL  hMem = LocalHandle((void NEAR*)FP_OFF(table));  // strip off ds:
  98. #endif
  99.   if (LocalUnlock(hMem))
  100.     LocalFree(hMem);
  101. }
  102.  
  103. TAppDictionaryEntry*
  104. TAppDictionary::GrowTable(int increment)
  105. {
  106.   int                   oldNumEntries = NumEntries;
  107.   TAppDictionaryEntry*  oldTable = Table;
  108.  
  109.   NumEntries = NumEntries + increment;
  110.   Table = AllocTable(NumEntries);
  111.  
  112.   //
  113.   // copy old table to new location
  114.   //
  115.   memcpy(Table, oldTable, oldNumEntries * sizeof(TAppDictionaryEntry));
  116.  
  117.   FreeTable(oldTable);
  118.  
  119.   //
  120.   // return pointer to first entry in new block
  121.   //
  122.   return &Table[oldNumEntries];
  123. }
  124.  
  125. void
  126. TAppDictionary::Add(unsigned pid, TApplication* app)
  127. {
  128.   TAppDictionaryEntry* freeEntry = 0;  // no free entry yet
  129.  
  130.   //
  131.   // first see if there is already a table; if so, replace the entry
  132.   //
  133.   for (TAppDictionaryEntry* entry = Table; entry < &Table[NumEntries]; entry++) {
  134.     if (entry->Pid == pid) {
  135.       entry->Application = app;        // already in table, update pointers
  136.       return;
  137.  
  138.     } else if (!freeEntry && !entry->Pid) {
  139.       freeEntry = entry;  // remember this free entry for use later
  140.     }
  141.   }
  142.  
  143.   //
  144.   // not in table. see if we encountered a free entry in the table
  145.   // if so, use it; otherwise grow the table
  146.   //
  147.   if ((entry = (freeEntry ? freeEntry : GrowTable())) != 0) {
  148.     entry->Pid = pid;
  149.     entry->Application = app;
  150.   }
  151. }
  152.  
  153. TApplication*
  154. TAppDictionary::LookupApp(unsigned pid)
  155. {
  156.   for (TAppDictionaryEntry* entry = Table; entry < &Table[NumEntries]; entry++)
  157.     if (entry->Pid == pid)
  158.       return entry->Application;
  159.   //
  160.   // Make alias app (will add itself) because Owl always needs an app around
  161.   // If the app is non-Owl, no TApplication will have been constructed.
  162.   // Override default constructor argument to prevent overwrite of ::Module
  163.   //
  164.   TModule* tempModule;
  165.   return new TApplication("ALIAS",tempModule);
  166. }
  167.  
  168. void
  169. TAppDictionary::Delete(unsigned pid)
  170. {
  171.   for (TAppDictionaryEntry* entry = Table; entry < &Table[NumEntries]; entry++)
  172.     if (entry->Pid == pid) {
  173.       entry->Pid = 0;  // found entry.  Zero it.
  174.       return;
  175.     }
  176. }
  177.  
  178. //
  179. // Static instance of the application dictionary
  180. //
  181. static TAppDictionary* AppDictionary = new TAppDictionary();
  182.  
  183. //
  184. // Locals used for Win32 to skip dictionary when perinstance data is available
  185. //
  186. #if defined(__WIN32__)
  187. static TApplication*   __OwlThisApplication;
  188. static int      PerInstanceData = -1;   // Is per-instance data supported?
  189.                                         // -1 for don't-know-yet
  190. #endif
  191.  
  192. //
  193. // Exported, public functions used to add, delete & get apps from the
  194. // dictionary in the DLL case
  195. //
  196. TApplication* _OWLFUNC 
  197. GetApplicationObject()
  198. {
  199. #if defined(__WIN32__)
  200.   if (PerInstanceData)
  201.     return __OwlThisApplication;
  202. #endif
  203.   return AppDictionary->LookupApp(::GetCurrentProcessId());
  204. }
  205.  
  206. extern "C" TApplication* PASCAL _OWLFUNC 
  207. GetTaskApplicationObject(unsigned pid)
  208. {
  209. #if defined(__WIN32__)
  210.   if (PerInstanceData)
  211.     return __OwlThisApplication;
  212. #endif
  213.   return AppDictionary->LookupApp(pid);
  214. }
  215.  
  216. void _OWLFUNC
  217. AddApplicationObject(TApplication* app)
  218. {
  219. #if defined(__WIN32__)
  220.   if (PerInstanceData < 0)
  221.     PerInstanceData = !(HIWORD(::GetVersion())&0x8000);  // not in win32s
  222.  
  223.   if (PerInstanceData)
  224.     __OwlThisApplication = app;
  225. #endif
  226.      
  227.   AppDictionary->Add(::GetCurrentProcessId(), app);
  228. }
  229.  
  230. void _OWLFUNC
  231. DeleteApplicationObject()
  232. {
  233. #if defined(__WIN32__)
  234.   if (PerInstanceData)
  235.     __OwlThisApplication = 0;
  236. #endif
  237.   AppDictionary->Delete(::GetCurrentProcessId());
  238. }
  239.  
  240. //----------------------------------------------------------------------------
  241.  
  242. #else  // defined(__DLL__)
  243.  
  244. //
  245. // Global statics containing the single application pointer
  246. //
  247. static TApplication*   __OwlThisApplication;
  248.  
  249. //
  250. // Exported, public functions used to add, delete & get apps from the
  251. // 'dictionary' in the non-DLL case
  252. //
  253.  
  254. TApplication* _OWLFUNC 
  255. GetApplicationObject()
  256. {
  257.   return __OwlThisApplication;
  258. }
  259.  
  260. void _OWLFUNC
  261. AddApplicationObject(TApplication* app)
  262. {
  263.   __OwlThisApplication = app;
  264. }
  265.  
  266. void _OWLFUNC
  267. DeleteApplicationObject()
  268. {
  269.   __OwlThisApplication = 0;
  270. }
  271.  
  272. #endif  // defined(__DLL__)
  273.