📄 insfile.c
字号:
instanceCount++;
ReturnExpression(theEnv,top->argList);
top->argList = NULL;
GetToken(theEnv,ilog,&DefclassData(theEnv)->ObjectParseToken);
}
rtn_struct(theEnv,expr,top);
if (isFileName) {
GenClose(theEnv,sfile);
SetFastLoad(theEnv,svload);
}
InstanceData(theEnv)->MkInsMsgPass = svoverride;
return(instanceCount);
}
/***************************************************
NAME : ProcessFileErrorMessage
DESCRIPTION : Prints an error message when a
file containing text or binary
instances cannot be processed.
INPUTS : The name of the input file and the
function which opened it.
RETURNS : No value
SIDE EFFECTS : None
NOTES : None
***************************************************/
static void ProcessFileErrorMessage(
void *theEnv,
char *functionName,
char *fileName)
{
PrintErrorID(theEnv,"INSFILE",1,FALSE);
EnvPrintRouter(theEnv,WERROR,"Function ");
EnvPrintRouter(theEnv,WERROR,functionName);
EnvPrintRouter(theEnv,WERROR," could not completely process file ");
EnvPrintRouter(theEnv,WERROR,fileName);
EnvPrintRouter(theEnv,WERROR,".\n");
}
#if BLOAD_INSTANCES
/*******************************************************
NAME : VerifyBinaryHeader
DESCRIPTION : Reads the prefix and version headers
from a file to verify that the
input is a valid binary instances file
INPUTS : The name of the file
RETURNS : TRUE if OK, FALSE otherwise
SIDE EFFECTS : Input prefix and version read
NOTES : Assumes file already open with
GenOpenReadBinary
*******************************************************/
static intBool VerifyBinaryHeader(
void *theEnv,
char *theFile)
{
char buf[20];
GenReadBinary(theEnv,(void *) buf,(unsigned long) (strlen(InstanceFileData(theEnv)->InstanceBinaryPrefixID) + 1));
if (strcmp(buf,InstanceFileData(theEnv)->InstanceBinaryPrefixID) != 0)
{
PrintErrorID(theEnv,"INSFILE",2,FALSE);
EnvPrintRouter(theEnv,WERROR,theFile);
EnvPrintRouter(theEnv,WERROR," file is not a binary instances file.\n");
return(FALSE);
}
GenReadBinary(theEnv,(void *) buf,(unsigned long) (strlen(InstanceFileData(theEnv)->InstanceBinaryVersionID) + 1));
if (strcmp(buf,InstanceFileData(theEnv)->InstanceBinaryVersionID) != 0)
{
PrintErrorID(theEnv,"INSFILE",3,FALSE);
EnvPrintRouter(theEnv,WERROR,theFile);
EnvPrintRouter(theEnv,WERROR," file is not a compatible binary instances file.\n");
return(FALSE);
}
return(TRUE);
}
/***************************************************
NAME : LoadSingleBinaryInstance
DESCRIPTION : Reads the binary data for a new
instance and its slot values and
creates/initializes the instance
INPUTS : None
RETURNS : TRUE if all OK,
FALSE otherwise
SIDE EFFECTS : Binary data read and instance
created
NOTES : Uses global GenReadBinary(theEnv,)
***************************************************/
static intBool LoadSingleBinaryInstance(
void *theEnv)
{
SYMBOL_HN *instanceName,
*className;
unsigned slotCount;
DEFCLASS *theDefclass;
INSTANCE_TYPE *newInstance;
struct bsaveSlotValue *bsArray;
struct bsaveSlotValueAtom *bsaArray = NULL;
long nameIndex;
unsigned long totalValueCount;
register unsigned i;
unsigned long j;
INSTANCE_SLOT *sp;
DATA_OBJECT slotValue,junkValue;
/* =====================
Get the instance name
===================== */
BufferedRead(theEnv,(void *) &nameIndex,(unsigned long) sizeof(long));
instanceName = SymbolPointer(nameIndex);
/* ==================
Get the class name
================== */
BufferedRead(theEnv,(void *) &nameIndex,(unsigned long) sizeof(long));
className = SymbolPointer(nameIndex);
/* ==================
Get the slot count
================== */
BufferedRead(theEnv,(void *) &slotCount,(unsigned long) sizeof(unsigned));
/* =============================
Make sure the defclass exists
and check the slot count
============================= */
theDefclass = LookupDefclassInScope(theEnv,ValueToString(className));
if (theDefclass == NULL)
{
ClassExistError(theEnv,"bload-instances",ValueToString(className));
return(FALSE);
}
if (theDefclass->instanceSlotCount != slotCount)
{
BinaryLoadInstanceError(theEnv,instanceName,theDefclass);
return(FALSE);
}
/* ===================================
Create the new unitialized instance
=================================== */
newInstance = BuildInstance(theEnv,instanceName,theDefclass,FALSE);
if (newInstance == NULL)
{
BinaryLoadInstanceError(theEnv,instanceName,theDefclass);
return(FALSE);
}
if (slotCount == 0)
return(TRUE);
/* ====================================
Read all slot override info and slot
value atoms into big arrays
==================================== */
bsArray = (struct bsaveSlotValue *) gm2(theEnv,(sizeof(struct bsaveSlotValue) * slotCount));
BufferedRead(theEnv,(void *) bsArray,(unsigned long) (sizeof(struct bsaveSlotValue) * slotCount));
BufferedRead(theEnv,(void *) &totalValueCount,(unsigned long) sizeof(unsigned long));
if (totalValueCount != 0L)
{
bsaArray = (struct bsaveSlotValueAtom *)
gm3(theEnv,(long) (totalValueCount * sizeof(struct bsaveSlotValueAtom)));
BufferedRead(theEnv,(void *) bsaArray,
(unsigned long) (totalValueCount * sizeof(struct bsaveSlotValueAtom)));
}
/* =========================
Insert the values for the
slot overrides
========================= */
for (i = 0 , j = 0L ; i < slotCount ; i++)
{
/* ===========================================================
Here is another check for the validity of the binary file -
the order of the slots in the file should match the
order in the class definition
=========================================================== */
sp = newInstance->slotAddresses[i];
if (sp->desc->slotName->name != SymbolPointer(bsArray[i].slotName))
goto LoadError;
CreateSlotValue(theEnv,&slotValue,(struct bsaveSlotValueAtom *) &bsaArray[j],
bsArray[i].valueCount);
if (PutSlotValue(theEnv,newInstance,sp,&slotValue,&junkValue,"bload-instances") == FALSE)
goto LoadError;
j += (unsigned long) bsArray[i].valueCount;
}
rm(theEnv,(void *) bsArray,(sizeof(struct bsaveSlotValue) * slotCount));
if (totalValueCount != 0L)
rm3(theEnv,(void *) bsaArray,
(long) (totalValueCount * sizeof(struct bsaveSlotValueAtom)));
return(TRUE);
LoadError:
BinaryLoadInstanceError(theEnv,instanceName,theDefclass);
QuashInstance(theEnv,newInstance);
rm(theEnv,(void *) bsArray,(sizeof(struct bsaveSlotValue) * slotCount));
rm3(theEnv,(void *) bsaArray,
(long) (totalValueCount * sizeof(struct bsaveSlotValueAtom)));
return(FALSE);
}
/***************************************************
NAME : BinaryLoadInstanceError
DESCRIPTION : Prints out an error message when
an instance could not be
successfully loaded from a
binary file
INPUTS : 1) The instance name
2) The defclass
RETURNS : Nothing useful
SIDE EFFECTS : Error message printed
NOTES : None
***************************************************/
static void BinaryLoadInstanceError(
void *theEnv,
SYMBOL_HN *instanceName,
DEFCLASS *theDefclass)
{
PrintErrorID(theEnv,"INSFILE",4,FALSE);
EnvPrintRouter(theEnv,WERROR,"Function bload-instances unable to load instance [");
EnvPrintRouter(theEnv,WERROR,ValueToString(instanceName));
EnvPrintRouter(theEnv,WERROR,"] of class ");
PrintClassName(theEnv,WERROR,theDefclass,TRUE);
}
/***************************************************
NAME : CreateSlotValue
DESCRIPTION : Creates a data object value from
the binary slot value atom data
INPUTS : 1) A data object buffer
2) The slot value atoms array
3) The number of values to put
in the data object
RETURNS : Nothing useful
SIDE EFFECTS : Data object initialized
(if more than one value, a
multifield is created)
NOTES : None
***************************************************/
static void CreateSlotValue(
void *theEnv,
DATA_OBJECT *result,
struct bsaveSlotValueAtom *bsaValues,
unsigned long valueCount)
{
register unsigned i;
if (valueCount == 0)
{
result->type = MULTIFIELD;
result->value = EnvCreateMultifield(theEnv,0L);
result->begin = 0;
result->end = -1;
}
else if (valueCount == 1)
{
result->type = bsaValues[0].type;
result->value = GetBinaryAtomValue(theEnv,&bsaValues[0]);
}
else
{
result->type = MULTIFIELD;
result->value = EnvCreateMultifield(theEnv,valueCount);
result->begin = 0;
SetpDOEnd(result,valueCount);
for (i = 1 ; i <= valueCount ; i++)
{
SetMFType(result->value,i,(short) bsaValues[i-1].type);
SetMFValue(result->value,i,GetBinaryAtomValue(theEnv,&bsaValues[i-1]));
}
}
}
/***************************************************
NAME : GetBinaryAtomValue
DESCRIPTION : Uses the binary index of an atom
to find the ephemeris value
INPUTS : The binary type and index
RETURNS : The symbol/etc. pointer
SIDE EFFECTS : None
NOTES : None
***************************************************/
static void *GetBinaryAtomValue(
void *theEnv,
struct bsaveSlotValueAtom *ba)
{
switch (ba->type)
{
case SYMBOL:
case STRING:
case INSTANCE_NAME:
return((void *) SymbolPointer(ba->value));
case FLOAT:
return((void *) FloatPointer(ba->value));
case INTEGER:
return((void *) IntegerPointer(ba->value));
case FACT_ADDRESS:
#if DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT
return((void *) &FactData(theEnv)->DummyFact);
#else
return(NULL);
#endif
case EXTERNAL_ADDRESS:
return(NULL);
default:
{
SystemError(theEnv,"INSFILE",1);
EnvExitRouter(theEnv,EXIT_FAILURE);
}
}
return(NULL);
}
/***************************************************
NAME : BufferedRead
DESCRIPTION : Reads data from binary file
(Larger blocks than requested size
may be read and buffered)
INPUTS : 1) The buffer
2) The buffer size
RETURNS : Nothing useful
SIDE EFFECTS : Data stored in buffer
NOTES : None
***************************************************/
static void BufferedRead(
void *theEnv,
void *buf,
unsigned long bufsz)
{
unsigned long i,amountLeftToRead;
if (InstanceFileData(theEnv)->CurrentReadBuffer != NULL)
{
amountLeftToRead = InstanceFileData(theEnv)->CurrentReadBufferSize - InstanceFileData(theEnv)->CurrentReadBufferOffset;
if (bufsz <= amountLeftToRead)
{
for (i = 0L ; i < bufsz ; i++)
((char *) buf)[i] = InstanceFileData(theEnv)->CurrentReadBuffer[i + InstanceFileData(theEnv)->CurrentReadBufferOffset];
InstanceFileData(theEnv)->CurrentReadBufferOffset += bufsz;
if (InstanceFileData(theEnv)->CurrentReadBufferOffset == InstanceFileData(theEnv)->CurrentReadBufferSize)
FreeReadBuffer(theEnv);
}
else
{
if (InstanceFileData(theEnv)->CurrentReadBufferOffset < InstanceFileData(theEnv)->CurrentReadBufferSize)
{
for (i = 0L ; i < amountLeftToRead ; i++)
((char *) buf)[i] = InstanceFileData(theEnv)->CurrentReadBuffer[i + InstanceFileData(theEnv)->CurrentReadBufferOffset];
bufsz -= amountLeftToRead;
buf = (void *) (((char *) buf) + amountLeftToRead);
}
FreeReadBuffer(theEnv);
BufferedRead(theEnv,buf,bufsz);
}
}
else
{
if (bufsz > MAX_BLOCK_SIZE)
{
InstanceFileData(theEnv)->CurrentReadBufferSize = bufsz;
if (bufsz > (InstanceFileData(theEnv)->BinaryInstanceFileSize - InstanceFileData(theEnv)->BinaryInstanceFileOffset))
{
SystemError(theEnv,"INSFILE",2);
EnvExitRouter(theEnv,EXIT_FAILURE);
}
}
else if (MAX_BLOCK_SIZE >
(InstanceFileData(theEnv)->BinaryInstanceFileSize - InstanceFileData(theEnv)->BinaryInstanceFileOffset))
InstanceFileData(theEnv)->CurrentReadBufferSize = InstanceFileData(theEnv)->BinaryInstanceFileSize - InstanceFileData(theEnv)->BinaryInstanceFileOffset;
else
InstanceFileData(theEnv)->CurrentReadBufferSize = (unsigned long) MAX_BLOCK_SIZE;
InstanceFileData(theEnv)->CurrentReadBuffer = (char *) genlongalloc(theEnv,InstanceFileData(theEnv)->CurrentReadBufferSize);
GenReadBinary(theEnv,(void *) InstanceFileData(theEnv)->CurrentReadBuffer,InstanceFileData(theEnv)->CurrentReadBufferSize);
for (i = 0L ; i < bufsz ; i++)
((char *) buf)[i] = InstanceFileData(theEnv)->CurrentReadBuffer[i];
InstanceFileData(theEnv)->CurrentReadBufferOffset = bufsz;
InstanceFileData(theEnv)->BinaryInstanceFileOffset += InstanceFileData(theEnv)->CurrentReadBufferSize;
}
}
/*****************************************************
NAME : FreeReadBuffer
DESCRIPTION : Deallocates buffer for binary reads
INPUTS : None
RETURNS : Nothing usefu
SIDE EFFECTS : Binary global read buffer deallocated
NOTES : None
*****************************************************/
static void FreeReadBuffer(
void *theEnv)
{
if (InstanceFileData(theEnv)->CurrentReadBufferSize != 0L)
{
genlongfree(theEnv,(void *) InstanceFileData(theEnv)->CurrentReadBuffer,InstanceFileData(theEnv)->CurrentReadBufferSize);
InstanceFileData(theEnv)->CurrentReadBuffer = NULL;
InstanceFileData(theEnv)->CurrentReadBufferSize = 0L;
}
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -