Esempio n. 1
0
/*  fSyncFile - Attempt to make logical file and physical file the same
 *
 *  When editing in a network or multi-tasking environment, we need to make
 *  sure that changes made underneath us are properly reflected to the
 *  user.  We do this by snapshotting the time-of-last-write and periodically
 *  comparing it with the version on disk.  When a mismatch is found, we
 *  prompt the user and give him the opportunity to reread the file
 *
 *  pFileLoc    file structure of interest
 *  fPrompt     TRUE => prompt user for permission to refresh, else just
 *              refresh.
 *
 *  returns     TRUE iff the logical file and the physical file are the same.
 */
flagType
fSyncFile (
    PFILE pFileLoc,
    flagType fPrompt
    ) {
    if (pFileLoc == NULL) {
        pFileLoc = pFileHead;
    }

    switch (FileStatus (pFileLoc, NULL)) {

    case FILECHANGED:
        if (!confirmx("%s has been changed.  Refresh? ", pFileLoc->pName)) {
            /* No, validate this edit session */
            SetModTime (pFileLoc);
            return FALSE;
        }

        FileRead (strcpy( buf, pFileLoc->pName ), pFileLoc, TRUE);
        RSETFLAG (FLAGS (pFileLoc), DIRTY);
        SETFLAG (fDisplay, RSTATUS);
        return TRUE;

    case FILEDELETED:
        domessage ("File has been deleted");
        break;

    default:
        break;

    }
    return TRUE;
}
//----------------------------------------------------------------------------------------
// Init
//----------------------------------------------------------------------------------------
ErrorCode
CZPLinkResource::Init(
	IDataLink* iDataLink, const URI& uri)
{
	NameInfo	nameInfo;
	PMString	formatName;
	uint32		fileType;
	ErrorCode	errorCode = iDataLink->GetNameInfo (&nameInfo, &formatName, &fileType);

	mId = uri;

	if (errorCode == kSuccess)
	{
		uint64		storedSize = 0;
		uint64		storedTime = 0;
		IDataLink::StateType	calculatedType = IDataLink::kLinkNormal;
		IDataLink::StateType	oldStoredType = iDataLink->GetStoredState (&storedSize, &storedTime);

		uint64		modTime = 0;

		//	Check if times are consistent or close enough.
		ResourceStamp	resourceStamp;
		if (oldStoredType != IDataLink::kEmbedded)
		{
			uint64		currentSize = 0;
			uint64		currentTime = 0;
			bool16		fileExists = GetCurrentTimeAndSizeFromURI (currentTime, currentSize);

			if (fileExists)
			{
#ifdef DEBUG
				bool	hasStamp = 
#endif
					ConstructStampFromURI (resourceStamp);
				ASSERT (hasStamp);

				if (storedSize != currentSize || TimeStampsCloseEnough (storedTime, currentTime) == false)
				{
					//ASSERT (oldStoredType == IDataLink::kLinkOutOfDate);

					ConstructStampFromTimeSize (storedTime, storedSize, resourceStamp);
					modTime = storedTime;

					if (oldStoredType != IDataLink::kLinkOutOfDate)
					{
						calculatedType = IDataLink::kLinkOutOfDate;
						iDataLink->SetStoredState (nil, nil, calculatedType);
					}
				}
				else
				{
					modTime = currentTime;
				}
			}
			else
			{
				//	File does not exist.
				// the persisted type can easily be different from the current type.

				calculatedType = IDataLink::kLinkMissing;
				ConstructStampFromTimeSize (storedTime, storedSize, resourceStamp);
				modTime = storedTime;
			}
		}
		else
		{
			//	Embedded
			calculatedType = IDataLink::kEmbedded;
			ConstructStampFromTimeSize (storedTime, storedSize, resourceStamp);
			modTime = storedTime;
		}

		SetSize(storedSize);

		// the persisted type can easily be different from the current type.
		// commenting out assert. dstephens 06/06/2007
		//ASSERT (calculatedType == oldStoredType);

		ILinkResource::ResourceState	state = (oldStoredType == IDataLink::kLinkMissing) ? kMissing : kAvailable;

		//	Set attributes
		SetFormatType(formatName);
		SetModTime(modTime);
		SetStamp(resourceStamp);
		SetState(state);

		//	Embeded
		if (oldStoredType == IDataLink::kEmbedded)
		{
			InterfacePtr<ILinkObjectReference>	iOldObjectRef (iDataLink, UseDefaultIID ());
			if (iOldObjectRef != nil && iOldObjectRef->GetUID () != kInvalidUID)
			{
				InterfacePtr<IStoreInternal>	iStoreInternal (mDB, iOldObjectRef->GetUID (), IID_ISTOREINTERNAL);
				
				//	Delete old stored data
				UID		storedUID = iStoreInternal->GetStoredUID ();
				if (storedUID != kInvalidUID && mDB->IsValidUID (storedUID))
				{
					//iStoreInternal->SetStoredUID (kInvalidUID);
					mStoreState = kEmbedded;
					SetState(kAvailable);
					mStoredResourceUID = storedUID;
				}
			}
		}
	}

	return errorCode;
}