|
|
|
/*
|
|
|
|
|
|
|
|
Copyright (C) 2000 Stefan Westerfeld
|
|
|
|
stefan@space.twc.de
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef DATAPACKET_H
|
|
|
|
#define DATAPACKET_H
|
|
|
|
|
|
|
|
#include "arts_export.h"
|
|
|
|
#include "buffer.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BC - Status (2002-03-08): GenericDataChannel, DataPacket types
|
|
|
|
*
|
|
|
|
* These classes must be kept binary compatible, as the do interact with
|
|
|
|
* generated code. So you MUST KNOW WHAT YOU ARE DOING, once you start
|
|
|
|
* using the provided d pointers for extensions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Arts {
|
|
|
|
class GenericDataChannelPrivate;
|
|
|
|
class GenericDataPacket;
|
|
|
|
/*
|
|
|
|
* The GenericDataChannel interface is to be implemented by the flowsystem
|
|
|
|
*/
|
|
|
|
class ARTS_EXPORT GenericDataChannel {
|
|
|
|
private:
|
|
|
|
GenericDataChannelPrivate *d; // unused
|
|
|
|
|
|
|
|
protected:
|
|
|
|
friend class GenericDataPacket;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* this is used internally by DataPacket
|
|
|
|
*/
|
|
|
|
virtual void processedPacket(GenericDataPacket *packet) = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* used internally by DataPacket
|
|
|
|
*/
|
|
|
|
virtual void sendPacket(GenericDataPacket *packet) = 0;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/*
|
|
|
|
* used to set pull delivery mode
|
|
|
|
*/
|
|
|
|
virtual void setPull(int packets, int capacity) = 0;
|
|
|
|
virtual void endPull() = 0;
|
|
|
|
|
|
|
|
GenericDataChannel() : d(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* DataPackets are the heard of asynchronous streaming (MCOP has synchronous
|
|
|
|
* and asynchronous streams). They are used
|
|
|
|
*
|
|
|
|
* - in the interface async streams expose to C++ implementations of MCOP
|
|
|
|
* interfaces (they directly deal with datapackets)
|
|
|
|
*
|
|
|
|
* - from the FlowSystem implemenentations
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The GenericDataPacket class provides the interface the flow system can
|
|
|
|
* use to deal with data packets.
|
|
|
|
*/
|
|
|
|
class GenericDataPacketPrivate;
|
|
|
|
|
|
|
|
class ARTS_EXPORT GenericDataPacket {
|
|
|
|
private:
|
|
|
|
GenericDataPacketPrivate *d;
|
|
|
|
static long _staticDataPacketCount;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* the amount of active data packets (memory leak debugging only)
|
|
|
|
*/
|
|
|
|
static long _dataPacketCount() { return _staticDataPacketCount; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the channel this datapacket belongs to
|
|
|
|
*/
|
|
|
|
GenericDataChannel *channel;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ensureCapactity ensures that there is room for at least capacity
|
|
|
|
* Elements in the packet. This is implemented destructive - that
|
|
|
|
* means: you may not find your old contents in the packet after
|
|
|
|
* calling ensureCapacity
|
|
|
|
*/
|
|
|
|
virtual void ensureCapacity(int capacity) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* read/write write the contents of the packet. Read will also
|
|
|
|
* automatically ensure that capacity is adapted before reading.
|
|
|
|
*/
|
|
|
|
virtual void read(Buffer& stream) = 0;
|
|
|
|
virtual void write(Buffer& stream) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* having size here (and not in the derived concrete DataPackets) is so
|
|
|
|
* that we can see whether the sender can't supply more data (and starts
|
|
|
|
* sending zero size packets
|
|
|
|
*/
|
|
|
|
int size;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* useCount is to be set from sendPacket
|
|
|
|
*/
|
|
|
|
int useCount;
|
|
|
|
|
|
|
|
inline void send()
|
|
|
|
{
|
|
|
|
channel->sendPacket(this);
|
|
|
|
}
|
|
|
|
inline void processed()
|
|
|
|
{
|
|
|
|
useCount--;
|
|
|
|
if(useCount == 0)
|
|
|
|
{
|
|
|
|
if(channel)
|
|
|
|
channel->processedPacket(this);
|
|
|
|
else
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~GenericDataPacket()
|
|
|
|
{
|
|
|
|
_staticDataPacketCount--;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
GenericDataPacket(GenericDataChannel *channel)
|
|
|
|
:d(0),channel(channel),useCount(0)
|
|
|
|
{
|
|
|
|
_staticDataPacketCount++;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The DataPacket<T> interface is what C++ implementations of MCOP interfaces
|
|
|
|
* will need to use.
|
|
|
|
*/
|
|
|
|
template<class T>
|
|
|
|
class DataPacket : public GenericDataPacket {
|
|
|
|
public:
|
|
|
|
T *contents;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
DataPacket(GenericDataChannel *channel)
|
|
|
|
: GenericDataPacket(channel) {}
|
|
|
|
~DataPacket() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The RawDataPacket<T> interface handles raw class T arrays of data
|
|
|
|
*/
|
|
|
|
template<class T>
|
|
|
|
class RawDataPacket : public DataPacket<T> {
|
|
|
|
protected:
|
|
|
|
int capacity;
|
|
|
|
void ensureCapacity(int newCapacity)
|
|
|
|
{
|
|
|
|
if(newCapacity > capacity)
|
|
|
|
{
|
|
|
|
delete[] this->contents;
|
|
|
|
capacity = newCapacity;
|
|
|
|
this->contents = new T[capacity];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RawDataPacket(int capacity, GenericDataChannel *channel)
|
|
|
|
:DataPacket<T>(channel), capacity(capacity)
|
|
|
|
{
|
|
|
|
this->size = capacity;
|
|
|
|
this->contents = new T[capacity];
|
|
|
|
}
|
|
|
|
~RawDataPacket()
|
|
|
|
{
|
|
|
|
delete[] this->contents;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* FloatDataPacket finally is one concrete DataPacket (which tqcontains the
|
|
|
|
* information how to marshal a datapacket of type float)
|
|
|
|
*/
|
|
|
|
class ARTS_EXPORT FloatDataPacket : public RawDataPacket<float> {
|
|
|
|
public:
|
|
|
|
FloatDataPacket(int capacity, GenericDataChannel *channel)
|
|
|
|
: RawDataPacket<float>(capacity, channel)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
}
|
|
|
|
void read(Buffer& stream);
|
|
|
|
void write(Buffer& stream);
|
|
|
|
};
|
|
|
|
|
|
|
|
class ARTS_EXPORT ByteDataPacket : public RawDataPacket<mcopbyte> {
|
|
|
|
public:
|
|
|
|
ByteDataPacket(int capacity, GenericDataChannel *channel)
|
|
|
|
: RawDataPacket<mcopbyte>(capacity, channel)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
}
|
|
|
|
void read(Buffer& stream);
|
|
|
|
void write(Buffer& stream);
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|