📄 memotransfer.c
字号:
if (descriptionSize > 0)
{
// Now form a file name. Use only the first word or two.
spaceP = StrChr(descriptionP, spaceChr);
if (spaceP)
// Check for a second space
spaceP = StrChr(spaceP + sizeOf7BitChar(spaceChr), spaceChr);
// If at least two spaces were found then use only that much of the description.
// If less than two spaces were found then use all of the description.
if (spaceP)
filenameLength = spaceP - descriptionP;
else
filenameLength = StrLen(descriptionP);
// Allocate space and form the filename
schemeLength = StrLen(prefix);
*filenameHP = MemHandleNew(schemeLength + filenameLength + StrLen(memoSuffix) + sizeOf7BitChar('\0'));
filenameP = MemHandleLock(*filenameHP);
if (filenameP)
{
StrCopy(filenameP, prefix);
MemMove(&filenameP[schemeLength], descriptionP, filenameLength);
MemMove(&filenameP[schemeLength + filenameLength], memoSuffix,
StrLen(memoSuffix) + sizeOf7BitChar('\0'));
}
}
else
{
resourceH = DmGetResource(strRsc, BeamFilenameStr);
resourceP = MemHandleLock(resourceH);
// Allocate space and form the filename
filenameLength = StrLen(resourceP);
schemeLength = StrLen(prefix);
*filenameHP = MemHandleNew(schemeLength + filenameLength + sizeOf7BitChar('\0'));
filenameP = MemHandleLock(*filenameHP);
if (filenameP)
{
StrCopy(filenameP, prefix);
StrCat(filenameP, resourceP);
}
MemHandleUnlock(resourceH);
DmReleaseResource(resourceH);
}
*descriptionPP = descriptionP;
*filenamePP = filenameP;
}
/***********************************************************************
*
* FUNCTION: PrvMemoSendRecordTryCatch
*
* DESCRIPTION: Send a record.
*
* PARAMETERS: dbP - pointer to the database to add the record to
* recordNum - the record number to send
* recordP - pointer to the record to send
* exgSocketP - the exchange socket used to send
*
* RETURNED: 0 if there's no error
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* roger 12/11/97 Initial Revision
*
***********************************************************************/
static Err PrvMemoSendRecordTryCatch (DmOpenRef dbP, Int16 recordNum,
MemoDBRecordPtr recordP, ExgSocketPtr exgSocketP)
{
volatile Err error = 0;
StreamType stream;
PrvStreamInit(&stream, exgSocketP);
// An error can happen anywhere during the send process. It's easier just to
// catch the error. If an error happens, we must pass it into ExgDisconnect.
// It will then cancel the send and display appropriate ui.
ErrTry
{
MemoExportMime(dbP, recordNum, recordP, &stream, PrvWriteFunction, true, false);
}
ErrCatch(inErr)
{
error = inErr;
} ErrEndCatch
PrvStreamFlush( &stream);
return error;
}
/***********************************************************************
*
* FUNCTION: PrvMemoSendCategoryTryCatch
*
* DESCRIPTION: Send all visible records in a category.
*
* PARAMETERS: dbP - pointer to the database to add the record to
* categoryNum - the category of records to send
* exgSocketP - the exchange socket used to send
* index - the record number of the first record in the category to send
*
* RETURNED: 0 if there's no error
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* roger 12/11/97 Initial Revision
*
***********************************************************************/
static Err PrvMemoSendCategoryTryCatch (DmOpenRef dbP, UInt16 categoryNum,
ExgSocketPtr exgSocketP, UInt16 index)
{
volatile Err error = 0;
volatile MemHandle outRecordH = 0;
MemoDBRecordType *outRecordP;
StreamType stream;
// An error can happen anywhere during the send process. It's easier just to
// catch the error. If an error happens, we must pass it into ExgDisconnect.
// It will then cancel the send and display appropriate ui.
ErrTry
{
PrvStreamInit(&stream, exgSocketP);
// Write out the beginning of a multipart mime message
PrvWriteFunction(&stream,
mimeVersionString
"Content-type: multipart/mixed; boundary=\"" simpleBoundary "\"" crlf crlf, stringZLen);
// Loop through all records in the category.
while (DmSeekRecordInCategory(dbP, &index, 0, dmSeekForward, categoryNum) == 0)
{
// Emit the record. If the record is private do not emit it.
outRecordH = DmQueryRecord (dbP, index);
if (outRecordH != 0)
{
outRecordP = (MemoDBRecordType *) MemHandleLock(outRecordH);
// Emit a mime boundary
PrvWriteFunction(&stream, delimiter crlf, stringZLen);
MemoExportMime(dbP, index, outRecordP, &stream, PrvWriteFunction, true, true);
MemHandleUnlock(outRecordH);
}
index++;
}
outRecordH = 0;
dbP = 0;
// All done. Write out an epilogue.
PrvWriteFunction(&stream, delimiter "--" crlf crlf, stringZLen);
}
ErrCatch(inErr)
{
error = inErr;
if (outRecordH)
MemHandleUnlock(outRecordH);
} ErrEndCatch
PrvStreamFlush(&stream);
return error;
}
/***********************************************************************
*
* FUNCTION: PrvMemoSetGoToParams
*
* DESCRIPTION: Store the information necessary to navigate to the
* record inserted into the launch code's parameter block.
*
* PARAMETERS: dbP - pointer to the database to add the record to
* exgSocketP - parameter block passed with the launch code
* uniqueID - unique id of the record inserted
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 10/17/97 Created
*
***********************************************************************/
static void PrvMemoSetGoToParams (DmOpenRef dbP, ExgSocketPtr exgSocketP, UInt32 uniqueID)
{
UInt16 recordNum;
UInt16 cardNo;
LocalID dbID;
if (! uniqueID) return;
DmOpenDatabaseInfo (dbP, &dbID, NULL, NULL, &cardNo, NULL);
// The this the the first record inserted, save the information
// necessary to navigate to the record.
if (! exgSocketP->goToParams.uniqueID)
{
DmFindRecordByID (dbP, uniqueID, &recordNum);
exgSocketP->goToCreator = sysFileCMemo;
exgSocketP->goToParams.uniqueID = uniqueID;
exgSocketP->goToParams.dbID = dbID;
exgSocketP->goToParams.dbCardNo = cardNo;
exgSocketP->goToParams.recordNum = recordNum;
}
// If we already have a record then make sure the record index
// is still correct. Don't update the index if the record is not
// in your the app's database.
else if (dbID == exgSocketP->goToParams.dbID &&
cardNo == exgSocketP->goToParams.dbCardNo)
{
DmFindRecordByID (dbP, exgSocketP->goToParams.uniqueID, &recordNum);
exgSocketP->goToParams.recordNum = recordNum;
}
}
/************************************************************
*
* FUNCTION: PrvReadThroughCRLF
*
* DESCRIPTION: Consume data up to and including the next CRLF.
*
* PARAMETERS:
* inputStreamP - pointer to where to import from
* bufferP - where the input stream is stored
* bufferLengthP - the length of bufferP used
*
* RETURNED: error code or zero for no error.
*
* ASSUMPTIONS:
* Buffer is full when called
* Buffer is big enough to hold a full line (including LF)
* ...so CR/LF will never split
* END CONDITION:
* Buffer is full when routine exits.
*
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* bob 1/26/98 initial revision
*
*************************************************************/
static Err PrvReadThroughCRLF(ReadFunctionF inputFunc, void * inputStreamP, Char * bufferP, UInt16 * bufferLengthP)
{
char *c;
UInt16 charsRead;
Err err = 0;
Boolean gotOne = false;
while (*bufferLengthP > 0 && !gotOne)
{
c = StrChr(bufferP, crChr);
if (c == NULL)
c = &bufferP[*bufferLengthP]; // end of the buffer
else if (c < bufferP + *bufferLengthP - 1) // guard against buffer splitting cr/lf
{
c += sizeOf7BitChar(crChr) + sizeOf7BitChar(linefeedChr);
gotOne = true;
}
// Consume everything up to the CR/NULL
MemMove(bufferP, c, &bufferP[*bufferLengthP] - c);
*bufferLengthP = &bufferP[*bufferLengthP] - c;
// Read in more chars
charsRead = inputFunc(inputStreamP, bufferP + *bufferLengthP, importBufferMaxLength - *bufferLengthP);
*bufferLengthP += charsRead;
bufferP[*bufferLengthP] = nullChr;
}
return err;
}
/************************************************************
*
* FUNCTION: PrvMemoImportFinishRecord
*
* DESCRIPTION: Make sure record is null terminated, and close it.
*
* PARAMETERS:
* dbP - pointer to the database to add the record to
* indexNew - index of new record
* newRecordH - MemHandle to new record
* newRecordSize - bytes currently in new record
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* bob 1998-02-05 Moved out of MemoImportMime
*
*************************************************************/
static void PrvMemoImportFinishRecord(DmOpenRef dbP, UInt16 indexNew, MemHandle *newRecordHPtr, UInt16 *newRecordSizePtr, void * inputStream)
{
Char * newRecordP;
MemHandle newHandle; // Used to follow resized records which move
ErrNonFatalDisplayIf(*newRecordHPtr == NULL, "Null record MemHandle.");
// Make sure the record is nullChr terminated
newRecordP = MemHandleLock(*newRecordHPtr);
if (newRecordP[*newRecordSizePtr - sizeof(char)] != nullChr)
{
MemHandleUnlock(*newRecordHPtr);
newHandle = DmResizeRecord(dbP, indexNew, *newRecordSizePtr + sizeOf7BitChar(nullChr));
if (newHandle)
*newRecordHPtr = newHandle;
else
ErrThrow(exgMemError);
newRecordP = MemHandleLock(*newRecordHPtr);
DmWrite(newRecordP, *newRecordSizePtr, "", sizeOf7BitChar(nullChr));
}
// let the record go
MemHandleUnlock(*newRecordHPtr);
DmReleaseRecord(dbP, indexNew, true);
*newRecordHPtr = NULL;
*newRecordSizePtr = 0;
}
/************************************************************
*
* FUNCTION: PrvMemoImportMimeCleanup
*
* DESCRIPTION: Cleanup function for MemoImportMime
*
* PARAMETERS:
* dbP - pointer to the database to add the record to
* firstRecordID - uniqueID of the first record we loaded
* inputStream - pointer to where to import the record from
* numRecordsReceived - number of records received
* numRecordsReceivedP - pointer to the number of records received
*
* RETURNS: None
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* FPa 11/22/00 Initial Revision
*
*************************************************************/
void PrvMemoImportMimeCleanup(DmOpenRef dbP, UInt32 firstRecordID, void* inputStream, UInt16 numRecordsReceived, UInt16* numRecordsReceivedP)
{
// if we got at least one record, sort and set goto parameters...
if (firstRecordID)
{
MemoSort(dbP);
PrvMemoSetGoToParams (dbP, PrvStreamSocket(inputStream), firstRecordID);
}
// return number of records received
*numRecordsReceivedP = numRecordsReceived;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -