⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 todotransfer.c

📁 我的Palm OS 5 SDK zhCN_PIMApps代码。 使用codewarrior 开发环境
💻 C
📖 第 1 页 / 共 3 页
字号:
        if (!error)
        {
        	if (media)
	            error = ToDoSendRecordTryCatch(dbP, recordNum, recordP, media);
	        else
	        	error = exgMemError;
	        	
            // Release the record before the database is sorted in loopback mode.
            if (recordH)
            {
                MemHandleUnlock(recordH);
                DmReleaseRecord(dbP, recordNum, false);
                recordH = NULL;
            }

            ExgDisconnect(&exgSocket, error);
        }
        
        if (media)
	        UDADelete(media);
 
	    // Clean up
	    if (descriptionH)
	        MemHandleFree(descriptionH);
	    if (nameH)
	        MemHandleFree(nameH);
   }
    else
        FrmAlert(noDataAlertID);

    if (recordH)
    {
        MemHandleUnlock(recordH);
        DmReleaseRecord(dbP, recordNum, false);
    }

    return;
}


/***********************************************************************
 *
 * FUNCTION:    ToDoSendCategoryTryCatch
 *
 * 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 ToDoSendCategoryTryCatch (DmOpenRef dbP, UInt16 categoryNum,
    UDAWriterType*  media, UInt16 recordNum)
{
    volatile Err error = 0;
    volatile MemHandle outRecordH = 0;
    ToDoDBRecordPtr outRecordP;

    UInt16 pdiRefNum;
    PdiWriterType* writer;
    Boolean loaded;

    if ((error = PrvPdiLibLoad(&pdiRefNum, &loaded)))
        return error;

    writer = PdiWriterNew(pdiRefNum, media, kPdiPalmCompatibility);
    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
        {
		    PdiWriteBeginObject(pdiRefNum, writer, kPdiPRN_BEGIN_VCALENDAR);
		    PdiWriteProperty(pdiRefNum, writer, kPdiPRN_VERSION);
		    PdiWritePropertyValue(pdiRefNum, writer, (Char*)"1.0", kPdiWriteData);
            // Loop through all records in the category.
	        while (DmSeekRecordInCategory(dbP, &recordNum, 0, dmSeekForward, categoryNum) == 0)
	        {
	            // Emit the record.  If the record is private do not emit it.
	            outRecordH = (MemHandle) DmQueryRecord(dbP, recordNum);
	
	            if (outRecordH != 0)
	            {
	                outRecordP = (ToDoDBRecordPtr) MemHandleLock(outRecordH);
	
	                ToDoExportVCal(dbP, recordNum, outRecordP, pdiRefNum, writer, true);
	
	                MemHandleUnlock(outRecordH);
	            }
	
	            recordNum++;
	        }
		    PdiWriteEndObject(pdiRefNum, writer, kPdiPRN_END_VCALENDAR);
			error = UDAWriterFlush(media);
        }

        ErrCatch(inErr)
        {
            error = inErr;
            if (outRecordH)
                MemHandleUnlock(outRecordH);
        } ErrEndCatch

        PdiWriterDelete(pdiRefNum, &writer);
    }
    else
    {
    	error = exgMemError;
    }
	PrvPdiLibUnload(pdiRefNum, loaded);

    return error;
}


/***********************************************************************
 *
 * FUNCTION:    ToDoSendCategory
 *
 * DESCRIPTION: Send all visible records in a category.
 *
 * PARAMETERS:  dbP - pointer to the database
 * 				categoryNum - the category of records to send
 *				prefix - the scheme with ":" suffix and optional "?" prefix
 *				noDataAlertID - alert to put up if there is nothing to send
 *
 * RETURNED:    true if any records are found and sent
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         roger   5/9/97   Initial Revision
 *
 ***********************************************************************/
extern void ToDoSendCategory (DmOpenRef dbP, UInt16 categoryNum, const Char * const prefix, UInt16 noDataAlertID)
{
    Err error;
    Char description[dmCategoryLength];
    UInt16 recordNum;
    Boolean foundAtLeastOneRecord;
    ExgSocketType exgSocket;
    UInt16 mode;
    LocalID dbID;
    UInt16 cardNo;
    Boolean databaseReopened;
    UDAWriterType* media;

    // If the database was opened to show secret records, reopen it to not see
    // secret records.  The idea is that secret records are not sent when a
    // category is sent.  They must be explicitly sent one by one.
    DmOpenDatabaseInfo(dbP, &dbID, NULL, &mode, &cardNo, NULL);
    if (mode & dmModeShowSecret)
    {
        dbP = DmOpenDatabase(cardNo, dbID, dmModeReadOnly);
        databaseReopened = true;
    }
    else
        databaseReopened = false;


    // important to init structure to zeros...
    MemSet(&exgSocket, sizeof(exgSocket), 0);


    // Make sure there is at least one record in the category.
    recordNum = 0;
    foundAtLeastOneRecord = false;
    while (true)
    {
        if (DmSeekRecordInCategory(dbP, &recordNum, 0, dmSeekForward, categoryNum) != 0)
            break;

        foundAtLeastOneRecord = DmQueryRecord(dbP, recordNum) != 0;
        if (foundAtLeastOneRecord)
            break;


        recordNum++;
    }

    // DOLATER ??? -蔠eird edge case: if the only record in the category is an empty record,
    // there will still be nothing to beam.  Result seems to be getting an empty
    // record at the other end, which immediately goes away.  Good enough!

    // We should send the category because there's at least one record to send.
    if (foundAtLeastOneRecord)
    {
        // Form a description of what's being sent.  This will be displayed
        // by the system send dialog on the sending and receiving devices.
        CategoryGetName (dbP, categoryNum, description);
        exgSocket.description = description;

        // Now form a file name
        exgSocket.name = MemPtrNew(StrLen(prefix) + StrLen(description) + StrLen(todoSuffix) + sizeOf7BitChar('\0'));
        if (exgSocket.name)
        {
			StrCopy(exgSocket.name, prefix);
            StrCat(exgSocket.name, description);
            StrCat(exgSocket.name, todoSuffix);
        }


		//ABa: remove superfluous '.' characters
		PrvTransferCleanFileName(exgSocket.name);

        exgSocket.length = 0;		// rough guess
        // Note, a hack in exgmgr will remap this to datebook
        // NOTE: ABa To test that the DateBook sublaunches the ToDo app
        // when parsing VTODO, just comment out the next line
        // And do the same in ToDoSendRecord
        exgSocket.target = sysFileCToDo;	// include target since todo and date book share an extension
        exgSocket.type = (Char *)todoMIMEType;
        error = ExgPut(&exgSocket);   // put data to destination

        media = UDAExchangeWriterNew(&exgSocket, 512);
        if (!error)
        {
        	if (media)
	            error = ToDoSendCategoryTryCatch (dbP, categoryNum, media, recordNum);
	        else
	        	error = exgMemError;
            ExgDisconnect(&exgSocket, error);
        }

        // Release file name
        if (exgSocket.name)
            MemPtrFree(exgSocket.name);

		if (media)
	        UDADelete(media);
    }
    else
        FrmAlert(noDataAlertID);

    if (databaseReopened)
        DmCloseDatabase(dbP);

    return;
}


/************************************************************
 *
 * FUNCTION: ToDoImportVEvent
 *
 * DESCRIPTION: Import a VCal record of type vEvent.
 *
 * This function doesn't exist on the device because
 * the Datebook imports vEvent records.  On the emulator
 * this function exists for linking completeness.
 *
 * PARAMETERS:
 *			dbP - pointer to the database to add the record to
 *			inputStream	- pointer to where to import the record from
 *			inputFunc - function to get input from the stream
 *			obeyUniqueIDs - true to obey any unique ids if possible
 *			beginAlreadyRead - whether the begin statement has been read
 *
 * RETURNS: true if the input was read
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			roger	9/12/97		Created
 *
 *************************************************************/

static Boolean ToDoImportVEvent(DmOpenRef UNUSED_PARAM(dbP), UInt16 UNUSED_PARAM(pdiRefNum), PdiReaderType* UNUSED_PARAM(reader), 
	Boolean UNUSED_PARAM(obeyUniqueIDs), Boolean UNUSED_PARAM(beginAlreadyRead), UInt32 * UNUSED_PARAM(uniqueIDP))
{
	return false;
}

/***********************************************************************
 *
 * FUNCTION:		ToDoSetGoToParams
 *
 * 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
 *			ABa	08/18/00 	make it public for use in ToDo.c
 *
 ***********************************************************************/
extern void ToDoSetGoToParams (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 = sysFileCToDo;
        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:		ReceiveData
 *
 * DESCRIPTION:	Receives data into the output field using the Exg API
 *
 * PARAMETERS:		exgSocketP, socket from the app code
 *						 sysAppLaunchCmdExgReceiveData
 *
 * RETURNED:		error code or zero for no error.
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			???	???		Created
 *			art	10/17/97	Added "go to" record logic
 *			bhall	09/27/99	Now always read until no more data
 *								(previously datebook called us once per event)
 *
 ***********************************************************************/
extern Err ToDoReceiveData(DmOpenRef dbP, ExgSocketPtr exgSocketP)
{
    volatile Err err = 0;
    UInt16 pdiRefNum = sysInvalidRefNum;
    PdiReaderType* reader;
    UDAReaderType* stream;
    Boolean loaded;

    // accept will open a progress dialog and wait for your receive commands
    if ((err = ExgAccept(exgSocketP)) != 0)
    	return err;

    if ((err = PrvPdiLibLoad(&pdiRefNum, &loaded)))
	{
		pdiRefNum = sysInvalidRefNum;
		goto errorDisconnect;
	}	
        
    if ((stream = UDAExchangeReaderNew(exgSocketP)) == NULL)
	{
		err = exgMemError;
		goto errorDisconnect;
	}	

    if ((reader = PdiReaderNew(pdiRefNum, stream, kPdiOpenParser)) == NULL)
	{
		err = exgMemError;
		goto errorDisconnect;
	}	

    reader->appData = exgSocketP;
    
    // Catch errors receiving records.  The import routine will clean up the
    // incomplete record.  This routine passes the error to ExgDisconnect
    // which displays appropriate ui.

    ErrTry
    {
    
        // Keep importing records until it can't
        while(ToDoImportVCal(dbP, pdiRefNum, reader, false, false, ToDoImportVEvent)){};
    }
    ErrCatch(inErr)
    {
        err = inErr;
    } ErrEndCatch

	// Aba: A record has been added in the Database iff the GoTo
	// uniqueID parameter != 0.
	// In the case no record is added, return an error
	if (err == errNone && exgSocketP->goToParams.uniqueID == 0)
		err = exgErrBadData;

errorDisconnect:
	if (reader)
		PdiReaderDelete(pdiRefNum, &reader);

	if (stream)
		UDADelete(stream);
	
	if (pdiRefNum != sysInvalidRefNum)
		PrvPdiLibUnload(pdiRefNum, loaded);
		
	ExgDisconnect(exgSocketP, err); // closes transfer dialog
	err = errNone;	// error was reported, so don't return it

    return err;
}


/************************************************************
 *
 * FUNCTION: ToDoImportVToDo
 *
 * DESCRIPTION: Import a VCal record of type vToDo
 *
 * PARAMETERS:
 *			dbP - pointer to the database to add the record to
 *			inputStream	- pointer to where to import the record from
 *			inputFunc - function to get input from the stream
 *			obeyUniqueIDs - true to obey any unique ids if possible
 *			beginAlreadyRead - whether the begin statement has been read
 *			uniqueIDP - (returned) id of record inserted.
 *
 * RETURNS: true if the input was read
 *
 *	REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			djk	8/9/97	Created
 *			art	10/17/97	Added parameter to return unique id
 *
 *************************************************************/

extern Boolean ToDoImportVToDo(DmOpenRef dbP, UInt16 pdiRefNum, PdiReaderType* reader, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -