LCOV - code coverage report
Current view: top level - src - SerialObj.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 59 137 43.1 %
Date: 2010-12-13 Functions: 6 10 60.0 %
Branches: 22 86 25.6 %

           Branch data     Line data    Source code
       1                 :            : // $Id: SerialObj.cc 7075 2010-09-13 02:39:38Z vern $
       2                 :            : 
       3                 :            : #include "SerialObj.h"
       4                 :            : #include "Serializer.h"
       5                 :            : 
       6                 :            : TransientID::ID TransientID::counter = 0;
       7                 :            : 
       8                 :            : SerialObj::FactoryMap* SerialObj::factories = 0;
       9                 :            : SerialObj::ClassNameMap* SerialObj::names = 0;
      10                 :            : uint64 SerialObj::time_counter = NEVER + ALWAYS + 1;
      11                 :            : 
      12                 :          0 : SerialObj* SerialObj::Instantiate(SerialType type)
      13                 :            :         {
      14                 :          0 :         FactoryMap::iterator f = factories->find(type & SER_TYPE_MASK_EXACT);
      15         [ #  # ]:          0 :         if ( f != factories->end() )
      16                 :            :                 {
      17                 :          0 :                 SerialObj* o = (SerialObj*) (*f->second)();
      18                 :            : #ifdef DEBUG
      19                 :          0 :                 o->serial_type = o->GetSerialType();
      20                 :            : #endif
      21                 :          0 :                 return o;
      22                 :            :                 }
      23                 :            : 
      24                 :          0 :         run_time(fmt("Unknown object type 0x%08x", type));
      25                 :          0 :         return 0;
      26                 :            :         }
      27                 :            : 
      28                 :          0 : const char* SerialObj::ClassName(SerialType type)
      29                 :            :         {
      30                 :          0 :         ClassNameMap::iterator f = names->find(type);
      31         [ #  # ]:          0 :         if ( f != names->end() )
      32                 :          0 :                 return f->second;
      33                 :            : 
      34                 :          0 :         run_time(fmt("Unknown object type 0x%08x", type));
      35                 :          0 :         return "<no-class-name>";
      36                 :            :         }
      37                 :            : 
      38                 :        288 : void SerialObj::Register(SerialType type, FactoryFunc f, const char* name)
      39                 :            :         {
      40         [ +  + ]:        288 :         if ( ! factories )
      41                 :            :                 {
      42                 :          3 :                 factories = new FactoryMap;
      43                 :          3 :                 names = new ClassNameMap;
      44                 :            :                 }
      45                 :            : 
      46                 :        288 :         type = type & SER_TYPE_MASK_EXACT;
      47                 :            : 
      48                 :        288 :         FactoryMap::iterator i = factories->find(type);
      49         [ -  + ]:        288 :         if ( i != factories->end() )
      50                 :          0 :                 internal_error("SerialType 0x%08x registered twice", type);
      51                 :            : 
      52                 :        288 :         (*factories)[type] = f;
      53                 :        288 :         (*names)[type] = name;
      54                 :        288 :         }
      55                 :            : 
      56                 :        107 : inline bool SerializePID(SerialInfo* info, bool full, SerializationCache::PermanentID pid)
      57                 :            :         {
      58         [ -  + ]:        107 :         if ( ! SERIALIZE(full) )
      59                 :          0 :                 return false;
      60                 :            : 
      61         [ +  - ]:        107 :         if ( ! info->pid_32bit )
      62                 :        107 :                 return SERIALIZE(pid);
      63                 :            : 
      64                 :            :         // Broccoli compatibility mode with 32bit pids.
      65                 :          0 :         uint32 tmp = uint32(pid);
      66                 :        107 :         return SERIALIZE(tmp);
      67                 :            :         }
      68                 :            : 
      69                 :        107 : bool SerialObj::Serialize(SerialInfo* info) const
      70                 :            :         {
      71         [ -  + ]:        107 :         assert(info);
      72                 :            : 
      73         [ +  - ]:        107 :         if ( info->cont.NewInstance() )
      74                 :            :                 {
      75                 :        107 :                 SerializationCache::PermanentID pid = SerializationCache::NONE;
      76                 :            : 
      77                 :        107 :                 const TransientID* tid = GetTID();
      78                 :            : 
      79         [ -  + ]:        107 :                 if ( ! tid )
      80                 :          0 :                         internal_error("no tid - missing DECLARE_SERIAL?");
      81                 :            : 
      82         [ +  - ]:        107 :                 if ( info->cache )
      83                 :        107 :                         pid = info->s->Cache()->Lookup(*tid);
      84                 :            : 
      85 [ +  + ][ +  - ]:        107 :                 if ( pid != SerializationCache::NONE && info->cache )
      86                 :            :                         {
      87                 :         42 :                         DBG_LOG(DBG_SERIAL, "%s [%p, ref pid %lld, tid %lld]", __PRETTY_FUNCTION__, this, (long long) pid, tid->Value() );
      88                 :            : 
      89                 :         42 :                         DBG_LOG(DBG_SERIAL, "-- Caching");
      90                 :         42 :                         DBG_PUSH(DBG_SERIAL);
      91                 :            : 
      92         [ -  + ]:         42 :                         if ( ! SerializePID(info, false, pid) )
      93                 :            :                                 {
      94                 :          0 :                                 DBG_POP(DBG_SERIAL);
      95                 :          0 :                                 return false;
      96                 :            :                                 }
      97                 :            : 
      98                 :         42 :                         DBG_POP(DBG_SERIAL);
      99                 :         42 :                         return true;
     100                 :            :                         }
     101                 :            : 
     102         [ +  - ]:         65 :                 if ( info->cache )
     103                 :            :                         pid = info->s->Cache()->Register(this,
     104                 :            :                                                 SerializationCache::NONE,
     105                 :         65 :                                                 info->new_cache_strategy);
     106                 :            : 
     107                 :         65 :                 DBG_LOG(DBG_SERIAL, "%s [%p, new pid %lld, tid %lld]", __PRETTY_FUNCTION__, this, (long long) pid, tid->Value() );
     108                 :         65 :                 DBG_LOG(DBG_SERIAL, "-- Caching");
     109                 :         65 :                 DBG_PUSH(DBG_SERIAL);
     110                 :            : 
     111         [ -  + ]:         65 :                 if ( ! SerializePID(info, true, pid) )
     112                 :            :                         {
     113                 :          0 :                         DBG_POP(DBG_SERIAL);
     114                 :          0 :                         return false;
     115                 :            :                         }
     116                 :            : 
     117                 :         65 :                 info->type = SER_NONE;
     118                 :         65 :                 DBG_POP(DBG_SERIAL);
     119                 :            :                 }
     120                 :            : 
     121                 :         65 :         DBG_PUSH(DBG_SERIAL);
     122                 :         65 :         info->cont.SaveContext();
     123                 :         65 :         bool ret = DoSerialize(info);
     124                 :         65 :         info->cont.RestoreContext();
     125                 :         65 :         DBG_POP(DBG_SERIAL);
     126                 :            : 
     127         [ -  + ]:         65 :         if ( info->cont.ChildSuspended() )
     128                 :          0 :                 return ret;
     129                 :            : 
     130                 :            : #ifdef DEBUG
     131 [ -  + ][ #  # ]:         65 :         if ( debug_logger.IsEnabled(DBG_SERIAL) && IsBroObj(serial_type) )
                 [ -  + ]
     132                 :            :                 {
     133                 :          0 :                 ODesc desc(DESC_READABLE);
     134                 :          0 :                 ((BroObj*)this)->Describe(&desc);
     135                 :          0 :                 DBG_LOG(DBG_SERIAL, "-- Desc: %s", desc.Description());
     136                 :            :                 }
     137                 :            : #endif
     138                 :            : 
     139                 :        107 :         return ret;
     140                 :            :         }
     141                 :            : 
     142                 :          0 : SerialObj* SerialObj::Unserialize(UnserialInfo* info, SerialType type)
     143                 :            :         {
     144                 :          0 :         SerializationCache::PermanentID pid = SerializationCache::NONE;
     145                 :            : 
     146                 :          0 :         DBG_LOG(DBG_SERIAL, "%s", __PRETTY_FUNCTION__);
     147                 :            : 
     148                 :            :         bool full_obj;
     149                 :            : 
     150                 :          0 :         DBG_LOG(DBG_SERIAL, "-- Caching");
     151                 :          0 :         DBG_PUSH(DBG_SERIAL);
     152                 :            : 
     153                 :            :         bool result;
     154                 :            : 
     155         [ #  # ]:          0 :         if ( ! info->pid_32bit )
     156 [ #  # ][ #  # ]:          0 :                 result = UNSERIALIZE(&full_obj) && UNSERIALIZE(&pid);
     157                 :            :         else
     158                 :            :                 {
     159                 :            :                 // Broccoli compatibility mode with 32bit pids.
     160                 :            :                 uint32 tmp;
     161 [ #  # ][ #  # ]:          0 :                 result = UNSERIALIZE(&full_obj) && UNSERIALIZE(&tmp);
     162                 :          0 :                 pid = tmp;
     163                 :            :                 }
     164                 :            : 
     165         [ #  # ]:          0 :         if ( ! result )
     166                 :            :                 {
     167                 :          0 :                 DBG_POP(DBG_SERIAL);
     168                 :          0 :                 return false;
     169                 :            :                 }
     170                 :            : 
     171                 :          0 :         DBG_POP(DBG_SERIAL);
     172                 :            : 
     173         [ #  # ]:          0 :         DBG_LOG(DBG_SERIAL, "-- [%s pid %lld]", full_obj ? "obj" : "ref", (long long) pid);
     174                 :            : 
     175         [ #  # ]:          0 :         if ( ! full_obj )
     176                 :            :                 {
     177                 :            :                 // FIXME: Yet another const_cast to check eventually...
     178                 :            :                 SerialObj* obj =
     179                 :          0 :                         const_cast<SerialObj*>(info->s->Cache()->Lookup(pid));
     180         [ #  # ]:          0 :                 if ( obj )
     181                 :            :                         {
     182         [ #  # ]:          0 :                         if ( obj->IsBroObj() )
     183                 :          0 :                                 Ref((BroObj*) obj);
     184                 :          0 :                         return obj;
     185                 :            :                         }
     186                 :            : 
     187                 :            :                 // In the following we'd like the format specifier to match
     188                 :            :                 // the type of pid; but pid is uint64, for which there's
     189                 :            :                 // no portable format specifier.  So we upcast it to long long,
     190                 :            :                 // which is at least that size, and use a matching format.
     191                 :            :                 info->s->Error(fmt("unknown object %lld referenced",
     192                 :          0 :                                 (long long) pid));
     193                 :          0 :                 return 0;
     194                 :            :                 }
     195                 :            : 
     196                 :            :         uint16 stype;
     197         [ #  # ]:          0 :         if ( ! UNSERIALIZE(&stype) )
     198                 :          0 :                 return 0;
     199                 :            : 
     200                 :          0 :         SerialObj* obj = Instantiate(SerialType(stype));
     201                 :            : 
     202         [ #  # ]:          0 :         if ( ! obj )
     203                 :            :                 {
     204                 :          0 :                 info->s->Error("unknown object type");
     205                 :          0 :                 return 0;
     206                 :            :                 }
     207                 :            : 
     208                 :            : #ifdef DEBUG
     209                 :          0 :         obj->serial_type = stype;
     210                 :            : #endif
     211                 :            : 
     212                 :          0 :         const TransientID* tid = obj->GetTID();
     213         [ #  # ]:          0 :         if ( ! tid )
     214                 :          0 :                 internal_error("no tid - missing DECLARE_SERIAL?");
     215                 :            : 
     216         [ #  # ]:          0 :         if ( info->cache )
     217                 :          0 :                 info->s->Cache()->Register(obj, pid, info->new_cache_strategy);
     218                 :            : 
     219                 :          0 :         info->type = stype;
     220                 :            : 
     221                 :          0 :         DBG_PUSH(DBG_SERIAL);
     222         [ #  # ]:          0 :         if ( ! obj->DoUnserialize(info) )
     223                 :            :                 {
     224                 :          0 :                 DBG_POP(DBG_SERIAL);
     225                 :          0 :                 return 0;
     226                 :            :                 }
     227                 :            : 
     228                 :          0 :         DBG_POP(DBG_SERIAL);
     229                 :            : 
     230         [ #  # ]:          0 :         if ( ! SerialObj::CheckTypes(stype, type) )
     231                 :            :                 {
     232                 :          0 :                 info->s->Error("type mismatch");
     233                 :          0 :                 return 0;
     234                 :            :                 }
     235                 :            : 
     236                 :            : #ifdef DEBUG
     237 [ #  # ][ #  # ]:          0 :         if ( debug_logger.IsEnabled(DBG_SERIAL) && IsBroObj(stype) )
                 [ #  # ]
     238                 :            :                 {
     239                 :          0 :                 ODesc desc(DESC_READABLE);
     240                 :          0 :                 ((BroObj*)obj)->Describe(&desc);
     241                 :          0 :                 DBG_LOG(DBG_SERIAL, "-- Desc: %s", desc.Description());
     242                 :            :                 }
     243                 :            : #endif
     244                 :            : 
     245         [ #  # ]:          0 :         assert(obj);
     246                 :          0 :         return obj;
     247                 :            :         }
     248                 :            : 
     249                 :         65 : bool SerialObj::DoSerialize(SerialInfo* info) const
     250                 :            :         {
     251         [ -  + ]:         65 :         assert(info->type != SER_NONE);
     252                 :            : 
     253                 :            : #ifdef DEBUG
     254                 :         65 :         const_cast<SerialObj*>(this)->serial_type = info->type;
     255                 :            : #endif
     256                 :            : 
     257                 :         65 :         DBG_LOG(DBG_SERIAL, __PRETTY_FUNCTION__);
     258                 :         65 :         DBG_PUSH(DBG_SERIAL);
     259                 :            : 
     260                 :         65 :         uint16 stype = uint16(info->type);
     261                 :            : 
     262         [ +  - ]:         65 :         if ( ! info->new_cache_strategy )
     263                 :            :                 {
     264                 :            :                 // This is a bit unfortunate: to make sure we're sending
     265                 :            :                 // out the same types as in the past, we need to strip out
     266                 :            :                 // the new cache stable bit.
     267                 :         65 :                 stype &= ~SER_IS_CACHE_STABLE;
     268                 :            :                 }
     269                 :            : 
     270                 :         65 :         bool ret = SERIALIZE(stype);
     271                 :         65 :         DBG_POP(DBG_SERIAL);
     272                 :         65 :         return ret;
     273                 :            :         }
     274                 :            : 
     275                 :          0 : bool SerialObj::DoUnserialize(UnserialInfo* info)
     276                 :            :         {
     277                 :          0 :         DBG_LOG(DBG_SERIAL, __PRETTY_FUNCTION__);
     278                 :          0 :         return true;
     279 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8