diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/poco/Net/src/DialogSocket.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/poco/Net/src/DialogSocket.cpp')
-rw-r--r-- | contrib/libs/poco/Net/src/DialogSocket.cpp | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/contrib/libs/poco/Net/src/DialogSocket.cpp b/contrib/libs/poco/Net/src/DialogSocket.cpp new file mode 100644 index 0000000000..030280c6c3 --- /dev/null +++ b/contrib/libs/poco/Net/src/DialogSocket.cpp @@ -0,0 +1,295 @@ +// +// DialogSocket.cpp +// +// Library: Net +// Package: Sockets +// Module: DialogSocket +// +// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Net/DialogSocket.h" +#include "Poco/Exception.h" +#include "Poco/Ascii.h" +#include <cstring> + + +namespace Poco { +namespace Net { + + +DialogSocket::DialogSocket(): + _pBuffer(0), + _pNext(0), + _pEnd(0) +{ + allocBuffer(); +} + + +DialogSocket::DialogSocket(const SocketAddress& address): + StreamSocket(address), + _pBuffer(0), + _pNext(0), + _pEnd(0) +{ + allocBuffer(); +} + + +DialogSocket::DialogSocket(const Socket& socket): + StreamSocket(socket), + _pBuffer(0), + _pNext(0), + _pEnd(0) +{ + allocBuffer(); +} + + +DialogSocket::DialogSocket(const DialogSocket& socket): + StreamSocket(socket), + _pBuffer(0), + _pNext(0), + _pEnd(0) +{ + allocBuffer(); +} + + +DialogSocket::~DialogSocket() +{ + delete [] _pBuffer; +} + + +DialogSocket& DialogSocket::operator = (const Socket& socket) +{ + StreamSocket::operator = (socket); + _pNext = _pBuffer; + _pEnd = _pBuffer; + return *this; +} + + +DialogSocket& DialogSocket::operator = (const DialogSocket& socket) +{ + StreamSocket::operator = (socket); + _pNext = _pBuffer; + _pEnd = _pBuffer; + return *this; +} + + +void DialogSocket::sendByte(unsigned char ch) +{ + sendBytes(&ch, 1); +} + + +void DialogSocket::sendString(const char* str) +{ + sendBytes(str, (int) std::strlen(str)); +} + + +void DialogSocket::sendString(const std::string& str) +{ + sendBytes(str.data(), (int) str.length()); +} + + +void DialogSocket::sendMessage(const std::string& message) +{ + std::string line; + line.reserve(message.length() + 2); + line.append(message); + line.append("\r\n"); + sendString(line); +} + + +void DialogSocket::sendMessage(const std::string& message, const std::string& arg) +{ + std::string line; + line.reserve(message.length() + arg.length() + 3); + line.append(message); + if (!arg.empty()) + { + line.append(" "); + line.append(arg); + } + line.append("\r\n"); + sendString(line); +} + + +void DialogSocket::sendMessage(const std::string& message, const std::string& arg1, const std::string& arg2) +{ + std::string line; + line.reserve(message.length() + arg1.length() +arg2.length() + 4); + line.append(message); + line.append(" "); + line.append(arg1); + if (!arg2.empty()) + { + line.append(" "); + line.append(arg2); + } + line.append("\r\n"); + sendString(line); +} + + +bool DialogSocket::receiveMessage(std::string& message) +{ + message.clear(); + return receiveLine(message, MAX_LINE_LENGTH); +} + + +int DialogSocket::receiveStatusMessage(std::string& message) +{ + message.clear(); + int status = receiveStatusLine(message, MAX_LINE_LENGTH); + if (status < 0) + { + while (status <= 0) + { + message += '\n'; + status = receiveStatusLine(message, message.length() + MAX_LINE_LENGTH); + } + } + return status; +} + + +int DialogSocket::get() +{ + refill(); + if (_pNext != _pEnd) + return std::char_traits<char>::to_int_type(*_pNext++); + else + return EOF_CHAR; +} + + +int DialogSocket::peek() +{ + refill(); + if (_pNext != _pEnd) + return std::char_traits<char>::to_int_type(*_pNext); + else + return EOF_CHAR; +} + + +void DialogSocket::synch() +{ + sendUrgent(TELNET_DM); +} + + +void DialogSocket::sendTelnetCommand(unsigned char command) +{ + unsigned char buffer[2]; + buffer[0] = TELNET_IAC; + buffer[1] = command; + sendBytes(buffer, 2); +} + + +void DialogSocket::sendTelnetCommand(unsigned char command, unsigned char arg) +{ + unsigned char buffer[3]; + buffer[0] = TELNET_IAC; + buffer[1] = command; + buffer[2] = arg; + sendBytes(buffer, 3); +} + + +void DialogSocket::refill() +{ + if (_pNext == _pEnd) + { + int n = receiveBytes(_pBuffer, RECEIVE_BUFFER_SIZE); + if (n > 0) + { + _pNext = _pBuffer; + _pEnd = _pBuffer + n; + } + } +} + + +void DialogSocket::allocBuffer() +{ + _pBuffer = new char [RECEIVE_BUFFER_SIZE]; + _pNext = _pBuffer; + _pEnd = _pBuffer; +} + + +bool DialogSocket::receiveLine(std::string& line, std::size_t lineLengthLimit) +{ + // An old wisdom goes: be strict in what you emit + // and generous in what you accept. + int ch = get(); + while (ch != EOF_CHAR && ch != '\r' && ch != '\n') + { + if (lineLengthLimit == 0 || line.size() < lineLengthLimit) + line += (char) ch; + else + throw Poco::IOException("Line too long"); + ch = get(); + } + if (ch == '\r' && peek() == '\n') + get(); + else if (ch == EOF_CHAR) + return false; + return true; +} + + +int DialogSocket::receiveStatusLine(std::string& line, std::size_t lineLengthLimit) +{ + int status = 0; + int ch = get(); + if (ch != EOF_CHAR) line += (char) ch; + int n = 0; + while (Poco::Ascii::isDigit(ch) && n < 3) + { + status *= 10; + status += ch - '0'; + ++n; + ch = get(); + if (ch != EOF_CHAR) line += (char) ch; + } + if (n == 3) + { + if (ch == '-') + status = -status; + } + else status = 0; + if (ch != EOF_CHAR) receiveLine(line, lineLengthLimit); + return status; +} + + +int DialogSocket::receiveRawBytes(void* buffer, int length) +{ + refill(); + int n = static_cast<int>(_pEnd - _pNext); + if (n > length) n = length; + std::memcpy(buffer, _pNext, n); + _pNext += n; + return n; +} + + +} } // namespace Poco::Net |