At 04:29 PM 4/15/99 -0500, you wrote:
>I realize that making the link structure variably sized complicates
matters for
>applications that store links, but I don't see any way around that.
>
Why does this need to complicate things? Let's say we define a really
simple structure:
struct LinkType
{
ULong linkSize;
ULong creatorID;
ULong dataSize;
byte data [1];
};
typedef struct LinkType* LinkPtr; // Links cannot be declared on the stack!
This structure could then either be stored in a FTR or on the clipboard.
For the purpose of this discussion, let's say we use a FTR, where creatorID
and featureNum are defined in a header with the macros lnkCreatorID and
lnkFeatureNum.
We have an application create the link (the server):
Err LnkSetLink (ULong creatorID, ULong dataSize, BytePtr data)
{
ULong linkSize = 0;
VoidHand linkH = NULL;
LinkPtr linkP = NULL;
VoidHand prevLinkH = NULL;
Err err = 0;
// Allocate and lock the link (note there is one extra byte at the end)
linkSize = sizeof (LinkType) + dataSize;
linkH = MemHandleNew (linkSize);
linkP = (LinkPtr) MemHandleLock (linkH);
// Populate the link.
MemSet (linkP, linkSize, '\0');
linkP->linkSize = linkSize;
linkP->creatorID = creatorID;
linkP->dataSize = dataSize;
MemMove (linkP->data, data, dataSize);
// Unlock the handle, and have the system adopt it:
MemHandleUnlock (linkH);
MemHandleSetOwner (linkH, 0);
// Dispose of any pre-existing link:
err = FtrGet (lnkCreatorID, lnkFeatureNum, (DWordPtr)&prevLinkH);
if (!err && NULL != prevLinkH)
{
FtrSet (lnkCreatorID, lnkFeatureNum, NULL);
MemHandleFree (prevLinkH);
}
// Store the link in the feature:
err = FtrSet (lnkCreatorID, lnkFeatureNum, linkH);
return err;
}
Then we have the application that uses the link, the client. This app
would read the link handle from the FTR and store the entire structure in
the data record:
/*
CliSaveLink:
Append the link to the end of an existing, unlocked record.
Parms:
dbR is the database to write the link into
index is the index of the record for the link
nonRecLinkSize is the non-link size of the record
Return:
0 if success
Err CliSaveLink (DmOpenRef dbR, UInt index, ULong nonLinkRecSize)
{
Err err = 0;
VoidHand linkH = NULL;
VoidHand recH = NULL;
err = FtrGet (lnkCreatorID, lnkFeatureNum, &linkH);
if (!err && NULL != linkH)
{
// Lock down the link.
LinkPtr linkP = (LinkPtr) MemHandleLock (linkH);
// Calc. new record size
ULong newSize = linkP->linkSize + nonLinkRecSize;
// Resize the target record:
VoidHand recH = DmResizeRecord (dbR, index, newSize);
// Check resize succeeded:
if (recH)
{
// Write the link to the end of the record.
VoidPtr recP = MemHandleLock (recH);
err = DmWrite (recP, nonLinkRecSize, linkP, linkP->linkSize);
MemHandleUnlock (recP);
// Release the record
DmReleaseRecord (dbR, index, true);
}
// Remove the link and associated FTR
FtrUnregister (lnkCreatorID, lnkFeatureNum);
MemHandleFree (linkH);
}
return err;
}
Then, when the client application needs to launch the server, it passes
along this same link. Here's where I think the new launch code idea would
be a good one. We could again put the link into a feature and have the
server retrieve it, then use the link information in an
application-specific way.
All this could be implemented in a shared library - which would also remove
the need for the FTR or clipboard at all.
I think the most important thing here is to keep the coupling as low as
possible - this approach provides a standard header, mostly creator id and
2 size values, while leaving the actual link data to be defined by the
application which is serving that data.
Anyhow, that's my thoughts.
Greg
Greg Winton
Bachmann Software and Services, LLC
mailto:[EMAIL PROTECTED]
http://www.bachmannsoftware.com
Software Development for Handheld & Mobile Computing, Windows and the Internet
Home of Bachmann Print Manager, the only graphical printing solution for
the Palm Computing Platform