/* * @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: MrmIrid.c /main/13 1996/11/13 13:58:17 drk $" #endif #endif /* (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */ /* *++ * FACILITY: * * UIL Resource Manager (URM): IDB Facility * Resource ID management routines. * * ABSTRACT: * * These routines acquire RIDs, allow entering a data block under an RID, * and manage the RID and index map records. * *-- */ /* * * INCLUDE FILES * */ #include #include #include #include "MrmMsgI.h" /* * * TABLE OF CONTENTS * * Idb__RID_EnterItem - Enter a data entry under an RID * * Idb__RID_ReturnItem - Return the data entry for an RID * * Idb__RID_NextRID - Return next available RID * * Idb__RID_AddRecord - Set up a new resource ID record * */ /* * * DEFINE and MACRO DEFINITIONS * */ /* * Macros which validate index records in buffers */ #define Idb__RID_ValidRecord(buffer) \ (_IdbBufferRecordType(buffer)==IDBrtRIDMap) /* *++ * * PROCEDURE DESCRIPTION: * * Idb__RID_EnterItem makes an entry in the resource record for the * resourc id of the data entry pointer. * * 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 an RID map record * URMBadDataindex Data index out of range * * SIDE EFFECTS: * *-- */ Cardinal Idb__RID_EnterItem (IDBFile file_id, IDBResource resource_id, IDBDataHandle data_entry) { /* * Local variables */ Cardinal result; /* function results */ IDBRecordBufferPtr bufptr; /* header record buffer */ IDBridMapRecordPtr recptr; /* header record in buffer */ IDBridDesc resid; /* CAST resource id */ IDBResourceIndex resndx; /* to check resource index */ IDBRecordNumber recno; /* Map record record number */ /* * Get the resource map record. Let the header handle it if the * RID is in the header record. */ resid.external_id = resource_id; recno = resid.internal_id.map_rec; if ( recno == IDBHeaderRecordNumber ) return Idb__HDR_EnterItem (file_id, resource_id, data_entry); resndx = resid.internal_id.res_index; if ( recno > file_id->last_record ) return Urm__UT_Error ("Idb__RID_EnterItem", _MrmMMsg_0019, file_id, NULL, MrmOUT_OF_RANGE); result = Idb__BM_GetRecord (file_id, recno, &bufptr); if ( result != MrmSUCCESS ) return result; if ( ! Idb__RID_ValidRecord(bufptr) ) return Urm__UT_Error ("Idb__RID_EnterItem", _MrmMMsg_0010, file_id, NULL, MrmBAD_RECORD); recptr = (IDBridMapRecordPtr) bufptr->IDB_record; /* * Set the data item. */ if ( resndx >= IDBridPtrVecMax ) return Urm__UT_Error ("Idb__RID_EnterItem", _MrmMMsg_0013, file_id, NULL, MrmBAD_DATA_INDEX); recptr->pointers[resndx].internal_id.rec_no = data_entry.rec_no; recptr->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_RID_ReturnItem returns the data entry pointer for an item * entered in the database under a resource id. Since this routine * is also used to check if an entry exists before writing, it * uses a flag to determine if a null entry should be signalled. * * 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 an RID map record * MrmNULL_DATA no data for resource id * MrmFAILURE some other failure * URMBadDataindex Data index out of range * * SIDE EFFECTS: * *-- */ Cardinal Idb__RID_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 */ IDBridMapRecordPtr 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 resource map record. Let the header handle it if the RID is * in the header. */ resid.external_id = resource_id; recno = resid.internal_id.map_rec; if ( recno == IDBHeaderRecordNumber ) return Idb__HDR_ReturnItem (file_id, resource_id, signal_null, entry_return); resndx = resid.internal_id.res_index; if ( recno > file_id->last_record ) return Urm__UT_Error ("Idb__RID_ReturnItem", _MrmMMsg_0019, file_id, NULL, MrmOUT_OF_RANGE); result = Idb__BM_GetRecord (file_id, recno, &bufptr); if ( result != MrmSUCCESS ) return result; if ( ! Idb__RID_ValidRecord(bufptr) ) return Urm__UT_Error ("Idb__RID_ReturnItem", _MrmMMsg_0010, file_id, NULL, MrmBAD_RECORD); recptr = (IDBridMapRecordPtr) bufptr->IDB_record; /* * Retrieve the data item. */ if ( resndx >= IDBridPtrVecMax ) return Urm__UT_Error ("Idb__RID_ReturnItem", _MrmMMsg_0013, file_id, NULL, MrmBAD_DATA_INDEX); if ((recptr->pointers[resndx].internal_id.rec_no == 0) && (recptr->pointers[resndx].internal_id.item_offs == 0)) if ( signal_null ) return Urm__UT_Error ("Idb__RID_ReturnItem", _MrmMMsg_0014, file_id, NULL, MrmNULL_DATA); else return MrmNULL_DATA; entry_return->rec_no = recptr->pointers[resndx].internal_id.rec_no; entry_return->item_offs = recptr->pointers[resndx].internal_id.item_offs; /* * Successful retrieval */ Idb__BM_MarkActivity (bufptr); return MrmSUCCESS; } /* *++ * * PROCEDURE DESCRIPTION: * * Idb__RID_NextRID returns the next available resource ID in the * file. It is the internal version of UrmIdbGetResourceId. If a new * resource record is required, this routine: * - Acquires a new resource record, and initializes it * to all null pointers. * - Adds a new entry to map index vector in the file header * * 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 * MrmFAILURE some other failure * * SIDE EFFECTS: * *-- */ Cardinal Idb__RID_NextRID (IDBFile file_id, IDBResource *res_id_return) { /* * Local variables */ Cardinal result; /* function results */ IDBResourceIndex resndx; /* to check resource index */ /* * use the next available ID, or acquire a new record. Handle both header * record and RID record maps. */ resndx = file_id->next_RID.internal_id.res_index; if ( file_id->next_RID.internal_id.map_rec == IDBHeaderRecordNumber ) { if ( resndx >= IDBHeaderRIDMax ) { result = Idb__RID_AddRecord (file_id); if ( result != MrmSUCCESS ) return result; resndx = file_id->next_RID.internal_id.res_index; } } /* * RID comes from a RID record */ if ( resndx >= IDBridPtrVecMax ) { result = Idb__RID_AddRecord (file_id); if ( result != MrmSUCCESS ) return result; resndx = file_id->next_RID.internal_id.res_index; } /* * 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__RID_AddRecord initializes a new resource id record and enters * in in the index map in the header. * * FORMAL PARAMETERS: * * file_id Open IDB file * * IMPLICIT INPUTS: * * IMPLICIT OUTPUTS: * * FUNCTION VALUE: * * MrmSUCCESS operation succeeded * MrmFAILURE some other failure * * SIDE EFFECTS: * *-- */ Cardinal Idb__RID_AddRecord (IDBFile file_id) { /* * Local variables */ Cardinal result; /* function results */ IDBRecordBufferPtr bufptr; /* RID map record buffer */ IDBridMapRecordPtr recptr; /* RID map record in buffer */ int ndx; /* loop index */ /* * Acquire a record. */ result = Idb__BM_InitRecord (file_id, 0, IDBrtRIDMap, &bufptr); if ( result != MrmSUCCESS ) return result; recptr = (IDBridMapRecordPtr) bufptr->IDB_record; /* * Initialize the record contents */ for (ndx=0 ; ndxpointers[ndx].internal_id.rec_no = 0; recptr->pointers[ndx].internal_id.item_offs = 0; } Idb__BM_MarkModified (bufptr); /* * Update the next RID in the file header to point to the first entry in * the new record. */ file_id->next_RID.internal_id.map_rec = recptr->map_header.header.record_num; file_id->next_RID.internal_id.res_index = 0; /* * Record successfully created. */ Idb__BM_MarkModified (bufptr); return MrmSUCCESS; }