2002-07-09 12:24:59 +00:00
|
|
|
/*
|
|
|
|
|
PortLink.cpp:
|
|
|
|
|
A helper class for port-based messaging
|
|
|
|
|
|
|
|
|
|
------------------------------------------------------------------------
|
|
|
|
|
How it works:
|
|
|
|
|
The class utilizes a fixed-size array of PortLinkData object pointers. When
|
|
|
|
|
data is attached, a new PortLinkData object is allocated and a copy of the
|
|
|
|
|
passed data is created inside it. When the time comes for the message to be sent,
|
|
|
|
|
the data is pieced together into a flattened array and written to the port.
|
|
|
|
|
------------------------------------------------------------------------
|
|
|
|
|
Data members:
|
|
|
|
|
|
|
|
|
|
*attachments[] - fixed-size array of pointers used to hold the attached data
|
|
|
|
|
opcode - message value which is sent along with any data
|
|
|
|
|
target - port to which the message is sent when Flush() is called
|
|
|
|
|
replyport - port used with synchronous messaging - FlushWithReply()
|
|
|
|
|
bufferlength - total bytes taken up by attachments
|
|
|
|
|
num_attachments - internal variable which is used to track which "slot"
|
|
|
|
|
will be the next one to receive an attachment object
|
2002-09-30 22:34:20 +00:00
|
|
|
port_ok - flag to signal whether it's ok to send a message
|
|
|
|
|
capacity - contains the storage capacity of the target port.
|
2002-07-09 12:24:59 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "PortLink.h"
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <malloc.h>
|
|
|
|
|
|
2003-03-06 22:24:45 +00:00
|
|
|
//#define PLDEBUG
|
2002-11-19 00:30:49 +00:00
|
|
|
//#define PLD_DEBUG
|
|
|
|
|
|
2002-11-20 00:17:22 +00:00
|
|
|
//#define CAPACITY_CHECKING
|
|
|
|
|
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef PLD_DEBUG
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
// Internal data storage class for holding attached data whilst it is waiting
|
|
|
|
|
// to be Flattened() and then Flushed(). There is no need for this to be called outside
|
|
|
|
|
// the PortLink class.
|
|
|
|
|
class PortLinkData
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
PortLinkData(void);
|
|
|
|
|
~PortLinkData(void);
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t Set(void *data, size_t size);
|
2002-07-09 12:24:59 +00:00
|
|
|
char *buffer;
|
|
|
|
|
size_t buffersize;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PortLink::PortLink(port_id port)
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("PortLink(%lu)\n",port);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
// For this class to be useful (and to prevent a lot of init problems)
|
|
|
|
|
// we require a port in the constructor
|
|
|
|
|
target=port;
|
2002-09-30 22:34:20 +00:00
|
|
|
port_info pi;
|
|
|
|
|
port_ok=(get_port_info(target,&pi)==B_OK)?true:false;
|
|
|
|
|
capacity=pi.capacity;
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
// We start out without any data attached to the port message
|
|
|
|
|
opcode=0;
|
|
|
|
|
bufferlength=0;
|
|
|
|
|
replyport=create_port(30,"PortLink reply port");
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist=new BList(0);
|
2002-11-20 00:17:22 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tPort valid: %s\n",(port_ok)?"true":"false");
|
|
|
|
|
printf("\tReply port: %lu\n",replyport);
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
|
|
|
|
|
// TODO: initialize all attachments pointers to NULL
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PortLink::PortLink(const PortLink &link)
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("PortLink(PortLink*)\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
// The copy constructor copies everything except a PortLink's attachments. If there
|
|
|
|
|
// is some reason why someday I might need to change this behavior, I will, but
|
|
|
|
|
// for now there is no real reason I can think of.
|
|
|
|
|
target=link.target;
|
|
|
|
|
opcode=link.opcode;
|
|
|
|
|
port_ok=link.port_ok;
|
|
|
|
|
capacity=link.capacity;
|
|
|
|
|
bufferlength=0;
|
|
|
|
|
replyport=create_port(30,"PortLink reply port");
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist=new BList(0);
|
2002-11-20 00:17:22 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tOpcode: %lu\n",opcode);
|
|
|
|
|
printf("\tTarget port: %lu\n",target);
|
|
|
|
|
printf("\tCapacity: %lu\n",capacity);
|
|
|
|
|
printf("\tPort valid: %s\n",(port_ok)?"true":"false");
|
|
|
|
|
printf("\tReply port: %lu\n",replyport);
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
// TODO: initialize all attachments pointers to NULL
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PortLink::~PortLink(void)
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("~PortLink()\n");
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
// If, for some odd reason, this is deleted with something attached,
|
|
|
|
|
// free the memory used by the attachments. We do not flush the queue
|
|
|
|
|
// because the port may no longer be valid in cases such as the app
|
|
|
|
|
// is in the process of quitting
|
2003-03-06 22:24:45 +00:00
|
|
|
if(attachlist->CountItems()>0)
|
2002-11-19 00:30:49 +00:00
|
|
|
MakeEmpty();
|
2003-03-06 22:24:45 +00:00
|
|
|
|
|
|
|
|
delete attachlist;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PortLink::SetOpCode(int32 code)
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
2002-11-20 00:17:22 +00:00
|
|
|
printf("PortLink::SetOpCode(%c%c%c%c)\n",
|
|
|
|
|
(char)((code & 0xFF000000) >> 24),
|
|
|
|
|
(char)((code & 0x00FF0000) >> 16),
|
|
|
|
|
(char)((code & 0x0000FF00) >> 8),
|
|
|
|
|
(char)((code & 0x000000FF)) );
|
2002-11-19 00:30:49 +00:00
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
// Sets the message code. This does not change once the message is sent.
|
|
|
|
|
// Another call to SetOpCode() is required for such things.
|
|
|
|
|
opcode=code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PortLink::SetPort(port_id port)
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("PortLink::SetPort(%lu)\n",port);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
// Sets the target port. While not necessary in most uses, this exists
|
|
|
|
|
// mostly to prevent flexibility problems
|
|
|
|
|
target=port;
|
2002-09-30 22:34:20 +00:00
|
|
|
port_info pi;
|
|
|
|
|
port_ok=(get_port_info(target,&pi)==B_OK)?true:false;
|
|
|
|
|
capacity=pi.capacity;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
port_id PortLink::GetPort(void)
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("PortLink::GetPort() returned %lu\n",target);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
// Simply returns the port at which the object is pointed.
|
|
|
|
|
return target;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t PortLink::Flush(bigtime_t timeout=B_INFINITE_TIMEOUT)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("PortLink::Flush()\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
// Fires a message off to the target, complete with attachments.
|
2002-07-09 12:24:59 +00:00
|
|
|
int8 *msgbuffer;
|
|
|
|
|
int32 size;
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t write_stat=B_OK;
|
|
|
|
|
|
|
|
|
|
if(!port_ok)
|
2002-11-19 00:30:49 +00:00
|
|
|
{
|
|
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tFlush(): invalid port\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_BAD_VALUE;
|
2002-11-19 00:30:49 +00:00
|
|
|
}
|
2002-07-09 12:24:59 +00:00
|
|
|
|
2003-03-06 22:24:45 +00:00
|
|
|
if(attachlist->CountItems()>0)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tFlush(): flushing %d attachments\n",num_attachments);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
FlattenData(&msgbuffer,&size);
|
|
|
|
|
|
|
|
|
|
// Dump message to port, reset attachments, and clean up
|
|
|
|
|
if(timeout!=B_INFINITE_TIMEOUT)
|
2002-09-30 22:34:20 +00:00
|
|
|
write_stat=write_port_etc(target,opcode,msgbuffer,size,B_TIMEOUT, timeout);
|
2002-07-09 12:24:59 +00:00
|
|
|
else
|
2002-09-30 22:34:20 +00:00
|
|
|
write_stat=write_port(target,opcode,msgbuffer,size);
|
2002-07-09 12:24:59 +00:00
|
|
|
MakeEmpty();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tFlush(): flushing without attachments\n");
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
if(timeout!=B_INFINITE_TIMEOUT)
|
2002-09-30 22:34:20 +00:00
|
|
|
write_stat=write_port_etc(target,opcode,NULL,0,B_TIMEOUT, timeout);
|
2002-07-09 12:24:59 +00:00
|
|
|
else
|
2002-09-30 22:34:20 +00:00
|
|
|
write_stat=write_port(target,opcode,NULL,0);
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2002-09-30 22:34:20 +00:00
|
|
|
return write_stat;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
|
2002-07-09 12:24:59 +00:00
|
|
|
int8* PortLink::FlushWithReply(int32 *code, status_t *status, ssize_t *buffersize, bigtime_t timeout=B_INFINITE_TIMEOUT)
|
|
|
|
|
{
|
2002-09-30 22:34:20 +00:00
|
|
|
// Deprecated call which functions exactly like PortLink(PortLink::ReplyData *data)
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("PortLink::FlushWithReply(int32*,status_t*,ssize_t*,bigtime_t)\n");
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
if(!port_ok)
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("PortLink::FlushWithReply(): bad port\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
*status=B_BAD_VALUE;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2002-07-09 12:24:59 +00:00
|
|
|
// create a new storage object and stash the data
|
|
|
|
|
PortLinkData *pld=new PortLinkData;
|
2002-09-30 22:34:20 +00:00
|
|
|
if(pld->Set(&replyport,sizeof(port_id))==B_OK)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
|
|
|
|
bufferlength+=sizeof(port_id);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
delete pld;
|
|
|
|
|
*status=B_ERROR;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Flatten() inlined to make some necessary changes
|
|
|
|
|
int8 *buffer=new int8[bufferlength];
|
|
|
|
|
int8 *bufferindex=buffer;
|
|
|
|
|
size_t size=0;
|
|
|
|
|
|
|
|
|
|
// attach our port_id first
|
|
|
|
|
memcpy(bufferindex, pld->buffer, pld->buffersize);
|
|
|
|
|
bufferindex += pld->buffersize;
|
|
|
|
|
size+=pld->buffersize;
|
|
|
|
|
|
|
|
|
|
// attach everything else
|
2003-03-06 22:24:45 +00:00
|
|
|
for(int i=0;i<attachlist->CountItems();i++)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
pld=(PortLinkData*)attachlist->ItemAt(i);
|
2002-07-09 12:24:59 +00:00
|
|
|
memcpy(bufferindex, pld->buffer, pld->buffersize);
|
|
|
|
|
bufferindex += pld->buffersize;
|
|
|
|
|
size+=pld->buffersize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Flush the thing....FOOSH! :P
|
|
|
|
|
write_port(target,opcode,buffer,size);
|
|
|
|
|
MakeEmpty();
|
|
|
|
|
delete buffer;
|
|
|
|
|
|
|
|
|
|
// Now we wait for the reply
|
2002-11-20 00:17:22 +00:00
|
|
|
buffer=NULL;
|
2002-07-09 12:24:59 +00:00
|
|
|
if(timeout==B_INFINITE_TIMEOUT)
|
|
|
|
|
{
|
|
|
|
|
*buffersize=port_buffer_size(replyport);
|
|
|
|
|
if(*buffersize>0)
|
|
|
|
|
buffer=(int8*)new int8[*buffersize];
|
|
|
|
|
read_port(replyport,code, buffer, *buffersize);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*buffersize=port_buffer_size_etc(replyport,0,timeout);
|
|
|
|
|
if(*buffersize==B_TIMED_OUT)
|
|
|
|
|
{
|
|
|
|
|
*status=*buffersize;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if(*buffersize>0)
|
|
|
|
|
buffer=(int8*)new int8[*buffersize];
|
|
|
|
|
read_port(replyport,code, buffer, *buffersize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We got this far, so we apparently have some data
|
|
|
|
|
*status=B_OK;
|
|
|
|
|
return buffer;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
|
|
|
|
|
status_t PortLink::FlushWithReply(PortLink::ReplyData *data,bigtime_t timeout=B_INFINITE_TIMEOUT)
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("PortLink::FlushWithReply(ReplyData*,bigtime_t)\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
// Fires a message to the target and then waits for a reply. The target will
|
|
|
|
|
// receive a message with the first item being the port_id to reply to.
|
|
|
|
|
// NOTE: like Flush(), any attached data must be deleted.
|
|
|
|
|
|
|
|
|
|
// Effectively, an Attach() call inlined for changes
|
|
|
|
|
|
|
|
|
|
if(!port_ok)
|
2002-11-19 00:30:49 +00:00
|
|
|
{
|
|
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tFlushWithReply(): invalid port\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_BAD_VALUE;
|
2002-11-19 00:30:49 +00:00
|
|
|
}
|
2002-09-30 22:34:20 +00:00
|
|
|
|
|
|
|
|
// create a new storage object and stash the data
|
|
|
|
|
PortLinkData *pld=new PortLinkData;
|
2002-11-19 00:30:49 +00:00
|
|
|
if(pld->Set(&replyport,sizeof(port_id))==B_OK)
|
2002-09-30 22:34:20 +00:00
|
|
|
{
|
|
|
|
|
bufferlength+=sizeof(port_id);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tFlushWithReply(): unable to assign reply port to data\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
delete pld;
|
|
|
|
|
return B_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Flatten() inlined to make some necessary changes
|
|
|
|
|
int8 *buffer=new int8[bufferlength];
|
|
|
|
|
int8 *bufferindex=buffer;
|
|
|
|
|
size_t size=0;
|
|
|
|
|
|
|
|
|
|
// attach our port_id first
|
|
|
|
|
memcpy(bufferindex, pld->buffer, pld->buffersize);
|
|
|
|
|
bufferindex += pld->buffersize;
|
|
|
|
|
size+=pld->buffersize;
|
|
|
|
|
|
|
|
|
|
// attach everything else
|
2003-03-06 22:24:45 +00:00
|
|
|
for(int i=0;i<attachlist->CountItems();i++)
|
2002-09-30 22:34:20 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
pld=(PortLinkData*)attachlist->ItemAt(i);
|
2002-09-30 22:34:20 +00:00
|
|
|
memcpy(bufferindex, pld->buffer, pld->buffersize);
|
|
|
|
|
bufferindex += pld->buffersize;
|
|
|
|
|
size+=pld->buffersize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Flush the thing....FOOSH! :P
|
|
|
|
|
write_port(target,opcode,buffer,size);
|
|
|
|
|
MakeEmpty();
|
|
|
|
|
delete buffer;
|
|
|
|
|
|
|
|
|
|
// Now we wait for the reply
|
|
|
|
|
if(timeout==B_INFINITE_TIMEOUT)
|
|
|
|
|
{
|
|
|
|
|
data->buffersize=port_buffer_size(replyport);
|
|
|
|
|
if(data->buffersize>0)
|
2003-03-12 18:01:55 +00:00
|
|
|
{
|
|
|
|
|
if(data->buffer)
|
|
|
|
|
delete data->buffer;
|
2002-09-30 22:34:20 +00:00
|
|
|
data->buffer=(int8*)new int8[data->buffersize];
|
2003-03-12 18:01:55 +00:00
|
|
|
}
|
2002-11-19 00:30:49 +00:00
|
|
|
read_port(replyport,&(data->code),data->buffer, data->buffersize);
|
2002-09-30 22:34:20 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
data->buffersize=port_buffer_size_etc(replyport,0,timeout);
|
|
|
|
|
if(data->buffersize==B_TIMED_OUT)
|
|
|
|
|
return B_TIMED_OUT;
|
|
|
|
|
|
|
|
|
|
if(data->buffersize>0)
|
2003-03-12 18:01:55 +00:00
|
|
|
{
|
2002-09-30 22:34:20 +00:00
|
|
|
data->buffer=(int8*)new int8[data->buffersize];
|
2003-03-12 18:01:55 +00:00
|
|
|
}
|
2002-11-19 00:30:49 +00:00
|
|
|
read_port(replyport,&(data->code),data->buffer, data->buffersize);
|
2002-09-30 22:34:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We got this far, so we apparently have some data
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status_t PortLink::Attach(void *data, size_t size)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("Attach(%p,%ld)\n",data,size);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
// This is the member called to attach data to a message. Attachments are
|
|
|
|
|
// treated to be in 'Append' mode, tacking on each attached piece of data
|
|
|
|
|
// to the end of the list.
|
|
|
|
|
|
|
|
|
|
// Prevent parameter problems
|
|
|
|
|
if(size==0)
|
2002-11-19 00:30:49 +00:00
|
|
|
{
|
|
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tAttach(): size invalid -> size=0\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_ERROR;
|
2002-11-19 00:30:49 +00:00
|
|
|
}
|
2002-09-30 22:34:20 +00:00
|
|
|
|
2002-11-20 00:17:22 +00:00
|
|
|
#ifdef CAPACITY_CHECKING
|
2002-09-30 22:34:20 +00:00
|
|
|
if(bufferlength+size>capacity)
|
2002-11-19 00:30:49 +00:00
|
|
|
{
|
|
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tAttach(): bufferlength+size > port capacity\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_NO_MEMORY;
|
2002-11-19 00:30:49 +00:00
|
|
|
}
|
2002-11-20 00:17:22 +00:00
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
// create a new storage object and stash the data
|
|
|
|
|
PortLinkData *pld=new PortLinkData;
|
2002-11-19 00:30:49 +00:00
|
|
|
if(pld->Set(data,size)==B_OK)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist->AddItem(pld);
|
2002-07-09 12:24:59 +00:00
|
|
|
bufferlength+=size;
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tAttach(): successful\n");
|
|
|
|
|
printf("\t\tAttach(): attachments now %u\n", num_attachments);
|
|
|
|
|
printf("\t\tAttach(): buffer length is %lu\n", bufferlength);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("\tAttach(): Couldn't assign data to PortLinkData object\n");
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
delete pld;
|
2003-03-06 22:24:45 +00:00
|
|
|
return B_ERROR;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2002-11-19 00:30:49 +00:00
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_OK;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// These functions were added for a major convenience in passing common types
|
|
|
|
|
// Eventually, I'd like to templatize these, but for now, this'll do
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t PortLink::Attach(int32 data)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("Attach(%ld)\n",data);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
int32 size=sizeof(int32);
|
2002-09-30 22:34:20 +00:00
|
|
|
|
2002-11-20 00:17:22 +00:00
|
|
|
#ifdef CAPACITY_CHECKING
|
2002-09-30 22:34:20 +00:00
|
|
|
if(bufferlength+size>capacity)
|
|
|
|
|
return B_NO_MEMORY;
|
2002-11-20 00:17:22 +00:00
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
// create a new storage object and stash the data
|
|
|
|
|
PortLinkData *pld=new PortLinkData;
|
2002-11-20 00:17:22 +00:00
|
|
|
if(pld->Set(&data,size)==B_OK)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist->AddItem(pld);
|
2002-07-09 12:24:59 +00:00
|
|
|
bufferlength+=size;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
delete pld;
|
2003-03-06 22:24:45 +00:00
|
|
|
return B_ERROR;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_OK;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t PortLink::Attach(int16 data)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("Attach(%d)\n",data);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
int32 size=sizeof(int16);
|
2002-09-30 22:34:20 +00:00
|
|
|
|
2002-11-20 00:17:22 +00:00
|
|
|
#ifdef CAPACITY_CHECKING
|
2002-09-30 22:34:20 +00:00
|
|
|
if(bufferlength+size>capacity)
|
|
|
|
|
return B_NO_MEMORY;
|
2002-11-20 00:17:22 +00:00
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
// create a new storage object and stash the data
|
|
|
|
|
PortLinkData *pld=new PortLinkData;
|
2002-11-20 00:17:22 +00:00
|
|
|
if(pld->Set(&data,size)==B_OK)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist->AddItem(pld);
|
2002-07-09 12:24:59 +00:00
|
|
|
bufferlength+=size;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
delete pld;
|
2003-03-06 22:24:45 +00:00
|
|
|
return B_ERROR;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_OK;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t PortLink::Attach(int8 data)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("Attach(%d)\n",data);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
int32 size=sizeof(int8);
|
2002-09-30 22:34:20 +00:00
|
|
|
|
2002-11-20 00:17:22 +00:00
|
|
|
#ifdef CAPACITY_CHECKING
|
2002-09-30 22:34:20 +00:00
|
|
|
if(bufferlength+size>capacity)
|
|
|
|
|
return B_NO_MEMORY;
|
2002-11-20 00:17:22 +00:00
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
// create a new storage object and stash the data
|
|
|
|
|
PortLinkData *pld=new PortLinkData;
|
2002-11-20 00:17:22 +00:00
|
|
|
if(pld->Set(&data,size)==B_OK)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist->AddItem(pld);
|
2002-07-09 12:24:59 +00:00
|
|
|
bufferlength+=size;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
delete pld;
|
2003-03-06 22:24:45 +00:00
|
|
|
return B_ERROR;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_OK;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t PortLink::Attach(float data)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("Attach(%f)\n",data);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
int32 size=sizeof(float);
|
2002-09-30 22:34:20 +00:00
|
|
|
|
2002-11-20 00:17:22 +00:00
|
|
|
#ifdef CAPACITY_CHECKING
|
2002-09-30 22:34:20 +00:00
|
|
|
if(bufferlength+size>capacity)
|
|
|
|
|
return B_NO_MEMORY;
|
2002-11-20 00:17:22 +00:00
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
// create a new storage object and stash the data
|
|
|
|
|
PortLinkData *pld=new PortLinkData;
|
2002-11-20 00:17:22 +00:00
|
|
|
if(pld->Set(&data,size)==B_OK)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist->AddItem(pld);
|
2002-07-09 12:24:59 +00:00
|
|
|
bufferlength+=size;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
delete pld;
|
2003-03-06 22:24:45 +00:00
|
|
|
return B_ERROR;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_OK;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t PortLink::Attach(bool data)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("Attach(%s)\n",(data)?"true":"false");
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
int32 size=sizeof(bool);
|
2002-09-30 22:34:20 +00:00
|
|
|
|
2002-11-20 00:17:22 +00:00
|
|
|
#ifdef CAPACITY_CHECKING
|
2002-09-30 22:34:20 +00:00
|
|
|
if(bufferlength+size>capacity)
|
|
|
|
|
return B_NO_MEMORY;
|
2002-11-20 00:17:22 +00:00
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
// create a new storage object and stash the data
|
|
|
|
|
PortLinkData *pld=new PortLinkData;
|
2002-11-20 00:17:22 +00:00
|
|
|
if(pld->Set(&data,size)==B_OK)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist->AddItem(pld);
|
2002-07-09 12:24:59 +00:00
|
|
|
bufferlength+=size;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
delete pld;
|
2003-03-06 22:24:45 +00:00
|
|
|
return B_ERROR;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_OK;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t PortLink::Attach(BRect data)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("Attach(BRect(%f,%f,%f,%f))\n",data.left,data.top,data.right,data.bottom);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
int32 size=sizeof(BRect);
|
2002-09-30 22:34:20 +00:00
|
|
|
|
2002-11-20 00:17:22 +00:00
|
|
|
#ifdef CAPACITY_CHECKING
|
2002-09-30 22:34:20 +00:00
|
|
|
if(bufferlength+size>capacity)
|
|
|
|
|
return B_NO_MEMORY;
|
2002-11-20 00:17:22 +00:00
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
// create a new storage object and stash the data
|
|
|
|
|
PortLinkData *pld=new PortLinkData;
|
2002-11-20 00:17:22 +00:00
|
|
|
if(pld->Set(&data,size)==B_OK)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist->AddItem(pld);
|
2002-07-09 12:24:59 +00:00
|
|
|
bufferlength+=size;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
delete pld;
|
2003-03-06 22:24:45 +00:00
|
|
|
return B_ERROR;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_OK;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t PortLink::Attach(BPoint data)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("Attach(BPoint(%f,%f))\n",data.x,data.y);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
int32 size=sizeof(BPoint);
|
2002-09-30 22:34:20 +00:00
|
|
|
|
2002-11-20 00:17:22 +00:00
|
|
|
#ifdef CAPACITY_CHECKING
|
2002-09-30 22:34:20 +00:00
|
|
|
if(bufferlength+size>capacity)
|
|
|
|
|
return B_NO_MEMORY;
|
2002-11-20 00:17:22 +00:00
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
// create a new storage object and stash the data
|
|
|
|
|
PortLinkData *pld=new PortLinkData;
|
2002-11-20 00:17:22 +00:00
|
|
|
if(pld->Set(&data,size)==B_OK)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist->AddItem(pld);
|
2002-07-09 12:24:59 +00:00
|
|
|
bufferlength+=size;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
delete pld;
|
2003-03-06 22:24:45 +00:00
|
|
|
return B_ERROR;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_OK;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PortLink::FlattenData(int8 **buffer,int32 *size)
|
|
|
|
|
{
|
|
|
|
|
// This function is where all the magic happens, but it is strictly internal.
|
|
|
|
|
// It iterates through each PortLinkData object and copies it to the main buffer
|
|
|
|
|
// which ends up, ultimately, being written to the PortLink's target port.
|
|
|
|
|
|
|
|
|
|
// skip if there aree no attachments
|
|
|
|
|
if(bufferlength<1)
|
2002-11-19 00:30:49 +00:00
|
|
|
{
|
|
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("PortLink::FlattenData: bufferlength<1\n");
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
return;
|
2002-11-19 00:30:49 +00:00
|
|
|
}
|
2002-07-09 12:24:59 +00:00
|
|
|
|
|
|
|
|
*buffer=new int8[bufferlength];
|
|
|
|
|
int8 *bufferindex=*buffer;
|
|
|
|
|
PortLinkData *pld;
|
|
|
|
|
*size=0;
|
|
|
|
|
|
2003-03-06 22:24:45 +00:00
|
|
|
int32 count=attachlist->CountItems();
|
|
|
|
|
for(int i=0;i<count;i++)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
pld=(PortLinkData*)attachlist->ItemAt(i);
|
2002-07-09 12:24:59 +00:00
|
|
|
memcpy(bufferindex, pld->buffer, pld->buffersize);
|
|
|
|
|
bufferindex += pld->buffersize;
|
|
|
|
|
*size+=pld->buffersize;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PortLink::MakeEmpty(void)
|
|
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLDEBUG
|
|
|
|
|
printf("PortLink::MakeEmpty\n");
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
// Nukes all the attachments currently held by the PortLink class
|
2003-03-06 22:24:45 +00:00
|
|
|
PortLinkData *pld;
|
|
|
|
|
int32 count=attachlist->CountItems();
|
|
|
|
|
for(int32 i=0; i<count; i++)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2003-03-06 22:24:45 +00:00
|
|
|
pld=(PortLinkData*)attachlist->ItemAt(i);
|
|
|
|
|
if(pld)
|
|
|
|
|
delete pld;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2003-03-06 22:24:45 +00:00
|
|
|
attachlist->MakeEmpty();
|
2002-07-09 12:24:59 +00:00
|
|
|
bufferlength=0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PortLinkData::PortLinkData(void)
|
|
|
|
|
{
|
|
|
|
|
// Initialize object to empty
|
|
|
|
|
buffersize=0;
|
2002-09-30 22:34:20 +00:00
|
|
|
buffer=NULL;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PortLinkData::~PortLinkData(void)
|
|
|
|
|
{
|
|
|
|
|
// Frees the buffer if we actually used the class to store data
|
2002-09-30 22:34:20 +00:00
|
|
|
if(buffersize>0 && buffer!=NULL)
|
2002-07-09 12:24:59 +00:00
|
|
|
free(buffer);
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
status_t PortLinkData::Set(void *data, size_t size)
|
2002-07-09 12:24:59 +00:00
|
|
|
{
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLD_DEBUG
|
|
|
|
|
printf("PortLinkData::Set(%p,%lu)\n",data,size);
|
|
|
|
|
#endif
|
2002-07-09 12:24:59 +00:00
|
|
|
// Function copies the passed to the internal buffers for storage
|
|
|
|
|
if(size>0 && buffersize==0 && data!=NULL)
|
|
|
|
|
{
|
|
|
|
|
buffer=(char *)malloc(size);
|
2002-11-19 00:30:49 +00:00
|
|
|
if(!buffer)
|
|
|
|
|
{
|
|
|
|
|
#ifdef PLD_DEBUG
|
|
|
|
|
printf("\tSet(): Couldn't allocate buffer\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_NO_MEMORY;
|
2002-11-19 00:30:49 +00:00
|
|
|
}
|
2002-07-09 12:24:59 +00:00
|
|
|
memcpy(buffer, data, size);
|
|
|
|
|
buffersize=size;
|
2002-11-19 00:30:49 +00:00
|
|
|
#ifdef PLD_DEBUG
|
|
|
|
|
printf("\tSet(): SUCCESS\n");
|
|
|
|
|
#endif
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_OK;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|
2002-11-19 00:30:49 +00:00
|
|
|
|
|
|
|
|
#ifdef PLD_DEBUG
|
|
|
|
|
if(size==0)
|
|
|
|
|
printf("\tSet(): given an invalid size\n");
|
|
|
|
|
if(buffersize>0)
|
|
|
|
|
printf("\tSet(): buffersize is nonzero\n");
|
|
|
|
|
if(buffersize>0)
|
|
|
|
|
printf("\tSet(): data is NULL\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-09-30 22:34:20 +00:00
|
|
|
return B_ERROR;
|
2002-07-09 12:24:59 +00:00
|
|
|
}
|