#line 1 "/user/cvsspst/ees1cg/RAVL/RAVL-0.7/Core/IO/Port.hh" // This file is part of RAVL, Recognition And Vision Library // Copyright (C) 2001, University of Surrey // This code may be redistributed under the terms of the GNU Lesser // General Public License (LGPL). See the lgpl.licence file for details or // see http://www.gnu.org/copyleft/lesser.html // file-header-ends-here #ifndef RAVL_DPPORT_HEADER #define RAVL_DPPORT_HEADER 1 //////////////////////////////////////////////////// //! docentry="Ravl.Core.Data Processing.Ports" //! rcsid="$Id: Port.hh,v 1.11 2002/07/31 15:47:01 craftit Exp $" //! file="Ravl/Core/IO/Port.hh" //! lib=RavlIO //! author="Charles Galambos" //! date="16/06/1998" //! userlevel=Normal #include "Ravl/DP/Entity.hh" #include "Ravl/Assert.hh" #include "Ravl/Exception.hh" #include "Ravl/SArray1d.hh" #include "Ravl/SArr1Iter.hh" #include "Ravl/Stream.hh" #if RAVL_HAVE_ANSICPPHEADERS #include #else #include #endif namespace RavlN { class DPPortC; class StringC; //! userlevel=Normal //: Exception, Data Not Ready. // This is throw if a Get is unabled to // comlete because there is no data available. class DataNotReadyC : public ExceptionC { public: DataNotReadyC(const char *msg = "") : ExceptionC(msg) {} }; //! userlevel=Develop //: Abstract port body. class DPPortBodyC : virtual public DPEntityBodyC { public: DPPortBodyC() {} //: Default constructor. DPPortBodyC(const StringC &nportId) : portId(nportId) {} //: Constructor with a port id. DPPortBodyC(istream &in); //: Stream constructor. virtual ~DPPortBodyC() {} //: Destructor. virtual bool IsAsync() const; //: Does port work asynchronously ? virtual bool Save(ostream &out) const; //: Save to ostream. virtual DPPortC ConnectedTo() const; //: Is this port connected to another ? // If not returns invalid handle. virtual bool GetAttr(const StringC &attrName,StringC &attrValue); //: Get a stream attribute. // Returns false if the attribute name is unknown. // This is for handling stream attributes such as frame rate, and compression ratios. virtual bool SetAttr(const StringC &attrName,const StringC &attrValue); //: Set a stream attribute. // Returns false if the attribute name is unknown. // This is for handling stream attributes such as frame rate, and compression ratios. protected: StringC portId; // Port ID, this can be accessed as the attribute 'id', defaults to empty string. }; //! userlevel=Develop //: Input port base body. class DPIPortBaseBodyC : public DPPortBodyC { public: DPIPortBaseBodyC() {} //: Default constuctor. DPIPortBaseBodyC(const StringC &nportId) : DPPortBodyC(nportId) {} //: Constructor with a port id. DPIPortBaseBodyC(istream &in) : DPPortBodyC(in) {} // Stream constuctor. virtual bool IsGetReady() const; //: Is some data ready ? // true = yes. // Defaults to !IsGetEOS(). virtual bool IsGetEOS() const; //: Has the End Of Stream been reached ? // true = yes. virtual const type_info &InputType() const; //: Input type. virtual bool Save(ostream &out) const { return DPPortBodyC::Save(out); } //: Save to ostream. virtual bool Discard(); //: Discard the next input datum. }; //! userlevel=Develop //: Input port body. template class DPIPortBodyC : public DPIPortBaseBodyC { public: DPIPortBodyC() {} //: Default constructor. DPIPortBodyC(const StringC &nportId) : DPIPortBaseBodyC(nportId) {} //: Constructor with a port id. DPIPortBodyC(istream &in) : DPIPortBaseBodyC(in) {} //: Stream constructor. virtual DataT Get() { cerr << "DPIPortBodyC::Get(), ERROR: Abstract method called. \n"; RavlAssert(0); return DataT(); } //: Get next piece of data. // May block if not ready, or it could throw an // DataNotReadyC exception. // NB. This function MUST be provided by client class. virtual bool Get(DataT &buff) { try { buff = Get(); } catch(DataNotReadyC &) { return false; } return true; } //: Try and get next piece of data. // This may not NOT block, if no data is ready // it will return false, and not set buff. // NB. The default version of this function uses // the Get() method defined above and so need // not be provided by derived classes. virtual IntT GetArray(SArray1dC &data); //: Get an array of data from stream. // returns the number of elements succesfully processed. // NB. This need NOT be overridden in client classes // unless fast handling of arrays of data elements is required. virtual const type_info &InputType() const { return typeid(DataT); } // Input type. virtual bool Save(ostream &out) const { return DPIPortBaseBodyC::Save(out); } //: Save to ostream. virtual bool Discard() { DataT tmp; return Get(tmp); } //: Discard the next input datum. }; template IntT DPIPortBodyC::GetArray(SArray1dC &data) { for(SArray1dIterC it(data);it;it++) { if(!Get(*it)) return it.Index().V(); } return data.Size(); } //! userlevel=Develop //: Output port base body. class DPOPortBaseBodyC : public DPPortBodyC { public: DPOPortBaseBodyC() {} //: Default constuctor. DPOPortBaseBodyC(const StringC &nportId) : DPPortBodyC(nportId) {} //: Constructor with a port id. DPOPortBaseBodyC(istream &in) : DPPortBodyC(in) {} //: Stream constuctor. virtual void PutEOS(); //: Put End Of Stream marker. virtual bool IsPutReady() const; //: Is port ready for data ? virtual const type_info &OutputType() const; //: Output type. virtual bool Save(ostream &out) const { return DPPortBodyC::Save(out); } //: Save to ostream. }; //! userlevel=Develop //: Output port body. template class DPOPortBodyC : public DPOPortBaseBodyC { public: DPOPortBodyC() {} //: Default constructor. DPOPortBodyC(const StringC &nportId) : DPOPortBaseBodyC(nportId) {} //: Constructor with a port id. DPOPortBodyC(istream &in) : DPOPortBaseBodyC(in) {} //: Default constructor. virtual bool Put(const DataT &) { cerr << "DPOPortBodyC::Put(), ERROR: Abstract method called. \n"; RavlAssert(0); return false; } //: Put data. // This function MUST be provided by client class. virtual IntT PutArray(const SArray1dC &data); //: Put an array of data to stream. // returns number of elements processed. // NB. This need NOT be overridden in client classes // unless fast handling of arrays of data elements is required. virtual const type_info &OutputType() const { return typeid(DataT); } //: Input type. virtual bool Save(ostream &out) const { return DPOPortBaseBodyC::Save(out); } //: Save to ostream. }; template IntT DPOPortBodyC::PutArray(const SArray1dC &data) { for(SArray1dIterC it(data);it;it++) { if(!Put(*it)) return it.Index().V(); } return data.Size(); } template class DPPlugC; /////////////////////////// //! userlevel=Develop //: Base port handle. class DPPortC : virtual public DPEntityC { public: DPPortC() : DPEntityC(false) {} //: Default constructor. DPPortC(DPPortBodyC &bod) : DPEntityC(bod) {} //: Constructor. DPPortC(istream &in) : DPEntityC(in) {} //: Stream constructor. DPPortC(const DPPortC &oth) : DPEntityC(oth) {} //: Copy constructor. protected: inline DPPortBodyC &Body() { return dynamic_cast (DPEntityC::Body()); } //: Access body. inline const DPPortBodyC &Body() const { return dynamic_cast (DPEntityC::Body()); } //: Access body. public: inline bool IsAsync() const { return Body().IsAsync(); } //: Does port work asynchronously ?? inline DPPortC ConnectedTo() const { return Body().ConnectedTo(); } //: Is this port connected to another ? // If not returns invalid handle. inline bool GetAttr(const StringC &attrName,StringC &attrValue) { return Body().GetAttr(attrName,attrValue); } //: Get a stream attribute. // Returns false if the attribute name is unknown. // This is for handling stream attributes such as frame rate, and compression ratios. StringC GetAttr(const StringC &attrName); //: Get a stream attribute. // Return the value of an attribute or an empty string if its unkown. // This is for handling stream attributes such as frame rate, and compression ratios. inline bool SetAttr(const StringC &attrName,const StringC &attrValue) { return Body().SetAttr(attrName,attrValue); } //: Set a stream attribute. // Returns false if the attribute name is unknown. // This is for handling stream attributes such as frame rate, and compression ratios. }; ////////////////////////// //! userlevel=Develop //: Input port base class. class DPIPortBaseC : public DPPortC { public: DPIPortBaseC() : DPEntityC(true) {} //: Default constructor. DPIPortBaseC(const DPIPortBaseC &oth) : DPEntityC(oth), DPPortC(oth) {} //: Copy constructor. DPIPortBaseC(DPIPortBaseBodyC &bod) : DPEntityC(bod), DPPortC(bod) {} //: Body constructor. DPIPortBaseC(istream &strm) : DPEntityC(strm) {} //: Stream constructor. DPIPortBaseC(const DPPortC &bod) : DPEntityC(bod), DPPortC(bod) { if(dynamic_cast(&DPEntityC::Body()) == 0) Invalidate(); } //: Body constructor. protected: inline DPIPortBaseBodyC &Body() { return dynamic_cast(DPEntityC::Body()); } //: Access body. inline const DPIPortBaseBodyC &Body() const { return dynamic_cast(DPEntityC::Body()); } //: Access body. public: inline const type_info &InputType() const { return Body().InputType(); } // Get type of input port. inline bool IsGetReady() const { return Body().IsGetReady(); } // Is valid data. inline bool IsGetEOS() const { return Body().IsGetEOS(); } // Is valid data. inline bool Discard() { return Body().Discard(); } //: Discard the next input datum. // returns true on success. }; ///////////////////////////////// //! userlevel=Normal //: Input port. template class DPIPortC : public DPIPortBaseC { public: DPIPortC() : DPEntityC(true) {} //: Default constructor. #ifdef __sgi__ DPIPortC(const DPIPortC &oth) : DPEntityC(oth), DPIPortBaseC(oth) {} //: Copy constructor. #endif DPIPortC(DPIPortBodyC &bod) : DPEntityC(bod), DPIPortBaseC(bod) {} //: Body constructor. DPIPortC(const DPIPortBaseC &oth) : DPEntityC(oth) { #if RAVL_CHECK if(IsValid()) { if(oth.InputType() != typeid(DataT)) { cerr << "DPIPortC() Type mismatch. " << oth.InputType().name() << " given to " << typeid(DataT).name() << endl; RavlAssert(0); } } #endif } //: Base constructor. DPIPortC(istream &in) : DPEntityC(in) {} //: Stream constructor. protected: DPIPortBodyC &Body() { return dynamic_cast &>(DPEntityC::Body()); } //: Access body. const DPIPortBodyC &Body() const { return dynamic_cast &>(DPEntityC::Body()); } //: Access body. public: inline DataT Get() { return Body().Get(); } // Get next piece of data. inline bool Get(DataT &buff) { return Body().Get(buff); } //: Try and get next piece of data. // If none, return false. // else put data into buff. inline IntT GetArray(SArray1dC &data) { return Body().GetArray(data); } //: Get an array of data from stream. // returns the number of elements processed. friend class DPPlugC; }; template ostream & operator<<(ostream & s,const DPIPortC &port) { port.Save(s); return s; } template istream & operator>>(istream & s, DPIPortC &port) { DPIPortC nport(s); port = nport; return s; } //////////////////////////////// //! userlevel=Develop //: Output port base. class DPOPortBaseC : public DPPortC { public: DPOPortBaseC() : DPEntityC(true) {} //: Default constructor. DPOPortBaseC(const DPOPortBaseC &oth) : DPEntityC(oth), DPPortC(oth) {} // Copy constructor. DPOPortBaseC(DPOPortBaseBodyC &bod) : DPEntityC(bod), DPPortC(bod) {} // Body constructor. DPOPortBaseC(istream &strm) : DPEntityC(strm) {} // Stream constructor. protected: inline DPOPortBaseBodyC &Body() { return dynamic_cast(DPEntityC::Body()); } //: Access body. inline const DPOPortBaseBodyC &Body() const { return dynamic_cast(DPEntityC::Body()); } //: Access body. public: inline void PutEOS() { Body().PutEOS(); } //: Put End Of Stream marker. inline const type_info &OutputType() const { return Body().OutputType(); } //: Get type of output port. }; ////////////////////////////// //! userlevel=Normal //: Output port. template class DPOPortC : public DPOPortBaseC { public: DPOPortC() : DPEntityC(true) {} // Default constructor. #ifdef __sgi__ DPOPortC(const DPOPortC &oth) : DPEntityC(oth), DPOPortBaseC(oth) {} //: Copy constructor. #endif DPOPortC(DPOPortBodyC &bod) : DPEntityC(bod), DPOPortBaseC(bod) {} //: Body constructor. DPOPortC(istream &in) : DPEntityC(in) {} //: Stream constructor. DPOPortC(const DPOPortBaseC &oth) : DPEntityC(oth) { #if RAVL_CHECK if(IsValid()) { if(oth.OutputType() != typeid(DataT)) { cerr << "DPOPortC() Type mismatch. " << oth.OutputType().name() << " given to " << typeid(DataT).name() << endl; RavlAssert(0); } } #endif } //: Base constructor. protected: DPOPortBodyC &Body() { return dynamic_cast &>(DPEntityC::Body()); } //: Access body. const DPOPortBodyC &Body() const { return dynamic_cast &>(DPEntityC::Body()); } //: Access body. public: inline bool Put(const DataT &dat) { return Body().Put(dat); } //: Put data to stream // Returns true if data is put into stream succesfully. inline IntT PutArray(const SArray1dC &data) { return Body().PutArray(data); } //: Put an array of data elements into a stream. // returns the number of elements processed from the array. inline bool IsPutReady() const { return Body().IsPutReady(); } // Is port ready for data ? }; template ostream & operator<<(ostream & s,const DPOPortC &port) { port.Save(s); return s; } template istream & operator>>(istream & s, DPOPortC &port) { DPOPortC nport(s); port = nport; return s; } } #endif