Ssrc C++ Binding for Spread 1.0.15 Unit Test Coverage
Current view: top level - ssrc/spread - GroupList.h (source / functions) Hit Total Coverage
Test: Ssrc C++/Lua/Perl/Python/Ruby Bindings for Spread 1.0.15 Unit Tests Lines: 50 51 98.0 %
Date: 2017-11-28 00:28:17 Functions: 15 15 100.0 %
Branches: 11 18 61.1 %

           Branch data     Line data    Source code
       1                 :            : /* Copyright 2006 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 GroupList class.
      19                 :            :  */
      20                 :            : 
      21                 :            : #ifndef __SSRC_SPREAD_GROUP_LIST_H
      22                 :            : #define __SSRC_SPREAD_GROUP_LIST_H
      23                 :            : 
      24                 :            : #include <string>
      25                 :            : #include <ostream>
      26                 :            : 
      27                 :            : #include <ssrc/spread/detail/Buffer.h>
      28                 :            : 
      29                 :            : // sp.h includes stddef.h, so we need to include it before sp.h in
      30                 :            : // order to ensure it gets skipped while inside the Spread namespace.
      31                 :            : #include <cstddef>
      32                 :            : 
      33                 :            : __BEGIN_NS_SPREAD_INCLUDE
      34                 :            : # include <sp.h>
      35                 :            :   /** This is an internal typedef not meant for use in end-user code. */
      36                 :            :   typedef char group_type[MAX_GROUP_NAME];
      37                 :            : __END_NS_SPREAD_INCLUDE
      38                 :            : 
      39                 :            : __BEGIN_NS_SSRC_SPREAD
      40                 :            : 
      41                 :            : using std::string;
      42                 :            : 
      43                 :            : enum {
      44                 :            :   /**
      45                 :            :    * Maximum number of characters in a private name.  This is
      46                 :            :    * inconsistent with MaxSizeProcessName and MaxSizeGroupName
      47                 :            :    * (which are max + 1), but it's how the %Spread Toolkit does it;
      48                 :            :    * so we don't deviate, even though we'd rather they all be
      49                 :            :    * consistently defined as maximum values.
      50                 :            :    */
      51                 :            :   MaxSizePrivateName = MAX_PRIVATE_NAME,
      52                 :            :   /** Maximum number of characters in the name of a daemon process + 1. */
      53                 :            :   MaxSizeProcessName = MAX_PROC_NAME,
      54                 :            :   /** The maximum number of characters in a group name + 1. */
      55                 :            :   MaxSizeGroupName = MAX_GROUP_NAME,
      56                 :            :   /** The minimum value of a valid group name character. */
      57                 :            :   MinValidGroupNameChar = 36,
      58                 :            :   /** The maximum value of a valid group name character. */
      59                 :            :   MaxValidGroupNameChar = 126,
      60                 :            :   /** The value of the group name character separator. */
      61                 :            :   GroupNameSeparatorChar = 35
      62                 :            : };
      63                 :            : 
      64                 :            : 
      65                 :            : /**
      66                 :            :  * Splits a private group name into its private name and process name
      67                 :            :  * components.  This functions assumes it is provided a valid private
      68                 :            :  * group name, otherwise its behavior is undefined.
      69                 :            :  *
      70                 :            :  * @param private_group The private group name to split.
      71                 :            :  * @return A std::pair<string,string> where the first element is the
      72                 :            :  * private name component and the second element is the process name
      73                 :            :  * component.
      74                 :            :  */
      75                 :            : inline
      76                 :         21 : std::pair<string,string> split_private_group(const string & private_group) {
      77                 :         21 :   string::size_type length = private_group.find(GroupNameSeparatorChar, 1) - 1;
      78         [ +  - ]:         42 :   return std::pair<string,string>(string(private_group, 1, length),
      79                 :         42 :                                   string(private_group, length + 2,
      80                 :         63 :                                          private_group.size() - length - 2));
      81                 :            : }
      82                 :            : 
      83                 :            : /**
      84                 :            :  * GroupList is a container for %Spread group names.  You use it to
      85                 :            :  * determine the destination of a message or ascertain membership
      86                 :            :  * information.  A GroupList can be resized by its friend classes as
      87                 :            :  * needed so that you don't have to pre-allocate a very large list or
      88                 :            :  * handle short buffer errors.
      89                 :            :  */
      90                 :         37 : class GroupList {
      91                 :            : private:
      92                 :            :   struct group_type {
      93                 :            :     Spread::group_type group;
      94                 :            :   };
      95                 :            : 
      96                 :            :   typedef detail::Buffer<group_type> group_vector;
      97                 :            : 
      98                 :            :   group_vector _groups;
      99                 :            : 
     100                 :         31 :   const Spread::group_type *groups() const {
     101                 :         31 :     return reinterpret_cast<const Spread::group_type *>(&_groups[0]);
     102                 :            :   }
     103                 :            : 
     104                 :         22 :   Spread::group_type *groups() {
     105                 :            :     return
     106                 :         22 :       const_cast<Spread::group_type *>(reinterpret_cast<const Spread::group_type *>(&_groups[0]));
     107                 :            :   }
     108                 :            : 
     109                 :         13 :   unsigned int capacity() const {
     110                 :         13 :     return _groups.capacity();
     111                 :            :   }
     112                 :            : 
     113                 :         34 :   void resize(const unsigned int size) {
     114                 :         34 :     _groups.resize(size);
     115                 :         34 :   }
     116                 :            : 
     117                 :            : public:
     118                 :            : 
     119                 :            :   /**
     120                 :            :    * Creates an empty GroupList with the specified initial capacity.
     121                 :            :    */
     122                 :         37 :   explicit GroupList(const unsigned int capacity = 10) : _groups(capacity) { }
     123                 :            : 
     124                 :            :   /**
     125                 :            :    * Appends a group name to the list.
     126                 :            :    *
     127                 :            :    * @param group The group name to add.
     128                 :            :    */
     129                 :         19 :   void add(const string & group) {
     130                 :            :     int size;
     131                 :            :     group_type gname;
     132         [ +  - ]:         19 :     size = group.copy(gname.group, sizeof(Spread::group_type) - 1);
     133                 :         19 :     gname.group[size] = 0;
     134         [ +  - ]:         19 :     _groups.add(gname);
     135                 :         19 :   }
     136                 :            : 
     137                 :            :   /**
     138                 :            :    * Appends the contents another GroupList to this one.
     139                 :            :    *
     140                 :            :    * @param groups The GroupList to append.
     141                 :            :    */
     142                 :          4 :   void add(const GroupList & groups) {
     143         [ +  - ]:          4 :     if(&groups != this) {
     144                 :          4 :       unsigned int offset = size();
     145                 :          4 :       resize(size() + groups.size());
     146                 :          4 :       std::memcpy(GroupList::groups() + offset, groups.groups(),
     147                 :          8 :                   groups.size()*sizeof(group_type));
     148                 :            :     }
     149                 :          4 :   }
     150                 :            : 
     151                 :            :   /**
     152                 :            :    * Returns the group name at the specified index.  No bounds checking
     153                 :            :    * is performed; it is the responsibility of the caller to ensure a
     154                 :            :    * valid index is provided.
     155                 :            :    *
     156                 :            :    * @param index The index of the group name to return.
     157                 :            :    * @return The group name at the specified index.
     158                 :            :    */
     159                 :          8 :   string group(const unsigned int index) const {
     160         [ +  - ]:          8 :     return _groups[index].group;
     161                 :            :   }
     162                 :            : 
     163                 :            :   /** Same as {@link #group group(index)}. */
     164                 :          5 :   string operator[](const unsigned int index) const {
     165                 :          5 :     return group(index);
     166                 :            :   }
     167                 :            : 
     168                 :            :   /**
     169                 :            :    * Assigns the value of another GroupList to this one.
     170                 :            :    *
     171                 :            :    * @param groups The GroupList to copy.
     172                 :            :    * @return *this
     173                 :            :    */
     174                 :          4 :   GroupList & operator=(const GroupList & groups) {
     175         [ +  - ]:          4 :     if(&groups != this) {
     176                 :          4 :       resize(groups.size());
     177                 :          4 :       std::memcpy(GroupList::groups(), groups.groups(),
     178                 :          8 :                   size()*sizeof(group_type));
     179                 :            :     }
     180                 :          4 :     return *this;
     181                 :            :   }
     182                 :            : 
     183                 :            :   /** Empties the list. */
     184                 :         14 :   void clear() {
     185                 :         14 :     _groups.clear();
     186                 :         14 :   }
     187                 :            : 
     188                 :            :   /**
     189                 :            :    * Returns the number of groups in the list.
     190                 :            :    * @return The number of groups in the list.
     191                 :            :    */
     192                 :         66 :   unsigned int size() const {
     193                 :         66 :     return _groups.size();
     194                 :            :   }
     195                 :            : 
     196                 :            : private:
     197                 :            :   friend class Mailbox;
     198                 :            :   friend class BaseMessage;
     199                 :            : 
     200                 :            :   /**
     201                 :            :    * Tests that two GroupLists contain the exact same number of groups
     202                 :            :    * with the exact same values in the exact same order.  Use namespace
     203                 :            :    * std::rel_ops to gain the != operator.
     204                 :            :    *
     205                 :            :    * @param groups1 The first GroupList in the comparison.
     206                 :            :    * @param groups2 The second GroupList in the comparison.
     207                 :            :    * @return true if the GroupLists contain the same groups in the
     208                 :            :    * same order, false if not.
     209                 :            :    */
     210                 :          6 :   friend bool operator==(const GroupList & groups1,
     211                 :            :                          const GroupList & groups2)
     212                 :            :   {
     213                 :          6 :     unsigned int size = groups1.size();
     214                 :            : 
     215         [ +  + ]:          6 :     if(size != groups2.size())
     216                 :          2 :       return false;
     217                 :            :     else
     218         [ +  + ]:         16 :       while(size-- > 0) {
     219         [ -  + ]:          6 :         if(std::strncmp(groups1.groups()[size], groups2.groups()[size],
     220                 :            :                         MaxSizeGroupName))
     221                 :          0 :           return false;
     222                 :            :       }
     223                 :            : 
     224                 :          4 :     return true;
     225                 :            :   }
     226                 :            : 
     227                 :            :   /**
     228                 :            :    * Outputs the group names contained in the list&mdash;one per line.
     229                 :            :    *
     230                 :            :    * @param output The ostream to write to.
     231                 :            :    * @param groups The GroupList to output.
     232                 :            :    * @return The std::ostream output parameter.
     233                 :            :    */
     234                 :            :   friend std::ostream & operator<<(std::ostream & output,
     235                 :            :                                    const GroupList & groups)
     236                 :            :   {
     237                 :            :     for(unsigned int i = 0; i < groups.size(); ++i)
     238                 :            :       output << groups._groups[i].group << std::endl;
     239                 :            :     return output;
     240                 :            :   }
     241                 :            : };
     242                 :            : 
     243                 :            : __END_NS_SSRC_SPREAD
     244                 :            : 
     245                 :            : #endif