Blame lib/Mrm/MrmIrid.c

Packit b099d7
/* 
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
 */ 
Packit b099d7
/* 
Packit b099d7
 * HISTORY
Packit b099d7
 */ 
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#ifdef REV_INFO
Packit b099d7
#ifndef lint
Packit b099d7
static char rcsid[] = "$XConsortium: MrmIrid.c /main/13 1996/11/13 13:58:17 drk $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
Packit b099d7
/* (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 *++
Packit b099d7
 *  FACILITY:
Packit b099d7
 *
Packit b099d7
 *      UIL Resource Manager (URM): IDB Facility
Packit b099d7
 *	Resource ID management routines.
Packit b099d7
 *
Packit b099d7
 *  ABSTRACT:
Packit b099d7
 *
Packit b099d7
 *	These routines acquire RIDs, allow entering a data block under an RID,
Packit b099d7
 *	and manage the RID and index map records.
Packit b099d7
 *
Packit b099d7
 *--
Packit b099d7
 */
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 *
Packit b099d7
 *  INCLUDE FILES
Packit b099d7
 *
Packit b099d7
 */
Packit b099d7
Packit b099d7
#include <Mrm/MrmAppl.h>
Packit b099d7
#include <Mrm/Mrm.h>
Packit b099d7
#include <Mrm/IDB.h>
Packit b099d7
#include "MrmMsgI.h"
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 *
Packit b099d7
 *  TABLE OF CONTENTS
Packit b099d7
 *
Packit b099d7
 *	Idb__RID_EnterItem		- Enter a data entry under an RID
Packit b099d7
 *
Packit b099d7
 *	Idb__RID_ReturnItem		- Return the data entry for an RID
Packit b099d7
 *
Packit b099d7
 *	Idb__RID_NextRID		- Return next available RID
Packit b099d7
 *
Packit b099d7
 *	Idb__RID_AddRecord		- Set up a new resource ID record
Packit b099d7
 *
Packit b099d7
 */
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 *
Packit b099d7
 *  DEFINE and MACRO DEFINITIONS
Packit b099d7
 *
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Macros which validate index records in buffers
Packit b099d7
 */
Packit b099d7
#define	Idb__RID_ValidRecord(buffer) \
Packit b099d7
	(_IdbBufferRecordType(buffer)==IDBrtRIDMap)
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *++
Packit b099d7
 *
Packit b099d7
 *  PROCEDURE DESCRIPTION:
Packit b099d7
 *
Packit b099d7
 *	Idb__RID_EnterItem makes an entry in the resource record for the
Packit b099d7
 *	resourc id of the data entry pointer.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open IDB file in which to write entry
Packit b099d7
 *	resource_id	Resource ID under which to enter entry
Packit b099d7
 *	data_entry	Data entry pointer for data
Packit b099d7
 *
Packit b099d7
 *  IMPLICIT INPUTS:
Packit b099d7
 *
Packit b099d7
 *  IMPLICIT OUTPUTS:
Packit b099d7
 *
Packit b099d7
 *  FUNCTION VALUE:
Packit b099d7
 *
Packit b099d7
 *	MrmSUCCESS	operation succeeded
Packit b099d7
 *	MrmFAILURE	some other failure
Packit b099d7
 *	MrmOUT_OF_RANGE	Record number out of range
Packit b099d7
 *	MrmBAD_RECORD	not an RID map record
Packit b099d7
 *	URMBadDataindex	Data index out of range
Packit b099d7
 *
Packit b099d7
 *  SIDE EFFECTS:
Packit b099d7
 *
Packit b099d7
 *--
Packit b099d7
 */
Packit b099d7
Packit b099d7
Cardinal 
Packit b099d7
Idb__RID_EnterItem (IDBFile			file_id,
Packit b099d7
		    IDBResource			resource_id,
Packit b099d7
		    IDBDataHandle		data_entry)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result;		/* function results */
Packit b099d7
  IDBRecordBufferPtr	bufptr;		/* header record buffer */
Packit b099d7
  IDBridMapRecordPtr	recptr;		/* header record in buffer */
Packit b099d7
  IDBridDesc		resid;		/* CAST resource id */
Packit b099d7
  IDBResourceIndex	resndx;		/* to check resource index */
Packit b099d7
  IDBRecordNumber	recno;		/* Map record record number */
Packit b099d7
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Get the resource map record. Let the header handle it if the
Packit b099d7
   * RID is in the header record.
Packit b099d7
   */
Packit b099d7
  resid.external_id = resource_id;
Packit b099d7
  recno = resid.internal_id.map_rec;
Packit b099d7
  if ( recno == IDBHeaderRecordNumber )
Packit b099d7
    return Idb__HDR_EnterItem (file_id, resource_id, data_entry);
Packit b099d7
Packit b099d7
  resndx = resid.internal_id.res_index;
Packit b099d7
  if ( recno > file_id->last_record )
Packit b099d7
    return Urm__UT_Error ("Idb__RID_EnterItem", _MrmMMsg_0019,
Packit b099d7
			  file_id, NULL, MrmOUT_OF_RANGE);
Packit b099d7
  result = Idb__BM_GetRecord (file_id, recno, &bufptr);
Packit b099d7
  if ( result != MrmSUCCESS ) return result;
Packit b099d7
  if ( ! Idb__RID_ValidRecord(bufptr) )
Packit b099d7
    return Urm__UT_Error ("Idb__RID_EnterItem", _MrmMMsg_0010,
Packit b099d7
			  file_id, NULL, MrmBAD_RECORD);
Packit b099d7
Packit b099d7
  recptr = (IDBridMapRecordPtr) bufptr->IDB_record;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Set the data item.
Packit b099d7
   */
Packit b099d7
  if ( resndx >= IDBridPtrVecMax )
Packit b099d7
    return Urm__UT_Error ("Idb__RID_EnterItem", _MrmMMsg_0013,
Packit b099d7
			  file_id, NULL, MrmBAD_DATA_INDEX);
Packit b099d7
  recptr->pointers[resndx].internal_id.rec_no = data_entry.rec_no;
Packit b099d7
  recptr->pointers[resndx].internal_id.item_offs = data_entry.item_offs;
Packit b099d7
  Idb__BM_MarkActivity (bufptr);
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * successful entry
Packit b099d7
   */
Packit b099d7
  Idb__BM_MarkModified (bufptr);
Packit b099d7
  return MrmSUCCESS;
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *++
Packit b099d7
 *
Packit b099d7
 *  PROCEDURE DESCRIPTION:
Packit b099d7
 *
Packit b099d7
 *	Idb_RID_ReturnItem returns the data entry pointer for an item
Packit b099d7
 *	entered in the database under a resource id. Since this routine
Packit b099d7
 *	is also used to check if an entry exists before writing, it
Packit b099d7
 *	uses a flag to determine if a null entry should be signalled.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open IDB file in which to write entry
Packit b099d7
 *	resource_id	Entry's resource id
Packit b099d7
 *	signal_null	if TRUE, signal error on null data entry
Packit b099d7
 *	entry_return	To return data pointer for data
Packit b099d7
 *
Packit b099d7
 *  IMPLICIT INPUTS:
Packit b099d7
 *
Packit b099d7
 *  IMPLICIT OUTPUTS:
Packit b099d7
 *
Packit b099d7
 *  FUNCTION VALUE:
Packit b099d7
 *
Packit b099d7
 *	MrmSUCCESS	operation succeeded
Packit b099d7
 *	MrmOUT_OF_RANGE	Record number out of range
Packit b099d7
 *	MrmBAD_RECORD	not an RID map record
Packit b099d7
 *	MrmNULL_DATA	no data for resource id
Packit b099d7
 *	MrmFAILURE	some other failure
Packit b099d7
 *	URMBadDataindex	Data index out of range
Packit b099d7
 *
Packit b099d7
 *  SIDE EFFECTS:
Packit b099d7
 *
Packit b099d7
 *--
Packit b099d7
 */
Packit b099d7
Packit b099d7
Cardinal 
Packit b099d7
Idb__RID_ReturnItem (IDBFile			file_id,
Packit b099d7
		     IDBResource		resource_id,
Packit b099d7
		     Boolean			signal_null,
Packit b099d7
		     IDBDataHandle		*entry_return)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result;		/* function results */
Packit b099d7
  IDBRecordBufferPtr	bufptr;		/* RID map record buffer */
Packit b099d7
  IDBridMapRecordPtr	recptr;		/* RID map record in buffer */
Packit b099d7
  IDBridDesc		resid;		/* CAST resource id */
Packit b099d7
  IDBResourceIndex	resndx;		/* to check resource index */
Packit b099d7
  IDBRecordNumber	recno;		/* Map record record number */
Packit b099d7
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Get the resource map record. Let the header handle it if the RID is
Packit b099d7
   * in the header.
Packit b099d7
   */
Packit b099d7
  resid.external_id = resource_id;
Packit b099d7
  recno = resid.internal_id.map_rec;
Packit b099d7
  if ( recno == IDBHeaderRecordNumber )
Packit b099d7
    return Idb__HDR_ReturnItem
Packit b099d7
      (file_id, resource_id, signal_null, entry_return);
Packit b099d7
  resndx = resid.internal_id.res_index;
Packit b099d7
  if ( recno > file_id->last_record )
Packit b099d7
    return Urm__UT_Error ("Idb__RID_ReturnItem", _MrmMMsg_0019,
Packit b099d7
			  file_id, NULL, MrmOUT_OF_RANGE);
Packit b099d7
  result = Idb__BM_GetRecord (file_id, recno, &bufptr);
Packit b099d7
  if ( result != MrmSUCCESS ) return result;
Packit b099d7
  if ( ! Idb__RID_ValidRecord(bufptr) )
Packit b099d7
    return Urm__UT_Error ("Idb__RID_ReturnItem", _MrmMMsg_0010,
Packit b099d7
			  file_id, NULL, MrmBAD_RECORD);
Packit b099d7
Packit b099d7
  recptr = (IDBridMapRecordPtr) bufptr->IDB_record;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Retrieve the data item.
Packit b099d7
   */
Packit b099d7
  if ( resndx >= IDBridPtrVecMax )
Packit b099d7
    return Urm__UT_Error ("Idb__RID_ReturnItem", _MrmMMsg_0013,
Packit b099d7
			  file_id, NULL, MrmBAD_DATA_INDEX);
Packit b099d7
  if ((recptr->pointers[resndx].internal_id.rec_no == 0) &&
Packit b099d7
      (recptr->pointers[resndx].internal_id.item_offs == 0))
Packit b099d7
    if ( signal_null )
Packit b099d7
      return Urm__UT_Error ("Idb__RID_ReturnItem", _MrmMMsg_0014,
Packit b099d7
			    file_id, NULL, MrmNULL_DATA);
Packit b099d7
    else return MrmNULL_DATA;
Packit b099d7
  entry_return->rec_no = recptr->pointers[resndx].internal_id.rec_no;
Packit b099d7
  entry_return->item_offs = recptr->pointers[resndx].internal_id.item_offs;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Successful retrieval
Packit b099d7
   */
Packit b099d7
  Idb__BM_MarkActivity (bufptr);
Packit b099d7
  return MrmSUCCESS;
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *++
Packit b099d7
 *
Packit b099d7
 *  PROCEDURE DESCRIPTION:
Packit b099d7
 *
Packit b099d7
 *	Idb__RID_NextRID returns the next available resource ID in the
Packit b099d7
 *	file. It is the internal version of UrmIdbGetResourceId. If a new
Packit b099d7
 *	resource record is required, this routine:
Packit b099d7
 *		- Acquires a new resource record, and initializes it
Packit b099d7
 *		  to all null pointers.
Packit b099d7
 *		- Adds a new entry to map index vector in the file header
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open IDB file in which to write entry
Packit b099d7
 *	res_id_return	To return new resource id
Packit b099d7
 *
Packit b099d7
 *  IMPLICIT INPUTS:
Packit b099d7
 *
Packit b099d7
 *  IMPLICIT OUTPUTS:
Packit b099d7
 *
Packit b099d7
 *  FUNCTION VALUE:
Packit b099d7
 *
Packit b099d7
 *	MrmSUCCESS	operation succeeded
Packit b099d7
 *	MrmFAILURE	some other failure
Packit b099d7
 *
Packit b099d7
 *  SIDE EFFECTS:
Packit b099d7
 *
Packit b099d7
 *--
Packit b099d7
 */
Packit b099d7
Packit b099d7
Cardinal 
Packit b099d7
Idb__RID_NextRID (IDBFile		file_id,
Packit b099d7
		  IDBResource		*res_id_return)
Packit b099d7
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result;		/* function results */
Packit b099d7
  IDBResourceIndex	resndx;		/* to check resource index */
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * use the next available ID, or acquire a new record. Handle both header
Packit b099d7
   * record and RID record maps.
Packit b099d7
   */
Packit b099d7
  resndx = file_id->next_RID.internal_id.res_index;
Packit b099d7
  if ( file_id->next_RID.internal_id.map_rec == IDBHeaderRecordNumber )
Packit b099d7
    {
Packit b099d7
      if ( resndx >= IDBHeaderRIDMax )
Packit b099d7
	{
Packit b099d7
	  result = Idb__RID_AddRecord (file_id);
Packit b099d7
	  if ( result != MrmSUCCESS ) return result;
Packit b099d7
	  resndx = file_id->next_RID.internal_id.res_index;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * RID comes from a RID record
Packit b099d7
   */
Packit b099d7
  if ( resndx >= IDBridPtrVecMax )
Packit b099d7
    {
Packit b099d7
      result = Idb__RID_AddRecord (file_id);
Packit b099d7
      if ( result != MrmSUCCESS ) return result;
Packit b099d7
      resndx = file_id->next_RID.internal_id.res_index;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Increment resource index, returning current value.
Packit b099d7
   */
Packit b099d7
  *res_id_return = (IDBResource) file_id->next_RID.external_id;
Packit b099d7
  file_id->next_RID.internal_id.res_index++;
Packit b099d7
  return MrmSUCCESS;
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *++
Packit b099d7
 *
Packit b099d7
 *  PROCEDURE DESCRIPTION:
Packit b099d7
 *
Packit b099d7
 *	Idb__RID_AddRecord initializes a new resource id record and enters
Packit b099d7
 *	in in the index map in the header.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open IDB file
Packit b099d7
 *
Packit b099d7
 *  IMPLICIT INPUTS:
Packit b099d7
 *
Packit b099d7
 *  IMPLICIT OUTPUTS:
Packit b099d7
 *
Packit b099d7
 *  FUNCTION VALUE:
Packit b099d7
 *
Packit b099d7
 *	MrmSUCCESS	operation succeeded
Packit b099d7
 *	MrmFAILURE	some other failure
Packit b099d7
 *
Packit b099d7
 *  SIDE EFFECTS:
Packit b099d7
 *
Packit b099d7
 *--
Packit b099d7
 */
Packit b099d7
Packit b099d7
Cardinal 
Packit b099d7
Idb__RID_AddRecord (IDBFile		file_id)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result;		/* function results */
Packit b099d7
  IDBRecordBufferPtr	bufptr;		/* RID map record buffer */
Packit b099d7
  IDBridMapRecordPtr	recptr;		/* RID map record in buffer */
Packit b099d7
  int			ndx;		/* loop index */
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Acquire a record.
Packit b099d7
   */
Packit b099d7
  result = Idb__BM_InitRecord (file_id, 0, IDBrtRIDMap, &bufptr);
Packit b099d7
  if ( result != MrmSUCCESS ) return result;
Packit b099d7
  recptr = (IDBridMapRecordPtr) bufptr->IDB_record;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Initialize the record contents
Packit b099d7
   */
Packit b099d7
  for (ndx=0 ; ndx
Packit b099d7
    {
Packit b099d7
      recptr->pointers[ndx].internal_id.rec_no = 0;
Packit b099d7
      recptr->pointers[ndx].internal_id.item_offs = 0;
Packit b099d7
    }
Packit b099d7
  Idb__BM_MarkModified (bufptr);
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Update the next RID in the file header to point to the first entry in
Packit b099d7
   * the new record.
Packit b099d7
   */
Packit b099d7
  file_id->next_RID.internal_id.map_rec = recptr->map_header.header.record_num;
Packit b099d7
  file_id->next_RID.internal_id.res_index = 0;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Record successfully created.
Packit b099d7
   */
Packit b099d7
  Idb__BM_MarkModified (bufptr);
Packit b099d7
  return MrmSUCCESS;
Packit b099d7
Packit b099d7
}
Packit b099d7