45 using std::ostringstream;
46 using std::istringstream;
51 #include "PPTConnection.h"
52 #include "PPTProtocol.h"
55 #include "BESInternalError.h"
57 PPTConnection::~PPTConnection()
101 if (!buffer.empty()) {
102 sendChunk(buffer, extensions);
105 map<string, string> no_extensions;
106 sendChunk(
"", no_extensions);
109 sendChunk(
"", extensions);
117 map<string, string> extensions;
118 extensions[
"status"] = PPTProtocol::PPT_EXIT_NOW;
119 send(
"", extensions);
123 sendChunk(
"", extensions);
134 void PPTConnection::sendChunk(
const string &buffer, map<string, string> &extensions)
137 if (extensions.size()) {
140 strm << hex << setw(7) << setfill(
'0') << buffer.length() <<
"d";
141 if (!buffer.empty()) {
144 string toSend = strm.str();
155 if (extensions.size()) {
157 map<string, string>::const_iterator i = extensions.begin();
158 map<string, string>::const_iterator ie = extensions.end();
159 for (; i != ie; i++) {
161 string value = (*i).second;
162 if (!value.empty()) {
163 estrm <<
"=" << value;
167 string xstr = estrm.str();
168 strm << hex << setw(7) << setfill(
'0') << xstr.length() <<
"x" << xstr;
169 string toSend = strm.str();
182 BESDEBUG(
"ppt",
"PPTConnection::send - sending " << buffer << endl);
184 _mySock->send(buffer, 0, buffer.length());
202 return _mySock->receive(buffer, buffer_size);
205 int PPTConnection::readChunkHeader(
char *buffer,
int buffer_size)
207 char *temp_buffer = buffer;
208 int totalBytesRead = 0;
211 int bytesRead =
readBuffer(temp_buffer, buffer_size);
212 BESDEBUG(
"ppt",
"PPTConnection::readChunkHeader - read " << bytesRead <<
" bytes" << endl );
217 if (bytesRead == 0) {
220 if (bytesRead < buffer_size) {
221 buffer_size = buffer_size - bytesRead;
222 temp_buffer = temp_buffer + bytesRead;
223 totalBytesRead += bytesRead;
226 totalBytesRead += bytesRead;
230 buffer[totalBytesRead] =
'\0';
231 return totalBytesRead;
249 bool PPTConnection::receive(map<string, string> &extensions, ostream *strm)
251 ostream *use_strm = _out;
252 if (strm) use_strm = strm;
256 BESDEBUG(
"ppt",
"PPTConnection::receive: buffer size = " << _inBuff_len << endl );
258 _inBuff_len = _mySock->getRecvBufferSize() + 1;
259 _inBuff =
new char[_inBuff_len + 1];
265 int bytesRead = readChunkHeader(_inBuff, 8);
266 BESDEBUG(
"ppt",
"Reading header, read " << bytesRead <<
" bytes" << endl );
271 lenbuffer[0] = _inBuff[0];
272 lenbuffer[1] = _inBuff[1];
273 lenbuffer[2] = _inBuff[2];
274 lenbuffer[3] = _inBuff[3];
275 lenbuffer[4] = _inBuff[4];
276 lenbuffer[5] = _inBuff[5];
277 lenbuffer[6] = _inBuff[6];
279 istringstream lenstrm(lenbuffer);
280 unsigned long inlen = 0;
281 lenstrm >> hex >> setw(7) >> inlen;
282 BESDEBUG(
"ppt",
"Reading header, chunk length = " << inlen << endl );
283 BESDEBUG(
"ppt",
"Reading header, chunk type = " << _inBuff[7] << endl );
285 if (_inBuff[7] ==
'x') {
287 receive(xstrm, inlen);
290 else if (_inBuff[7] ==
'd') {
296 receive(*use_strm, inlen);
299 string err = (string)
"type of data is " + _inBuff[7] +
", should be x for extensions or d for data";
315 void PPTConnection::receive(ostream &strm,
const int len)
317 BESDEBUG(
"ppt",
"PPTConnect::receive - len = " << len << endl );
320 string err =
"buffer has not been initialized";
325 if( len > _inBuff_len )
327 to_read = _inBuff_len;
329 BESDEBUG(
"ppt",
"PPTConnect::receive - to_read = " << to_read << endl );
332 int bytesRead =
readBuffer( _inBuff, to_read );
335 string err =
"Failed to read data from socket";
338 BESDEBUG(
"ppt",
"PPTConnect::receive - bytesRead = "
339 << bytesRead << endl );
342 _inBuff[bytesRead] =
'\0';
343 strm.write( _inBuff, bytesRead );
348 if( bytesRead < len )
350 BESDEBUG(
"ppt",
"PPTConnect::receive - remaining = "
351 << (len - bytesRead) << endl );
352 receive( strm, len - bytesRead );
373 unsigned int index = 0;
376 string::size_type semi = xstr.find(
';', index);
377 if (semi == string::npos) {
378 string err =
"malformed extensions " + xstr.substr(index, xstr.length() - index) +
", missing semicolon";
381 string::size_type eq = xstr.find(
'=', index);
382 if (eq == string::npos || eq > semi) {
384 var = xstr.substr(index, semi - index);
385 extensions[var] =
"";
387 else if (eq == semi - 1) {
388 string err =
"malformed extensions " + xstr.substr(index, xstr.length() - index)
389 +
", missing value after =";
393 var = xstr.substr(index, eq - index);
394 val = xstr.substr(eq + 1, semi - eq - 1);
395 extensions[var] = val;
398 if (index >= xstr.length()) {
416 struct pollfd arr[1];
417 arr[0].fd = getSocket()->getSocketDescriptor();
418 arr[0].events = POLLIN;
421 struct pollfd p = {};
422 p.fd = getSocket()->getSocketDescriptor();
424 struct pollfd arr[1];
429 for (
int j = 0; j < _timeout; j++) {
430 if (poll(arr, 1, 1000) < 0) {
432 if (errno == EINTR || errno == EAGAIN)
continue;
434 throw BESInternalError(
string(
"poll error") +
" " + strerror(errno), __FILE__, __LINE__);
437 if (arr[0].revents == POLLIN) {
441 cout <<
" " << j << flush;
449 unsigned int PPTConnection::getRecvChunkSize()
451 return _mySock->getRecvBufferSize() - PPT_CHUNK_HEADER_SPACE;
454 unsigned int PPTConnection::getSendChunkSize()
456 return _mySock->getSendBufferSize() - PPT_CHUNK_HEADER_SPACE;
467 strm << BESIndent::LMarg <<
"PPTConnection::dump - (" << (
void *)
this <<
")" << endl;
470 BESIndent::UnIndent();