/* * @OPENGROUP_COPYRIGHT@ * COPYRIGHT NOTICE * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for * the full copyright text. * * This software is subject to an open license. It may only be * used on, with or for operating systems which are themselves open * source systems. You must contact The Open Group for a license * allowing distribution and sublicensing of this software on, with, * or for operating systems which are not Open Source programs. * * See http://www.opengroup.org/openmotif/license for full * details of the license agreement. Any use, reproduction, or * distribution of the program constitutes recipient's acceptance of * this agreement. * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY * OR FITNESS FOR A PARTICULAR PURPOSE * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ /* * HISTORY */ #ifdef REV_INFO #ifndef lint static char rcsid[] = "$XConsortium: MrmIheader.c /main/16 1996/11/13 13:56:56 drk $" #endif #endif /* (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */ /* *++ * FACILITY: * * UIL Resource Manager (URM): IDB facility * * ABSTRACT: * * These routines transfer header information between a file and the * in-memory file header struct. All IDB routines maintain the in-memory * file header; the on-disk header is only updated when the header is * initialized or the file is closed. These routines assume that all * information required in the header is continuously up-to-date in * the open file struct. * * All header information must be updated at the time a record is * modified, not written. * *-- */ /* * * INCLUDE FILES * */ #include #include #include #include #include "MrmMsgI.h" /* * * TABLE OF CONTENTS * * Idb__HDR_GetHeader - Read a file header to memory * * Idb__HDR_InitHeader - Initialize a file header * * Idb__HDR_PutHeader - Write the header to disk * */ /* * * DEFINE and MACRO DEFINITIONS * */ /* * Macros which validate index records in buffers */ #define Idb__HDR_ValidRecord(buffer) \ (_IdbBufferRecordType(buffer)==IDBrtHeader) /* * * OWN VARIABLE DECLARATIONS * */ /* * The following defines the database version written into all * header records. */ static XmConst char *idb__database_version = URMversion; /* *++ * * PROCEDURE DESCRIPTION: * * Idb__HDR_GetHeader reads the file's header record into a buffer, * copies the information into the in-memory header. * * This routine is called as part of InitHeader to move the contents * of the initialized header to memory. This usage expects the * the record to be in the buffer pool, of course. * * FORMAL PARAMETERS: * * file_id Partially initialized in-memory file header struct; the * file is open and the low-level file id is saved. * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * MrmSUCCESS operation succeeded * MrmNOT_FOUND header record not found * MrmNOT_VALID database version mismatch * MrmBAD_RECORD not the header record * MrmFAILURE some other failure * * SIDE EFFECTS: * *-- */ Cardinal Idb__HDR_GetHeader (IDBFile file_id) { /* * Local variables */ Cardinal result; /* function results */ IDBRecordBufferPtr hdrbuf; /* header record buffer */ IDBHeaderRecordPtr recptr; /* header record in buffer */ IDBHeaderHdrPtr hdrptr; /* record header */ int ndx; /* loop index */ char errmsg[300]; int file_major, file_minor; /* version numbers of file */ int db_major, db_minor; /* version nums of database */ /* * Get the header record */ result = Idb__BM_GetRecord (file_id, IDBHeaderRecordNumber, &hdrbuf); if ( result != MrmSUCCESS ) return result; if ( ! Idb__HDR_ValidRecord(hdrbuf) ) return Urm__UT_Error ("Idb__HDR_GetHeader", _MrmMMsg_0010, file_id, NULL, MrmBAD_RECORD); /* * Read the header contents into memory, acquiring buffers as necessary */ recptr = (IDBHeaderRecordPtr) hdrbuf->IDB_record; hdrptr = (IDBHeaderHdrPtr) &recptr->header_hdr; file_id->index_root = hdrptr->index_root; file_id->num_indexed = hdrptr->num_indexed; file_id->num_RID = hdrptr->num_RID; file_id->next_RID = hdrptr->next_RID; file_id->last_record = hdrptr->last_record; file_id->last_data_record = hdrptr->last_data_record; for ( ndx=IDBrtMin ; ndx<=IDBrtMax ; ndx++ ) file_id->rt_counts[ndx] = hdrptr->rt_counts[ndx]; for ( ndx=URMgMin ; ndx<=URMgMax ; ndx++ ) file_id->group_counts[ndx] = hdrptr->group_counts[ndx]; strcpy (file_id->db_version, hdrptr->db_version); strcpy (file_id->creator, hdrptr->creator); strcpy (file_id->creator_version, hdrptr->creator_version); strcpy (file_id->creation_date, hdrptr->creation_date); strcpy (file_id->module, hdrptr->module); strcpy (file_id->module_version, hdrptr->module_version); /* * Header successfully read. Leave the buffer committed in case data * will be read from it. * * Compare version in header against compiled-in version, flagging * mismatch if found. */ if (sscanf(hdrptr->db_version, "URM %d.%d", &file_major, &file_minor) != 2) { sprintf(errmsg, _MrmMMsg_0117, hdrptr->db_version); return Urm__UT_Error ("Idb__HDR_GetHeader", errmsg, file_id, NULL, MrmNOT_VALID); } { /* sscanf() may call ungetc(), which would write the XmConst string. */ char buf[XtNumber(idb__database_version) + 1]; strcpy(buf, idb__database_version); sscanf(buf, "URM %d.%d", &db_major, &db_minor); } if ((file_major > db_major) || ((file_major == db_major) && (file_minor > db_minor))) { sprintf (errmsg, _MrmMMsg_0011, hdrptr->db_version, idb__database_version); return Urm__UT_Error ("Idb__HDR_GetHeader", errmsg, file_id, NULL, MrmNOT_VALID); } else if (db_major > file_major) { sprintf(errmsg, _MrmMMsg_0118, idb__database_version, hdrptr->db_version); return Urm__UT_Error ("Idb__HDR_GetHeader", errmsg, file_id, NULL, MrmNOT_VALID); } return MrmSUCCESS; } /* *++ * * PROCEDURE DESCRIPTION: * * Idb__HDR_InitHeader initializes a header record for a new file. The * information in the routine arguments is combined with information * derived by the routine (database version, dates and times) and * written into the file header record. Then the buffer is * decommitted. * * FORMAL PARAMETERS: * * creator Creator id for the file * creator_version Creator version string * module Module id for the file * module_version Module version string * file_id To return new in-memory file header for the file. * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * MrmSUCCESS operation succeeded * MrmFAILURE some other failure * * SIDE EFFECTS: * *-- */ Cardinal Idb__HDR_InitHeader (IDBFile file_id, String creator, String creator_version, String module, String module_version) { /* * Local variables */ Cardinal result; /* function results */ IDBRecordBufferPtr hdrbuf; /* header record buffer */ IDBHeaderRecordPtr recptr; /* header record in buffer */ IDBHeaderHdrPtr hdrptr; /* record header */ int ndx; /* loop index */ /* * Acquire a buffer for the header, initialize it, and set pointers * into it. */ result = Idb__BM_InitRecord (file_id, IDBHeaderRecordNumber, IDBrtHeader, &hdrbuf); if ( result != MrmSUCCESS ) return result; recptr = (IDBHeaderRecordPtr) hdrbuf->IDB_record; hdrptr = (IDBHeaderHdrPtr) &recptr->header_hdr; /* * Initialize the record contents, first the ones which occur only in * the file header, then those in common with the in-memory file struct. */ strcpy ( hdrptr->db_version, "" ); strncat (hdrptr->db_version, idb__database_version, IDBhsVersion); strcpy ( hdrptr->creator, "" ); strncat (hdrptr->creator, creator, IDBhsCreator); strcpy ( hdrptr->creator_version, "" ); strncat (hdrptr->creator_version, creator_version, IDBhsVersion); Urm__UT_Time (hdrptr->creation_date); strcpy ( hdrptr->module, "" ); strncat (hdrptr->module, module, IDBhsModule); strcpy ( hdrptr->module_version, "" ); strncat (hdrptr->module_version, module_version, IDBhsVersion); hdrptr->index_root = 0; hdrptr->num_indexed = 0; hdrptr->num_RID = 0; hdrptr->next_RID.internal_id.map_rec = hdrptr->header.record_num; hdrptr->next_RID.internal_id.res_index = 0; hdrptr->last_data_record = 0; for ( ndx=IDBrtMin ; ndx<=IDBrtMax ; ndx++ ) hdrptr->rt_counts[ndx] = file_id->rt_counts[ndx]; for ( ndx=URMgMin ; ndx<=URMgMax ; ndx++ ) hdrptr->group_counts[ndx] = 0; for ( ndx=0 ; ndxRID_pointers[ndx].internal_id.rec_no = 0; recptr->RID_pointers[ndx].internal_id.item_offs = 0; } recptr->num_entry = 0; recptr->last_entry = 0; recptr->free_ptr = 0; recptr->free_count = IDBHeaderFreeMax; Idb__BM_MarkModified (hdrbuf); /* * Set the file structure in memory */ file_id->index_root = hdrptr->index_root; file_id->num_indexed = hdrptr->num_indexed; file_id->num_RID = hdrptr->num_RID; file_id->next_RID = hdrptr->next_RID; file_id->last_data_record = hdrptr->last_data_record; for ( ndx=URMgMin ; ndx<=URMgMax ; ndx++ ) file_id->group_counts[ndx] = 0; /* * Header successfully initialized */ return MrmSUCCESS; } /* *++ * * PROCEDURE DESCRIPTION: * * Idb__Hdr_PutHeader copies all dynamic information from the in-memory * file header into the on-disk file header. This routine is called * before the final DecommitAll on a file as it is being closed. It * is required that no information be placed in the header as a result * of the DecommitAll; thus all header modifications take place as * records are modified, not written. * * This routine updates the header, then decommits it. * * FORMAL PARAMETERS: * * IDBFile file_id; * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * MrmSUCCESS operation succeeded * MrmFAILURE some other failure * * SIDE EFFECTS: * *-- */ Cardinal Idb__HDR_PutHeader (IDBFile file_id) { /* * Local variables */ Cardinal result; /* function results */ IDBRecordBufferPtr hdrbuf; /* header record buffer */ result = Idb__HDR_UpdateHeader (file_id, &hdrbuf); if ( result != MrmSUCCESS ) return result; /* * Header successfully written */ return Idb__BM_Decommit (hdrbuf); } /* *++ * * PROCEDURE DESCRIPTION: * * Idb__Hdr_UpdateHeader copies all dynamic information from the * in-memory file header into the on-disk file header. * * FORMAL PARAMETERS: * * file_id Open IDB file * buffer To return pointer to buffer containing header record * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * MrmSUCCESS operation succeeded * MrmBAD_RECORD not the header record * MrmFAILURE some other failure * * SIDE EFFECTS: * *-- */ Cardinal Idb__HDR_UpdateHeader (IDBFile file_id, IDBRecordBufferPtr *buffer) { /* * Local variables */ Cardinal result; /* function results */ IDBHeaderRecordPtr recptr; /* header record in buffer */ IDBHeaderHdrPtr hdrptr; /* record header */ int ndx; /* loop index */ /* * Get the header record */ result = Idb__BM_GetRecord (file_id, IDBHeaderRecordNumber, buffer); if ( result != MrmSUCCESS ) return result; if ( ! Idb__HDR_ValidRecord(*buffer) ) return Urm__UT_Error("Idb__HDR_PutHeader", _MrmMMsg_0010, file_id, NULL, MrmBAD_RECORD); /* * Set up pointers into the record, then copy from the memory structure * into it. */ recptr = (IDBHeaderRecordPtr) (*buffer)->IDB_record; hdrptr = (IDBHeaderHdrPtr) &recptr->header_hdr; hdrptr->index_root = file_id->index_root; hdrptr->num_indexed = file_id->num_indexed; hdrptr->num_RID = file_id->num_RID; hdrptr->next_RID = file_id->next_RID; hdrptr->last_record = file_id->last_record; hdrptr->last_data_record = file_id->last_data_record; for ( ndx=IDBrtMin ; ndx<=IDBrtMax ; ndx++ ) hdrptr->rt_counts[ndx] = file_id->rt_counts[ndx]; for ( ndx=URMgMin ; ndx<=URMgMax ; ndx++ ) hdrptr->group_counts[ndx] = file_id->group_counts[ndx]; /* * Header successfully written */ Idb__BM_MarkModified (*buffer); return MrmSUCCESS; } /* *++ * * PROCEDURE DESCRIPTION: * * Idb__HDR_EnterItem is the analog of Idb__RID_EnterItem for entering * a resource id in the header record. * * FORMAL PARAMETERS: * * file_id Open IDB file in which to write entry * resource_id Resource ID under which to enter entry * data_entry Data entry pointer for data * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * MrmSUCCESS operation succeeded * MrmFAILURE some other failure * MrmOUT_OF_RANGE Record number out of range * MrmBAD_RECORD not the header record * URMBadDataindex Data index out of range * * SIDE EFFECTS: * *-- */ Cardinal Idb__HDR_EnterItem (IDBFile file_id, IDBResource resource_id, IDBDataHandle data_entry) { /* * Local variables */ Cardinal result; /* function results */ IDBRecordBufferPtr bufptr; /* header record buffer */ IDBHeaderRecordPtr recptr; /* header record in buffer */ IDBridDesc resid; /* CAST resource id */ IDBResourceIndex resndx; /* to check resource index */ IDBRecordNumber recno; /* Map record record number */ /* * Get the header record. */ resid.external_id = resource_id; recno = resid.internal_id.map_rec; resndx = resid.internal_id.res_index; if ( recno != IDBHeaderRecordNumber ) return Urm__UT_Error("Idb__HDR_EnterItem", _MrmMMsg_0012, file_id, NULL, MrmOUT_OF_RANGE); result = Idb__BM_GetRecord (file_id, recno, &bufptr); if ( result != MrmSUCCESS ) return result; if ( ! Idb__HDR_ValidRecord(bufptr) ) return Urm__UT_Error("Idb__HDR_EnterItem", _MrmMMsg_0010, file_id, NULL, MrmBAD_RECORD); recptr = (IDBHeaderRecordPtr) bufptr->IDB_record; /* * Set the data item. */ if ( resndx >= IDBHeaderRIDMax ) return Urm__UT_Error("Idb__HDR_EnterItem", _MrmMMsg_0013, file_id, NULL, MrmBAD_DATA_INDEX); recptr->RID_pointers[resndx].internal_id.rec_no = data_entry.rec_no; recptr->RID_pointers[resndx].internal_id.item_offs = data_entry.item_offs; Idb__BM_MarkActivity (bufptr); /* * successful entry */ Idb__BM_MarkModified (bufptr); return MrmSUCCESS; } /* *++ * * PROCEDURE DESCRIPTION: * * Idb__HDR_ReturnItem returns the data entry pointer for an item * entered under a resource ID maintained in the header record. It * is an analog of Idb__RID_ReturnItem. * * FORMAL PARAMETERS: * * file_id Open IDB file in which to write entry * resource_id Entry's resource id * signal_null if TRUE, signal error on null data entry * entry_return To return data pointer for data * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * MrmSUCCESS operation succeeded * MrmOUT_OF_RANGE Record number out of range * MrmBAD_RECORD not the data record * MrmNULL_DATA no data for resource id * MrmFAILURE some other failure * URMBadDataindex Data index out of range * * SIDE EFFECTS: * *-- */ Cardinal Idb__HDR_ReturnItem (IDBFile file_id, IDBResource resource_id, Boolean signal_null, IDBDataHandle *entry_return) { /* * Local variables */ Cardinal result; /* function results */ IDBRecordBufferPtr bufptr; /* RID map record buffer */ IDBHeaderRecordPtr recptr; /* RID map record in buffer */ IDBridDesc resid; /* CAST resource id */ IDBResourceIndex resndx; /* to check resource index */ IDBRecordNumber recno; /* Map record record number */ /* * Get the header record */ resid.external_id = resource_id; recno = resid.internal_id.map_rec; resndx = resid.internal_id.res_index; if ( recno != IDBHeaderRecordNumber ) return Urm__UT_Error("Idb__HDR_ReturnItem", _MrmMMsg_0012, file_id, NULL, MrmOUT_OF_RANGE); result = Idb__BM_GetRecord (file_id, recno, &bufptr); if ( result != MrmSUCCESS ) return result; if ( ! Idb__HDR_ValidRecord(bufptr) ) return Urm__UT_Error("Idb__HDR_ReturnItem", _MrmMMsg_0010, file_id, NULL, MrmBAD_RECORD); recptr = (IDBHeaderRecordPtr) bufptr->IDB_record; /* * Retrieve the data item. */ if ( resndx >= IDBHeaderRIDMax ) return Urm__UT_Error("Idb__HDR_ReturnItem", _MrmMMsg_0013, file_id, NULL, MrmBAD_DATA_INDEX); if (( recptr->RID_pointers[resndx].internal_id.rec_no == 0) && ( recptr->RID_pointers[resndx].internal_id.item_offs == 0)) if ( signal_null ) return Urm__UT_Error("Idb__HDR_ReturnItem", _MrmMMsg_0014, file_id, NULL, MrmNULL_DATA); else return MrmNULL_DATA; entry_return->rec_no = recptr->RID_pointers[resndx].internal_id.rec_no; entry_return->item_offs = recptr->RID_pointers[resndx].internal_id.item_offs; /* * Successful retrieval */ Idb__BM_MarkActivity (bufptr); return MrmSUCCESS; } /* *++ * * PROCEDURE DESCRIPTION: * * Idb__HDR_NextRID returns the next available resource ID in the * header record, if there is one. It is an analog of Idb__RID_NextRID, * and serves it. * * FORMAL PARAMETERS: * * file_id Open IDB file in which to write entry * res_id_return To return new resource id * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * MrmSUCCESS operation succeeded * MrmBAD_RECORD not the header record * MrmFAILURE some other failure. Use an RID record. * * SIDE EFFECTS: * *-- */ Cardinal Idb__HDR_NextRID (IDBFile file_id, IDBResource *res_id_return) { /* * Local variables */ IDBResourceIndex resndx; /* to check resource index */ /* * use the next available ID, or fail. */ resndx = file_id->next_RID.internal_id.res_index; if ( file_id->next_RID.internal_id.map_rec != IDBHeaderRecordNumber ) return Urm__UT_Error("Idb__HDR_NextRID", _MrmMMsg_0012, file_id, NULL, MrmBAD_RECORD); if ( resndx >= IDBHeaderRIDMax ) return MrmFAILURE; /* * Increment resource index, returning current value. */ *res_id_return = (IDBResource) file_id->next_RID.external_id; file_id->next_RID.internal_id.res_index++; return MrmSUCCESS; } /* *++ * * PROCEDURE DESCRIPTION: * * Idb__HDR_GetDataEntry is the analog to Idb__HDR_GetDataEntry for * retrieving data entries from the header record. * * FORMAL PARAMETERS: * * file_id Open ID file * data_entry Data entry to be fetched * context_id To receive data block for data entry * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * MrmSUCCESS operation succeeded * MrmBAD_RECORD not the header record * MrmFAILURE some other failure * * SIDE EFFECTS: * *-- */ Cardinal Idb__HDR_GetDataEntry (IDBFile file_id, IDBDataHandle data_entry, URMResourceContextPtr context_id) { /* * Local variables */ Cardinal result; /* return status */ IDBRecordNumber record_number; /* Record to be read in */ IDBDataEntryHdrPtr datahdr; /* Header part of entry */ IDBSimpleDataPtr sim_data; /* Simple data entry */ IDBHeaderRecordPtr recptr; /* pointer data record */ IDBRecordBufferPtr bufptr; /* temp buffer for record */ char *buff_ptr; /* ptr into context buffer */ /* * Check and see if the context is valid */ if (! UrmRCValid (context_id)) return Urm__UT_Error("Idb__HDR_GetDataEntry", _MrmMMsg_0006, NULL, NULL, MrmBAD_CONTEXT); /* * Make the data entry accessible as a data pointer. */ record_number = data_entry.rec_no; if ( record_number != IDBHeaderRecordNumber ) return Urm__UT_Error("Idb__HDR_GetDataEntry", _MrmMMsg_0012, NULL, NULL, MrmBAD_RECORD); /* * Get the record that contains this data, get to the correct offset in * that record. */ result = Idb__BM_GetRecord (file_id, record_number, &bufptr); if ( result != MrmSUCCESS ) return result; /* * Point to the header in the data entry, set the context data. The context * is resized if necessary. Note that all context info except the * actual data can be set now regardless of the entry type. */ recptr = (IDBHeaderRecordPtr) bufptr->IDB_record; datahdr = (IDBDataEntryHdrPtr) &recptr->data[data_entry.item_offs]; if ((datahdr->validation != IDBDataEntryValid) && ( file_id->byte_swapped )) SwapIDBDataEntryHdr(datahdr) ; if (datahdr->validation != IDBDataEntryValid) return Urm__UT_Error("Idb__HDR_GetDataEntry", _MrmMMsg_0007, NULL, context_id, MrmNOT_VALID); if ( datahdr->entry_size > UrmRCSize(context_id) ) { result = UrmResizeResourceContext (context_id, datahdr->entry_size); if ( result != MrmSUCCESS ) return result; } UrmRCSetSize (context_id, datahdr->entry_size); UrmRCSetGroup (context_id, datahdr->resource_group); UrmRCSetType (context_id, datahdr->resource_type); UrmRCSetAccess (context_id, datahdr->access); UrmRCSetLock (context_id, datahdr->lock); UrmRCSetByteSwap (context_id, file_id->byte_swapped) ; /* * Read the data into the context. It must always be a simple type in * the header record. */ buff_ptr = (char *) UrmRCBuffer(context_id); switch ( datahdr->entry_type ) { case IDBdrSimple: sim_data = (IDBSimpleDataPtr) datahdr; UrmBCopy (sim_data->data, buff_ptr, datahdr->entry_size); return MrmSUCCESS; case IDBdrOverflow: return Urm__UT_Error("Idb__HDR_GetDAtaEntry", _MrmMMsg_0015, file_id, NULL, MrmFAILURE); default: return Urm__UT_Error("Idb__HDR_GetDataEntry", _MrmMMsg_0009, NULL, context_id, MrmFAILURE); } } /* *++ * * PROCEDURE DESCRIPTION: * * Idb_DB_PutDataEntry stores the resource described in the resource * context into the database, returning the resulting data entry pointer. * * FORMAL PARAMETERS: * * file_id Open IDB file * context_id contains data block to be stored * one_entry To return data entry for newly stored entry * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * MrmSUCCESS operation succeeded * MrmFAILURE some other failure * * SIDE EFFECTS: * *-- */ Cardinal Idb__HDR_PutDataEntry (IDBFile file_id, URMResourceContextPtr context_id, IDBDataHandle *data_entry) { /* * Local variables */ Cardinal result; /* returned status */ IDBSimpleDataPtr simpledata; /* simple data entry ptr */ IDBHeaderRecordPtr recptr; /* pointer data record */ IDBRecordBufferPtr bufptr; /* current record buffer pointer */ int entsiz; /* Number of bytes for new entry */ MrmOffset entoffs; /* Entry offset in buffer */ char *dataptr; /* pointer to data in context */ /* * Consistency check */ if (! UrmRCValid (context_id)) return Urm__UT_Error("Idb__HDR_PutDataEntry", _MrmMMsg_0006, NULL, NULL, MrmBAD_CONTEXT); /* * Acquire the header record and pointers to it */ result = Idb__BM_GetRecord (file_id, IDBHeaderRecordNumber, &bufptr); if ( result != MrmSUCCESS ) return result; recptr = (IDBHeaderRecordPtr) bufptr->IDB_record; /* * See if the entry will fit. Simple failure if not, use a regular data * record. */ entsiz = (int) (IDBSimpleDataHdrSize + UrmRCSize(context_id)); entsiz = _FULLWORD (entsiz); if ( entsiz > (int) recptr->free_count ) return MrmFAILURE; /* * Acquire a simple data entry, and put this entry into it. */ entoffs = recptr->free_ptr; simpledata = (IDBSimpleDataPtr) &recptr->data[entoffs]; simpledata->header.validation = IDBDataEntryValid; simpledata->header.entry_type = IDBdrSimple; simpledata->header.resource_group = UrmRCGroup(context_id); simpledata->header.resource_type = UrmRCType(context_id); simpledata->header.access = UrmRCAccess(context_id); simpledata->header.entry_size = UrmRCSize(context_id); simpledata->header.lock = UrmRCLock(context_id); dataptr = (char *) UrmRCBuffer(context_id); UrmBCopy (dataptr, simpledata->data, UrmRCSize(context_id)); /* * Set the return value to the data pointer for this entry */ data_entry->rec_no = _IdbBufferRecordNumber (bufptr); data_entry->item_offs = recptr->free_ptr; /* * Update the entry chain, mark the buffer, and return. */ simpledata->header.prev_entry = recptr->last_entry; recptr->num_entry++; recptr->last_entry = entoffs; recptr->free_ptr += entsiz; recptr->free_count -= entsiz; Idb__BM_MarkModified (bufptr); return MrmSUCCESS; } /* *++ * * PROCEDURE DESCRIPTION: * * This routine checks if a data entry matchs a set of filters. * It reads the record containing the header for the data entry, * then does the filter match. If both filters are NUL, then * the test becomes merely one of confirming the data entry * can be read. * * FORMAL PARAMETERS: * * file_id Open ID file * data_entry Data entry to be matched * group_filter if not null, entry found must match this group * type_filter if not null, entry found must match this type * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * TRUE Match is good * FALSE match not good. * * SIDE EFFECTS: * *-- */ Boolean Idb__HDR_MatchFilter (IDBFile file_id, IDBDataHandle data_entry, MrmCode group_filter, MrmCode type_filter) { /* * Local variables */ Cardinal result; /* return status */ IDBRecordNumber record_number; /* Record to be read in */ IDBRecordBufferPtr bufptr; /* buffer for data record */ IDBHeaderRecordPtr recptr; /* pointer data record */ IDBDataEntryHdrPtr datahdr; /* Header part of entry */ /* * Get the header record and get to the correct offset in * that record. Immediately decommit the buffer, since it won't be * compromised by this read. */ record_number = data_entry.rec_no; if ( record_number != IDBHeaderRecordNumber ) { Urm__UT_Error("Idb__HDR_MatchFilter", _MrmMMsg_0012, file_id, NULL, MrmBAD_RECORD); return FALSE; } result = Idb__BM_GetRecord (file_id, record_number, &bufptr); if ( result != MrmSUCCESS ) return FALSE; Idb__BM_Decommit (bufptr); /* * Point to the header in the entry, and check the filters. */ recptr = (IDBHeaderRecordPtr) bufptr->IDB_record; datahdr = (IDBDataEntryHdrPtr) &recptr->data[data_entry.item_offs]; if (datahdr->validation != IDBDataEntryValid) { Urm__UT_Error("Idb__HDR_GetDataEntry", _MrmMMsg_0007, NULL, NULL, MrmNOT_VALID); return FALSE; } if ( group_filter!=URMgNul && group_filter!=datahdr->resource_group ) return FALSE; if ( type_filter!=URMtNul && type_filter!=datahdr->resource_type ) return FALSE; return TRUE; }