Ssrc C++ Binding for Spread 1.0.15 Unit Test Coverage
Current view: top level - ssrc/spread - ScatterMessage.h (source / functions) Hit Total Coverage
Test: Ssrc C++/Lua/Perl/Python/Ruby Bindings for Spread 1.0.15 Unit Tests Lines: 33 41 80.5 %
Date: 2017-11-28 00:28:17 Functions: 10 14 71.4 %
Branches: 2 4 50.0 %

           Branch data     Line data    Source code
       1                 :            : /* Copyright 2006,2007 Savarese Software Research Corporation
       2                 :            :  *
       3                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       4                 :            :  * you may not use this file except in compliance with the License.
       5                 :            :  * You may obtain a copy of the License at
       6                 :            :  *
       7                 :            :  *     http://www.savarese.com/software/ApacheLicense-2.0
       8                 :            :  *
       9                 :            :  * Unless required by applicable law or agreed to in writing, software
      10                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      11                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12                 :            :  * See the License for the specific language governing permissions and
      13                 :            :  * limitations under the License.
      14                 :            :  */
      15                 :            : 
      16                 :            : /**
      17                 :            :  * @file
      18                 :            :  * This header defines the ScatterMessage class.
      19                 :            :  */
      20                 :            : 
      21                 :            : #ifndef __SSRC_SPREAD_SCATTER_MESSAGE_H
      22                 :            : #define __SSRC_SPREAD_SCATTER_MESSAGE_H
      23                 :            : 
      24                 :            : #include <ssrc/spread/Message.h>
      25                 :            : 
      26                 :            : #include <utility>
      27                 :            : #include <vector>
      28                 :            : 
      29                 :            : __BEGIN_NS_SSRC_SPREAD
      30                 :            : 
      31                 :            : /**
      32                 :            :  * ScatterMessage is a reusable container of multiple in-place data
      33                 :            :  * buffers.  It can be populated with Message instances or straight
      34                 :            :  * data pointers.  However, the auto-resizing feature of
      35                 :            :  * Mailbox::receive will be exercised only if the ScatterMessage
      36                 :            :  * contains at least one Message instance.  You will want to use a
      37                 :            :  * ScatterMessage primarily when you want to avoid multiple buffer
      38                 :            :  * copies.  For example, if you know the format of an incoming message
      39                 :            :  * you can add data pointers for each message part instead of parsing
      40                 :            :  * the message and copying the data.  Also, instead of allocating a
      41                 :            :  * message buffer and copying multiple data items to it for a send,
      42                 :            :  * you can populate a ScatterMessage with pointers to the data items
      43                 :            :  * and avoid an extra copy.
      44                 :            :  *
      45                 :            :  * We do not document ScatterMessage protected members because they
      46                 :            :  * are intended only for internal library use.
      47                 :            :  */
      48                 :         23 : class ScatterMessage : public BaseMessage {
      49                 :            : public:
      50                 :            : 
      51                 :            :   enum {
      52                 :            :     /**
      53                 :            :      * The maximum number of elements that can be added to a scatter
      54                 :            :      * message.
      55                 :            :      */
      56                 :            :     MaxScatterElements = MAX_CLIENT_SCATTER_ELEMENTS
      57                 :            :   };
      58                 :            : 
      59                 :            : private:
      60                 :            :   friend class Mailbox;
      61                 :            : 
      62                 :            :   typedef std::pair<Message *, int> value_type;
      63                 :            : 
      64                 :            :   Spread::scatter _scatter;
      65                 :            :   std::vector<value_type> _messages;
      66                 :            :   unsigned int _size;
      67                 :            : 
      68                 :         11 :   const Spread::scatter *scatter() const {
      69                 :         11 :     return &_scatter;
      70                 :            :   }
      71                 :            : 
      72                 :         11 :   Spread::scatter *scatter() {
      73                 :         11 :     return &_scatter;
      74                 :            :   }
      75                 :            : 
      76                 :            :   void init_pre_receive();
      77                 :            : 
      78                 :            :   void init_post_receive(int bytes_received);
      79                 :            : 
      80                 :          1 :   Message * message(const unsigned int index) {
      81                 :          1 :     return _messages[index].first;
      82                 :            :   }
      83                 :            : 
      84                 :          1 :   void resize_message(const unsigned int message_index,
      85                 :            :                       const unsigned int size)
      86                 :            :   {
      87                 :          1 :     value_type & v = _messages[message_index];
      88                 :          1 :     Message *m = v.first;
      89                 :            : 
      90                 :          1 :     _size-=m->size();
      91                 :          1 :     m->resize(size);
      92                 :          1 :     _size+=m->size();
      93                 :          1 :     _scatter.elements[v.second].buf = &((*m)[0]);
      94                 :          1 :     _scatter.elements[v.second].len = m->size();
      95                 :          1 :   }
      96                 :            : 
      97                 :            : protected:
      98                 :            : 
      99                 :            : #ifdef LIBSSRCSPREAD_ENABLE_MEMBERSHIP_INFO
     100                 :            : 
     101                 :          0 :   virtual int sp_get_membership_info(Spread::membership_info *info) const {
     102                 :          0 :     return Spread::SP_scat_get_memb_info(&_scatter, service(), info);
     103                 :            :   }
     104                 :            : 
     105                 :          0 :   virtual int sp_get_vs_set_members(const Spread::vs_set_info *vs_set,
     106                 :            :                                         Spread::group_type member_names[],
     107                 :            :                                         unsigned int member_names_count)
     108                 :            :     const
     109                 :            :   {
     110                 :            :     return
     111                 :          0 :       Spread::SP_scat_get_vs_set_members(&_scatter, vs_set, member_names,
     112                 :          0 :                                          member_names_count);
     113                 :            :   }
     114                 :            : 
     115                 :          0 :   virtual int sp_get_vs_sets_info(Spread::vs_set_info *vs_sets,
     116                 :            :                                       unsigned int num_vs_sets,
     117                 :            :                                       unsigned int *index)
     118                 :            :     const
     119                 :            :   {
     120                 :            :     return
     121                 :          0 :       Spread::SP_scat_get_vs_sets_info(&_scatter, vs_sets, num_vs_sets, index);
     122                 :            :   }
     123                 :            : 
     124                 :            : #endif
     125                 :            : 
     126                 :            : public:
     127                 :            : 
     128                 :            :   /**
     129                 :            :    * Creates a ScatterMessage with a size of zero and no message parts.
     130                 :            :    * See BaseMessage() for the default values of various properties,
     131                 :            :    * including service type.
     132                 :            :    */
     133                 :         23 :   ScatterMessage() : _messages(), _size(0) {
     134                 :         23 :     _scatter.num_elements = 0;
     135                 :         23 :   }
     136                 :            : 
     137                 :            :   /**
     138                 :            :    * Returns the total size of the message (comprising all of its
     139                 :            :    * parts) in bytes.
     140                 :            :    * @returns The total size of the message in bytes.
     141                 :            :    */
     142                 :          1 :   virtual unsigned int size() const {
     143                 :          1 :     return _size;
     144                 :            :   }
     145                 :            : 
     146                 :            :   /**
     147                 :            :    * Clears the message for reuse, resetting both its size and number
     148                 :            :    * of message parts to zero.
     149                 :            :    */
     150                 :         17 :   virtual void clear() {
     151                 :         17 :     _scatter.num_elements = 0;
     152                 :         17 :     _size = 0;
     153                 :         17 :     _messages.clear();
     154                 :         17 :   }
     155                 :            : 
     156                 :            :   /**
     157                 :            :    * Returns the number of parts that have been added to the message.
     158                 :            :    * @return The number of parts that have been added to the message.
     159                 :            :    */
     160                 :            :   unsigned int count_message_parts() const {
     161                 :            :     return _scatter.num_elements;
     162                 :            :   }
     163                 :            : 
     164                 :            :   /**
     165                 :            :    * Returns the number of Message instances that have been added to
     166                 :            :    * the message.  This number will be different from that returned by
     167                 :            :    * count_message_parts() if any straight pointers have ben added.
     168                 :            :    *
     169                 :            :    * @return The number of Message instances that have been added to the
     170                 :            :    * message.
     171                 :            :    */
     172                 :          2 :   unsigned int count_message_objects() const {
     173                 :          2 :     return _messages.size();
     174                 :            :   }
     175                 :            : 
     176                 :            :   bool add(const void *data, const unsigned int size);
     177                 :            : 
     178                 :            :   /**
     179                 :            :    * Adds a Message as a message part.  ScatterMessage will store a
     180                 :            :    * pointer to the original Message; therefore you should not alter
     181                 :            :    * the Message between the time it is added and when the send or
     182                 :            :    * receive is performed.  Note that for receives, each Message added
     183                 :            :    * will be filled up to its capacity, not its size.  The size will
     184                 :            :    * be ajdusted to reflect the amount of data written to the Message.
     185                 :            :    * The capacity will not be increased to accommodate more data
     186                 :            :    * except for the last Message added to the ScatterMessage.  If you
     187                 :            :    * don't want this behavior, use add(const void *, const unsigned int)
     188                 :            :    * instead, with <code>&message[0]</code> as the data argument.
     189                 :            :    * When using fixed-length message parts, it is often useful to tack
     190                 :            :    * on a Message as the last message part to store any unexpected
     191                 :            :    * overflow.
     192                 :            :    *
     193                 :            :    * @param message The Message to add.
     194                 :            :    * @return true if the message part was added, false if no more parts
     195                 :            :    *         can be added.
     196                 :            :    */
     197                 :         22 :   bool add(const Message & message) {
     198         [ +  - ]:         22 :     if(add(&message[0], message.size())) {
     199                 :            :       // We cheat and cast away constness!
     200                 :         44 :       _messages.push_back(value_type(const_cast<Message*>(&message),
     201         [ +  - ]:         66 :                                      _scatter.num_elements - 1));
     202                 :         22 :       return true;
     203                 :            :     } else
     204                 :          0 :       return false;
     205                 :            :   }
     206                 :            : };
     207                 :            : 
     208                 :            : 
     209                 :            : __END_NS_SSRC_SPREAD
     210                 :            : 
     211                 :            : #endif