home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWResour / FWResAcc.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  9.2 KB  |  305 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWResAcc.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef   FWRESACC_H
  13. #include "FWResAcc.h"
  14. #endif
  15.  
  16.  
  17. #ifdef FW_BUILD_MAC
  18. #pragma segment fwresour
  19. #endif
  20.  
  21. //========================================================================================
  22. //    Template instantiation
  23. //========================================================================================
  24.  
  25. #include "FWSOMPtr.tpp"
  26.  
  27. FW_DEFINE_AUTO_TEMPLATE(FW_TCountedSOMPtr, FW_OResource)
  28.  
  29. #if FW_USE_TEMPLATE_PRAGMAS
  30. #pragma template_access public
  31. #pragma template FW_TCountedSOMPtr<FW_OResource>
  32. #endif
  33.  
  34. #if FW_ANSI_TEMPLATE_INSTANTIATION
  35. template class FW_TCountedSOMPtr<FW_OResource>;
  36. #endif
  37.  
  38. //========================================================================================
  39. // CLASS FW_PResource
  40. //========================================================================================
  41.  
  42. FW_DEFINE_AUTO(FW_PResource)
  43.  
  44. //----------------------------------------------------------------------------------------
  45. // FW_PResource::FW_PResource
  46. //----------------------------------------------------------------------------------------
  47.  
  48. FW_PResource::FW_PResource(Environment* ev,
  49.                            FW_OResourceFile* file,
  50.                            FW_ResourceID resourceID,
  51.                            FW_ResourceType resourceType)
  52. {
  53.     FW_OResource* rep = new FW_OResource();
  54.  
  55.     SetRep(ev, rep);
  56.     rep->InitFromFile(ev,
  57.                       file, 
  58.                       resourceID, 
  59.                       resourceType);
  60.     FW_END_CONSTRUCTOR
  61. }
  62.  
  63. //----------------------------------------------------------------------------------------
  64. // FW_PResource::FW_PResource
  65. //----------------------------------------------------------------------------------------
  66.  
  67. FW_PResource::FW_PResource(const FW_PResource& other) :
  68.     FW_TCountedSOMPtr<FW_OResource>(other)
  69. {
  70.     FW_END_CONSTRUCTOR
  71. }
  72.  
  73. //----------------------------------------------------------------------------------------
  74. // FW_PResource::FW_PResource
  75. //----------------------------------------------------------------------------------------
  76.  
  77. FW_PResource::FW_PResource(Environment* ev, FW_OResource* rep) :
  78.     FW_TCountedSOMPtr<FW_OResource>(ev, rep)
  79. {
  80.     FW_END_CONSTRUCTOR
  81. }
  82.  
  83. //----------------------------------------------------------------------------------------
  84. // FW_PResource::~FW_PResource
  85. //----------------------------------------------------------------------------------------
  86.  
  87. FW_PResource::~FW_PResource()
  88. {
  89.     FW_START_DESTRUCTOR
  90. }
  91.  
  92. //========================================================================================
  93. //    CLASS FW_CAcquireResourceData
  94. //
  95. //    A resource data acquistion helper object.  This object can be used in order
  96. //    to obtain access to resource data in an exception safe manner.
  97. //========================================================================================
  98.  
  99. FW_DEFINE_AUTO(FW_CAcquireResourceData)
  100.  
  101. //----------------------------------------------------------------------------------------
  102. // FW_CAcquireResourceData::FW_CAcquireResourceData
  103. //----------------------------------------------------------------------------------------
  104.  
  105. FW_CAcquireResourceData::FW_CAcquireResourceData(Environment *ev, FW_OResource* resource) :
  106.     fResource(ev, resource)
  107. {
  108.     fData = fResource->AcquireData(ev);
  109.     fSize = fResource->GetSize(ev);
  110.     FW_END_CONSTRUCTOR
  111. }
  112.  
  113. //----------------------------------------------------------------------------------------
  114. // FW_CAcquireResourceData::~FW_CAcquireResourceData
  115. //----------------------------------------------------------------------------------------
  116.  
  117. FW_CAcquireResourceData::~FW_CAcquireResourceData()
  118. {
  119.     FW_START_DESTRUCTOR
  120.     FW_SOMEnvironment ev;
  121.  
  122.     fResource->ReleaseData(ev);
  123. }
  124.  
  125. //========================================================================================
  126. //    Global Utility Functions
  127. //========================================================================================
  128.  
  129. #ifdef FW_BUILD_WIN
  130. #pragma pack(push,1)
  131. #endif
  132.  
  133. struct FW_SMultiStringResEntry
  134. {
  135.     short fStringID;
  136.     unsigned short fStringOffset;
  137. };
  138.  
  139. struct FW_SMultiStringHeader
  140. {
  141.     unsigned short fStringCount;                // number of entrys
  142.     FW_SMultiStringResEntry fEntryArray[1];        // table of entries
  143.     unsigned short GetStringOffset(short theKey);
  144. };
  145.  
  146. #ifdef FW_BUILD_WIN
  147. #pragma pack(pop)
  148. #endif
  149.  
  150. //----------------------------------------------------------------------------------------
  151. // FW_SMultiStringHeader::GetStringOffset
  152. //----------------------------------------------------------------------------------------
  153.  
  154. static const unsigned short kBadOffset = 0xFFFF;
  155.  
  156. unsigned short FW_SMultiStringHeader::GetStringOffset(short theKey)
  157. {
  158.     short wLo = 0,
  159.     wHi = fStringCount - 1;
  160.     short wValue;                                // trial Value
  161.     // X[wLo..wHi] are ordered, but untested
  162.     do
  163.     {
  164.         short wMid = (wLo + wHi) / 2;
  165.         wValue = fEntryArray[wMid].fStringID;    // try middle Value
  166.         if (wValue <= theKey)
  167.             wLo = wMid + 1;                // X[0..wLo-1] <= theKey
  168.  
  169.         if (wValue >= theKey)
  170.             wHi = wMid - 1;                // X[wHi+1..wMax] >= theKey  X[wLo..wHi] untested
  171.     } while (wLo <= wHi);                // still at least one untested
  172.  
  173.     if (wLo - wHi == 2)
  174.         return fEntryArray[wHi + 1].fStringOffset;
  175.  
  176.     return kBadOffset;
  177. }
  178.  
  179. //========================================================================================
  180. //    Global Functions
  181. //========================================================================================
  182.  
  183. //----------------------------------------------------------------------------------------
  184. // FW_HasStringByPosition
  185. //----------------------------------------------------------------------------------------
  186.  
  187. FW_Boolean FW_HasStringByPosition(Environment *ev,
  188.                               FW_PResourceFile &file,
  189.                               FW_ResourceID resourceID,
  190.                               FW_ResourceType resourceType,
  191.                               unsigned short position)
  192. {
  193.     FW_PResource resource(ev, file, resourceID, resourceType);
  194.     FW_CAcquireResourceData data(ev, resource);
  195.     void *p = data.GetData();
  196.     
  197.     FW_SMultiStringHeader* head = (FW_SMultiStringHeader*) p;
  198.  
  199.     FW_ASSERT(position >= 0);
  200.     FW_ASSERT(head->fStringCount > 0);
  201.     
  202.     return position < head->fStringCount;
  203. }
  204.  
  205. //----------------------------------------------------------------------------------------
  206. // FW_LoadStringByPosition
  207. //----------------------------------------------------------------------------------------
  208.  
  209. FW_Boolean FW_HasStringByID(Environment *ev,
  210.                               FW_PResourceFile &file,
  211.                               FW_ResourceID resourceID,
  212.                               FW_ResourceType resourceType,
  213.                               unsigned short id)
  214. {
  215.     FW_PResource resource(ev, file, resourceID, resourceType);
  216.     FW_CAcquireResourceData data(ev, resource);
  217.     void *p = data.GetData();
  218.     
  219.     FW_SMultiStringHeader* head = (FW_SMultiStringHeader*) p;
  220.     FW_ASSERT(head->fStringCount > 0);
  221.     
  222.     // Compute the Offset into the table, based on the position.
  223.     const unsigned short offset = head->GetStringOffset(id);
  224.     return (offset != kBadOffset);
  225. }
  226.  
  227. //----------------------------------------------------------------------------------------
  228. // FW_LoadStringByPosition
  229. //----------------------------------------------------------------------------------------
  230.  
  231. void FW_LoadStringByPosition(Environment *ev,
  232.                               FW_PResourceFile &file,
  233.                               FW_ResourceID resourceID,
  234.                               FW_ResourceType resourceType,
  235.                               unsigned short position,
  236.                               FW_CString &string)
  237. {
  238.     FW_PResource resource(ev, file, resourceID, resourceType);
  239.     FW_CAcquireResourceData data(ev, resource);
  240.     void *p = data.GetData();
  241.     
  242.     FW_SMultiStringHeader* head = (FW_SMultiStringHeader*) p;
  243.     FW_ASSERT(head->fStringCount > 0);
  244.     
  245.     // Compute the Offset into the table, based on the position.
  246.     const unsigned short offset = head->fEntryArray[position].fStringOffset;
  247.     
  248.     string.ReplaceAll(((const FW_Char*)p)+offset);
  249. }
  250.  
  251. //----------------------------------------------------------------------------------------
  252. // FW_LoadStringByIDNoFail
  253. //----------------------------------------------------------------------------------------
  254.  
  255. FW_Boolean FW_LoadStringByIDNoFail(Environment *ev,
  256.                                 FW_PResourceFile &file,
  257.                                 FW_ResourceID resourceID,
  258.                                 FW_ResourceType resourceType,
  259.                                 unsigned short id,
  260.                                 FW_CString &string)
  261. {
  262.     FW_Boolean success = TRUE;
  263.     
  264.     FW_TRY
  265.     {
  266.         ::FW_LoadStringByID(ev, file, resourceID, resourceType, id, string);
  267.     }
  268.     FW_CATCH_BEGIN
  269.     FW_CATCH_EVERYTHING()
  270.     {
  271.         string.Truncate(0);
  272.         success = FALSE;
  273.     }
  274.     FW_CATCH_END
  275.  
  276.     return success;
  277. }
  278.  
  279. //----------------------------------------------------------------------------------------
  280. // FW_LoadStringByID
  281. //----------------------------------------------------------------------------------------
  282.                     
  283. void FW_LoadStringByID(Environment *ev,
  284.                         FW_PResourceFile &file,
  285.                         FW_ResourceID resourceID,
  286.                         FW_ResourceType resourceType,
  287.                         unsigned short id,
  288.                         FW_CString &string)
  289. {
  290.     FW_PResource resource(ev, file, resourceID, resourceType);
  291.     FW_CAcquireResourceData data(ev, resource);
  292.     void *p = data.GetData();
  293.     
  294.     FW_SMultiStringHeader* head = (FW_SMultiStringHeader*) p;
  295.     FW_ASSERT(head->fStringCount > 0);
  296.  
  297.     // Compute the Offset into the table, based on the position.
  298.     const unsigned short offset = head->GetStringOffset(id);
  299.     if (offset == kBadOffset)
  300.         FW_Failure(FW_xStringResourceNotFound);
  301.  
  302.     string.ReplaceAll(((const FW_Char*)p)+offset);
  303. }
  304.                     
  305.