📄 addresstransfer.c
字号:
infoP->string[infoP->size - 1] = chrNull;
}
else
{
ParseError:
err = exgErrBadData;
}
}
// clean up
if (lastNameP)
MemPtrFree(lastNameP);
if (firstNameP)
MemPtrFree(firstNameP);
if (companyP)
MemPtrFree(companyP);
ExgDisconnect(infoP->socketP, err);
}
PdiReaderDelete(pdiRefNum, &reader);
UDADelete(stream);
PrvTransferPdiLibUnload(pdiRefNum, loaded);
}
infoP->error = err;
}
#pragma mark -
/***********************************************************************
*
* FUNCTION: PrvTransferPdiLibLoad
*
* DESCRIPTION: Load Pdi library
* PARAMETERS: a pointer to an integer: the refNum of the libary
* return whether the library had to be loaded (and therefore
* needs to be unloaded)
*
* RETURNED: An error if library is not found
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* ABa 4/10/00 Created
*
***********************************************************************/
static Err PrvTransferPdiLibLoad(UInt16* refNum, Boolean *loadedP)
{
Err error;
// Load the Pdi library
// Check if the library was pre-loaded (this is useful if we can
// be called from another app via an action code and want to use an existing
// instance of the library in case our caller has already loaded it)
*loadedP = false;
error = SysLibFind(kPdiLibName, refNum);
if (error != 0)
{
error = SysLibLoad(sysResTLibrary, sysFileCPdiLib, refNum);
if (! error)
*loadedP = true;
}
if (error)
{
// We're here because the Pdi library failed to load.
// Inform the user or do something else defensive here.
ErrNonFatalDisplay(kPdiLibName " not found");
return error;
}
error = PdiLibOpen(*refNum);
return error;
}
/***********************************************************************
*
* FUNCTION: PrvTransferPdiLibUnload
*
* DESCRIPTION: Unload Pdi library
* PARAMETERS: The refnum of the pdi library
* Whether the library was loaded (and therefore needs to be unloaded)
*
* RETURNED: An error if library is not found
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* ABa 4/10/00 Created
*
***********************************************************************/
static void PrvTransferPdiLibUnload(UInt16 refNum, Boolean loaded)
{
if (PdiLibClose(refNum) == errNone)
{
TraceOutput(TL(appErrorClass, "Removing library..."));
if (loaded)
SysLibRemove(refNum);
}
}
/***********************************************************************
*
* FUNCTION: PrvTransferSendRecordTryCatch
*
* 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
* outputStream - place to send the data
*
* RETURNED: 0 if there's no error
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* roger 12/11/97 Initial Revision
* ABa 4/10/00 Load Pdi library
*
***********************************************************************/
static Err PrvTransferSendRecordTryCatch (DmOpenRef dbP, Int16 recordNum,
AddrDBRecordPtr recordP, UDAWriterType* media)
{
Err error = 0;
UInt16 pdiRefNum;
Boolean loaded;
PdiWriterType* writer;
if ((error = PrvTransferPdiLibLoad(&pdiRefNum, &loaded)))
{
ErrNonFatalDisplay("Can't load Pdi library");
return error;
}
writer = PdiWriterNew(pdiRefNum, media, kPdiEnableQuotedPrintable);
if (writer)
{
// 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
{
TransferExportVCard(dbP, recordNum, recordP, pdiRefNum, writer, true);
error = UDAWriterFlush(media);
}
ErrCatch(inErr)
{
error = inErr;
} ErrEndCatch
PdiWriterDelete(pdiRefNum, &writer);
}
else
{
error = exgMemError;
}
PrvTransferPdiLibUnload(pdiRefNum, loaded);
return error;
}
/***********************************************************************
*
* FUNCTION: PrvTransferCleanFileName
*
* DESCRIPTION: Remove dot characters in file name but not the least
* PARAMETERS: a pointer to a string
*
* RETURNED: String parameter doesn't contains superfluous dot characters
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* ABa 7/28/00 Created
*
***********************************************************************/
static void PrvTransferCleanFileName(Char* ioFileName)
{
Char* mayBeLastDotP;
Char* lastDotP;
UInt32 chrFullStopSize = TxtCharSize(chrFullStop);
// prevent NULL & empty string
if (ioFileName == NULL || *ioFileName == 0)
return;
// remove dot but not the last one
mayBeLastDotP = StrChr(ioFileName, chrFullStop);
while ((lastDotP = StrChr(mayBeLastDotP + chrFullStopSize, chrFullStop)))
{
// remove the dot
StrCopy(mayBeLastDotP, mayBeLastDotP + chrFullStopSize);
mayBeLastDotP = lastDotP - chrFullStopSize;
}
}
/***********************************************************************
*
* FUNCTION: PrvTransferSendCategoryTryCatch
*
* 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 5/9/97 Initial Revision
* ABa 6/20/00 Integrate Pdi library
*
***********************************************************************/
static Err PrvTransferSendCategoryTryCatch (DmOpenRef dbP, UInt16 categoryNum,
UDAWriterType* media, UInt16 index)
{
volatile Err error = 0;
volatile MemHandle outRecordH = 0;
AddrDBRecordType outRecord;
UInt16 pdiRefNum;
PdiWriterType* writer;
Boolean loaded;
if ((error = PrvTransferPdiLibLoad(&pdiRefNum, &loaded)))
return error;
writer = PdiWriterNew(pdiRefNum, media, kPdiEnableQuotedPrintable);
if (writer)
{
// 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
{
// 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.
if (AddrDBGetRecord(dbP, index, &outRecord, (MemHandle*)&outRecordH) == 0)
{
TransferExportVCard(dbP, index, &outRecord, pdiRefNum, writer, true);
MemHandleUnlock(outRecordH);
}
index++;
}
error = UDAWriterFlush(media);
}
ErrCatch(inErr)
{
error = inErr;
if (outRecordH)
MemHandleUnlock(outRecordH);
} ErrEndCatch
PdiWriterDelete(pdiRefNum, &writer);
}
else
{
error = exgMemError;
}
PrvTransferPdiLibUnload(pdiRefNum, loaded);
return error;
}
/***********************************************************************
*
* FUNCTION: PrvTransferSetGoToParams
*
* 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 PrvTransferSetGoToParams (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 = sysFileCAddress;
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: PrvTransferGetFullName
*
* DESCRIPTION: This function builds (lays out) the name that is used
* when displaying status during a transfer. It deals
* with the layout of the lastname, firstname and company
* name based on the encoding of the data and also based
* on whether the sort by company flag has been set.
*
* PARAMETERS: r - pointer to the record being transferred.
* useCompany - flag indicating whether we are sorting by
* company.
*
* RETURNED: A handle to the full formed name to be used for status
* display.
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vsm 12/05/02 Created.
*
***********************************************************************/
static MemHandle PrvTransferGetFullName (AddrDBRecordPtr r, Int16 useCompany)
{
NameLayoutFieldMapType nameLayoutFMap;
Char separatorStr[kMaxSeparatorStrLen];
MemHandle nameH = 0;
Char* str1;
Char* str2;
UInt16 str1Len;
UInt16 str2Len;
UInt16 separatorStrLen = 0;
if (!(useCompany && r->fields[company]) && (r->fields[firstName] || r->fields[name]))
{
if (ToolsGetDisplayNameLayout(r->fields[firstName], r->fields[name], &nameLayoutFMap))
{
str1 = r->fields[nameLayoutFMap.firstFieldNum];
str2 = r->fields[nameLayoutFMap.secondFieldNum];
ToolsGetStringResource (nameLayoutFMap.separatorStrID, separatorStr);
}
else
{
// default EFIGS way of dealing with the issue - DOLATER: change this by adding the template
// resources for all versions.
// first<space>last
str1 = r->fields[firstName];
str2 = r->fields[name];
StrCopy(separatorStr, " ");
}
}
else
{
/* using company name */
str1 = r->fields[company];
str2 = NULL;
separatorStr[0] = 0; // No separator string
}
separatorStrLen = StrLen(separatorStr);
str1Len = 0;
if (str1)
str1Len = StrLen (str1);
str2Len = 0;
if (str2)
str2Len = StrLen (str2);
if (str1Len + str2Len != 0) // We have a field to show
{
nameH = MemHandleNew (str1Len + separatorStrLen + str2Len + sizeOf7BitChar ('\0'));
if (nameH != 0)
{
Char* nameP = MemHandleLock (nameH);
if (str1Len != 0)
{
MemMove (nameP, str1, str1Len);
nameP += str1Len;
}
if (separatorStrLen)
{
MemMove (nameP, separatorStr, separatorStrLen);
nameP += separatorStrLen;
}
if (str2Len != 0)
{
MemMove (nameP, str2, str2Len);
nameP += str2Len;
}
*nameP = '\0';
MemHandleUnlock (nameH);
}
}
return (nameH);
}
/***********************************************************************
* FUNCTION: PrvTransferAlternateFieldExists
*
* DESCRIPTION: Checks if an alternate field (used when the name, firstName,
* and company fields are NULL) exists and is not NULL.
*
* PARAMETERS: recordP - pointer to the record being transferred.
*
* RETURNED: true - if we have a non NULL alternate field.
* false - false otherwise.
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vsm 01/07/03 Created.
*
***********************************************************************/
static Boolean PrvTransferAlternateFieldExists(AddrDBRecordPtr recordP)
{
Boolean retVal = false;
UInt16 fieldNum;
MemHandle resH;
// Check if there is an alternate field; ensure that it is a valid fieldNum.
resH = DmGet1Resource(constantRscType, TransferAltFieldConst);
if (resH)
{
fieldNum = (UInt16)*(UInt32 *) MemHandleLock (resH);
MemHandleUnlock (resH);
DmReleaseResource (resH);
if (fieldNum < addressFieldsCount)
{
if (recordP->fields[fieldNum])
retVal = true;
}
}
return retVal;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -