Blame lib/Mrm/MrmIentry.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
 
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: MrmIentry.c /main/13 1996/11/13 13:56:11 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
 *	Data entry management routines
Packit b099d7
 *
Packit b099d7
 *  ABSTRACT:
Packit b099d7
 *
Packit b099d7
 *	These routines get and put data entries from a record into a buffer.
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__DB_GetDataEntry		- Get data entry into buffer
Packit b099d7
 *
Packit b099d7
 *	Idb__DB_PutDataEntry		- Put data entry into record
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__DB_GetDataEntry retrieves the requested data entry into a
Packit b099d7
 *	resource context, returning the number of bytes, resource group, and
Packit b099d7
 *	resource type. The resource context is resized as required to hold
Packit b099d7
 *	the data block.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open ID file
Packit b099d7
 *	data_entry	Data entry to be fetched
Packit b099d7
 *	context_id	To receive data block for data entry
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__DB_GetDataEntry (IDBFile			file_id,
Packit b099d7
		      IDBDataHandle		data_entry,
Packit b099d7
		      URMResourceContextPtr	context_id)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		status;		/* return status */
Packit b099d7
  IDBRecordNumber	record_number ;	/* Record to be read in */
Packit b099d7
  IDBDataEntryHdrPtr	datahdr ;	/* Header part of entry */
Packit b099d7
  IDBSimpleDataPtr	sim_data ;	/* Simple data entry */
Packit b099d7
  IDBOverflowDataPtr	ofl_data ;	/* Overflow data entry */
Packit b099d7
  IDBDataRecordPtr	data_rec;	/* pointer data record */
Packit b099d7
  IDBRecordBufferPtr	curbuf ;	/* temp buffer for record */
Packit b099d7
  Cardinal		num_recs;	/* # records to save overflow */
Packit b099d7
  Cardinal		cur_rec;	/* the current record */
Packit b099d7
  char			*buff_ptr;	/* ptr into context buffer */
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Check and see if the context is valid
Packit b099d7
   */
Packit b099d7
  if (! UrmRCValid (context_id))
Packit b099d7
    return Urm__UT_Error ("Idb__DB_GetDataEntry", _MrmMMsg_0006,
Packit b099d7
			  NULL, NULL, MrmBAD_CONTEXT) ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Make the data entry accessible as a data pointer. Let the header
Packit b099d7
   * handle this request if the entry is there.
Packit b099d7
   */
Packit b099d7
  record_number = data_entry.rec_no;
Packit b099d7
  if ( record_number == IDBHeaderRecordNumber ) 
Packit b099d7
    return Idb__HDR_GetDataEntry (file_id, data_entry, context_id);
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Get the record that contains this data, get to the correct offset in
Packit b099d7
   * that record.
Packit b099d7
   */
Packit b099d7
  status = Idb__BM_GetRecord (file_id, record_number, &curbuf) ;
Packit b099d7
  if ( status != MrmSUCCESS ) return status ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Point to the header in the data entry, set the context data. The context
Packit b099d7
   * is resized if necessary. Note that all context info except the
Packit b099d7
   * actual data can be set now regardless of the entry type.
Packit b099d7
   */
Packit b099d7
  data_rec = (IDBDataRecord *) curbuf->IDB_record;
Packit b099d7
  datahdr = (IDBDataEntryHdrPtr)
Packit b099d7
    &data_rec->data[data_entry.item_offs] ;
Packit b099d7
Packit b099d7
  if ((datahdr->validation != IDBDataEntryValid) && ( file_id->byte_swapped ))
Packit b099d7
    SwapIDBDataEntryHdr(datahdr) ;
Packit b099d7
  if (datahdr->validation != IDBDataEntryValid)
Packit b099d7
    return Urm__UT_Error ("Idb__DB_GetDataEntry", _MrmMMsg_0007,
Packit b099d7
			  NULL, context_id, MrmNOT_VALID) ;
Packit b099d7
Packit b099d7
  if ( datahdr->entry_size > UrmRCSize(context_id) )
Packit b099d7
    {
Packit b099d7
      status = UrmResizeResourceContext (context_id, datahdr->entry_size) ;
Packit b099d7
      if ( status != MrmSUCCESS ) return status ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  UrmRCSetSize (context_id, datahdr->entry_size) ;
Packit b099d7
  UrmRCSetGroup (context_id, datahdr->resource_group) ;
Packit b099d7
  UrmRCSetType (context_id, datahdr->resource_type) ;
Packit b099d7
  UrmRCSetAccess (context_id, datahdr->access) ;
Packit b099d7
  UrmRCSetLock (context_id, datahdr->lock) ;
Packit b099d7
  UrmRCSetByteSwap (context_id, file_id->byte_swapped) ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Read the data into the context. Technique depends on entry type.
Packit b099d7
   */
Packit b099d7
  buff_ptr = (char *) UrmRCBuffer(context_id) ;
Packit b099d7
  switch ( datahdr->entry_type )
Packit b099d7
    {
Packit b099d7
    case IDBdrSimple:
Packit b099d7
      sim_data = (IDBSimpleDataPtr) datahdr ;
Packit b099d7
      UrmBCopy (sim_data->data, buff_ptr, datahdr->entry_size) ;
Packit b099d7
      return MrmSUCCESS ;
Packit b099d7
Packit b099d7
    case IDBdrOverflow:
Packit b099d7
      ofl_data = (IDBOverflowDataPtr) datahdr ;
Packit b099d7
      if ( file_id->byte_swapped ) SwapIDBOverflowData(ofl_data);
Packit b099d7
      num_recs = ofl_data->segment_count ;
Packit b099d7
      for ( cur_rec=1 ; cur_rec<=num_recs ; cur_rec++ )
Packit b099d7
	{
Packit b099d7
	  UrmBCopy (ofl_data->data, buff_ptr, ofl_data->segment_size) ;
Packit b099d7
	  buff_ptr += ofl_data->segment_size ;
Packit b099d7
Packit b099d7
	  /*
Packit b099d7
	   * Read the next record in the chain if this is not the last
Packit b099d7
	   */
Packit b099d7
	  if ( cur_rec < num_recs )
Packit b099d7
	    {
Packit b099d7
	      record_number = ofl_data->next_segment.internal_id.rec_no;
Packit b099d7
	      status =
Packit b099d7
		Idb__BM_GetRecord (file_id, record_number, &curbuf) ;
Packit b099d7
	      if ( status != MrmSUCCESS ) return status ;
Packit b099d7
Packit b099d7
	      data_rec = (IDBDataRecord *) curbuf->IDB_record;
Packit b099d7
	      datahdr = (IDBDataEntryHdrPtr)
Packit b099d7
		&data_rec->data[data_entry.item_offs] ;
Packit b099d7
	      if ( file_id->byte_swapped ) SwapIDBDataEntryHdr(datahdr) ;
Packit b099d7
	      if (datahdr->validation != IDBDataEntryValid)
Packit b099d7
		return Urm__UT_Error ("Idb__DB_GetDataEntry", _MrmMMsg_0008,
Packit b099d7
				      NULL, context_id, MrmNOT_VALID) ;
Packit b099d7
	      ofl_data = (IDBOverflowDataPtr) datahdr ;
Packit b099d7
	      if ( file_id->byte_swapped ) SwapIDBOverflowData(ofl_data);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
      return MrmSUCCESS ;
Packit b099d7
Packit b099d7
    default:
Packit b099d7
      return Urm__UT_Error ("Idb__DB_GetDataEntry", _MrmMMsg_0009,
Packit b099d7
			    NULL, context_id, MrmFAILURE) ;
Packit b099d7
    }
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_DB_PutDataEntry stores the resource described in the resource
Packit b099d7
 *	context into the database, returning the resulting data entry pointer.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open IDB file
Packit b099d7
 *	context_id	contains data block to be stored
Packit b099d7
 *	one_entry	To return data entry for newly stored entry
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__DB_PutDataEntry (IDBFile			file_id,
Packit b099d7
		      URMResourceContextPtr	context_id,
Packit b099d7
		      IDBDataHandle		*data_entry)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result;		/* returned status */
Packit b099d7
  MrmType		ent_typ ;	/* entry type */
Packit b099d7
  IDBOverflowDataPtr	overflowdata;	/* complex data entry ptr */
Packit b099d7
  IDBSimpleDataPtr	simpledata;	/* simple data entry ptr */
Packit b099d7
  IDBDataRecordPtr	data_rec;	/* pointer data record */
Packit b099d7
  IDBRecordBufferPtr	curbuf;		/* current record buffer pointer */
Packit b099d7
  IDBRecordBufferPtr	nxtbuf;		/* next record buffer pointer */
Packit b099d7
  IDBDataHdrPtr		dataheader;	/* data record header */
Packit b099d7
  MrmCount		entsiz ;	/* Number of bytes for new entry */
Packit b099d7
  MrmOffset		entoffs ;	/* Entry offset in buffer */
Packit b099d7
  Cardinal		num_recs;	/* # records to save overflow */
Packit b099d7
  Cardinal		cur_rec;	/* the current record */
Packit b099d7
  char			*dataptr ;	/* pointer to data in context */
Packit b099d7
  MrmCount		datarem ;	/* # bytes left to copy in data */
Packit b099d7
  MrmCount		cursiz ;	/* # bytse of data in cur. segment */
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Consistency check
Packit b099d7
   */
Packit b099d7
  if (! UrmRCValid (context_id))
Packit b099d7
    return Urm__UT_Error ("Idb__DB_PutDataEntry", _MrmMMsg_0006,
Packit b099d7
			  NULL, NULL, MrmBAD_CONTEXT) ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Try to put this entry in the header record.
Packit b099d7
   */
Packit b099d7
  result = Idb__HDR_PutDataEntry (file_id, context_id, data_entry );
Packit b099d7
  if ( result == MrmSUCCESS )
Packit b099d7
    return result;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Initialize the first data record if required, or use the last one.
Packit b099d7
   */
Packit b099d7
  if ( !file_id->last_data_record )
Packit b099d7
    {
Packit b099d7
      result = Idb__BM_InitDataRecord (file_id, &curbuf) ;
Packit b099d7
      if ( result != MrmSUCCESS ) return result ;
Packit b099d7
      file_id->last_data_record = _IdbBufferRecordNumber (curbuf) ;
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      result =
Packit b099d7
	Idb__BM_GetRecord (file_id, file_id->last_data_record, &curbuf) ;
Packit b099d7
      if ( result != MrmSUCCESS ) return result ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * This is a simple data entry if it will fit, else it is an overflow entry.
Packit b099d7
   * The size computes is of a simple entry, which will be used if this turns
Packit b099d7
   * out to be correct.
Packit b099d7
   */
Packit b099d7
  entsiz = IDBSimpleDataHdrSize + UrmRCSize(context_id) ;
Packit b099d7
  entsiz = _FULLWORD (entsiz) ;
Packit b099d7
  if ( entsiz <= IDBDataFreeMax )
Packit b099d7
    ent_typ = IDBdrSimple ;
Packit b099d7
  else ent_typ = IDBdrOverflow ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Create the data entry depending on entry type.
Packit b099d7
   */
Packit b099d7
  switch ( ent_typ )
Packit b099d7
    {
Packit b099d7
    case IDBdrSimple:
Packit b099d7
Packit b099d7
      /*
Packit b099d7
       * Bind pointers into this record, and see if this entry will fit. If
Packit b099d7
       * not, get a new record and rebind pointers.
Packit b099d7
       */
Packit b099d7
      data_rec = (IDBDataRecord *) curbuf->IDB_record;
Packit b099d7
      dataheader = (IDBDataHdr *) &data_rec->data_header;
Packit b099d7
      if ( entsiz > dataheader->free_count )
Packit b099d7
	{
Packit b099d7
	  result = Idb__BM_InitDataRecord (file_id, &curbuf) ;
Packit b099d7
	  if ( result != MrmSUCCESS ) return result ;
Packit b099d7
	  data_rec = (IDBDataRecord *) curbuf->IDB_record;
Packit b099d7
	  dataheader = (IDBDataHdr *) &data_rec->data_header;
Packit b099d7
	}
Packit b099d7
Packit b099d7
      /*
Packit b099d7
       * Get the offset for the entry, and create the entry at that offset.
Packit b099d7
       * Copy in the data contents.
Packit b099d7
       */
Packit b099d7
      entoffs = dataheader->free_ptr ;
Packit b099d7
      simpledata = (IDBSimpleData *) &data_rec->data[entoffs];
Packit b099d7
      simpledata->header.validation	= IDBDataEntryValid;
Packit b099d7
      simpledata->header.entry_type	= IDBdrSimple;
Packit b099d7
      simpledata->header.resource_group	= UrmRCGroup(context_id);
Packit b099d7
      simpledata->header.resource_type	= UrmRCType(context_id);
Packit b099d7
      simpledata->header.access		= UrmRCAccess(context_id);
Packit b099d7
      simpledata->header.entry_size	= UrmRCSize(context_id);
Packit b099d7
      simpledata->header.lock		= UrmRCLock(context_id);
Packit b099d7
Packit b099d7
      dataptr = (char *) UrmRCBuffer(context_id) ;
Packit b099d7
Packit b099d7
      UrmBCopy (dataptr, simpledata->data, UrmRCSize(context_id));
Packit b099d7
Packit b099d7
      /*
Packit b099d7
       * Set the return value to the data pointer for this entry
Packit b099d7
       */	
Packit b099d7
      data_entry->rec_no = _IdbBufferRecordNumber (curbuf) ;
Packit b099d7
      data_entry->item_offs = dataheader->free_ptr;
Packit b099d7
Packit b099d7
      /*
Packit b099d7
       * Update the entry chain, mark the buffer, and return.
Packit b099d7
       */
Packit b099d7
      simpledata->header.prev_entry = dataheader->last_entry ;
Packit b099d7
      dataheader->num_entry++ ;
Packit b099d7
      dataheader->last_entry = entoffs ;
Packit b099d7
      dataheader->free_ptr += entsiz ;
Packit b099d7
      dataheader->free_count -= entsiz ;
Packit b099d7
Packit b099d7
      Idb__BM_MarkModified (curbuf) ;
Packit b099d7
      return MrmSUCCESS ;
Packit b099d7
Packit b099d7
    case IDBdrOverflow:
Packit b099d7
Packit b099d7
      /*
Packit b099d7
       * Compute the number of records required to hold this entry. Each segment
Packit b099d7
       * of the entry will begin in a new record, and occupy all of it, except,
Packit b099d7
       * usually, the last.
Packit b099d7
       */
Packit b099d7
      num_recs = (UrmRCSize(context_id)+IDBDataOverflowMax-1) /
Packit b099d7
	IDBDataOverflowMax ;
Packit b099d7
Packit b099d7
      /*
Packit b099d7
       * Enter a loop to create and fill all the records needed. Initialize the
Packit b099d7
       * record and pointers outside the loop, as a convenience for chaining
Packit b099d7
       * the segments. Also set the the result data pointer to point to this
Packit b099d7
       * record. Note that the offset of all overflow segments is 0.
Packit b099d7
       */
Packit b099d7
      result = Idb__BM_InitDataRecord (file_id, &curbuf) ;
Packit b099d7
      if ( result != MrmSUCCESS ) return result ;
Packit b099d7
      data_rec = (IDBDataRecordPtr) curbuf->IDB_record ;
Packit b099d7
      dataheader = (IDBDataHdrPtr) &data_rec->data_header ;
Packit b099d7
      overflowdata = (IDBOverflowDataPtr) data_rec->data ;
Packit b099d7
Packit b099d7
      data_entry->rec_no = _IdbBufferRecordNumber (curbuf) ;
Packit b099d7
      data_entry->item_offs = 0 ;
Packit b099d7
Packit b099d7
      /*
Packit b099d7
       * Set up pointers to copy the data from the context.
Packit b099d7
       */
Packit b099d7
      dataptr = (char *) UrmRCBuffer (context_id) ;
Packit b099d7
      datarem = UrmRCSize (context_id) ;
Packit b099d7
Packit b099d7
      for ( cur_rec=1 ; cur_rec<=num_recs ; cur_rec++ )
Packit b099d7
	{
Packit b099d7
Packit b099d7
	  /*
Packit b099d7
	   * Set up the header of this segment, and copy in the appropriate part
Packit b099d7
	   * of the data buffer in the context
Packit b099d7
	   */
Packit b099d7
	  cursiz = MIN(datarem, IDBDataOverflowMax) ;
Packit b099d7
	  entsiz = cursiz + IDBOverflowDataHdrSize ;
Packit b099d7
	  entsiz = _FULLWORD (entsiz) ;
Packit b099d7
	  overflowdata->header.validation	= IDBDataEntryValid;
Packit b099d7
	  overflowdata->header.entry_type	= IDBdrOverflow;
Packit b099d7
	  overflowdata->header.resource_group	= UrmRCGroup(context_id);
Packit b099d7
	  overflowdata->header.resource_type	= UrmRCType(context_id);
Packit b099d7
	  overflowdata->header.access		= UrmRCAccess(context_id);
Packit b099d7
	  overflowdata->header.lock		= UrmRCLock(context_id);
Packit b099d7
	  overflowdata->header.entry_size	= UrmRCSize(context_id);
Packit b099d7
Packit b099d7
	  UrmBCopy (dataptr, overflowdata->data, cursiz) ;
Packit b099d7
	  dataptr += cursiz ;
Packit b099d7
	  datarem -= cursiz ;
Packit b099d7
Packit b099d7
	  /*
Packit b099d7
	   * Set up the segment info, including chaining.  Chaining is
Packit b099d7
	   * done after the next buffer is acquired.  If this is not the
Packit b099d7
	   * last record, then the chain is updated.  If it is the last
Packit b099d7
	   * record, then the free pointer is set.  This code assumes
Packit b099d7
	   * that acquiring a new data record does not free/reuse the
Packit b099d7
	   * current buffer. 
Packit b099d7
	   */
Packit b099d7
	  overflowdata->segment_size = cursiz ;
Packit b099d7
	  overflowdata->segment_count = num_recs ;
Packit b099d7
	  overflowdata->segment_num = cur_rec ;
Packit b099d7
Packit b099d7
	  overflowdata->header.prev_entry = 0 ;
Packit b099d7
	  dataheader->num_entry++ ;
Packit b099d7
	  dataheader->last_entry = 0 ;
Packit b099d7
	  dataheader->free_ptr += entsiz ;
Packit b099d7
	  dataheader->free_count -= entsiz ;
Packit b099d7
Packit b099d7
	  Idb__BM_MarkModified (curbuf) ;
Packit b099d7
Packit b099d7
	  if ( cur_rec == num_recs ) 
Packit b099d7
	    {
Packit b099d7
	      overflowdata->next_segment.internal_id.rec_no = 0 ;
Packit b099d7
	      overflowdata->next_segment.internal_id.item_offs = 0 ;
Packit b099d7
	    }
Packit b099d7
	  else
Packit b099d7
	    {
Packit b099d7
	      result = Idb__BM_InitDataRecord (file_id, &nxtbuf) ;
Packit b099d7
	      if ( result != MrmSUCCESS ) return result ;
Packit b099d7
Packit b099d7
	      overflowdata->next_segment.internal_id.rec_no =
Packit b099d7
		_IdbBufferRecordNumber (nxtbuf) ;
Packit b099d7
	      overflowdata->next_segment.internal_id.item_offs = 0 ;
Packit b099d7
Packit b099d7
	      curbuf = nxtbuf ;
Packit b099d7
	      data_rec = (IDBDataRecordPtr) curbuf->IDB_record ;
Packit b099d7
	      dataheader = (IDBDataHdrPtr) &data_rec->data_header ;
Packit b099d7
	      overflowdata = (IDBOverflowDataPtr) data_rec->data ;
Packit b099d7
	    }
Packit b099d7
        }
Packit b099d7
Packit b099d7
      return MrmSUCCESS ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  return MrmFAILURE;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 *++
Packit b099d7
 *
Packit b099d7
 *  PROCEDURE DESCRIPTION:
Packit b099d7
 *
Packit b099d7
 *	This routine checks if a data entry matchs a set of filters.
Packit b099d7
 *	It reads the record containing the header for the data entry,
Packit b099d7
 *	then does the filter match. If both filters are NUL, then
Packit b099d7
 *	the test becomes merely one of confirming the data entry
Packit b099d7
 *	can be read.
Packit b099d7
 *
Packit b099d7
 *  FORMAL PARAMETERS:
Packit b099d7
 *
Packit b099d7
 *	file_id		Open ID file
Packit b099d7
 *	data_entry	Data entry to be matched
Packit b099d7
 *	group_filter	if not null, entry found must match this group
Packit b099d7
 *	type_filter	if not null, entry found must match this type
Packit b099d7
 *
Packit b099d7
 *  IMPLICIT INPUTS:
Packit b099d7
 *
Packit b099d7
 *  IMPLICIT OUTPUTS:
Packit b099d7
 *
Packit b099d7
 *  FUNCTION VALUE:
Packit b099d7
 *
Packit b099d7
 *	TRUE		Match is good
Packit b099d7
 *	FALSE		match not good.
Packit b099d7
 *
Packit b099d7
 *  SIDE EFFECTS:
Packit b099d7
 *
Packit b099d7
 *--
Packit b099d7
 */
Packit b099d7
Packit b099d7
Boolean 
Packit b099d7
Idb__DB_MatchFilter (IDBFile 		file_id,
Packit b099d7
		     IDBDataHandle	data_entry,
Packit b099d7
		     MrmCode 		group_filter,
Packit b099d7
		     MrmCode 		type_filter)
Packit b099d7
{
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   *  Local variables
Packit b099d7
   */
Packit b099d7
  Cardinal		result ;	/* return status */
Packit b099d7
  IDBRecordNumber	record_number ;	/* Record to be read in */
Packit b099d7
  IDBRecordBufferPtr	bufptr ;	/* buffer for data record */
Packit b099d7
  IDBDataRecordPtr	data_rec;	/* pointer data record */
Packit b099d7
  IDBDataEntryHdrPtr	datahdr ;	/* Header part of entry */
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Get the record that contains this data, get to the correct offset in
Packit b099d7
   * that record. Immediately decommit the buffer, since it won't be
Packit b099d7
   * compromised by this read. As usual, go to the header record if required.
Packit b099d7
   */
Packit b099d7
  record_number = data_entry.rec_no ;
Packit b099d7
  if ( record_number == IDBHeaderRecordNumber )
Packit b099d7
    return Idb__HDR_MatchFilter
Packit b099d7
      (file_id, data_entry, group_filter, type_filter);
Packit b099d7
Packit b099d7
  result = Idb__BM_GetRecord (file_id, record_number, &bufptr) ;
Packit b099d7
  if ( result != MrmSUCCESS ) return FALSE ;
Packit b099d7
  Idb__BM_Decommit (bufptr) ;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Point to the header in the entry, and check the filters.
Packit b099d7
   */
Packit b099d7
  data_rec = (IDBDataRecord *) bufptr->IDB_record;
Packit b099d7
  datahdr = (IDBDataEntryHdrPtr) &data_rec->data[data_entry.item_offs] ;
Packit b099d7
  if (datahdr->validation != IDBDataEntryValid)
Packit b099d7
    {
Packit b099d7
      Urm__UT_Error ("Idb__DB_GetDataEntry", _MrmMMsg_0007,
Packit b099d7
		     NULL, NULL, MrmNOT_VALID) ;
Packit b099d7
      return FALSE ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  if ( group_filter!=URMgNul && group_filter!=datahdr->resource_group )
Packit b099d7
    return FALSE ;
Packit b099d7
  if ( type_filter!=URMtNul && type_filter!=datahdr->resource_type )
Packit b099d7
    return FALSE ;
Packit b099d7
Packit b099d7
  return TRUE ;
Packit b099d7
Packit b099d7
}
Packit b099d7