home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Storage / Bento / IndHdr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  14.5 KB  |  405 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        IndHdr.cpp
  3.  
  4.     Contains:    Indirect Handler for Bento Container Suite
  5.  
  6.     Owned by:    Vincent Lo
  7.  
  8.     Copyright:    © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <7>    10/22/95    EL        1294623: Indirect value contains endian-
  13.                                     specific name length.
  14.          <6>    10/13/95    EL        1287340: Use standard ISO prefix
  15.          <5>      8/8/95    jpa        Fixed DebugStrs [1265584]
  16.          <4>     5/26/95    VL        1251403: Multithreading naming support.
  17.          <3>      7/5/94    CC        Type cast pascal strings.
  18.          <2>     6/18/94    MB        Correct memory includes, still problems
  19.          <1>     5/27/94    VL        first checked in
  20.  
  21.     To Do:
  22.     In Progress:
  23.         
  24. */
  25.  
  26. #ifndef _ODTYPES_
  27. #include "ODTypes.h"
  28. #endif
  29.  
  30. #ifndef _SESSHDR_
  31. #include "SessHdr.h"
  32. #endif
  33.  
  34. #ifndef _INDHDR_
  35. #include "IndHdr.h"
  36. #endif
  37.  
  38. #ifndef _ODMEMORY_
  39. #include "ODMemory.h"
  40. #endif
  41.  
  42. #ifndef _FLIPEND_
  43. #include "FlipEnd.h"
  44. #endif
  45.  
  46. #ifndef __CM_API__
  47. #include "CMAPI.h"
  48. #endif
  49.  
  50. #ifndef som_xh
  51. #include "som.xh"
  52. #endif
  53.  
  54. #include <stddef.h>
  55. #include <stdlib.h>
  56. #include <stdio.h>
  57. #include <string.h>
  58. #include <errno.h>
  59. #include <stdarg.h>
  60.  
  61. #ifndef _FILECTR_
  62. #include "FileCtr.xh"
  63. #endif
  64.  
  65. //==============================================================================
  66. // Constants
  67. //==============================================================================
  68.  
  69. const CMGlobalName kODIndirectValueGlobalName = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Bento Container Suite:Type:IndirectValue";
  70. const ODType    kODEmbeddedContainerProperty = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Bento Container Suite:Property:EmbeddedContainer";
  71. const ODType    kODEmbeddedContainerType = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Bento Container Suite:Type:EmbeddedContainer";
  72.  
  73. //==============================================================================
  74. // Scalar Types
  75. //==============================================================================
  76. typedef struct {
  77.     CMValue        targetValue;
  78.     CMSession    sessionData;
  79.     ODType        objectName;
  80. } IndirectValueRefCon;
  81. typedef IndirectValueRefCon *IndirectValueRefConPtr;
  82.  
  83. //------------------------------------------------------------------------------
  84. // For IndirectValueMetahandler
  85. //------------------------------------------------------------------------------
  86.     CM_CFUNCTIONS
  87.  
  88.  static CMHandlerAddr IndirectValueMetahandler(CMType targetType, const CMGlobalName operationType);
  89.                                                     
  90.  static CMSize getValueSize_Handler(CMValue value);
  91.  static CMSize readValueData_Handler(CMValue value, CMPtr buffer, CMCount offset, CMSize maxSize);
  92.  static void writeValueData_Handler(CMValue value, CMPtr buffer, CMCount offset, CMSize size);
  93.  static void insertValueData_Handler(CMValue value, CMPtr buffer, CMCount offset, CMSize size);
  94.  static void deleteValueData_Handler(CMValue value, CMCount offset, CMSize size);
  95.  static void getValueInfo_Handler(CMValue value, CMContainer *container, CMObject *object,
  96.                                                                     CMProperty *property, CMType *type, 
  97.                                                                     CMGeneration *generation);
  98.  static void setValueType_Handler(CMValue value, CMType type);
  99.  static void setValueGeneration_Handler(CMValue value, CMGeneration generation);
  100.  static void releaseValue_Handler(CMValue value);
  101.                                                                   
  102. //------------------------------------------------------------------------------
  103. // For IndirectDynamicValueMetahandler
  104. //------------------------------------------------------------------------------
  105.  
  106.  static CMMetaData metaData_Handler(CMType type);
  107.  static CMBoolean newValue_Handler(CMValue dynamicBaseValue, 
  108.                                      CMType type,
  109.                                      CMDataPacket dataPacket);
  110.  static CMBoolean useValue_Handler(CMValue dynamicBaseValue,
  111.                                      CMType type,
  112.                                      CMMetaHandler *metahandler,
  113.                                     CMRefCon *refCon);
  114.     CM_END_CFUNCTIONS
  115.  
  116.  
  117. //==============================================================================
  118. // IndirectDynamicValueMetahandler
  119. //==============================================================================
  120.                                                                                                                                                                                  
  121. CMHandlerAddr CM_FIXEDARGS IndirectDynamicValueMetahandler(CMType targetType, CMconst_CMGlobalName operationType)
  122. {
  123.     CMType ignored = targetType;
  124.     
  125.     if (strcmp((ODSByte*) operationType, CMDefineMetaDataOpType)==0)
  126.         return ((CMHandlerAddr) metaData_Handler);
  127.     else if (strcmp((ODSByte*) operationType, CMNewValueOpType) == 0)
  128.         return ((CMHandlerAddr) newValue_Handler);
  129.     else if (strcmp((ODSByte*) operationType, CMUseValueOpType) == 0)
  130.         return ((CMHandlerAddr) useValue_Handler);
  131.     else                                                                                                            
  132.         return (kODNULL);
  133. }
  134.  
  135. //------------------------------------------------------------------------------
  136. // metaData_Handler
  137. //------------------------------------------------------------------------------
  138.  
  139. static CMMetaData metaData_Handler(CMType type)
  140. {
  141.     CMType unused = type;
  142.     
  143.     return ((CMMetaData)"%p(=remoteObject)");    
  144. }
  145.  
  146. //------------------------------------------------------------------------------
  147. // newValue_Handler
  148. //------------------------------------------------------------------------------
  149.  
  150. static CMBoolean newValue_Handler(CMValue dynamicBaseValue, CMType type, CMDataPacket dataPacket)
  151. {
  152.     CMContainer    container   = CMGetObjectContainer(type);
  153.     CMSession    sessionData = CMGetSession(container);
  154.     CMCount     i;    
  155.     ODType        objectName;
  156.     ODULong        objectNameSize, stdNameSize;
  157.         
  158.     i = CMScanDataPacket(type, metaData_Handler(type), dataPacket, &objectName);
  159.     
  160.     if (i != 1) {
  161.         CMError(sessionData,
  162.                 "Unable to get all of CMNewValue()'s parameter in container \"^0\"",
  163.                 CMReturnContainerName(container));
  164.         return (kODFalse);
  165.     }
  166.     
  167.     if (objectName == kODNULL) {
  168.         objectNameSize = 0;
  169.     }
  170.     else {
  171.         objectNameSize = strlen(objectName) + 1;
  172.     }
  173.     stdNameSize = ConvertODULongToStd(objectNameSize);
  174.     CMWriteValueData(dynamicBaseValue, &stdNameSize, 0, sizeof(ODULong));
  175.     if (objectName == kODNULL)
  176.         CMWriteValueData(dynamicBaseValue, "", sizeof(ODULong), 1);
  177.     else
  178.         CMWriteValueData(dynamicBaseValue, objectName, sizeof(ODULong), objectNameSize);
  179.     
  180.     return (kODTrue);
  181. }
  182.  
  183.  
  184. //------------------------------------------------------------------------------
  185. // useValue_Handler
  186. //------------------------------------------------------------------------------
  187.  
  188. static CMBoolean useValue_Handler(CMValue dynamicBaseValue,
  189.                                 CMType type,
  190.                                 CMMetaHandler *metahandler,
  191.                                 CMRefCon *refCon)
  192. {
  193.     CMContainer              container      = CMGetObjectContainer(type);
  194.     CMSession                sessionData = CMGetSession(container);
  195.     IndirectValueRefConPtr    myRefCon;
  196.     CMProperty                targetProperty,
  197.                             embeddedContainerProperty;
  198.     CMType                    embeddedContainerType;
  199.     CMObject                targetObject;
  200.     CMValue                    targetValue;
  201.     ODULong                objectNameSize;
  202.     ODFileContainer*        parentContainer;
  203.     ODSessionRefCon*        sessionRefCon;
  204.  
  205.     sessionRefCon = (ODSessionRefCon*) CMGetSessionRefCon(container);
  206.     if (sessionRefCon == kODNULL)
  207.         WARN("No Session.");
  208.  
  209.     objectNameSize = CMGetValueSize(dynamicBaseValue);
  210.     if (objectNameSize < sizeof(ODULong)) {
  211.         CMError(sessionData, 
  212.             "Incorrect byte length read while reading indirect value data in container \"^0\"", 
  213.             CMReturnContainerName(container));
  214.         return (kODFalse);
  215.     }
  216.     else
  217.         objectNameSize -= sizeof(ODULong);
  218.     
  219.     /* Allocate the refCon that we will pass among the handlers.  Since we are doing a        */
  220.     /* dynamic allocation here we will use the "malloc" handler defined for the container.*/
  221.     
  222.     myRefCon = (IndirectValueRefConPtr) ODNewPtr(sizeof(IndirectValueRefCon), sessionRefCon->heap);
  223.     
  224.     myRefCon->objectName = (ODType) ODNewPtr(objectNameSize, sessionRefCon->heap);
  225.     if (CMReadValueData(dynamicBaseValue, myRefCon->objectName, sizeof(ODULong), objectNameSize) != objectNameSize) {
  226.         CMError(sessionData, 
  227.             "Incorrect byte length read while reading indirect value data in container \"^0\"", 
  228.             CMReturnContainerName(container));
  229.         return (kODFalse);
  230.     }
  231.     
  232.     myRefCon->sessionData = sessionData;                                /* save the current session ptr        */
  233.         
  234.     parentContainer = (ODFileContainer*) sessionRefCon->container;
  235.     if (parentContainer == kODNULL)
  236.         WARN("No File Container.");
  237.         
  238.     Environment* ev = somGetGlobalEnvironment();
  239.     targetProperty = CMRegisterProperty(parentContainer->GetCMContainer(ev), myRefCon->objectName);
  240.     embeddedContainerProperty = CMRegisterProperty(parentContainer->GetCMContainer(ev), kODEmbeddedContainerProperty);
  241.     embeddedContainerType = CMRegisterType(parentContainer->GetCMContainer(ev), kODEmbeddedContainerType);
  242.     targetObject = CMGetNextObjectWithProperty(parentContainer->GetCMContainer(ev), kODNULL, targetProperty);
  243.     targetValue = CMUseValue(targetObject, embeddedContainerProperty, embeddedContainerType);
  244.     
  245.     if (targetValue != kODNULL)
  246.         myRefCon->targetValue = targetValue;
  247.     else
  248.         WARN("No target value.");
  249.         
  250.     *metahandler = (CMMetaHandler) IndirectValueMetahandler;            /* return metahandler            */
  251.     *refCon    = (CMRefCon) myRefCon;                                        /* ...and refCon                */
  252.         
  253.     return (kODTrue);
  254. }
  255.  
  256. //==============================================================================
  257. // IndirectValueMetahandler
  258. //==============================================================================
  259.  
  260. static CMHandlerAddr IndirectValueMetahandler(CMType targetType, const CMGlobalName operationType)
  261. {
  262.     static char *operationTypes[] = {CMGetValueSizeOpType,            /* 0 */ /* Operation Types    */
  263.                                         CMReadValueDataOpType,        /* 1 */
  264.                                          CMWriteValueDataOpType,        /* 2 */
  265.                                         CMInsertValueDataOpType,    /* 3 */
  266.                                         CMDeleteValueDataOpType,    /* 4 */
  267.                                         CMGetValueInfoOpType,        /* 5 */
  268.                                         CMSetValueTypeOpType,        /* 6 */
  269.                                         CMSetValueGenOpType,        /* 7 */
  270.                                         CMReleaseValueOpType,        /* 8 */
  271.                                         NULL};
  272.     char      **t;
  273.     CMType ignored = targetType;
  274.     
  275.     /* Look up the operation type in the operationTypes table above...    */
  276.     
  277.     t = operationTypes - 1;
  278.     while (*++t) if (strcmp((char *)operationType, *t) == 0) break;
  279.  
  280.     /* Now that we got it (hopefully), return the appropriate routine address...*/
  281.     
  282.     switch (t - operationTypes) {
  283.         case  0:    return ((CMHandlerAddr)getValueSize_Handler);        /* CMGetValueSizeOpType     */
  284.         case  1:    return ((CMHandlerAddr)readValueData_Handler);        /* CMReadValueDataOpType     */
  285.         case  2:    return ((CMHandlerAddr)writeValueData_Handler);        /* CMWriteValueDataOpType */
  286.         case  3:    return ((CMHandlerAddr)insertValueData_Handler);    /* CMInsertValueDataOpType*/
  287.         case  4:    return ((CMHandlerAddr)deleteValueData_Handler);    /* CMDeleteValueDataOpType*/
  288.         case  5:    return (NULL);/* use inherited handler or API */    /* CMGetValueInfoOpType     */
  289.         case  6:    return (NULL);/* use inherited handler or API */    /* CMSetValueTypeOpType     */
  290.         case  7:    return (NULL);/* use inherited handler or API */    /* CMSetValueGenOpType         */
  291.         case  8:    return ((CMHandlerAddr)releaseValue_Handler);        /* CMReleaseValueOpType     */
  292.         
  293.         default:    return (NULL);
  294.     }
  295. }
  296.  
  297. //------------------------------------------------------------------------------
  298. // getValueSize_Handler
  299. //------------------------------------------------------------------------------
  300. static CMSize getValueSize_Handler(CMValue value)
  301. {
  302.     IndirectValueRefConPtr    myRefCon = (IndirectValueRefConPtr) CMGetValueRefCon(value);
  303.  
  304.     return (CMGetValueSize(myRefCon->targetValue));
  305. }
  306.  
  307.  
  308. //------------------------------------------------------------------------------
  309. // readValueData_Handler
  310. //------------------------------------------------------------------------------
  311. static CMSize readValueData_Handler(CMValue value, CMPtr buffer, CMCount offset, CMSize maxSize)
  312. {
  313.     IndirectValueRefConPtr    myRefCon = (IndirectValueRefConPtr) CMGetValueRefCon(value);
  314.     
  315.     return CMReadValueData(myRefCon->targetValue, buffer, offset, maxSize);
  316. }
  317.  
  318.  
  319. //------------------------------------------------------------------------------
  320. // writeValueData_Handler
  321. //------------------------------------------------------------------------------
  322. static void writeValueData_Handler(CMValue value, CMPtr buffer, CMCount offset, CMSize size)
  323. {
  324.     IndirectValueRefConPtr    myRefCon = (IndirectValueRefConPtr) CMGetValueRefCon(value);
  325.     
  326.     CMWriteValueData(myRefCon->targetValue, buffer, offset, size);
  327. }
  328.  
  329.  
  330. //------------------------------------------------------------------------------
  331. // insertValueData_Handler
  332. //------------------------------------------------------------------------------
  333. static void insertValueData_Handler(CMValue value, CMPtr buffer, CMCount offset, CMSize size)
  334. {
  335.     IndirectValueRefConPtr refCon = (IndirectValueRefConPtr)CMGetValueRefCon(value);
  336.     CMCount                unused1 = offset;
  337.     CMSize                unused2 = size;
  338.     CMPtr                unused3 = buffer;
  339.  
  340.     CMError(refCon->sessionData,
  341.                 "Insertions into an embedded container \"^0\" are not supported",
  342.                 CMReturnContainerName(CMGetValueContainer(value)));
  343. }
  344.  
  345.  
  346. //------------------------------------------------------------------------------
  347. // deleteValueData_Handler
  348. //------------------------------------------------------------------------------
  349. static void deleteValueData_Handler(CMValue value, CMCount offset, CMSize size)
  350. {
  351.     IndirectValueRefConPtr refCon = (IndirectValueRefConPtr)CMGetValueRefCon(value);
  352.     CMCount                unused1 = offset;
  353.     CMSize                unused2 = size;
  354.  
  355.     CMError(refCon->sessionData,
  356.             "Deletions of data in an embedded container \"^0\" are not supported",
  357.             CMReturnContainerName(CMGetValueContainer(value)));
  358. }
  359.  
  360.  
  361. //------------------------------------------------------------------------------
  362. // getValueInfo_Handler
  363. //------------------------------------------------------------------------------
  364. static void getValueInfo_Handler(CMValue value, CMContainer *container, CMObject *object,
  365.                                     CMProperty *property, CMType *type,
  366.                                     CMGeneration *generation)
  367. {    
  368.     CMGetValueInfo(CMGetBaseValue(value), container, object, property, type, generation);
  369. }
  370.  
  371.  
  372. //------------------------------------------------------------------------------
  373. // setValueType_Handler
  374. //------------------------------------------------------------------------------
  375. static void setValueType_Handler(CMValue value, CMType type)
  376. {    
  377.     CMSetValueType(CMGetBaseValue(value), type);
  378. }
  379.  
  380.  
  381. //------------------------------------------------------------------------------
  382. // setValueGeneration_Handler
  383. //------------------------------------------------------------------------------
  384. static void setValueGeneration_Handler(CMValue value, CMGeneration generation)
  385. {
  386.     CMSetValueGeneration(CMGetBaseValue(value), generation);
  387. }
  388.  
  389.  
  390. //------------------------------------------------------------------------------
  391. // releaseValue_Handler
  392. //------------------------------------------------------------------------------
  393. static void releaseValue_Handler(CMValue value)
  394. {
  395.     IndirectValueRefConPtr myRefCon = (IndirectValueRefConPtr)CMGetValueRefCon(value);
  396.     CMSession            sessionData = myRefCon->sessionData;
  397.     
  398.     CMReleaseValue(myRefCon->targetValue);
  399.     if (myRefCon != kODNULL) {
  400.         if (myRefCon->objectName != kODNULL)
  401.             ODDisposePtr(myRefCon->objectName);
  402.         ODDisposePtr(myRefCon);
  403.     }
  404. }
  405.