|
TOBI Interface A
0.1
|
00001 /* 00002 This file is part of the TOBI Interface A (TiA) library. 00003 00004 Commercial Usage 00005 Licensees holding valid Graz University of Technology Commercial 00006 licenses may use this file in accordance with the Graz University 00007 of Technology Commercial License Agreement provided with the 00008 Software or, alternatively, in accordance with the terms contained in 00009 a written agreement between you and Graz University of Technology. 00010 00011 -------------------------------------------------- 00012 00013 GNU Lesser General Public License Usage 00014 Alternatively, this file may be used under the terms of the GNU Lesser 00015 General Public License version 3.0 as published by the Free Software 00016 Foundation and appearing in the file lgpl.txt included in the 00017 packaging of this file. Please review the following information to 00018 ensure the GNU General Public License version 3.0 requirements will be 00019 met: http://www.gnu.org/copyleft/lgpl.html. 00020 00021 In case of GNU Lesser General Public License Usage ,the TiA library 00022 is distributed in the hope that it will be useful, 00023 but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00025 GNU General Public License for more details. 00026 00027 You should have received a copy of the GNU Lesser General Public License 00028 along with the TiA library. If not, see <http://www.gnu.org/licenses/>. 00029 00030 Copyright 2010 Graz University of Technology 00031 Contact: TiA@tobi-project.org 00032 */ 00033 00034 #include "tia-private/newtia/network_impl/boost_tcp_socket_impl.h" 00035 #include "tia-private/newtia/messages/tia_control_message_tags_1_0.h" 00036 #include "tia-private/newtia/tia_exceptions.h" 00037 00038 #include <boost/asio.hpp> 00039 #include <boost/lexical_cast.hpp> 00040 #include <iostream> 00041 00042 using std::string; 00043 00044 static const int RESERVED_STRING_LENGTH = 2048; 00045 static const int RESERVED_STREAM_BUFFER_SIZE = 2048; 00046 00047 namespace tia 00048 { 00049 BoostTCPSocketImpl::BoostTCPSocketImpl (boost::asio::io_service& io_service, 00050 boost::asio::ip::tcp::endpoint const& endpoint, unsigned buffer_size) 00051 : socket_ (new boost::asio::ip::tcp::socket (io_service) ), input_stream_(&stream_buffer_) 00052 { 00053 socket_->connect (endpoint); 00054 boost::asio::socket_base::receive_buffer_size option (buffer_size); 00055 socket_->set_option (option); 00056 00057 remote_endpoint_str_ = socket_->remote_endpoint().address().to_string() + ":" 00058 + boost::lexical_cast<std::string>( socket_->remote_endpoint().port() ); 00059 00060 local_endpoint_str_ = socket_->local_endpoint().address().to_string() + ":" 00061 + boost::lexical_cast<std::string>( socket_->local_endpoint().port() ); 00062 00063 00064 stream_buffer_.prepare(RESERVED_STREAM_BUFFER_SIZE); 00065 str_buffer_.reserve(RESERVED_STRING_LENGTH); 00066 } 00067 00068 //----------------------------------------------------------------------------- 00069 00070 BoostTCPSocketImpl::BoostTCPSocketImpl (boost::shared_ptr<boost::asio::ip::tcp::socket> boost_socket) 00071 : socket_ (boost_socket), input_stream_(&stream_buffer_) 00072 { 00073 remote_endpoint_str_ = socket_->remote_endpoint().address().to_string() + ":" 00074 + boost::lexical_cast<std::string>( socket_->remote_endpoint().port() ); 00075 00076 local_endpoint_str_ = socket_->local_endpoint().address().to_string() + ":" 00077 + boost::lexical_cast<std::string>( socket_->local_endpoint().port() ); 00078 00079 stream_buffer_.prepare(RESERVED_STREAM_BUFFER_SIZE); 00080 str_buffer_.reserve(RESERVED_STRING_LENGTH); 00081 } 00082 00083 //----------------------------------------------------------------------------- 00084 BoostTCPSocketImpl::~BoostTCPSocketImpl () 00085 { 00086 if (socket_) 00087 { 00088 socket_->close (); 00089 } 00090 str_buffer_.clear (); 00091 } 00092 00093 //----------------------------------------------------------------------------- 00094 void BoostTCPSocketImpl::setReceiveBufferSize (unsigned size) 00095 { 00096 boost::asio::socket_base::receive_buffer_size option(size); 00097 if (socket_) 00098 socket_->set_option (option); 00099 } 00100 00101 //----------------------------------------------------------------------------- 00102 00103 string BoostTCPSocketImpl::readUntil (char delimiter) 00104 { 00105 error_.clear(); 00106 str_buffer_.clear(); 00107 size_t transfered = boost::asio::read_until (*socket_, stream_buffer_, delimiter, error_ ); 00108 00109 if(error_) 00110 throw TiALostConnection ("InputStreamSocket::readUntil error_ read_until: " 00111 + string (error_.category().name()) + error_.message()); 00112 str_buffer_.resize(transfered -1); 00113 00114 size_t n = 0; 00115 while(n != transfered-1) 00116 { 00117 str_buffer_[n] = input_stream_.peek(); 00118 stream_buffer_.consume(1); 00119 n++; 00120 } 00121 input_stream_.get(); 00122 00123 return(str_buffer_); 00124 } 00125 00126 //----------------------------------------------------------------------------- 00127 00128 string BoostTCPSocketImpl::readUntil (std::string delimiter) 00129 { 00130 error_.clear(); 00131 str_buffer_.clear(); 00132 size_t transfered = boost::asio::read_until (*socket_, stream_buffer_, delimiter,error_ ); 00133 00134 if(error_) 00135 throw TiALostConnection ("InputStreamSocket::readUntil error_ read_until: " 00136 + string (error_.category().name()) + error_.message()); 00137 str_buffer_.resize(transfered -delimiter.size()); 00138 00139 size_t n = 0; 00140 while(n != transfered-delimiter.size()) 00141 { 00142 str_buffer_[n] = input_stream_.peek(); 00143 stream_buffer_.consume(1); 00144 n++; 00145 } 00146 00147 for(unsigned int s = 0; s < delimiter.size(); s++) 00148 input_stream_.get(); 00149 00150 return(str_buffer_); 00151 } 00152 00153 00154 //----------------------------------------------------------------------------- 00155 string BoostTCPSocketImpl::readString (unsigned length) 00156 { 00157 str_buffer_.clear(); 00158 if(stream_buffer_.size() < length) 00159 { 00160 error_.clear(); 00161 boost::asio::read (*socket_, stream_buffer_, 00162 boost::asio::transfer_at_least( length - stream_buffer_.size() ), error_ ) ; 00163 if (error_) 00164 throw TiALostConnection ("InputStreamSocket::readString error_ read: " 00165 + string (error_.category().name()) + error_.message()); 00166 } 00167 00168 str_buffer_.clear(); 00169 str_buffer_.resize(length); 00170 00171 for(unsigned int n = 0; n < length; n++) 00172 { 00173 str_buffer_[n] = input_stream_.peek(); 00174 stream_buffer_.consume(1); 00175 } 00176 return(str_buffer_); 00177 } 00178 00179 //----------------------------------------------------------------------------- 00180 char BoostTCPSocketImpl::readCharacter () 00181 { 00182 if(!stream_buffer_.size()) 00183 waitForData(); 00184 00185 char c = input_stream_.peek(); 00186 stream_buffer_.consume(1); 00187 return(c); 00188 00189 } 00190 00191 //----------------------------------------------------------------------------- 00192 void BoostTCPSocketImpl::waitForData () 00193 { 00194 error_.clear(); 00195 if (!stream_buffer_.size () ) 00196 boost::asio::read (*socket_, stream_buffer_, boost::asio::transfer_at_least(1), error_) ; 00197 00198 if (error_) 00199 throw TiALostConnection ("InputStreamSocket::readBytes error_ read: " 00200 + string (error_.category().name()) + error_.message()); 00201 } 00202 00203 //----------------------------------------------------------------------------- 00204 void BoostTCPSocketImpl::sendString (string const& str) throw (TiALostConnection) 00205 { 00206 error_.clear(); 00207 socket_->send (boost::asio::buffer (str), 0, error_); 00208 if (error_) 00209 throw TiALostConnection ("BoostTCPSocketImpl: sending string failed"); 00210 } 00211 00212 //----------------------------------------------------------------------------- 00213 00214 size_t BoostTCPSocketImpl::readBytes (char* data, size_t bytes_to_read) 00215 { 00216 00217 if(stream_buffer_.size () < bytes_to_read ) 00218 { 00219 error_.clear(); 00220 boost::asio::read (*socket_, stream_buffer_, 00221 boost::asio::transfer_at_least(bytes_to_read-stream_buffer_.size ()),error_); 00222 if (error_) 00223 throw TiALostConnection ("InputStreamSocket::readBytes error_ read: " 00224 + string (error_.category().name()) + error_.message()); 00225 00226 input_stream_.read(data, bytes_to_read); 00227 return bytes_to_read; 00228 } 00229 else 00230 { 00231 input_stream_.read( data, bytes_to_read); 00232 return bytes_to_read; 00233 } 00234 } 00235 00236 //----------------------------------------------------------------------------- 00237 00238 size_t BoostTCPSocketImpl::getAvailableData (char* data, size_t max_size) 00239 { 00240 00241 size_t available_data = stream_buffer_.size (); 00242 if ( !available_data ) 00243 { 00244 data = 0; 00245 return 0; 00246 } 00247 else 00248 { 00249 if(available_data > max_size) 00250 { 00251 input_stream_.read( data, max_size); 00252 return max_size; 00253 } 00254 else 00255 { 00256 input_stream_.read( data, available_data); 00257 return available_data; 00258 } 00259 } 00260 } 00261 00262 //----------------------------------------------------------------------------- 00263 00264 std::string BoostTCPSocketImpl::getRemoteEndPointAsString() 00265 { 00266 return(remote_endpoint_str_); 00267 } 00268 00269 //----------------------------------------------------------------------------- 00270 00271 std::string BoostTCPSocketImpl::getLocalEndPointAsString() 00272 { 00273 return(local_endpoint_str_); 00274 } 00275 00276 //----------------------------------------------------------------------------- 00277 00278 }