home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / warphead.zip / H / TOCIO.H < prev    next >
C/C++ Source or Header  |  1997-02-28  |  34KB  |  638 lines

  1. /* @(#)Z 1.4 com/src/cm/TOCIO.h, odstorage, od96os2, odos29646d 96/11/15 15:27:26 (96/10/29 09:19:44) */
  2. /*====START_GENERATED_PROLOG======================================
  3.  */
  4. /*
  5.  *   COMPONENT_NAME: odstorage
  6.  *
  7.  *   CLASSES: none
  8.  *
  9.  *   ORIGINS: 82,27
  10.  *
  11.  *
  12.  *   (C) COPYRIGHT International Business Machines Corp. 1995,1996
  13.  *   All Rights Reserved
  14.  *   Licensed Materials - Property of IBM
  15.  *   US Government Users Restricted Rights - Use, duplication or
  16.  *   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  17.  *       
  18.  *   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  19.  *   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20.  *   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  21.  *   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  22.  *   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  23.  *   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  24.  *   OR PERFORMANCE OF THIS SOFTWARE.
  25.  */
  26. /*====END_GENERATED_PROLOG========================================
  27.  */
  28.  
  29. /*
  30.     File:        TOCIO.h
  31.  
  32.     Contains:    Container Manager TOC I/O Interfaces
  33.  
  34.     Written by:    Ira L. Ruben
  35.  
  36.     Owned by:    Ed Lai
  37.  
  38.     Copyright:    ⌐ 1992-1994 by Apple Computer, Inc., all rights reserved.
  39.  
  40.     Change History (most recent first):
  41.  
  42.          <2>     8/26/94    EL        #1182275 extra parameter in cmWriteTOC to
  43.                                     truncate free space.
  44.          <4>      2/3/94    EL        Bento File names are now eight chars or
  45.                                                     less.
  46.          <3>    11/23/93    EL        When updating save TOC data so that TOC
  47.                                                     don't need to be read twice.
  48.          <2>    10/21/93    EL        In cmReadTOC, allow restriction of kind of
  49.                                                     entry read.
  50.  
  51.     To Do:
  52. */
  53.  
  54. /*---------------------------------------------------------------------------*
  55.  |                                                                           |
  56.  |                              <<< TOCIO.h >>>                              |
  57.  |                                                                           |
  58.  |                   Container Manager TOC I/O Interfaces                    |
  59.  |                                                                           |
  60.  |                               Ira L. Ruben                                |
  61.  |                                 10/01/92                                  |
  62.  |                                                                           |
  63.  |                     Copyright Apple Computer, Inc. 1992-1994              |
  64.  |                           All rights reserved.                            |
  65.  |                                                                           |
  66.  *---------------------------------------------------------------------------*
  67.  
  68.  This file defines the routines responsible for reading and writing the container TOC. 
  69.  The routines are divided into two main groups as follows:
  70.  
  71.  (1). "Raw" low-level TOC I/O: all the routines to read and write TOC basic value segment
  72.            entries.  These routines format the TOC with the syntatic layout described later in
  73.             this header.
  74.  
  75.            cmStartTOCIO                        -    initiate TOC I/O
  76.             cmEndTOCIO                            - end TOC I/O
  77.             cmFtellTOC                            - get current container TOC I/O "seek" position
  78.             cmFlushTOCOutputBuffer    - write current TOC output buffer
  79.             cmWrite1TOCSegment            - write one value segment
  80.             cmRead1TOCSegment                - read one value segment
  81.                 
  82.  (2). High-level TOC I/O control that determines how to generate or process TOC entries.
  83.             This calles the group (1) routines.
  84.             
  85.             cmBuildGlobalNameTable    - add a global name to the global name table
  86.             cmReadTOC                                - read (laod) in a container TOC
  87.             cmWriteTOC                            - write a TOC to the container
  88.             cmDoBackPatches                    - back patch certain TOC entries
  89. */
  90.  
  91. #ifndef __TOCIO__
  92. #define __TOCIO__
  93.  
  94. #ifndef __CMTYPES__
  95. #include "CMTypes.h"
  96. #endif
  97. #ifndef __CM_API_TYPES__
  98. #include "CMAPITyp.h"
  99. #endif
  100. #ifndef __GLOBALNAMES__
  101. #include "GlbNames.h"   
  102. #endif
  103. #ifndef __CONTAINEROPS__
  104. #include "Containr.h"  
  105. #endif
  106. #ifndef __TOCENTRIES__
  107. #include "TOCEnts.h"   
  108. #endif
  109.  
  110.                                                                         CM_CFUNCTIONS
  111.  
  112. #if TOC1_SUPPORT
  113.                                                 /*-------------------------------------*
  114.                                                  | Defined "Old" Layout of a TOC Entry |
  115.                                                  *-------------------------------------*
  116.  
  117. As defined by the original API documentation, a container TOC entry has the following
  118. layout:
  119.  
  120.       0           4           8           12          16          20    22    24
  121.          +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  122.          | Object ID |Property ID|  Type ID  |Valu Offset| Value Len | Gen |Flags|
  123.          +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  124.                4           4           4           4           4        2     2
  125.  
  126. These are defined as "hard-coded" constants since the format is, by definition, platform
  127. independent.  The actual formatting and I/O for a TOC entry is done by a handler because
  128. of this.                                                                                                                                                                */
  129.  
  130. #define TOCentryObjectID          0                /* 4 bytes: the object's ID                                                */
  131. #define TOCentryPropertyID      4                /* 4        its property ID                                                */
  132. #define TOCentryTypeID              8                /* 4        its type ID                                                        */
  133. #define TOCentryValueOffset 12                /* 4        offset to its value                                        */
  134. #define TOCentryValueLength    16                /* 4        size of the value                                            */
  135. #define TOCentryGeneration    20                /* 2        generation number                                            */
  136. #define TOCentryFlags                22                /* 2        flags                                                                    */
  137.                      
  138. #define TOCentrySize                 24                /* defined size of a TOC entry in its container        */
  139.  
  140. /* The following macros allow portable (I hope) access to a TOC's entry fields.  There     */
  141. /* are two sets of macros; one set for input, and one for output.  Each set consists of    */
  142. /* two definitions; one when using buffered I/O and the other when calling a handler        */
  143. /* directly.  The code is configurable (CMConfig.h) to do either.  But in some cases        */
  144. /* we ignore the configuration, so all definitions must be defined here.  The goal here */
  145. /* is to define in THIS ONE PLACE all the dependencies on the actual TOC format.  If it    */
  146. /* changes, then theoritically all we need to do is change this stuff here.  Cross your    */
  147. /* fingers!                                                                                                                                                            */
  148.  
  149. /* The first pair of macros are for extracting the TOC fields.  In the buffered case the*/
  150. /* fields are extracted directly out of the buffer.  In the nonbuffered case, the buffer*/
  151. /* is supplied to the macro to extract the fields.                                                                            */
  152.  
  153. #define BufferedExtractTOC(ioBuffer, objectID, propertyID, typeID, value, valueLen, generation, flags) \
  154.                     {objectID      = (CM_ULONG)GET4(ioBuffer);    \
  155.                      propertyID = (CM_ULONG)GET4(ioBuffer);    \
  156.                      typeID          = (CM_ULONG)GET4(ioBuffer);    \
  157.                      value          = (CM_ULONG)GET4(ioBuffer);    \
  158.                      valueLen     = (CM_ULONG)GET4(ioBuffer);    \
  159.                      generation = (CM_USHORT)GET2(ioBuffer);    \
  160.                      flags            = (CM_USHORT)GET2(ioBuffer);}
  161.  
  162. #define ExtractTOC(tocBuffer, objectID, propertyID, typeID, value, valueLen, generation, flags) \
  163.                     {CMextractData(container, (char *)tocBuffer + TOCentryObjectID,      4, &objectID);            \
  164.                      CMextractData(container, (char *)tocBuffer + TOCentryPropertyID,  4, &propertyID);        \
  165.                      CMextractData(container, (char *)tocBuffer + TOCentryTypeID,          4, &typeID);                \
  166.                      CMextractData(container, (char *)tocBuffer + TOCentryValueOffset, 4, &value);                \
  167.                      CMextractData(container, (char *)tocBuffer + TOCentryValueLength, 4, &valueLen);            \
  168.                      CMextractData(container, (char *)tocBuffer + TOCentryGeneration,  2, &generation);        \
  169.                      CMextractData(container, (char *)tocBuffer + TOCentryFlags,            2, &flags);}
  170. #endif
  171.  
  172.                                                 /*-------------------------------------*
  173.                                                  | Defined "New" Layout of a TOC Entry |
  174.                                                  *-------------------------------------*
  175.  
  176. The TOC in the container has the following syntatic layout:
  177.  
  178.                                                  --                        --   
  179.                                                    |  ( PT [g] [R] v... )     |   
  180.                           { OPT [g] [R] v... |  <                 > ... | } ...
  181.                                                    |  ( T  [g] [R] v... )     |   
  182.                                                  --                        --   
  183.                                                     
  184. where OPT = object entry (NewObject code plus 4-byte object, property, and type ID)
  185.             PT  = property entry (NewProperty code plus 4-byte property and type ID)
  186.             T   = type entry (newType plus 4-byte type ID)
  187.             g   = optional generation number if different from previous generation number
  188.           R      = object ID of value's references recording object (if any)
  189.             v   = value entry (code plus offset/length or 4-byte immediate) -- code determines
  190.                         4 or 8 byte offsets and actual size of immediate
  191.                         
  192. In other words, nothing is repeated if it doesn't change.  The 4-byte data entries are
  193. preceded by byte codes defined as follows:                                                                                            
  194.                                                                                                                                                               Bytes        */
  195. /*      Code                                                          Meaning                                                           Consumed    */
  196. /*======================================================================================*/
  197. #define NewObject                      1U                    /* object + property + type                                    12         */
  198. #define NewProperty                  2U                    /* property + type                                                     8         */
  199. #define NewType                          3U                    /* type                                                                          4         */
  200. #define ExplicitGen                 4U                    /* generation                                                                 4         */
  201. #define Offset4Len4                  5U                    /* 4-byte offset + 4-byte length                         8         */
  202. #define ContdOffset4Len4     6U                    /* continued 4-byte offset + 4-byte length     8         */
  203. #define Offset8Len4                  7U                    /* 8-byte offset + 4-byte length                        12         */
  204. #define ContdOffset8Len4     8U                    /* continued 8-byte offset + 4-byte length    12         */
  205. #define Immediate0                 9U                    /* immediate (length = 0)                                         0         */
  206. #define Immediate1                10U                    /* immediate (length = 1)                                         4         */
  207. #define Immediate2                11U                    /* immediate (length = 2)                                         4         */
  208. #define Immediate3                12U                    /* immediate (length = 3)                                          4         */
  209. #define Immediate4                13U                    /* immediate (length = 4)                                          4         */
  210. #define ContdImmediate4        14U                    /* continued immediate (length = 4)                     4         */
  211. #define ReferenceListID        15U                    /* references recording object ID                         4        */
  212. #define Reserved4b                16U                    /*     "     "     "    "  "  "   "    "         4        */
  213. #define Reserved4c                17U                    /*     "     "     "    "  "  "   "    "         4        */
  214. #define Reserved8a                18U                    /* reserved for future use of 8 byte entry     8        */
  215. #define Reserved8b                19U                    /*     "     "     "    "  "  "   "    "         8        */
  216. #define Reserved8c                20U                    /*     "     "     "    "  "  "   "    "         8        */
  217. #define Reserved12a                21U                    /* reserved for future use of 12 byte entry    12        */
  218. #define Reserved12b                22U                    /*     "     "     "    "  "   "   "    "        12        */
  219. #define Reserved12c                23U                    /*     "     "     "    "  "   "   "    "        12        */
  220. #define EndOfBufr                    24U                    /* end of current buffer, go to next                  0        */
  221. /*======================================================================================*/
  222.  
  223. /* The following define special codes and values related to the above TOC codes:                */
  224.  
  225. #define FirstCode                     1U        /* lowest code used (see notes below)                                        */
  226. #define LastCode                 24U        /* highest code used (see notes below)                                    */
  227.  
  228. #define NOP                         0xFFU        /* NOP or filler                                                                                 */
  229. #define TOCEOF                 0x00U        /* EOF signal code only returned for TOC input                    */
  230.                                                                                                                                                                                 /*
  231. Notes: 1. The TOCEOF code is NOT a code placed in the TOC.  It is used only reading the
  232.                     TOC to signal that all TOC bytes have been read.
  233.              
  234.              2. The codes form a dense set starting at 1 (FirstCode) and extend up to LastCode.
  235.                    This is done to allow the definition arrays associated with the codes using the
  236.                     following typedef:                                                                                                                        */
  237.                     
  238.                   typedef unsigned char TOCCodeArray[LastCode+1];
  239.                                                                                                                                                                                  /*
  240.              3. One use of the codes and the code array is to define the size of the data 
  241.                      associated with each code.  To keep the size info in proximity with the above
  242.                     definitions (to make it easier for changing), the following macro is defined to
  243.                     init an entry size array to the proper size for each code:                                        */
  244.  
  245.                     #define InitCodeSizes(entrySizeArray)    entrySizeArray[NewObject       ]    =    12;    \
  246.                                                                                                 entrySizeArray[NewProperty     ]    =     8;    \
  247.                                                                                                 entrySizeArray[NewType         ]    =     4;    \
  248.                                                                                                 entrySizeArray[ExplicitGen     ]    =     4;    \
  249.                                                                                                 entrySizeArray[Offset4Len4     ]    =     8;    \
  250.                                                                                                 entrySizeArray[ContdOffset4Len4]    =     8;    \
  251.                                                                                                 entrySizeArray[Offset8Len4     ]    =    12;    \
  252.                                                                                                 entrySizeArray[ContdOffset8Len4]    =    12;    \
  253.                                                                                                 entrySizeArray[Immediate0      ]    =     0;    \
  254.                                                                                                 entrySizeArray[Immediate1      ]    =     4;    \
  255.                                                                                                 entrySizeArray[Immediate2      ]    =     4;    \
  256.                                                                                                 entrySizeArray[Immediate3      ]    =     4;    \
  257.                                                                                                 entrySizeArray[Immediate4      ]    =     4;    \
  258.                                                                                                 entrySizeArray[ContdImmediate4 ]    =     4;    \
  259.                                                                                                 entrySizeArray[ReferenceListID ]    =     4;    \
  260.                                                                                                 entrySizeArray[Reserved4b      ]    =     4;    \
  261.                                                                                                 entrySizeArray[Reserved4c      ]    =     4;    \
  262.                                                                                                 entrySizeArray[Reserved8a      ]    =     8;    \
  263.                                                                                                 entrySizeArray[Reserved8b      ]    =     8;    \
  264.                                                                                                 entrySizeArray[Reserved8c      ]    =     8;    \
  265.                                                                                                 entrySizeArray[Reserved12a     ]    =    12;    \
  266.                                                                                                 entrySizeArray[Reserved12b     ]    =    12;    \
  267.                                                                                                 entrySizeArray[Reserved12c     ]    =    12;    \
  268.                                                                                                 entrySizeArray[EndOfBufr         ]    =     0
  269.                                                                                                                                                                                 /*
  270.              4. All data entry sizes are a multiple of 4.  Thus data values are passed around
  271.                      in (unsigned) long variables.  Therefore, in terms of long variables, a maximum
  272.                     of 12/4 longs would be needed to hold the largest value according to the above
  273.                     sizes.                                                                                                                                                */
  274.  
  275.                     #define MaxEntrySize (12/4)                        /* max nbr of longs to hold entry data    */
  276.                                                                                                                                                                                 /*
  277.              5. In general, ignoring immediates, a value segment takes a minimum of 8 bytes.    
  278.                    Thus, when maintaining the free list, we should not add anything to that list
  279.                     if it is less than 8 plus 1 for the entry code.                                                                */
  280.                     
  281.                     #define MinTOCSize (1+8)                            /* assumed min TOC entry size                        */
  282.  
  283. /* The following defines all the information associated with a single TOC value data         */
  284. /* segment.  It is clustered as a struct to make it easier to "carry around".                     */
  285.  
  286. struct TOCentry {                                            /* Place to put a TOC entry during its write:            */
  287.     CM_ULONG           objectID;                        /*         the object's ID                                                            */
  288.     CM_ULONG           propertyID;                    /*         an object's property ID                                            */
  289.     CM_ULONG           typeID;                            /*         an object's type ID                                                    */
  290.     TOCValueBytes  value;                                /*         value and length or immediate value                    */
  291.     CM_ULONG           generation;                    /*         generation number                                                        */
  292.     CM_USHORT             flags;                                /*         object flags                                                                */
  293. };
  294. typedef struct TOCentry TOCentry, *TOCentryPtr;
  295.  
  296. struct TOCEntryListItem {                            /* So that we can put TOCEntry in a list                    */
  297.     ListLinks                tocEntryLinks;            /*     links to nex/prev toc entry                                        */
  298.     TOCentry                tocEntryItem;                /*     the toc entry                                                                    */
  299.     CM_ULONG              refsDataObjectID;        /*     reference object id                                                        */
  300. };
  301. typedef struct TOCEntryListItem TOCEntryListItem, *TOCEntryListItemPtr;
  302.  
  303. enum TocEntryType {                                    /* Select what TOC entries to read:    */
  304.     TocEntry_All,                                                /*        read everything                                                            */
  305.     TocEntry_Update,                                        /*        only the update entries                                         */
  306.     TocEntry_NewEntry                                        /*        the new additions to the TOC                                */
  307. };
  308. typedef enum TocEntryType TocEntryType;
  309.  
  310. /* In some cases, when the TOC is written, it is necessary to backpatch certain entries    */
  311. /* because we don't know the information when the entry is initially written.  The             */
  312. /* following defines "BackPatches" area used to remember what has to be back patched and*/
  313. /* the corresponding container offsets that will get the back patch.  These will always    */
  314. /*( be offsets to the value of the value/length fields in the TOC.                                            */
  315.  
  316. struct BackPatches {                                    /* All the info on all possible patches:                    */
  317.     CM_USHORT             whatWeGot;                        /*        flags indicating upatched entries we got        */
  318.     CM_ULONG             tocSizeEntry;                /*        offset to TOC #1 size value                                    */
  319.     CM_ULONG             tocContEntry;                /*        offset to TOC #1 container value                        */
  320.     CM_ULONG             tocNewValuesTOCEntry;/*        offset to TOC #1 new values TOC value                */
  321. };
  322. typedef struct BackPatches BackPatches, *BackPatchesPtr;
  323.  
  324. #define Patch_TOCsize                  0x0001U    /* indicates tocSizeEntry created                                    */
  325. #define Patch_TOCContSize          0x0002U    /* indicates tocContEntry created                                    */
  326. #define Patch_TOCNewValuesTOC 0x0004U    /* indicates tocNewValuesTOCEntry created                    */
  327.  
  328. #define InitBackPatches(patches) (((BackPatchesPtr)(patches))->whatWeGot = 0x0000U)
  329.     /*
  330.     This macro is used to init the back-patches data prior to writing TOC(s).  The macro 
  331.     takes a pointer to a BackPatches struct.
  332.     */
  333.  
  334.  
  335. void *cmStartTOCIO(ContainerPtr container, CM_ULONG tocBufSize, jmp_buf *ioEnv,
  336.                                      CM_ULONG tocOffset, CM_ULONG tocSize);
  337.     /*
  338.     This must be called prior to any reading or writing of the TOC.  The basic standard
  339.     protocol to be followed is as follows:
  340.     
  341.      if (setjmp(env)) {
  342.          <caller's recovery and exit>
  343.      }
  344.      
  345.      CMseek(to proper TOC position in the container);
  346.      
  347.      t = cmStartTOCIO(container, container->tocBufSize, (jmp_buf *)&env, tocOffset, tocSize);
  348.      
  349.                             when reading                  or          when writing
  350.                             ------------                              ------------
  351.      
  352.              while (cmRead1TOCSegment(t, ...)) {   |   some kind loop through the TOC
  353.                  cmRead1TOCSegment(t, ...);          |   {
  354.                  <process TOC entry>                 |             <set up TOC entry>
  355.              }                                     |      cmWrite1TOCSegment(t, ...);
  356.                                                                                          |   }
  357.                                                                                          |   cmFlushTOCOutputBuffer(t, true);
  358.      cmEndTOCIO(t);
  359.     
  360.     The TOC to be read or written is assumed to start at the specified tocOffset. It is the
  361.     caller's responsibility to seek to this position.  For reading a TOC, tocSize defines the
  362.     EXACT amount of TOC to be read.  For writing, tocSize must be passed as 0. The final size
  363.     will be returned when endTOCIO() is called to terminate TOC creation (alternatively,
  364.     cmFlushTOCOutputBuffer() will return the final size).
  365.      
  366.     cmStartTOCIO() allocates an I/O buffer and its associated control information. The buffer
  367.     is used to format or extract TOC entries.  The TOC I/O control block pointer allocated is
  368.     returned as the function result as an anonymous "void *" pointer.  This is passed to all
  369.     the other low level TOC externalized buffering routines (cmWrite1TOCSegment(),
  370.     cmread1TOCSegment(), cmFlushTOCOutputBuffer(), cmFTellTOC(), and endTOCIO()).  An error
  371.     is reported for allocation errors.  If the error reporter returns, NULL is returned as
  372.     the function result.
  373.     
  374.     The maximum size of the buffer to be allocated is passed.  This will generally be
  375.     determined from the container label, but that is not assumed here.  The size is, however,
  376.     always ensured to be rounded up to a multiple of 4.
  377.     
  378.     A set setjmp/longjmp environment variable is also passed for read and write error
  379.     reporting and recovery.  The setjmp/longjmp is used rather than have to check for errors
  380.     on each I/O call of the buffered I/O routines.  If the longjmp is taken, the caller can
  381.     assume that the appropriate error has been reported and the buffer and its control block
  382.     freed.
  383.      
  384.     Note, in the case of updating, the private TOC and the non-private (updating) TOC are
  385.     viewed as two INDEPENDENT TOCs.  There is no need to worry that the non-private (i.e.,
  386.     second TOC) does not start on a buffer boundary with respect to the private (first) TOC.
  387.     Each is read or written independently and viewed as distinct from one another.  They just
  388.     happen to be adjacent to one another in the container.  The tocBufSize and tocOffset
  389.     must be appropriately passed for each TOC.
  390.     
  391.     Also note, that the reason some of the low level buffering routines have been made
  392.     external (cmWrite1TOCSegment(), cmread1TOCSegment(), cmFlushTOCOutputBuffer(), 
  393.     cmFTellTOC(), and endTOCIO()) is to mainly allow for the debugging trace routines to read
  394.     the TOC.  cmWrite1TOCSegment() and cmFlushTOCOutputBuffer() are external only for
  395.     symmetry, but it should have no external callers (i.e., they're all in this file).  
  396.     Making these routines externally visable is also why the I/O control block pointer is
  397.     returned as an anonymous "void *".  We may have to make the routines visable outside of
  398.     here, but no one outside has any business knowing what's in the control block!
  399.     */
  400.     
  401.  
  402. CM_ULONG cmEndTOCIO(void *tocIOCtl);
  403.     /*
  404.     After all I/O to a TOC is completed, this routine must be called to free the TOC I/O
  405.     buffer and control block (whose pointer is passed as the t parameter).  If the TOC was
  406.     created (written), then it is assumed the last buffer was already flushed by calling
  407.     flushTOCOutputBuffer() with its finalFlush parameter set to true. 
  408.     
  409.     The function returns the size of the TOC.  For TOC creation (writing), this will be the
  410.     size of the TOC now written to the container.  For reading, the returned value is 
  411.     identical to the size passed to cmStartTOCIO() (i.e., the returned value is not looked at
  412.     for reading).
  413.     
  414.     Note, this routine must NOT be called if an error was reported and the longjmp taken 
  415.     through the setjmp environment buffer passed to cmStartTOCIO()>  Part of standard error
  416.     recovery for TOC I/O errors is effectively do a cmEndTOCIO() and then report the error.
  417.     If the error reporter returns, the longjmp is taken.
  418.     */
  419.  
  420.  
  421. CM_ULONG cmFtellTOC(void *tocIOCtl);
  422.     /*
  423.     This returns the current container I/O position.  The position is updated as the TOC I/O
  424.     buffer fills and is written or reloaded when reading.
  425.     
  426.     This routine is needed when only when there is the possibility that other code might be
  427.     doing "seeks" to the same container behind the TOC I/O routine's back!  Code doing such
  428.     seeks must be able to reseek the container position according to the value returned here.
  429.     */
  430.  
  431.  
  432. CM_ULONG cmFlushTOCOutputBuffer(void *tocIOCtl, CMBoolean finalFlush);
  433.     /*
  434.     This must be called to make sure that the TOC output buffer (allocated by cmStartTOCIO()
  435.     and associated with tocIOCtl) is flushed, i.e., fully written.  This buffer will be the
  436.     remaining partial buffer when finalFlush is true, and a full buffer otherwise.  The 
  437.     buffer is padded if necessary up to the full buffer size (defined by cmStartTOCIO()) or
  438.     to the nearest multiple of 4 when finalFlush is true.  finalFlush would, of course, only
  439.     be true prior to calling cmEndTOCIO() to write the LAST buffer out as a "short" buffer.
  440.     
  441.     Padding consists of a EndOfBufr byte followed by 0 or more NOP bytes.  Padding is not
  442.     necessary, of course, if the buffer is exactly full.
  443.  
  444.   The function returns the current total size of the TOC including the flushed buffer. This
  445.   generally has no meaning until finalFlush is true, at which time the returned amount will
  446.   be the total size of the TOC written to the container. 
  447.     */
  448.  
  449.  
  450. CM_ULONG cmWrite1TOCSegment(void *tocIOCtl,
  451.                                                         CM_ULONG  objectID, 
  452.                                                         CM_ULONG  propertyID, 
  453.                                                         CM_ULONG  typeID,
  454.                                                         CM_ULONG  value,
  455.                                                         CM_ULONG  valueLen,
  456.                                                         CM_ULONG  generation,
  457.                                                         CM_USHORT flags,
  458.                                                         TOCObjectPtr     refDataObject);
  459.     /*
  460.     All TOC value segment writing is done with this routine.  This routine interfaces the
  461.     low-level TOC entry buffering routines (whose I/O control block is associated with
  462.     tocIOCtl and allocated by cmStartTOCIO()) with the upper-level writers.  The upper level
  463.     (i.e., the caller) views all value segments in terms of the fields shown as this
  464.     routine's parameters.  Here that information is selectively passed to the lower-level
  465.     buffering routines to generate a TOC in the container with the syntactic layout described
  466.     above.  
  467.     
  468.     Since this syntax describes a TOC layout where nothing is repeated if it doesn't change,
  469.     this routine remembers and controls what goes out and when.  Note that, at a minimum, a
  470.     data value (v) is always generated.
  471.  
  472.   Note the refDataObject parameter represents the "R" in the syntax.  refDataObject is a
  473.   pointer to a value's private reference recording object ID.  This is the value's private
  474.   object used to hold the list of CMReference "key"/object ID associations as value data.
  475.   If refDataObject is NULL no "R" is generated.  If not NULL we generate the ID after the
  476.   OPT, PT, or T.  
  477.  
  478.     The function returns the container offset to the value entry entry data (v).  This can
  479.     be remembered by the higher-level caller for possible back patching later.
  480.     
  481.     Note, no consistency checking is done here. It is assumed all error checks have been done
  482.     by the caller, and that by the time this routine is called, it is EXPECTED that a TOC
  483.     entry will be created.  I/O errors can, of course, occur.  They use the setjmp/longjmp
  484.     mechanism defined by cmStartTOCIO().
  485.     */
  486.     
  487.  
  488. CMBoolean cmRead1TOCSegment(void *tocIOCtl,
  489.                                                         TOCentry  *tocEntry, 
  490.                                                         CM_ULONG  *refsDataObjectID);
  491.     /*
  492.     All TOC value segment reading is done with this routine.  This routine interfaces the
  493.     low-level TOC entry buffering routines (whose I/O control block is associated with
  494.     tocIOCtl and allocated by cmStartTOCIO()) with the upper-level writers.  The upper level
  495.     (caller) views all value segments in terms of the fields shown as this routine's
  496.     parameters.  
  497.     
  498.     The container TOC has the syntactic layout described above.  Since this syntax describes
  499.     a TOC layout where nothing is repeated if it doesn't change, this routine remembers the
  500.     unrepeated information are repeats it back to the caller.
  501.  
  502.     The function always returns true until an "eof" is detected, i.e., until all the bytes, 
  503.     whose size was specified to cmStartTOCIO(), are read.  False is returned for the "eof".
  504.  
  505.     Note, refsDataObjectID represents a value's private reference recording object ID.  This
  506.     is the value's private object used to hold the list of CMReference "key"/object ID
  507.     associations as value data.  0x00000000UL is returned in refsDataObjectID if there is no
  508.     recording object and, of course, will be the object ID if it is.
  509.     */
  510.  
  511.  
  512. CMBoolean cmBuildGlobalNameTable(TOCValuePtr theValue);
  513.     /*
  514.      This routine creates a global name symbol table entry for each value that has a property
  515.      ID that indicates the value is for a global name.
  516.      
  517.      When a TOC is read in from a container we must build up our memory structures exactly as
  518.      they were when the container was previously written.  That means that, in addition to the
  519.      TOC data structures, we have to build the global name symbol table containing the global
  520.      name strings for those values. Thus is routine is ONLY called during read-in (and only
  521.      from cmAppendValue()).  At that time the switch tocFullyReadIn is false, which is a status
  522.      switch indicating the TOC read is not yet complete.
  523.      
  524.      A word of caution!  Remember that this routine is only called during read in of a TOC. But
  525.      here we must read in a global name.  That will CHANGE the current "seek" position of the
  526.      next read.  cmReadTOC(), which is the routine that does the TOC reading, always keeps its
  527.      current TOC offset (the one just read) in tocInputOffset in the container.  We use that to
  528.      re-seek so that cmReadTOC() is none the wiser.
  529.     */
  530.     
  531.     
  532. CMBoolean cmReadTOC(ContainerPtr container, TocEntryType whichKind, 
  533.                                         CM_ULONG tocOffset, CM_ULONG tocSize,
  534.                                         ListHdr *newEntryList);
  535.     /*
  536.     This routine is called to read in a TOC from a container which has been opened for input
  537.     by a call to CMOpenContainer().  The container, offset to TOC, and the size of the TOC
  538.     are passed.  The function returns true if successfully loaded and false otherwise (this
  539.     is a safety, since error reports should never return from the error handler).
  540.     
  541.     Note, the entire TOC whose size is defined by tocSize will be read.  It is an error if
  542.     not all the bytes are read.  This means that it is expected that tocSize be the EXACT 
  543.     amount to read from tocOffset.  This is emphasized because, for updating, two TOCs must
  544.     be read; the private TOC, and the non-private (updating) TOC.  The private offset and
  545.     size are defined in the container label (by definition).  For non-updating containers,
  546.     this will reflect the entire (only) TOC.  The non-private (updating) portion is defined
  547.     by a TOC #1 property.
  548.     
  549.     WhichKind controls what kind of entry will be read. This is because we need to read in the
  550.     update entry first because they may contains deletion, then we read in the rest, otherwise the
  551.     newly read entries may be deleted.
  552.     
  553.     When whickKind is TocEntry_Update, pass in an initialized but empty list so that the
  554.     newEntry may be collected. Later when cmReadTOC is called again for the new entries,
  555.     pass in the same newEntryList to avoid reading the TOC again fro the new entries.
  556.     */
  557.  
  558.  
  559. CMBoolean cmWriteTOC(ContainerPtr container, void *toc, CMObjectID startingID,
  560.                                          CMObjectID endingID, BackPatchesPtr thePatches,
  561.                                          CM_ULONG *tocStart, CM_ULONG *tocSize,
  562.                                          CMBoolean truncFreeSpace);
  563.     /*
  564.     This routine is the inverse to cmReadTOC() to write the in-memory TOC to a container. The
  565.     TOC is written to the end of the container.  Only objects with ID's greater than or equal
  566.     to the startingID and less than or equal to the endingID are written.  Further, only
  567.     objects whose value headers are equal to the specified container are written.
  568.     
  569.     With the restriction on the container, we will only write to the TOC newly created values
  570.     for this open session.  If we're not updating, only one container so this is not an
  571.     issue.  But for updating, only looking at the stuff in the updating container will yield
  572.     all new objects and all new properties for "old" objects.  We can split these two groups
  573.     using the ID limits.
  574.     
  575.     Note, non-TOC updates are generated by a separate walk not done here.  See Updating.c.
  576.     
  577.     For updating, a container may have its own TOC and the target TOC.  Thus the TOC pointer
  578.     is an explicit parameter.  The container offset is returned in tocStart and the size of
  579.     the TOC in tocSize.  The function returns true to indicate success and false otherwise
  580.     (as a safety).
  581.     
  582.     There are some TOC entries that must be back-patched. This is because they are a function
  583.     of the final TOC size in the container.  We don't know that until the entire TOC is
  584.     written.  At that time we can rewrite the entries with the proper values filled in.
  585.     
  586.     Because of updating, there may be multiple calls to cmWriteTOC() to write various subsets
  587.     of the TOC (i.e., the updates).  Thus we may not know the final TOC size when we return
  588.     from here.  The back-patching cannot be done.  Only the caller knows when all TOC writes
  589.     are complete and the back-patching can be done.
  590.     
  591.     To allow this to happen, thePatches is passed as a pointer to a BackPatches struct where
  592.     we save the original unpatched TOC info and offset for the entries of interest.  As these
  593.     entries are encountered (and they must be sometime) during TOC writing, we save them and
  594.     their offsets in the struct. When the caller is ready to rewrite them cmDoBackPathes() is
  595.     called to do it.
  596.     
  597.     If thePatches is passed as NULL, nothing (obviously) is saved for back-patching.
  598.     */
  599.  
  600.  
  601. CMBoolean cmDoBackPatches(ContainerPtr container, BackPatchesPtr thePatches,
  602.                                                   CM_ULONG tocStart, CM_ULONG tocSize,
  603.                                                     CM_ULONG newValuesTOCStart, CM_ULONG newValuesTOCSize);
  604.     /*
  605.     When a TOC is written (e.g., cmWriteTOC()), there are some entries that are dependent on
  606.     the final size of the TOC.  Such entries must be back-pached with the proper info.  Only
  607.     the callers generating the TOC in the container know when it is time to do the patching.
  608.     They call this routine to do it when that time comes.
  609.     
  610.     True is returned if the back-patching is successful and false otherwise.
  611.     
  612.     By the time this routine is called, the original TOC entries in question and their
  613.     offsets within the container have been recorded in a BackPatches struct whose pointer is
  614.     passed in thePatches.  Currently only 3 such entries need back-patching:
  615.     
  616.     tocSizeEntry                  -    The TOC size entry.  This is a property of TOC #1 which
  617.                                                     represents the size and offset of the TOC itself.  The caller
  618.                                                     passes this info in the tocSize and tocStart parameters
  619.                                                     respectively.
  620.                                             
  621.     tocContEntry                  -    The TOC container entry. This is a property of TOC #1 which
  622.                                                     represents the entire container, from offset 0 to the end of the
  623.                                                     label.  No additional parameters are passed for this.  But to
  624.                                                     compute this, it is required that cmDoBackPathes() be the LAST
  625.                                                     thing called prior to writing the container label.
  626.      
  627.     tocNewValuesTOCEntry - The non-private TOC offset/size entry.  An updating TOC contains
  628.                                                  a TOC #1 property that defines the offset and size of all TOC
  629.                                                  entries that are to be applied to this container's target.  The
  630.                                                  caller passes this info in the newValuesTOCSize and
  631.                                                  newValuesTOCStart parameters respectively.  For non-updating
  632.                                                  containers, these are ignored.
  633.     */
  634.  
  635.  
  636.                                                           CM_END_CFUNCTIONS
  637. #endif
  638.