NetCpp
v0.2
Main Page
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Macros
Pages
abstract_socket.cpp
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2013 Evidence Srl - www.evidence.eu.com
3
*
4
* Boost Software License - Version 1.0 - August 17th, 2003
5
*
6
* Permission is hereby granted, free of charge, to any person or organization
7
* obtaining a copy of the software and accompanying documentation covered by
8
* this license (the "Software") to use, reproduce, display, distribute,
9
* execute, and transmit the Software, and to prepare derivative works of the
10
* Software, and to permit third-parties to whom the Software is furnished to
11
* do so, all subject to the following:
12
*
13
* The copyright notices in the Software and this entire statement, including
14
* the above license grant, this restriction and the following disclaimer,
15
* must be included in all copies of the Software, in whole or in part, and
16
* all derivative works of the Software, unless such copies or derivative
17
* works are solely in the form of machine-executable object code generated by
18
* a source language processor.
19
*
20
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
23
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
24
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
25
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26
* DEALINGS IN THE SOFTWARE.
27
*/
28
29
#include "
abstract_socket.hpp
"
30
31
namespace
net {
32
33
/**
34
* @brief Receive operation
35
*
36
* This function sendsendsensendsendsendcare of synchronization
37
* with any other asynchronous operations.
38
* Note: it can block the caller, because it calls __receive() which
39
* continues receiving until the given number of bytes have been received.
40
* @param buf Pointer where received data must be put
41
* @param size Size of data to be received
42
* @return Number of bytes actually received
43
* @exception runtime_error in case of too small buffer
44
*
45
* Example of usage:
46
* <code>
47
* std::array<char, 5> buf;
48
* AbstractSocket::receive(net::buffer(b), 3);
49
* </code>
50
*/
51
int
AbstractSocket::receive
(
struct
__buffer
buf, std::size_t size)
52
{
53
int
ret;
54
if
(buf.
size_
== 0 || size > buf.
size_
){
55
ERROR
(
"Wrong buffer size!"
);
56
throw
std::runtime_error (
"Wrong buffer size"
);
57
}
58
receive_lock_
.lock();
59
try
{
60
ret =
__receive
(buf.
ptr_
, size);
61
}
catch
(...) {
62
ERROR
(
"Receive error!"
);
63
}
64
65
receive_lock_
.unlock();
66
return
ret;
67
}
68
69
/**
70
* @brief Send operation
71
*
72
* This function sends data to the socket taking care of synchronization
73
* with any other asynchronous operations.
74
* Note: it can block the caller, because it calls __send() which
75
* continues writing until the given number of bytes have been written.
76
* @param buf Pointer to data to be written
77
* @param size Size of data to be written
78
* @return Number of bytes actually written
79
* @exception runtime_error in case of too small buffer
80
*
81
* Example of usage:
82
* <code>
83
* std::array<char, 5> buf;
84
* AbstractSocket::send(net::buffer(b), 3);
85
* </code>
86
*/
87
int
AbstractSocket::send
(
struct
__buffer
buf, std::size_t size)
88
{
89
int
ret;
90
if
(buf.
size_
== 0 || size > buf.
size_
){
91
ERROR
(
"Wrong buffer size!"
);
92
throw
std::runtime_error (
"Wrong buffer size"
);
93
}
94
send_lock_
.lock();
95
try
{
96
ret =
__send
(buf.
ptr_
, size);
97
}
catch
(...) {
98
ERROR
(
"Send error!"
);
99
}
100
101
send_lock_
.unlock();
102
return
ret;
103
104
}
105
106
/**
107
* \brief Low-level receive
108
*
109
* This method is private because it is meant to be used through the other receive()
110
* method.
111
* Note: it can block the caller, because it continues receiving until the given
112
* number of bytes have been received.
113
* @param buffer Pointer to the buffer where received bytes must be stored
114
* @param size Number of bytes to be received
115
* @exception runtime_error if the read() returns an error
116
* @return The number of actually received bytes or -1 in case of error
117
*/
118
int
AbstractSocket::__receive
(
void
*
buffer
,
size_t
size)
119
{
120
size_t
remaining = size;
121
while
(remaining > 0) {
122
ssize_t ret = socket_->read (((
char
*)buffer)+(size-remaining),
123
remaining);
124
if
(ret == 0){
125
// End of file reached
126
DEBUG
(
"End of file reached"
);
127
break
;
128
}
else
if
(ret < 0) {
129
ERROR
(
"Receive error"
);
130
throw
std::runtime_error (
"Receive error"
);
131
return
-1;
132
}
133
remaining -= ret;
134
}
135
return
(size-remaining);
136
}
137
138
139
140
/**
141
* \brief Low-level send
142
*
143
* This method is private because it is meant to be used through the other
144
* send() method.
145
* Note: it can block the caller, because it continues writing until the
146
* given number of bytes have been written.
147
* @param buffer Pointer to the buffer containing bytes to be written
148
* @param size Number of bytes to be written
149
* @exception runtime_error if the write() returns 0 or an error
150
* @return The number of actually written bytes or -1 in case of error
151
*/
152
int
AbstractSocket::__send
(
const
void
*
buffer
,
size_t
size)
153
{
154
size_t
remaining = size;
155
while
(remaining > 0) {
156
ssize_t ret = socket_->write (((
char
*)buffer)+(size-remaining), remaining);
157
if
(ret == 0){
158
DEBUG
(
"Cannot send any further"
);
159
// Cannot send more
160
break
;
161
}
else
if
(ret < 0) {
162
ERROR
(
"Send error"
);
163
throw
std::runtime_error (
"Send error"
);
164
return
-1;
165
}
166
remaining -= ret;
167
}
168
return
(size-remaining);
169
}
170
171
}
// net
src
abstract_socket.cpp
Generated on Tue Jul 23 2013 09:15:00 for NetCpp by
1.8.1.2