|
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 |
|