Reassemble.cpp

Go to the documentation of this file.
00001 // file      : ace/RMCast/Reassemble.cpp
00002 // author    : Boris Kolpackov <boris@kolpackov.net>
00003 // cvs-id    : $Id: Reassemble.cpp 78774 2007-07-04 06:06:59Z sowayaa $
00004 
00005 #include "Reassemble.h"
00006 #include "ace/OS_NS_stdlib.h"
00007 
00008 /*
00009 #include <iostream>
00010 using std::cerr;
00011 using std::endl;
00012 */
00013 
00014 namespace ACE_RMCast
00015 {
00016   Reassemble::
00017   Reassemble (Parameters const& params)
00018       : params_ (params)
00019   {
00020   }
00021 
00022   void Reassemble::recv (Message_ptr m)
00023   {
00024     Map::ENTRY* e;
00025     Address from (
00026       static_cast<From const*> (m->find (From::id))->address ());
00027 
00028     if (Data const* data = static_cast<Data const*> (m->find (Data::id)))
00029     {
00030       if (Part const* part = static_cast<Part const*> (m->find (Part::id)))
00031       {
00032         if (map_.find (from, e) == -1)
00033         {
00034           // First part of the message.
00035           //
00036 
00037           if (part->num () != 1)
00038           {
00039             // We assume that we received NoData for one of the preceding
00040             // fragments. Ignore this one.
00041             return;
00042           }
00043 
00044           Data_ptr new_data (new Data (data->buf (),
00045                                        static_cast<size_t> (data->size ()),
00046                                        static_cast<size_t> (part->total_size ())));
00047 
00048           //std::cerr << "part->total_size (): " << part->total_size () << endl;
00049 
00050           map_.bind (from, new_data);
00051         }
00052         else
00053         {
00054           // Next part of the message.
00055           //
00056 
00057           if (part->num () == 1)
00058             ACE_OS::abort ();
00059 
00060 
00061           Data const* data = static_cast<Data const*> (m->find (Data::id));
00062 
00063           Data_ptr& new_data = e->int_id_;
00064 
00065           ACE_OS::memcpy (new_data->buf () + new_data->size (),
00066                           data->buf (),
00067                           data->size ());
00068 
00069           //std::cerr << "data->size (): " << data->size () << endl
00070           //          << "new_data->size (): " << new_data->size () << endl
00071           //          << "new_data->capa (): " << new_data->capacity () << endl;
00072 
00073           new_data->size (new_data->size () + data->size ());
00074 
00075 
00076           if (part->num () == part->of ())
00077           {
00078             // Reassembly is complete.
00079             //
00080             if (part->total_size () != new_data->size ())
00081               ACE_OS::abort ();
00082 
00083             Message_ptr new_msg (new Message ());
00084 
00085             Address to (
00086               static_cast<To const*> (m->find (To::id))->address ());
00087 
00088             new_msg->add (Profile_ptr (new To (to)));
00089             new_msg->add (Profile_ptr (new From (from)));
00090             /*
00091              * Heads up... we need to add the new_data to new_msg then
00092              * unbind the entry that maps to new_data, which will decrement
00093              * its reference count. If the bound/refcounted pointer acted
00094              * polymorphically like a regular pointer does, we'd be able to
00095              * just pass new_data to add(Profile_Ptr) and it would work.
00096              * However, Profile_Ptr and Data_Ptr are not compatible, but
00097              * we can use the secret knowledge that both are instances of the
00098              * same template and that the pointers they contain really are
00099              * hierarchically compatible, and do this funky cast to get
00100              * the result we want.
00101              */
00102             //new_msg->add (*(reinterpret_cast<Profile_ptr*> (&new_data)));
00103 
00104             new_msg->add (Profile_ptr (new_data));
00105 
00106             map_.unbind (from);
00107 
00108             in_->recv (new_msg);
00109           }
00110         }
00111       }
00112       else
00113       {
00114         // Non-fragmented message. Make sure we are in the consistent state
00115         // and forward it up.
00116         //
00117         if (map_.find (from, e) != -1)
00118           ACE_OS::abort ();
00119 
00120         in_->recv (m);
00121       }
00122     }
00123     else if (m->find (NoData::id) != 0)
00124     {
00125       if (map_.find (from, e) != -1)
00126       {
00127         // We already received some fragments. Clean everyhting up.
00128         //
00129         map_.unbind (from);
00130       }
00131 
00132       in_->recv (m);
00133     }
00134   }
00135 }

Generated on Sun Jan 27 13:02:56 2008 for ACE_RMCast by doxygen 1.3.6