xref: /haiku/src/kits/app/PortLink.cpp (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
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 <stdlib.h>
28 
29 #include <ServerProtocol.h>
30 #include "PortLink.h"
31 #include "PortMessage.h"
32 #include "Session.h"
33 
34 PortLink::PortLink(port_id port)
35 {
36 	port_info pi;
37 	port_ok			= (get_port_info(port, &pi)==B_OK)? true: false;
38 
39 	fSendPort		= port;
40 	fReceivePort	= create_port(30,"PortLink reply port");
41 
42 	fSendCode		= 0;
43 	fSendBuffer		= (char*)malloc(4096);//new char[4096];
44 	fSendPosition	= 8;
45 	fDataSize		= (int32*)(fSendBuffer+sizeof(int32));
46 	*fDataSize		= 0;
47 }
48 
49 PortLink::PortLink( const PortLink &link )
50 {
51 	port_ok			= link.port_ok;
52 
53 	fSendPort		= link.fSendPort;
54 	fReceivePort	= create_port(30,"PortLink reply port");
55 
56 	fSendCode		= 0;
57 	fSendBuffer		= (char*)malloc(4096);//new char[4096];
58 	fSendPosition	= 8;
59 	fDataSize		= (int32*)(fSendBuffer+sizeof(int32));
60 	*fDataSize		= 0;
61 }
62 
63 PortLink::~PortLink(void)
64 {
65 	free(fSendBuffer);//delete [] fSendBuffer;
66 }
67 
68 void PortLink::SetOpCode( int32 code )
69 {
70 	fSendCode=code;
71 	int32 *cast=(int32*)fSendBuffer;
72 	*cast=code;
73 }
74 
75 void PortLink::SetPort( port_id port )
76 {
77 	port_info pi;
78 
79 	fSendPort=port;
80 	port_ok=(get_port_info(port, &pi) == B_OK)? true: false;
81 }
82 
83 port_id PortLink::GetPort()
84 {
85 	return fSendPort;
86 }
87 
88 status_t PortLink::Flush(bigtime_t timeout)
89 {
90 	status_t	write_stat;
91 
92 	if(!port_ok)
93 		return B_BAD_VALUE;
94 
95 	if(timeout!=B_INFINITE_TIMEOUT)
96 		write_stat=write_port_etc(fSendPort, AS_SERVER_PORTLINK, fSendBuffer,
97 									fSendPosition, B_TIMEOUT, timeout);
98 	else
99 		write_stat=write_port(fSendPort, AS_SERVER_PORTLINK, fSendBuffer, fSendPosition);
100 
101 	fSendPosition=8;
102 	*fDataSize=0;
103 
104 	return write_stat;
105 }
106 
107 status_t PortLink::FlushWithReply( PortMessage *msg,bigtime_t timeout )
108 {
109 	if(!port_ok || !msg)
110 		return B_BAD_VALUE;
111 
112 	// attach our reply port_id at the end
113 	Attach<int32>(fReceivePort);
114 
115 	// Flush the thing....FOOSH! :P
116 	write_port(fSendPort, AS_SERVER_PORTLINK, fSendBuffer, fSendPosition);
117 	fSendPosition	= 8;
118 	*fDataSize=0;
119 
120 	// Now we wait for the reply
121 	msg->ReadFromPort(fReceivePort,timeout);
122 
123 	return B_OK;
124 }
125 
126 status_t PortLink::FlushToSession(){
127 	BSession	ses(0, fSendPort);
128 // !!!!!!!!!!!!!!!!!!!
129 // DW, if you modify PortLink, DON'T forget to modify
130 //		BSession::CopyToSendBuffer() as well!!!
131 // !!!!!!!!!!!!!!!!!!!
132 	ses.CopyToSendBuffer(fSendBuffer, fSendPosition - 8);
133 	ses.Sync();
134 	return B_OK;
135 }
136 
137 status_t PortLink::Attach(const void *data, size_t size)
138 {
139 	if (size <= 0)
140 		return B_ERROR;
141 
142 	if (4096 - fSendPosition > (int32)size)
143 	{
144 		memcpy(fSendBuffer + fSendPosition, data, size);
145 		fSendPosition += size;
146 		*fDataSize+=size;
147 		return B_OK;
148 	}
149 	return B_NO_MEMORY;
150 }
151 
152 status_t PortLink::AttachString(const char *string)
153 {
154 	int16 len = (int16)strlen(string)+1;
155 
156 	Attach<int16>(len);
157 	return Attach(string, len);
158 }
159 
160 void PortLink::MakeEmpty()
161 {
162 	fSendPosition=8;
163 	*fDataSize=0;
164 }
165 
166