summaryrefslogtreecommitdiff
path: root/protocols/ace/RMCast/Protocol.h
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/ace/RMCast/Protocol.h')
-rw-r--r--protocols/ace/RMCast/Protocol.h715
1 files changed, 715 insertions, 0 deletions
diff --git a/protocols/ace/RMCast/Protocol.h b/protocols/ace/RMCast/Protocol.h
new file mode 100644
index 00000000000..f9f2956920f
--- /dev/null
+++ b/protocols/ace/RMCast/Protocol.h
@@ -0,0 +1,715 @@
+// file : ace/RMCast/Protocol.h
+// author : Boris Kolpackov <boris@kolpackov.net>
+// cvs-id : $Id$
+
+#ifndef ACE_RMCAST_PROTOCOL_H
+#define ACE_RMCAST_PROTOCOL_H
+
+#include <ace/Refcounted_Auto_Ptr.h>
+
+#include <ace/Vector_T.h>
+#include <ace/Hash_Map_Manager.h>
+
+#include <ace/OS.h>
+#include <ace/CDR_Stream.h>
+#include <ace/INET_Addr.h>
+
+#include <ace/RMCast/Bits.h>
+
+namespace ACE_RMCast
+{
+ // Basic types.
+ //
+ typedef ACE_CDR::UShort u16;
+ typedef ACE_CDR::ULong u32;
+ typedef ACE_CDR::ULongLong u64;
+
+ typedef ACE_INET_Addr Address;
+
+ struct AddressHasher
+ {
+ unsigned long
+ operator() (Address const& a) const
+ {
+ unsigned long port (a.get_port_number ());
+ unsigned long ip (a.get_ip_address ());
+
+ port <<= sizeof (sizeof (unsigned long) - sizeof (unsigned short));
+
+ return port ^ ip;
+ }
+ };
+
+ //@@ Provide stream<< (Address const&)
+ //
+
+ typedef ACE_OutputCDR ostream;
+ typedef ACE_InputCDR istream;
+
+ struct Profile;
+
+ typedef
+ ACE_Refcounted_Auto_Ptr<Profile, ACE_Null_Mutex>
+ Profile_ptr;
+
+ struct Profile
+ {
+ public:
+ class Header
+ {
+ public:
+ Header (u16 id, u16 size)
+ : id_ (id), size_ (size)
+ {
+ }
+
+ Header (istream& is)
+ {
+ is >> id_ >> size_;
+ }
+
+ public:
+ u16
+ id () const
+ {
+ return id_;
+ }
+
+ u16
+ size () const
+ {
+ return size_;
+ }
+
+ protected:
+ void
+ size (u16 s)
+ {
+ size_ = s;
+ }
+
+ friend class Profile;
+
+ private:
+ u16 id_;
+ u16 size_;
+ };
+
+ public:
+ virtual
+ ~Profile ()
+ {
+ }
+
+ protected:
+ Profile (u16 id, u16 size, u16 boundary)
+ : header_ (id, size), boundary_ (boundary)
+ {
+ }
+
+ Profile (Header const& h, u16 boundary)
+ : header_ (h), boundary_ (boundary)
+ {
+ }
+ public:
+ u16
+ id () const
+ {
+ return header_.id ();
+ }
+
+ u16
+ size () const
+ {
+ return header_.size ();
+ }
+
+ u16
+ boundary () const
+ {
+ return boundary_;
+ }
+
+ protected:
+ void
+ size (u16 s)
+ {
+ header_.size (s);
+ }
+
+ public:
+ virtual void
+ serialize_body (ostream&) const = 0;
+
+ friend
+ ostream&
+ operator<< (ostream& os, Profile const& p);
+
+ private:
+ Header header_;
+ u16 boundary_;
+ };
+
+ inline
+ ostream&
+ operator<< (ostream& os, Profile::Header const& hdr)
+ {
+ os << hdr.id ();
+ os << hdr.size ();
+
+ return os;
+ }
+
+ inline
+ ostream&
+ operator<< (ostream& os, Profile const& p)
+ {
+ os << p.header_;
+ p.serialize_body (os);
+
+ return os;
+ }
+
+ //
+ //
+ //
+
+ class Message;
+
+ typedef
+ ACE_Refcounted_Auto_Ptr<Message, ACE_Null_Mutex>
+ Message_ptr;
+
+ class Message
+ {
+ public:
+ Message ()
+ : profiles_ (4)
+ {
+ }
+
+ Message (Message const& m)
+ : profiles_ (4)
+ {
+ for (Profiles::const_iterator i (m.profiles_); !i.done (); i.advance ())
+ {
+ // Shallow copy of profiles.
+ //
+ profiles_.bind ((*i).ext_id_, (*i).int_id_);
+ }
+ }
+
+ public:
+ struct duplicate {};
+
+ void
+ add (Profile_ptr p)
+ {
+ u16 id (p->id ());
+
+ if (profiles_.find (id) == 0)
+ {
+ throw duplicate ();
+ }
+
+ profiles_.bind (id, p);
+ }
+
+ Profile const*
+ find (u16 id) const
+ {
+ Profiles::ENTRY* e;
+
+ if (profiles_.find (id, e) == -1) return 0;
+
+ return e->int_id_.get ();
+ }
+
+ public:
+ size_t
+ size () const
+ {
+ size_t s (4); // 4 is for size (u32)
+
+ for (Profiles::const_iterator i (profiles_); !i.done (); i.advance ())
+ {
+ //@@ This is so broken: in CDR the padding depends on
+ // what comes after.
+ //
+ s += s % 2; // Padding to the boundary of 2.
+ s += 4; // Profile header: u16 + u16
+ s += s % (*i).int_id_->boundary (); // Padding to the b. of profile body.
+ s += (*i).int_id_->size (); // Profile body.
+ }
+
+ return s;
+ }
+
+ friend
+ ostream&
+ operator<< (ostream& os, Message const& m)
+ {
+ u32 s (m.size ());
+
+ os << s;
+
+ for (Profiles::const_iterator i (m.profiles_); !i.done (); i.advance ())
+ {
+ os << *((*i).int_id_);
+ }
+
+ return os;
+ }
+
+ typedef
+ ACE_Hash_Map_Manager<u16, Profile_ptr, ACE_Null_Mutex>
+ Profiles;
+
+ Profiles profiles_;
+ };
+
+ typedef
+ ACE_Vector<Message_ptr>
+ Messages;
+
+
+ //
+ //
+ //
+ struct From;
+
+ typedef
+ ACE_Refcounted_Auto_Ptr<From, ACE_Null_Mutex>
+ From_ptr;
+
+ struct From : Profile
+ {
+ static u16 const id = 0x0001;
+
+ public:
+ From (Header const& h, istream& is)
+ : Profile (h, 4)
+ {
+ u32 addr;
+ u16 port;
+
+ is >> addr;
+ is >> port;
+
+ address_ = Address (port, addr);
+ }
+
+ // 6 is CDR-specific.
+ //
+ From (Address const& addr)
+ : Profile (id, 6, 4), address_ (addr)
+ {
+ }
+
+ public:
+ Address const&
+ address () const
+ {
+ return address_;
+ }
+
+ public:
+ virtual void
+ serialize_body (ostream& os) const
+ {
+ u32 addr (address_.get_ip_address ());
+ u16 port (address_.get_port_number ());
+
+ os << addr;
+ os << port;
+ }
+
+ private:
+ Address address_;
+ };
+
+
+ //
+ //
+ //
+ struct To;
+
+ typedef
+ ACE_Refcounted_Auto_Ptr<To, ACE_Null_Mutex>
+ To_ptr;
+
+ struct To : Profile
+ {
+ static u16 const id = 0x0002;
+
+ public:
+ To (Header const& h, istream& is)
+ : Profile (h, 4)
+ {
+ u32 addr;
+ u16 port;
+
+ is >> addr;
+ is >> port;
+
+ address_ = Address (port, addr);
+ }
+
+ // 6 is CDR-specific.
+ //
+ To (Address const& addr)
+ : Profile (id, 6, 4), address_ (addr)
+ {
+ }
+
+ public:
+ Address const&
+ address () const
+ {
+ return address_;
+ }
+
+ public:
+ virtual void
+ serialize_body (ostream& os) const
+ {
+ u32 addr (address_.get_ip_address ());
+ u16 port (address_.get_port_number ());
+
+ os << addr;
+ os << port;
+ }
+
+ private:
+ Address address_;
+ };
+
+ //
+ //
+ //
+ struct Data;
+
+ typedef
+ ACE_Refcounted_Auto_Ptr<Data, ACE_Null_Mutex>
+ Data_ptr;
+
+ struct Data : Profile
+ {
+ static u16 const id = 0x0003;
+
+ public:
+ Data (Header const& h, istream& is)
+ : Profile (h, 1), buf_ (0), size_ (h.size ())
+ {
+ if (size_)
+ {
+ buf_ = reinterpret_cast<char*> (operator new (size_));
+ is.read_char_array (buf_, size_);
+ }
+
+ }
+
+ Data (void const* buf, size_t s)
+ : Profile (id, s, 1), buf_ (0), size_ (s)
+ {
+ if (size_)
+ {
+ buf_ = reinterpret_cast<char*> (operator new (size_));
+ ACE_OS::memcpy (buf_, buf, size_);
+ }
+ }
+
+ public:
+ char const*
+ buf () const
+ {
+ return buf_;
+ }
+
+ size_t
+ size () const
+ {
+ return size_;
+ }
+
+ public:
+ virtual void
+ serialize_body (ostream& os) const
+ {
+ os.write_char_array (buf_, size_);
+ }
+
+ private:
+ char* buf_;
+ size_t size_;
+ };
+
+ //
+ //
+ //
+ struct SN;
+
+ typedef
+ ACE_Refcounted_Auto_Ptr<SN, ACE_Null_Mutex>
+ SN_ptr;
+
+ struct SN : Profile
+ {
+ static u16 const id = 0x0004;
+
+ public:
+ SN (Header const& h, istream& is)
+ : Profile (h, 8)
+ {
+ is >> n_;
+ }
+
+ // 8 is CDR-specific.
+ //
+ SN (u64 n)
+ : Profile (id, 8, 8), n_ (n)
+ {
+ }
+
+ public:
+ u64
+ num () const
+ {
+ return n_;
+ }
+
+ public:
+ virtual void
+ serialize_body (ostream& os) const
+ {
+ os << n_;
+ }
+
+ private:
+ u64 n_;
+ };
+
+
+ //
+ //
+ //
+ struct NAK;
+
+ typedef
+ ACE_Refcounted_Auto_Ptr<NAK, ACE_Null_Mutex>
+ NAK_ptr;
+
+ struct NAK : Profile
+ {
+ static u16 const id = 0x0005;
+
+ typedef
+ ACE_Vector<u64>
+ SerialNumbers;
+
+ typedef
+ SerialNumbers::Iterator
+ iterator;
+
+ public:
+ NAK (Header const& h, istream& is)
+ : Profile (h, 8)
+ {
+ //@@ All the numbers are CDR-specific.
+ //
+ // 8 = u32 + u16 + 2(padding to u64)
+ //
+ for (long i (0); i < ((h.size () - 8) / 8); ++i)
+ {
+ u64 sn;
+ is >> sn;
+ sns_.push_back (sn);
+ }
+
+ u32 addr;
+ u16 port;
+
+ is >> port;
+ is >> addr;
+
+ address_ = Address (port, addr);
+ }
+
+ // 8 is CDR-specific.
+ //
+ NAK (Address const& src)
+ : Profile (id, 8, 8), address_ (src)
+ {
+ }
+
+ public:
+ void
+ add (u64 sn)
+ {
+ sns_.push_back (sn);
+ size (size () + 8); //@@ 8 is CDR-specific
+ }
+
+ public:
+ Address const&
+ address () const
+ {
+ return address_;
+ }
+
+
+ iterator
+ begin () /* const */
+ {
+ return iterator (sns_);
+ }
+
+ /*
+ iterator
+ end () const
+ {
+ return sns_.end ();
+ }
+ */
+
+ size_t
+ count () const
+ {
+ return sns_.size ();
+ }
+
+ public:
+ virtual void
+ serialize_body (ostream& os) const
+ {
+ NAK& this_ (const_cast<NAK&> (*this)); // Don't put in ROM.
+
+ // Stone age iteration.
+ //
+ for (iterator i (this_.begin ()); !i.done (); i.advance ())
+ {
+ u64* psn;
+ i.next (psn);
+ os << *psn;
+ }
+
+
+ u32 addr (address_.get_ip_address ());
+ u16 port (address_.get_port_number ());
+
+ os << port;
+ os << addr;
+ }
+
+ private:
+ Address address_;
+ SerialNumbers sns_;
+ };
+
+ //
+ //
+ //
+ struct NRTM;
+
+ typedef
+ ACE_Refcounted_Auto_Ptr<NRTM, ACE_Null_Mutex>
+ NRTM_ptr;
+
+ struct NRTM : Profile
+ {
+ static u16 const id = 0x0006;
+
+ public:
+ NRTM (Header const& h, istream& is)
+ : Profile (h, 8), map_ (10)
+ {
+ //@@ 16 is CDR-specific.
+ //
+ // 16 = u32 + u16 + 2(padding to u64) + u64
+ for (u16 i (0); i < (h.size () / 16); ++i)
+ {
+ u32 addr;
+ u16 port;
+ u64 sn;
+
+ is >> sn;
+ is >> port;
+ is >> addr;
+
+ map_.bind (Address (port, addr), sn);
+ }
+ }
+
+ NRTM ()
+ : Profile (id, 0, 8), map_ (10)
+ {
+ }
+
+ public:
+ void
+ insert (Address const& addr, u64 sn)
+ {
+ map_.bind (addr, sn);
+
+ size (size () + 16); //@@ 16 is CDR-specific.
+ }
+
+ u64
+ find (Address const& addr) const
+ {
+ u64 sn;
+
+ if (map_.find (addr, sn) == -1) return 0;
+
+ return sn;
+ }
+
+ bool
+ empty () const
+ {
+ return map_.current_size () == 0;
+ }
+
+ public:
+ virtual void
+ serialize_body (ostream& os) const
+ {
+ for (Map::const_iterator i (map_), e (map_, 1); i != e; ++i)
+ {
+ u32 addr ((*i).ext_id_.get_ip_address ());
+ u16 port ((*i).ext_id_.get_port_number ());
+ u64 sn ((*i).int_id_);
+
+ os << sn;
+ os << port;
+ os << addr;
+ }
+ }
+
+ private:
+ typedef
+ ACE_Hash_Map_Manager_Ex<Address,
+ u64,
+ AddressHasher,
+ ACE_Equal_To<Address>,
+ ACE_Null_Mutex>
+ Map;
+
+ Map map_;
+ };
+
+}
+
+/*
+inline
+std::ostream&
+operator<< (std::ostream& os, RMCast::Address const& a)
+{
+ char buf[64];
+ a.addr_to_string (buf, 64, 1);
+ return os << buf;
+}
+*/
+
+
+#endif // ACE_RMCAST_PROTOCOL_H