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