home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / New System Software Extensions / OpenDoc A6 / OpenDoc Parts Framework / OPF / Found / FWArchiv / Sources / FWArDyna.cpp next >
Encoding:
Text File  |  1994-04-21  |  14.8 KB  |  404 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWArDyna.cpp
  4. //    Release Version:    $ 1.0d1 $
  5. //
  6. //    Creation Date:        3/28/94
  7. //
  8. //    Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #ifndef FWARDYNA_H
  13. #include "FWArDyna.h"
  14. #endif
  15.  
  16. #ifndef FWARSTRM_H
  17. #include "FWArStrm.h"
  18. #endif
  19.  
  20. #ifndef FWOBJREG_H
  21. #include "FWObjReg.h"
  22. #endif
  23.  
  24. #ifndef FWPRISTR_H
  25. #include "FWPriStr.h"
  26. #endif
  27.  
  28. #ifndef FWPRITAS_H
  29. #include "FWPriTas.h"
  30. #endif
  31.  
  32. #pragma segment FWArchiv
  33.  
  34. //========================================================================================
  35. //    Class FW_CDynamicArchiver
  36. //========================================================================================
  37.  
  38. //----------------------------------------------------------------------------------------
  39. // FW_CDynamicArchiver::FW_CDynamicArchiver
  40. //----------------------------------------------------------------------------------------
  41.  
  42. FW_CDynamicArchiver::FW_CDynamicArchiver(const char* classLabel,
  43.                             const char* className,
  44.                             FW_CDynamicArchiver::MapNameToLabel& localNameToLabelMap,
  45.                             FW_CDynamicArchiver::MapLabelToIOFunction& localLabelToIOFunctionMap,
  46.                             FW_CReadableArchive::InputFunction inputFunction,
  47.                             FW_CWritableArchive::OutputFunction outputFunction)
  48. {
  49.     BC_Boolean bindOkay;
  50.  
  51.     bindOkay = localNameToLabelMap.Bind(FW_SPrivArcStr(className), FW_SPrivArcStr(classLabel));
  52.     FW_ASSERT(bindOkay);
  53.  
  54.     bindOkay = localLabelToIOFunctionMap.Bind(FW_SPrivArcStr(classLabel), FW_SPrivArcFun(inputFunction, outputFunction));
  55.     FW_ASSERT(bindOkay);
  56. }
  57.  
  58. //----------------------------------------------------------------------------------------
  59. // FW_CDynamicArchiver::FW_CDynamicArchiver
  60. //----------------------------------------------------------------------------------------
  61.  
  62. FW_CDynamicArchiver::FW_CDynamicArchiver(const char* oldVersionClassLabel,
  63.                                          FW_CDynamicArchiver::MapLabelToIOFunction& localLabelToIOFunctionMap,
  64.                                          FW_CReadableArchive::InputFunction inputFunction)
  65. {
  66.     BC_Boolean bindOkay = localLabelToIOFunctionMap.Bind(FW_SPrivArcStr(oldVersionClassLabel), FW_SPrivArcFun(inputFunction, 0));
  67.     FW_ASSERT(bindOkay);
  68. }
  69.  
  70. //----------------------------------------------------------------------------------------
  71. // FW_CDynamicArchiver::InputObject
  72. //----------------------------------------------------------------------------------------
  73.  
  74. void FW_CDynamicArchiver::InputObject(FW_CReadableArchive& readableArchive,
  75.                                       void*& object)
  76. {
  77.     FW_CReadableArchive::InputFunction inputFunction = (FW_CReadableArchive::InputFunction)readableArchive.InputObject(ReadClassLabel);
  78.  
  79.     object = readableArchive.InputObject(inputFunction);
  80. }
  81.  
  82. //----------------------------------------------------------------------------------------
  83. // FW_CDynamicArchiver::ReadClassLabel
  84. //
  85. // Notes:
  86. //    1.    You may have expected this method to return a pointer to the class label. Doing
  87. //        so, however, would result in two problems. First, the pointer returned would have
  88. //        to be to a buffer allocated by this method and who would delete it? Second, even
  89. //        if a pointer to a class label was returned, by returning an:
  90. //            'FW_CReadableArchive::InputFunction'
  91. //        pointer, we only have to map a particular class label once (via the map
  92. //        'gMapClassLabelToObjectIOFunction') for the entire 'readableArchive'. That is,
  93. //        if there are "n" occurrences of a particular class label in a 'readableArchive',
  94. //        one reference to 'gMapClassLabelToObjectIOFunction' is made instead of "n".
  95. //----------------------------------------------------------------------------------------
  96.  
  97. void* FW_CDynamicArchiver::ReadClassLabel(FW_CReadableArchive& readableArchive)
  98. {
  99.     // Read the class label of the object from the archive.
  100.     char classLabel[kMaxClassLabelLength];
  101.     short labelLength;
  102.     readableArchive >> labelLength;
  103.     FW_ASSERT(labelLength < kMaxClassLabelLength);
  104.     readableArchive.Read(classLabel, labelLength);
  105.     classLabel[labelLength] = 0;
  106.  
  107.     // Look up the InputFunction in the map using the class label as the key.
  108.     FW_ASSERT(GetMapLabelToIOFunction().IsBound(FW_SPrivArcStr(classLabel)));
  109.     return GetMapLabelToIOFunction().ValueOf(FW_SPrivArcStr(classLabel))->fInputFunction;
  110. }
  111.  
  112. //----------------------------------------------------------------------------------------
  113. // FW_CDynamicArchiver::OutputObject
  114. //----------------------------------------------------------------------------------------
  115.  
  116. void FW_CDynamicArchiver::OutputObject(FW_CWritableArchive& writableArchive,
  117.                                        const void* object,
  118.                                        const char* className)
  119. {
  120.     // Use 'gMapClassNameToClassLabel' to map the 'className' to the class label.
  121.     FW_ASSERT(GetMapNameToLabel().IsBound(FW_SPrivArcStr(className)));
  122.     FW_SPrivArcStr label(*GetMapNameToLabel().ValueOf(FW_SPrivArcStr(className)));
  123.  
  124.     // Write the class label out to the archive.
  125.     writableArchive.OutputObject(WriteClassLabel, label.fString);
  126.  
  127.     // Write the 'object' data out to the archive.
  128.     FW_ASSERT(GetMapLabelToIOFunction().IsBound(label));
  129.     writableArchive.OutputObject(GetMapLabelToIOFunction().ValueOf(label)->fOutputFunction, object);
  130. }
  131.  
  132. //----------------------------------------------------------------------------------------
  133. // FW_CDynamicArchiver::WriteClassLabel
  134. //----------------------------------------------------------------------------------------
  135.  
  136. void FW_CDynamicArchiver::WriteClassLabel(FW_CWritableArchive& writableArchive,
  137.                                    const void* classLabel)
  138. {
  139.     short labelLength = FW_PrimitiveStringLength((const char *)classLabel);
  140.     writableArchive << labelLength;
  141.     writableArchive.Write(classLabel, labelLength);
  142. }
  143.  
  144. //----------------------------------------------------------------------------------------
  145. // FW_CDynamicArchiver::HashFunction
  146. //
  147. // The algorithm for the hash function is from:
  148. //    Sedgewick, Robert, "Algorithms in C", Addison-Wesley, 1990, Page 233
  149. //
  150. // The constant '64' used in the algorithm is (according to Sedgewick) "... not
  151. // particularly important".
  152. //----------------------------------------------------------------------------------------
  153.  
  154. BC_Index FW_CDynamicArchiver::HashFunction(const FW_SPrivArcStr& string)
  155. {
  156.     const char* charPtr = string.fString;
  157.     BC_Index hashValue = 0;
  158.  
  159.     while (*charPtr != '\0')
  160.     {
  161.         hashValue = ((64 * hashValue) + *charPtr) % kPrime;
  162.         ++charPtr;
  163.     }
  164.  
  165.     return hashValue;
  166. }
  167.  
  168. #ifndef FW_HAS_INSTANCE_DATA
  169. //----------------------------------------------------------------------------------------
  170. // FW_CDynamicArchiver::Initialize
  171. //----------------------------------------------------------------------------------------
  172.  
  173. void FW_CDynamicArchiver::Initialize(FW_SPrivDynamicArchiverGlobals& globals)
  174. {
  175.     globals.gMapClassNameToClassLabel = new MapNameToLabel(HashFunction);
  176.     globals.gMapClassNameToClassLabel->SetChunkSize(kChunkSize);
  177.     
  178.     globals.gMapClassLabelToObjectIOFunction = new MapLabelToIOFunction(HashFunction);
  179.     globals.gMapClassLabelToObjectIOFunction->SetChunkSize(kChunkSize);
  180. }
  181. #endif
  182.  
  183. #ifndef FW_HAS_INSTANCE_DATA
  184. //----------------------------------------------------------------------------------------
  185. // FW_CDynamicArchiver::Terminate
  186. //----------------------------------------------------------------------------------------
  187.  
  188. void FW_CDynamicArchiver::Terminate()
  189. {
  190.     FW_SPrivDynamicArchiverGlobals& globals = GetDynamicArchiverGlobals();
  191.     delete globals.gMapClassNameToClassLabel;
  192.     delete globals.gMapClassLabelToObjectIOFunction;
  193. }
  194. #endif
  195.  
  196. #ifndef FW_HAS_INSTANCE_DATA
  197. //----------------------------------------------------------------------------------------
  198. // FW_CDynamicArchiver::GetDynamicArchiverGlobals
  199. //----------------------------------------------------------------------------------------
  200.  
  201. FW_SPrivDynamicArchiverGlobals& FW_CDynamicArchiver::GetDynamicArchiverGlobals()
  202. {
  203.     FW_SPrivDynamicArchiverGlobals *globals = (FW_SPrivDynamicArchiverGlobals*)FW_CPrivTaskGlobals::GetTaskGlobals(kDynamicArchiverGlobalsOffset);
  204.  
  205.     if (globals->gMapClassNameToClassLabel == 0)
  206.         Initialize(*globals);
  207.     return *globals;
  208. }
  209. #endif
  210.  
  211. //----------------------------------------------------------------------------------------
  212. // FW_CDynamicArchiver::MapNameToLabel& FW_CDynamicArchiver::GetMapNameToLabel
  213. //----------------------------------------------------------------------------------------
  214.  
  215. FW_CDynamicArchiver::MapNameToLabel& FW_CDynamicArchiver::GetMapNameToLabel()
  216. {
  217. #ifdef FW_HAS_INSTANCE_DATA
  218.     return *gLocalMapClassNameToClassLabel;
  219. #else
  220.     return *GetDynamicArchiverGlobals().gMapClassNameToClassLabel;
  221. #endif
  222. }
  223.  
  224. //----------------------------------------------------------------------------------------
  225. // FW_CDynamicArchiver::MapLabelToIOFunction& FW_CDynamicArchiver::GetMapLabelToIOFunction
  226. //----------------------------------------------------------------------------------------
  227.  
  228. FW_CDynamicArchiver::MapLabelToIOFunction& FW_CDynamicArchiver::GetMapLabelToIOFunction()
  229. {
  230. #ifdef FW_HAS_INSTANCE_DATA
  231.     return *gLocalMapClassLabelToObjectIOFunction;
  232. #else
  233.     return *GetDynamicArchiverGlobals().gMapClassLabelToObjectIOFunction;
  234. #endif
  235. }
  236.  
  237.  
  238. //========================================================================================
  239. //    Struct FW_SPrivArcStr
  240. //========================================================================================
  241.  
  242. //----------------------------------------------------------------------------------------
  243. // FW_SPrivArcStr::FW_SPrivArcStr
  244. //----------------------------------------------------------------------------------------
  245.  
  246. FW_SPrivArcStr::FW_SPrivArcStr() :
  247.     fString(0)
  248. {
  249. }
  250.  
  251. //----------------------------------------------------------------------------------------
  252. // FW_SPrivArcStr::FW_SPrivArcStr
  253. //----------------------------------------------------------------------------------------
  254.  
  255. FW_SPrivArcStr::FW_SPrivArcStr(const FW_SPrivArcStr& string) :
  256.     fString(string.fString)
  257. {
  258. }
  259.  
  260. //----------------------------------------------------------------------------------------
  261. // FW_SPrivArcStr::FW_SPrivArcStr
  262. //----------------------------------------------------------------------------------------
  263.  
  264. FW_SPrivArcStr::FW_SPrivArcStr(const char* string) :
  265.     fString(string)
  266. {
  267. }
  268.  
  269. //----------------------------------------------------------------------------------------
  270. // FW_SPrivArcStr::operator=
  271. //----------------------------------------------------------------------------------------
  272.  
  273. FW_SPrivArcStr& FW_SPrivArcStr::operator=(const FW_SPrivArcStr& string)
  274. {
  275.     fString = string.fString;
  276.     return *this;
  277. }
  278.  
  279. //----------------------------------------------------------------------------------------
  280. // FW_SPrivArcStr::operator==
  281. //----------------------------------------------------------------------------------------
  282.  
  283. BC_Boolean FW_SPrivArcStr::operator==(const FW_SPrivArcStr& string) const
  284. {
  285.     return FW_PrimitiveStringEqual(fString, string.fString);
  286. }
  287.  
  288. //----------------------------------------------------------------------------------------
  289. // FW_SPrivArcStr::operator!=
  290. //----------------------------------------------------------------------------------------
  291.  
  292. BC_Boolean FW_SPrivArcStr::operator!=(const FW_SPrivArcStr& string) const
  293. {
  294.     return !operator==(string);
  295. }
  296.  
  297.  
  298. //========================================================================================
  299. //    Struct FW_SPrivArcFun
  300. //========================================================================================
  301.  
  302. //----------------------------------------------------------------------------------------
  303. // FW_SPrivArcFun::FW_SPrivArcFun
  304. //----------------------------------------------------------------------------------------
  305.  
  306. FW_SPrivArcFun::FW_SPrivArcFun() :
  307.     fInputFunction(0),
  308.     fOutputFunction(0)
  309. {
  310. }
  311.  
  312. //----------------------------------------------------------------------------------------
  313. // FW_SPrivArcFun::FW_SPrivArcFun
  314. //----------------------------------------------------------------------------------------
  315.  
  316. FW_SPrivArcFun::FW_SPrivArcFun(const FW_SPrivArcFun& ioFunctions) :
  317.     fInputFunction(ioFunctions.fInputFunction),
  318.     fOutputFunction(ioFunctions.fOutputFunction)
  319. {
  320. }
  321.  
  322. //----------------------------------------------------------------------------------------
  323. // FW_SPrivArcFun::FW_SPrivArcFun
  324. //----------------------------------------------------------------------------------------
  325.  
  326. FW_SPrivArcFun::FW_SPrivArcFun(FW_CReadableArchive::InputFunction inputFunction,
  327.                          FW_CWritableArchive::OutputFunction outputFunction) :
  328.     fInputFunction(inputFunction),
  329.     fOutputFunction(outputFunction)
  330. {
  331. }
  332.  
  333. //----------------------------------------------------------------------------------------
  334. // FW_SPrivArcFun& FW_SPrivArcFun::operator=
  335. //----------------------------------------------------------------------------------------
  336.  
  337. FW_SPrivArcFun& FW_SPrivArcFun::operator=(const FW_SPrivArcFun& ioFunctions)
  338. {
  339.     fInputFunction = ioFunctions.fInputFunction;
  340.     fOutputFunction = ioFunctions.fOutputFunction;
  341.     return *this;
  342. }
  343.  
  344. //----------------------------------------------------------------------------------------
  345. // FW_SPrivArcFun::operator==
  346. //----------------------------------------------------------------------------------------
  347.  
  348. BC_Boolean FW_SPrivArcFun::operator==(const FW_SPrivArcFun& ioFunctions) const
  349. {
  350.     return (fInputFunction == ioFunctions.fInputFunction) && (fOutputFunction == ioFunctions.fOutputFunction);
  351. }
  352.  
  353. //----------------------------------------------------------------------------------------
  354. // FW_SPrivArcFun::operator!=
  355. //----------------------------------------------------------------------------------------
  356.  
  357. BC_Boolean FW_SPrivArcFun::operator!=(const FW_SPrivArcFun& ioFunctions) const
  358. {
  359.     return !operator==(ioFunctions);
  360. }
  361.  
  362. //----------------------------------------------------------------------------------------
  363. //    FW_CDynamicArchiver::MergeNameToLabelMaps
  364. //----------------------------------------------------------------------------------------
  365.  
  366. void FW_CDynamicArchiver::MergeNameToLabelMaps(
  367.                                     FW_CDynamicArchiver::MapNameToLabel& local,
  368.                                     FW_CDynamicArchiver::MapNameToLabel& global) 
  369. {
  370.     BC_TMapActiveIterator<FW_SPrivArcStr, FW_SPrivArcStr> iterator(local);
  371.     while (!iterator.IsDone())
  372.     {
  373.         BC_Boolean bindOkay;
  374.         if (!global.IsBound(*iterator.CurrentItem()))
  375.         {
  376.             bindOkay = global.Bind(*iterator.CurrentItem(), *iterator.CurrentValue());
  377.             FW_ASSERT(bindOkay);
  378.         }
  379.         iterator.Next();
  380.     }
  381. }
  382.  
  383. //----------------------------------------------------------------------------------------
  384. //    FW_CDynamicArchiver::MergeLabelToIOFunctionMaps
  385. //----------------------------------------------------------------------------------------
  386.  
  387. void FW_CDynamicArchiver::MergeLabelToIOFunctionMaps(
  388.                                     FW_CDynamicArchiver::MapLabelToIOFunction& local,
  389.                                     FW_CDynamicArchiver::MapLabelToIOFunction& global) 
  390. {
  391.     BC_TMapActiveIterator<FW_SPrivArcStr, FW_SPrivArcFun> iterator(local);
  392.     while (!iterator.IsDone())
  393.     {
  394.         BC_Boolean bindOkay;
  395.         if (!global.IsBound(*iterator.CurrentItem()))
  396.         {
  397.             bindOkay = global.Bind(*iterator.CurrentItem(), *iterator.CurrentValue());
  398.             FW_ASSERT(bindOkay);
  399.         }
  400.         iterator.Next();
  401.     }
  402. }
  403.  
  404.