179 lines
4.9 KiB
C++
179 lines
4.9 KiB
C++
/***************************************************************************
|
|
* Copyright (C) gempa GmbH *
|
|
* All rights reserved. *
|
|
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
|
* *
|
|
* GNU Affero General Public License Usage *
|
|
* This file may be used under the terms of the GNU Affero *
|
|
* Public License version 3.0 as published by the Free Software Foundation *
|
|
* and appearing in the file LICENSE included in the packaging of this *
|
|
* file. Please review the following information to ensure the GNU Affero *
|
|
* Public License version 3.0 requirements will be met: *
|
|
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
|
* *
|
|
* Other Usage *
|
|
* Alternatively, this file may be used in accordance with the terms and *
|
|
* conditions contained in a signed written agreement between you and *
|
|
* gempa GmbH. *
|
|
***************************************************************************/
|
|
|
|
|
|
#ifndef SEISCOMP_WIRED_CLIENTSESSION_H
|
|
#define SEISCOMP_WIRED_CLIENTSESSION_H
|
|
|
|
|
|
#include <seiscomp/wired/session.h>
|
|
#include <seiscomp/wired/buffer.h>
|
|
|
|
#include <vector>
|
|
|
|
|
|
namespace Seiscomp {
|
|
namespace Wired {
|
|
|
|
|
|
class SC_SYSTEM_CORE_API ClientSession : public Session {
|
|
public:
|
|
enum Error {
|
|
NoError = 0,
|
|
TooManyCharactersPerLine,
|
|
ErrorQuantity
|
|
};
|
|
|
|
public:
|
|
ClientSession(Device *dev, size_t maxCharactersPerLine = 200);
|
|
|
|
public:
|
|
//! Update the session state including flushing and
|
|
//! reading available data.
|
|
void update() override;
|
|
|
|
//! Sets keepReading to false
|
|
void close() override;
|
|
|
|
//! Queues a buffer and returns whether the queue was empty
|
|
bool send(Buffer *);
|
|
|
|
/**
|
|
* @brief Sends a null-terminated character string.
|
|
* If not all data could be sent then a buffer with remaining
|
|
* data will be created and queued.
|
|
* @param data The null-terminated string
|
|
*/
|
|
void send(const char *data);
|
|
|
|
/**
|
|
* @brief Sends a memory block of bytes.
|
|
* This function is faster than send(const char*) as it does not
|
|
* need to run strlen().
|
|
* @param data The byte array
|
|
* @param size The number of bytes
|
|
*/
|
|
void send(const char *data, size_t size);
|
|
|
|
//! Returns the number of bytes currently in the output buffer
|
|
//! which haven't been sent yet.
|
|
size_t outputBufferSize() const;
|
|
|
|
bool valid() const;
|
|
bool erroneous() const;
|
|
|
|
|
|
protected:
|
|
virtual void buffersFlushed();
|
|
virtual void bufferSent(Buffer*);
|
|
|
|
//! Sets the post data size that is read by handleReceived and
|
|
//! passed to handlePostData
|
|
void setPostDataSize(size_t len);
|
|
size_t postDataSize() const;
|
|
|
|
void setMIMEUnfoldingEnabled(bool);
|
|
|
|
void setError(const char* msg);
|
|
|
|
//! Sets the error state
|
|
void invalidate();
|
|
|
|
//! Break the reading loop to give control to other sessions. This
|
|
//! calls only makes sense if the reactor is level-triggered.
|
|
void finishReading();
|
|
|
|
//! Handles a socket read into _buffer. The default implementation
|
|
//! extracts lines and calls handleInbox/handleData.
|
|
virtual void handleReceive(const char *data, size_t len);
|
|
|
|
//! Handles a line
|
|
virtual void handleInbox(const char *data, size_t len);
|
|
|
|
//! Handles posted data that has been requested if setPOSTDataSize
|
|
//! is called with len > 0.
|
|
virtual void handlePostData(const char *data, size_t len);
|
|
|
|
virtual void handleInboxError(Error error);
|
|
|
|
|
|
private:
|
|
/**
|
|
* @brief Queues a buffer without the attempt to send it.
|
|
* @return True, if the queue was empty, false otherwise.
|
|
*/
|
|
bool queue(Buffer *);
|
|
|
|
//! Flush data still in the buffer.
|
|
void flush(bool flagFlush = false);
|
|
|
|
|
|
protected:
|
|
enum Flags {
|
|
NoFlags = 0x0000,
|
|
MIMEUnfolding = 0x0001,
|
|
KeepReading = 0x0002,
|
|
//Future1 = 0x0004,
|
|
//Future2 = 0x0008,
|
|
//Future3 = 0x0010,
|
|
//Future4 = 0x0020,
|
|
PendingFlush = 0x0040,
|
|
AppendBuffer = 0x0080,
|
|
Erroneous = 0x0100
|
|
};
|
|
|
|
std::vector<char> _inbox;
|
|
size_t _inboxPos{0};
|
|
uint16_t _flags{NoFlags};
|
|
size_t _postDataSize{0};
|
|
Device::count_t _bytesSent{0};
|
|
|
|
|
|
private:
|
|
BufferPtr _currentBuffer;
|
|
size_t _currentBufferHeaderOffset;
|
|
size_t _currentBufferDataOffset;
|
|
BufferList _bufferQueue;
|
|
size_t _bufferBytesPending{0};
|
|
};
|
|
|
|
|
|
inline size_t ClientSession::outputBufferSize() const {
|
|
return _bufferBytesPending;
|
|
}
|
|
|
|
inline bool ClientSession::valid() const {
|
|
return !erroneous();
|
|
}
|
|
|
|
inline void ClientSession::invalidate() {
|
|
_flags |= Erroneous;
|
|
}
|
|
|
|
inline bool ClientSession::erroneous() const {
|
|
return _flags & Erroneous;
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|