#ifndef __XRDSSISTREAM_HH__
#define __XRDSSISTREAM_HH__
/******************************************************************************/
/* */
/* X r d S s i S t r e a m . h h */
/* */
/* (c) 2013 by the Board of Trustees of the Leland Stanford, Jr., University */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD 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 Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include
#include "XrdSsi/XrdSsiErrInfo.hh"
//-----------------------------------------------------------------------------
//! The XrdSsiStream class describes an object capable of providing data for a
//! response in real time. A pointer to such an object may be used to set this
//! response mode via XrdSsiResponder::SetResponse(). Two kinds of streams exist:
//!
//! Active the stream supplies the buffer that contains the response data.
//! The buffer is recycled via Buffer::Recycle() once the response data
//! is sent. Active streams are supported only server-side.
//! Passive the stream requires a buffer to be passed to it where response data
//! will be placed. Only passive streams are created on the client-side.
//! Passive streams can also work in asynchronous mode. However, async
//! mode is never used server-side but may be requested client-side.
//!
//! The type of stream must be declared at the time the stream is created. You
//! must supply an implementation for the associated stream type.
//-----------------------------------------------------------------------------
class XrdSsiStream
{
public:
//-----------------------------------------------------------------------------
//! The Buffer object is returned by active streams as they supply the buffer
//! holding the requested data. Once the buffer is no longer needed it must be
//! recycled by calling Recycle().
//-----------------------------------------------------------------------------
class Buffer
{
public:
virtual void Recycle() = 0; //!> Call to recycle the buffer when finished
char *data; //!> -> Buffer containing the data
Buffer *next; //!> For chaining by buffer receiver
Buffer(char *dp=0) : data(dp), next(0) {}
virtual ~Buffer() {}
};
//-----------------------------------------------------------------------------
//! Synchronously obtain data from an active stream (server-side only).
//!
//! @param eRef The object to receive any error description.
//! @param dlen input: the optimal amount of data wanted (this is a hint)
//! output: the actual amount of data returned in the buffer.
//! @param last input: should be set to false.
//! output: if true it indicates that no more data remains to be
//! returned either for this call or on the next call.
//!
//! @return =0 No more data remains or an error occurred:
//! last = true: No more data remains.
//! last = false: A fatal error occurred, eRef has the reason.
//! @return !0 Pointer to the Buffer object that contains a pointer to the
//! the data (see below). The buffer must be returned to the
//! stream using Buffer::Recycle(). The next member is usable.
//-----------------------------------------------------------------------------
virtual Buffer *GetBuff(XrdSsiErrInfo &eRef, int &dlen, bool &last)
{eRef.Set("Not an active stream", EOPNOTSUPP); return 0;}
//-----------------------------------------------------------------------------
//! Asynchronously obtain data from a passive stream (client-side only).
//!
//! @param eRef reference to where error information is to be placed for
//! encountered before during the stream initiation. When data is
//! ready for processing, the ProcessResponseData() callback is
//! called on the request associated with this stream.
//! Also see XrdSsiRequest::GetResponseData() helper method.
//! @param buff pointer to the buffer to receive the data. The buffer must
//! remain valid until ProcessResponse() is called.
//! @param blen the length of the buffer (i.e. maximum that can be returned).
//!
//! @return true The stream has been successfully scheduled to return the data.
//! @return false The stream could not be scheduled; eRef holds the reason.
//-----------------------------------------------------------------------------
virtual bool SetBuff(XrdSsiErrInfo &eRef, char *buff, int blen)
{eRef.Set("Not a passive stream", EOPNOTSUPP); return false;}
//-----------------------------------------------------------------------------
//! Synchronously obtain data from a passive stream (client- or server-side).
//!
//! @param eRef The object to receive any error description.
//! @param buff pointer to the buffer to receive the data.
//! request object is notified that the operation completed.
//! @param blen the length of the buffer (i.e. maximum that can be returned).
//! @param last input: should be set to false.
//! output: if true it indicates that no more data remains to be
//! returned either for this call or on the next call.
//!
//! @return >0 The number of bytes placed in buff.
//! @return =0 No more data remains and the stream becomes invalid.
//! @return <0 Fatal error occurred; eRef holds the reason.
//-----------------------------------------------------------------------------
virtual int SetBuff(XrdSsiErrInfo &eRef, char *buff, int blen, bool &last)
{eRef.Set("Not a passive stream", EOPNOTSUPP); return 0;}
//-----------------------------------------------------------------------------
//! Stream type descriptor:
//!
//! isActive - Active stream that supplies it own buffers with data.
//! GetBuff() & RetBuff() must be used.
//!
//! isPassive - Passive stream that provides data via a supplied buffer.
//! SetBuff() must be used.
//-----------------------------------------------------------------------------
enum StreamType {isActive = 0, isPassive};
//-----------------------------------------------------------------------------
//! Get the stream type descriptor.
//!
//! @return The stream type, isActive or isPassive.
//-----------------------------------------------------------------------------
StreamType Type() {return SType;}
XrdSsiStream(StreamType stype) : SType(stype) {}
virtual ~XrdSsiStream() {}
protected:
const StreamType SType;
};
#endif