xref: /haiku/src/kits/app/PortLink.cpp (revision 01b25646004ff628ecad0281a9795e5e90f71746)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		PortLink.cpp
23 //	Author:			DarkWyrm <bpmagic@columbus.rr.com>
24 //	Description:	Class for low-overhead port-based messaging
25 //
26 //------------------------------------------------------------------------------
27 #include <ServerProtocol.h>
28 #include "PortLink.h"
29 #include "PortMessage.h"
30 
31 PortLink::PortLink(port_id port)
32 {
33 	port_info pi;
34 	port_ok	= (get_port_info(port, &pi)==B_OK)? true: false;
35 
36 	fSendPort=port;
37 	fReceivePort=create_port(30,"PortLink reply port");
38 
39 	fSendCode=0;
40 	fSendBuffer=new char[4096];
41 	fSendPosition=8;
42 	fDataSize=(int32*)(fSendBuffer+sizeof(int32));
43 	*fDataSize=0;
44 }
45 
46 PortLink::PortLink( const PortLink &link )
47 {
48 	port_ok=link.port_ok;
49 
50 	fSendPort=link.fSendPort;
51 	fReceivePort=create_port(30,"PortLink reply port");
52 
53 	fSendCode			= 0;
54 	fSendBuffer=new char[4096];
55 	fSendPosition		= 8;
56 	fDataSize=(int32*)(fSendBuffer+sizeof(int32));
57 	*fDataSize=0;
58 }
59 
60 PortLink::~PortLink(void)
61 {
62 	delete [] fSendBuffer;
63 }
64 
65 void PortLink::SetOpCode( int32 code )
66 {
67 	fSendCode=code;
68 	int32 *cast=(int32*)fSendBuffer;
69 	*cast=code;
70 }
71 
72 void PortLink::SetPort( port_id port )
73 {
74 	port_info pi;
75 
76 	fSendPort=port;
77 	port_ok=(get_port_info(port, &pi) == B_OK)? true: false;
78 }
79 
80 port_id PortLink::GetPort()
81 {
82 	return fSendPort;
83 }
84 
85 status_t PortLink::Flush(bigtime_t timeout)
86 {
87 	status_t	write_stat;
88 
89 	if(!port_ok)
90 		return B_BAD_VALUE;
91 
92 	if(timeout!=B_INFINITE_TIMEOUT)
93 		write_stat=write_port_etc(fSendPort, AS_SERVER_PORTLINK, fSendBuffer,
94 									fSendPosition, B_TIMEOUT, timeout);
95 	else
96 		write_stat=write_port(fSendPort, AS_SERVER_PORTLINK, fSendBuffer, fSendPosition);
97 
98 	fSendPosition=8;
99 	*fDataSize=0;
100 
101 	return write_stat;
102 }
103 
104 status_t PortLink::FlushWithReply( PortMessage *msg,bigtime_t timeout )
105 {
106 	if(!port_ok || !msg)
107 		return B_BAD_VALUE;
108 
109 	// attach our reply port_id at the end
110 	Attach<int32>(fReceivePort);
111 
112 	// Flush the thing....FOOSH! :P
113 	write_port(fSendPort, AS_SERVER_PORTLINK, fSendBuffer, fSendPosition);
114 	fSendPosition	= 8;
115 	*fDataSize=0;
116 
117 	// Now we wait for the reply
118 	msg->ReadFromPort(fReceivePort,timeout);
119 
120 	return B_OK;
121 }
122 
123 status_t PortLink::Attach(const void *data, size_t size)
124 {
125 	if (size <= 0)
126 		return B_ERROR;
127 
128 	if (4096 - fSendPosition > (int32)size)
129 	{
130 		memcpy(fSendBuffer + fSendPosition, data, size);
131 		fSendPosition += size;
132 		*fDataSize+=size;
133 		return B_OK;
134 	}
135 	return B_NO_MEMORY;
136 }
137 
138 status_t PortLink::AttachString(const char *string)
139 {
140 	int16 len = (int16)strlen(string)+1;
141 
142 	Attach<int16>(len);
143 	return Attach(string, len);
144 }
145 
146 void PortLink::MakeEmpty()
147 {
148 	fSendPosition=8;
149 	*fDataSize=0;
150 }
151 
152