LCOV - code coverage report
Current view: top level - disks2/fathom/slaves/sigma2/cgm-occ-cov/build/itaps - CATag.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 271 481 56.3 %
Date: 2020-06-30 00:58:45 Functions: 30 42 71.4 %
Branches: 278 1005 27.7 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * Copyright 2006 Sandia Corporation.  Under the terms of Contract
       3                 :            :  * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
       4                 :            :  * retains certain rights in this software.
       5                 :            :  * 
       6                 :            :  * This library is free software; you can redistribute it and/or
       7                 :            :  * modify it under the terms of the GNU Lesser General Public
       8                 :            :  * License as published by the Free Software Foundation; either
       9                 :            :  * version 2.1 of the License, or (at your option) any later version.
      10                 :            :  * 
      11                 :            :  */
      12                 :            :  
      13                 :            : /**\file CATag.cpp
      14                 :            :  *
      15                 :            :  *\author Tim Tautges
      16                 :            :  *\author Jason Kraftcheck
      17                 :            :  *
      18                 :            :  * Original file from SNL TSTT repository was named CATag.
      19                 :            :  *
      20                 :            :  * Renamed CATag and added to ANL ITAPS repository by J.Kraftcheck,
      21                 :            :  * 2007-6-15
      22                 :            :  */
      23                 :            : 
      24                 :            : #include <algorithm>
      25                 :            : #include <iostream>
      26                 :            : 
      27                 :            : #include "CATag.hpp"
      28                 :            : #include "RefEntity.hpp"
      29                 :            : #include "RefEntityName.hpp"
      30                 :            : #include "RefEntityFactory.hpp"
      31                 :            : #include "CubitAttribManager.hpp"
      32                 :            : #include "RefGroup.hpp"
      33                 :            : #include "TDUniqueId.hpp"
      34                 :            : #include "CGMApp.hpp"
      35                 :            : #include "iGeomError.h"
      36                 :            : #include "TopologyEntity.hpp"
      37                 :            : #include "CubitMessage.hpp"
      38                 :            : 
      39                 :            : #define CHECK_SIZE(array, type, this_size, retval)  \
      40                 :            :   if (0 == array ## _allocated || array ## _allocated < this_size) {\
      41                 :            :     if (NULL != array) free(array); \
      42                 :            :     array = (type*)malloc(this_size*sizeof(type));\
      43                 :            :     array ## _allocated=this_size;\
      44                 :            :     if (NULL == array) { \
      45                 :            :       CGM_iGeom_setLastError(iBase_MEMORY_ALLOCATION_FAILED);\
      46                 :            :       return retval; \
      47                 :            :     }\
      48                 :            :   }; \
      49                 :            :   array ## _size = this_size;
      50                 :            : 
      51                 :         34 : static inline iBase_ErrorType tag_check_size( char*& array,
      52                 :            :                                               int& allocated,
      53                 :            :                                               int size )
      54                 :            : {
      55 [ +  - ][ -  + ]:         34 :   if (!array || !allocated) {
      56                 :          0 :     allocated = size;
      57                 :          0 :     array = (char*)malloc(allocated);
      58         [ #  # ]:          0 :     if (!array) 
      59                 :          0 :       return iBase_MEMORY_ALLOCATION_FAILED;
      60                 :            :   }
      61         [ -  + ]:         34 :   else if (allocated < size) {
      62                 :          0 :     return iBase_BAD_ARRAY_SIZE;
      63                 :            :   }
      64                 :            :   
      65                 :         34 :   return iBase_SUCCESS;
      66                 :            : }
      67                 :            : 
      68                 :            : #define TAG_CHECK_SIZE(array, allocated, size)  \
      69                 :            :   if (iBase_ErrorType tag_check_size_tmp = tag_check_size( array, allocated, size )) \
      70                 :            :     return tag_check_size_tmp;
      71                 :            : 
      72                 :            : #define RETURN(a) {CGM_iGeom_setLastError(a); return a;}
      73                 :            : 
      74                 :            : const char *CGMTagManager::CATag_NAME = "ITAPS_Tag";
      75                 :            : const char *CGMTagManager::CATag_NAME_INTERNAL = "ITAPS_TAG";
      76                 :            : 
      77                 :            : 
      78                 :            : class CSATagData 
      79                 :            : {
      80                 :            : public:
      81                 :          0 :   CSATagData() 
      82                 :            :       : dblData(0), dblDataSize(0), intData(0), intDataSize(0),
      83                 :          0 :         stringData(0), stringDataSize(0), indivStringSize(0) 
      84                 :          0 :     {}
      85                 :            : 
      86                 :          0 :   ~CSATagData() 
      87                 :            :     {
      88                 :          0 :     }
      89                 :            : 
      90                 :            :   void reset();
      91                 :            : 
      92                 :            :   double *dblData;
      93                 :            :   int dblDataSize;
      94                 :            :   
      95                 :            :   int *intData;
      96                 :            :   int intDataSize;
      97                 :            :   
      98                 :            :   char *stringData;
      99                 :            :   int stringDataSize;
     100                 :            :   int indivStringSize;
     101                 :            : };
     102                 :            : 
     103                 :            : 
     104                 :        687 : CubitAttrib *CGMTagManager::CATag_creator(RefEntity* entity, const CubitSimpleAttrib &p_csa)
     105                 :            : {
     106         [ +  - ]:        687 :   CubitSimpleAttrib csa = p_csa;
     107 [ +  - ][ +  - ]:        687 :   CATag *this_ca = new CATag(&instance(), entity, &csa);
                 [ +  - ]
     108         [ +  - ]:        687 :   return this_ca;
     109                 :            : }
     110                 :            :  
     111                 :            : 
     112         [ +  + ]:         40 : static CGMTagManager::TagInfo preset_tag_list[] = {
     113                 :            :    // tag size      tag name           tag data type  default active
     114                 :            :  { 0,              "",                 iBase_BYTES,   NULL,  false },
     115                 :            :  { 32,             "NAME",             iBase_BYTES,   NULL,   true },
     116                 :            :  { sizeof(int),    "GLOBAL_ID",        iBase_INTEGER, NULL,   true },
     117                 :            :  { sizeof(int),    "UNIQUE_ID",        iBase_INTEGER, NULL,   true },
     118                 :            :  { sizeof(int),    "MESH_INTERVAL",    iBase_INTEGER, NULL,   true },
     119                 :            :  { sizeof(double), "MESH_SIZE",        iBase_DOUBLE,  NULL,   true },
     120 [ +  - ][ +  - ]:          4 :  { 4,              "SIZE_FIRMNESS",    iBase_BYTES,   NULL,   true } };
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
           [ #  #  #  # ]
     121                 :            :  
     122                 :            : 
     123                 :            : CGMTagManager::TagInfo* const CGMTagManager::presetTagInfo = preset_tag_list;
     124                 :            : const int CGMTagManager::numPresetTag = sizeof(preset_tag_list)/sizeof(preset_tag_list[0]);
     125                 :            : 
     126                 :          4 : CGMTagManager::CGMTagManager() 
     127         [ +  - ]:          4 :     : interfaceGroup(NULL)
     128                 :            : {
     129                 :          4 :   pcTag = 0;
     130         [ +  - ]:          4 :   tagInfo.push_back(preset_tag_list[0]);
     131                 :            :   
     132                 :            :     // get the tag number for CATag
     133         [ +  - ]:          4 :   DLIList<int> tag_types;
     134                 :          4 :   int max_type = 0;
     135 [ +  - ][ +  - ]:          4 :   CubitAttribManager *cam = CGMApp::instance()->attrib_manager();
     136         [ +  - ]:          4 :   cam->get_registered_types(tag_types);
     137 [ +  - ][ +  + ]:         64 :   for (int i = 0; i < tag_types.size(); i++) {
     138         [ +  - ]:         60 :     int this_type = tag_types.get_and_step();
     139         [ +  + ]:         60 :     max_type = (max_type < this_type ? this_type : max_type);
     140                 :            :   }
     141                 :            :   
     142                 :          4 :   max_type++;
     143                 :            :   CubitStatus status = cam->register_attrib_type(max_type, CATag_NAME, CATag_NAME_INTERNAL,
     144                 :            :                                                  &CGMTagManager::CATag_creator, false, true, 
     145         [ +  - ]:          4 :                                                  true, true, true, false);
     146         [ -  + ]:          4 :   if (CUBIT_FAILURE == status) {
     147         [ #  # ]:          0 :     CGM_iGeom_setLastError( iBase_FAILURE, "Couldn't create cgm attribute for tags." );
     148                 :            :   }
     149                 :            :   else
     150                 :          4 :     CATag_att_type = max_type;
     151                 :            : 
     152                 :            :     // create preset tags, for CGM attributes we want to be visible as tags
     153                 :            :     // name - make same as in MBTagConventions
     154         [ +  + ]:         28 :   for (int i = 1; i < numPresetTag; ++i)
     155 [ +  - ][ +  - ]:         28 :     tagNameMap[presetTagInfo[i].tagName] = -i; // neg handles beginning with -1
     156                 :          4 : }
     157                 :            : 
     158         [ +  - ]:          8 : CGMTagManager::~CGMTagManager() 
     159                 :            : {
     160                 :            : 
     161                 :          4 : }
     162                 :            : 
     163                 :         24 : long CGMTagManager::pc_tag(const bool create_if_missing) 
     164                 :            : {
     165 [ +  + ][ +  - ]:         24 :   if (0 == pcTag && create_if_missing) {
     166                 :          1 :     pcTag = getTagHandle("__cgm_parent_child_tag");
     167         [ +  - ]:          1 :     if (0 == pcTag) {
     168                 :            :         // ok, one doesn't exist, create one
     169                 :          1 :       void *def_val[] = {NULL, NULL};
     170                 :            :       
     171                 :            :       createTag("__cgm_parent_child_tag", 2*sizeof(std::vector<RefGroup*>*),
     172         [ +  - ]:          1 :                 iBase_BYTES, (char*)def_val, &pcTag);
     173                 :            :     }
     174                 :            :   }
     175                 :            :   
     176                 :         24 :   return pcTag;
     177                 :            : }
     178                 :            : 
     179                 :          0 : void CSATagData::reset()  
     180                 :            : {
     181         [ #  # ]:          0 :   if (0 != dblData) free(dblData);
     182         [ #  # ]:          0 :   if (0 != intData) free(intData);
     183         [ #  # ]:          0 :   if (0 != stringData) free(stringData);
     184                 :          0 : }
     185                 :            :   
     186                 :          0 : iBase_ErrorType CGMTagManager::create_csa_tag(const char *tag_name, long *tag_handle) 
     187                 :            : {
     188                 :            :     // make a special tag type to hold csa data from CGM; this tag holds, in this order:
     189                 :            :     // a) dbl_data (double*), dbl_data_size (int)
     190                 :            :     // b) int_data (int*), int_data_size (int)
     191                 :            :     // c) string_data (char*), string_data_size (int), indiv_string_size (int)
     192                 :            :     //
     193                 :            :     // For string data, multiple strings are packed into a single string, with each string
     194                 :            :     // occupying indiv_string_size bytes and string_size indicating number of such strings
     195                 :            :     // in packed string
     196                 :            :     // 
     197                 :            :     // So, size of this tag is 3*sizeof(void*) + 4*sizeof(int), assuming pointers occupy
     198                 :            :     // same space regardless of what they point to
     199                 :            : 
     200         [ #  # ]:          0 :   CSATagData dum_data;
     201 [ #  # ][ #  # ]:          0 :   return createTag(tag_name, sizeof(CSATagData), iBase_BYTES, (char*)&dum_data, tag_handle);
     202                 :            : }
     203                 :            : 
     204                 :          0 : iBase_ErrorType CGMTagManager::set_csa_tag(RefEntity *this_ent,
     205                 :            :                                            long tag_handle,
     206                 :            :                                            CubitSimpleAttrib *csa_ptr) 
     207                 :            : {
     208         [ #  # ]:          0 :   CSATagData this_data;
     209                 :          0 :   CSATagData *this_data_ptr = &this_data;
     210                 :          0 :   int this_data_size = sizeof(CSATagData), this_data_alloc = this_data_size;
     211                 :            : 
     212                 :            :     // if data was set on this tag, reset in an attempt to not leak memory
     213                 :            :   iBase_ErrorType result = getArrData(&this_ent, 1, tag_handle, 
     214         [ #  # ]:          0 :                                       (char**)&this_data_ptr, &this_data_alloc, &this_data_size);
     215 [ #  # ][ #  # ]:          0 :   if (iBase_SUCCESS != result && iBase_TAG_NOT_FOUND != result) return result;
     216                 :            :   
     217 [ #  # ][ #  # ]:          0 :   if (iBase_TAG_NOT_FOUND != result) this_data.reset();
     218                 :            :   
     219                 :            :     // set the data
     220 [ #  # ][ #  # ]:          0 :   this_data.dblDataSize = csa_ptr->double_data_list().size();
     221                 :          0 :   this_data.dblData = (double*) malloc(this_data.dblDataSize*sizeof(double));
     222         [ #  # ]:          0 :   for (int i = 0; i < this_data.dblDataSize; i++)
     223 [ #  # ][ #  # ]:          0 :     this_data.dblData[i] = csa_ptr->double_data_list()[0];
     224                 :            :   
     225 [ #  # ][ #  # ]:          0 :   this_data.intDataSize = csa_ptr->int_data_list().size();
     226                 :          0 :   this_data.intData = (int*) malloc(this_data.intDataSize*sizeof(int));
     227         [ #  # ]:          0 :   for (int i = 0; i < this_data.intDataSize; i++)
     228 [ #  # ][ #  # ]:          0 :     this_data.intData[i] = csa_ptr->int_data_list()[i];
     229                 :            :   
     230                 :            :     // find longest string, then allocate
     231 [ #  # ][ #  # ]:          0 :   std::vector<CubitString> sd = csa_ptr->string_data_list();
                 [ #  # ]
     232                 :          0 :   this_data.indivStringSize = 0;
     233 [ #  # ][ #  # ]:          0 :   for (int i = 0; i < (int)sd.size(); i++) {
     234 [ #  # ][ #  # ]:          0 :     if (((int) sd[i].length()) > this_data.indivStringSize) 
                 [ #  # ]
     235 [ #  # ][ #  # ]:          0 :       this_data.indivStringSize = sd[i].length();
     236                 :            :   }
     237                 :            :     // round to next highest multiple of sizeof(int)
     238         [ #  # ]:          0 :   if (this_data.indivStringSize%sizeof(int) != 0) 
     239                 :          0 :     this_data.indivStringSize = ((this_data.indivStringSize/sizeof(int))+1)*sizeof(int);
     240                 :            :     // now allocate
     241         [ #  # ]:          0 :   this_data.stringDataSize = sd.size()*this_data.indivStringSize;
     242                 :          0 :   this_data.stringData = (char*) malloc(this_data.stringDataSize);
     243 [ #  # ][ #  # ]:          0 :   for (int i = 0; i < (int)sd.size(); i++)
     244         [ #  # ]:          0 :     strncpy(this_data.stringData+i*this_data.indivStringSize, sd[i].c_str(),
     245         [ #  # ]:          0 :             this_data.indivStringSize);
     246                 :            : 
     247         [ #  # ]:          0 :   result = setArrData(&this_ent, 1, tag_handle, (const char*)&this_data_ptr, sizeof(CSATagData));
     248                 :            :   
     249         [ #  # ]:          0 :   return result;
     250                 :            : }
     251                 :            :   
     252                 :          4 : iBase_ErrorType CGMTagManager::createTag (/*in*/ const char *tag_name,
     253                 :            :                                           /*in*/ const int tag_length,
     254                 :            :                                           /*in*/ const int tag_type,
     255                 :            :                                           /*in*/ char* default_value,
     256                 :            :                                           /*out*/ long *tag_handle)
     257                 :            : {
     258         [ +  - ]:          4 :   std::string tmp_name(tag_name);
     259 [ +  - ][ +  - ]:          8 :   TagInfo tmp_info = {tag_length, tmp_name, tag_type, NULL, true};
     260                 :            : 
     261         [ +  - ]:          4 :   std::map<std::string,long>::iterator mit = tagNameMap.find(tmp_name);
     262 [ +  - ][ +  - ]:          4 :   if (mit != tagNameMap.end()) {
                 [ -  + ]
     263                 :            :     // we found a tag with this name; is it still active?
     264 [ #  # ][ #  # ]:          0 :     bool active = (mit->second > 0 ? tagInfo[mit->second] :
     265 [ #  # ][ #  # ]:          0 :                    presetTagInfo[-mit->second]).isActive;
                 [ #  # ]
     266         [ #  # ]:          0 :     *tag_handle = mit->second;
     267         [ #  # ]:          0 :     if (active) {
     268         [ #  # ]:          0 :       CGM_iGeom_setLastError( iBase_TAG_ALREADY_EXISTS );
     269                 :          0 :       return iBase_TAG_ALREADY_EXISTS;
     270                 :            :     }
     271                 :            : 
     272 [ #  # ][ #  # ]:          0 :     tagInfo[*tag_handle] = tmp_info;
     273                 :            :   }
     274                 :            :   else {
     275                 :            :     // create a new tag entirely
     276         [ +  - ]:          4 :     tagInfo.push_back(tmp_info);
     277         [ +  - ]:          4 :     *tag_handle = tagInfo.size() - 1;
     278                 :            : 
     279                 :            :     // put the name and handle into the map too
     280 [ +  - ][ +  - ]:          4 :     tagNameMap[std::string(tag_name)] = *tag_handle;
                 [ +  - ]
     281                 :            :   }
     282                 :            : 
     283         [ +  + ]:          4 :   if (default_value != NULL) {
     284         [ +  - ]:          1 :     tagInfo[*tag_handle].defaultValue = (char *) malloc(tag_length);
     285         [ +  - ]:          1 :     memcpy(tagInfo[*tag_handle].defaultValue, default_value, tag_length);
     286                 :            :   }
     287                 :            : 
     288 [ +  - ][ +  - ]:          8 :   RETURN(iBase_SUCCESS);
     289                 :            : }
     290                 :            : 
     291                 :            : 
     292                 :          2 : iBase_ErrorType CGMTagManager::destroyTag (/*in*/ const long tag_handle,
     293                 :            :                                            /*in*/ const bool forced)
     294                 :            : {
     295         [ -  + ]:          2 :   if (!forced) {
     296                 :            :       // see whether this tag is still assigned anywhere
     297                 :            :       // not implemented yet
     298                 :          0 :     RETURN(iBase_NOT_SUPPORTED);
     299                 :            :   }
     300                 :            :   
     301                 :            :     // if we got here, assume we can delete it
     302         [ +  - ]:          2 :   TagInfo *tinfo = (tag_handle > 0 ? &tagInfo[tag_handle] : &presetTagInfo[-tag_handle]);
     303                 :          2 :   tinfo->isActive = false;
     304                 :            : 
     305                 :          2 :   RETURN(iBase_SUCCESS);
     306                 :            : }
     307                 :            : 
     308                 :          3 : const char *CGMTagManager::getTagName (/*in*/ const long tag_handle)
     309                 :            : {
     310                 :          3 :   CGM_iGeom_clearLastError();
     311                 :          1 :   return (tag_handle > 0 ? tagInfo[tag_handle].tagName.c_str() : 
     312         [ +  + ]:          4 :           presetTagInfo[-tag_handle].tagName.c_str());
     313                 :            : }
     314                 :            : 
     315                 :         10 : int CGMTagManager::getTagSize (/*in*/ const long tag_handle)
     316                 :            : {
     317                 :         10 :   CGM_iGeom_clearLastError();
     318                 :            :   return (tag_handle > 0 ? 
     319                 :          6 :           tagInfo[tag_handle].tagLength : 
     320         [ +  + ]:         16 :           presetTagInfo[-tag_handle].tagLength);
     321                 :            : }
     322                 :            : 
     323                 :         13 : long CGMTagManager::getTagHandle (/*in*/ const char *tag_name)
     324                 :            : {
     325                 :            :   std::map<std::string,long>::iterator it =
     326 [ +  - ][ +  - ]:         13 :     tagNameMap.find(std::string(tag_name));
                 [ +  - ]
     327 [ +  - ][ +  - ]:         13 :   if (it != tagNameMap.end()) {
                 [ +  + ]
     328 [ +  - ][ +  - ]:         20 :     bool active = (it->second > 0 ? tagInfo[it->second] :
     329 [ +  + ][ +  - ]:         20 :                    presetTagInfo[-it->second]).isActive;
                 [ +  - ]
     330         [ +  - ]:         11 :     if (active) {
     331         [ +  - ]:         11 :       CGM_iGeom_clearLastError();
     332         [ +  - ]:         11 :       return it->second;
     333                 :            :     }
     334                 :            :   }
     335                 :            : 
     336         [ +  - ]:          2 :   CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND );
     337                 :         13 :   return 0;
     338                 :            : }
     339                 :            : 
     340                 :          2 : int CGMTagManager::getTagType (/*in*/ const long tag_handle) 
     341                 :            : {
     342                 :          2 :   CGM_iGeom_clearLastError();
     343                 :            :   return (tag_handle > 0 ? 
     344                 :          2 :           tagInfo[tag_handle].tagType : 
     345         [ +  - ]:          4 :           presetTagInfo[-tag_handle].tagType);
     346                 :            : }
     347                 :            : 
     348                 :         34 : iBase_ErrorType CGMTagManager::getArrData (ARRAY_IN_DECL(RefEntity*, entity_handles),
     349                 :            :                                            /*in*/ const long tag_handle,
     350                 :            :                                            /*inout*/ ARRAY_INOUT_DECL(char, tag_value))
     351                 :            : {
     352         [ +  + ]:         34 :   TagInfo *tinfo = (tag_handle > 0 ? &tagInfo[tag_handle] : &presetTagInfo[-tag_handle]);
     353                 :         34 :   int tag_size = tinfo->tagLength;
     354                 :            :     // either way, we have to have that many bytes when we leave this function
     355                 :         34 :   const bool allocated_data_arr = (*tag_value_allocated == 0);
     356         [ -  + ]:         34 :   TAG_CHECK_SIZE(*tag_value, *tag_value_allocated, entity_handles_size*tinfo->tagLength);
     357                 :         34 :   char *val_ptr = *tag_value;
     358         [ +  + ]:         34 :   if (tag_handle < 0) {
     359         [ +  + ]:         39 :     for (int i = 0; i < entity_handles_size; i++) {
     360                 :            :       bool result;
     361         [ -  + ]:         31 :       if (NULL == entity_handles[i])
     362                 :          0 :         result = getPresetTagData(interface_group(), tag_handle, val_ptr, tinfo->tagLength);
     363                 :            :       else
     364                 :         31 :         result = getPresetTagData(entity_handles[i], tag_handle, val_ptr, tinfo->tagLength);
     365         [ -  + ]:         31 :       if (!result) {
     366         [ #  # ]:          0 :         if (allocated_data_arr) {
     367                 :          0 :           free(*tag_value);
     368                 :          0 :           *tag_value = 0;
     369                 :          0 :           *tag_value_allocated = 0;
     370                 :            :         }
     371                 :          0 :         RETURN(iBase_TAG_NOT_FOUND);
     372                 :            :       }
     373                 :         31 :       val_ptr += tinfo->tagLength;
     374                 :            :     }
     375                 :          8 :     *tag_value_size = entity_handles_size*tinfo->tagLength;
     376                 :          8 :     RETURN(iBase_SUCCESS);
     377                 :            :   }
     378                 :            : 
     379                 :         26 :   iBase_ErrorType result = iBase_SUCCESS, tmp_result;
     380                 :            : 
     381         [ +  + ]:        370 :   for (int i = 0; i < entity_handles_size; i++) {
     382                 :            :       // ok to cast away const-ness because "false" passed in for create_if_missing
     383                 :        344 :     RefEntity *this_ent = (NULL == entity_handles[i] ? interface_group() :
     384         [ -  + ]:        344 :                            const_cast<RefEntity*>(entity_handles[i]));
     385                 :        344 :     CATag *catag = get_catag(this_ent);
     386         [ +  + ]:        344 :     if (NULL != catag) {
     387                 :        337 :       tmp_result = catag->get_tag_data(tag_handle, val_ptr);
     388         [ -  + ]:        337 :       if (iBase_SUCCESS != tmp_result)
     389                 :          0 :         CGM_iGeom_setLastError( tmp_result, "Problem getting tag data." );
     390                 :            :     }
     391         [ +  + ]:          7 :     else if (NULL != tinfo->defaultValue) {
     392                 :          5 :       memcpy(val_ptr, tinfo->defaultValue, tinfo->tagLength);
     393                 :          5 :       tmp_result = iBase_SUCCESS;
     394                 :            :     }
     395                 :            :     else {
     396                 :          2 :       tmp_result = iBase_TAG_NOT_FOUND;
     397                 :          2 :       CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND );
     398                 :            :     }
     399                 :            : 
     400         [ +  + ]:        344 :     if (iBase_SUCCESS != tmp_result) result = tmp_result;
     401                 :            :     
     402                 :        344 :     val_ptr += tag_size;
     403                 :            :   }
     404                 :            : 
     405         [ +  + ]:         26 :   if (iBase_SUCCESS != result)
     406                 :          2 :     *tag_value_size = 0;
     407                 :            :   else
     408                 :         24 :     *tag_value_size = entity_handles_size*tinfo->tagLength;
     409                 :            : 
     410                 :         26 :   RETURN(result);
     411                 :            : }
     412                 :            : 
     413                 :         14 : iBase_ErrorType CGMTagManager::setArrData (/*in*/ ARRAY_IN_DECL(RefEntity*, entity_handles),
     414                 :            :                                            /*in*/ const long tag_handle,
     415                 :            :                                            /*in*/ const char *tag_values, const int tag_values_size)
     416                 :            : {
     417         [ +  + ]:         14 :   TagInfo *tinfo = (tag_handle > 0 ? &tagInfo[tag_handle] : &presetTagInfo[-tag_handle]);
     418                 :         14 :   int tag_size = tinfo->tagLength;
     419                 :            :   
     420                 :         14 :   const char *val_ptr = tag_values;
     421                 :            : 
     422                 :         14 :   iBase_ErrorType result = iBase_SUCCESS, tmp_result;
     423                 :            :   
     424         [ +  + ]:         14 :   if (tag_handle < 0) {
     425         [ +  + ]:          4 :     for (int i = 0; i < entity_handles_size; i++) {
     426         [ -  + ]:          2 :       if (NULL == entity_handles[i])
     427                 :          0 :         tmp_result = setPresetTagData(interface_group(), tag_handle, val_ptr, tag_size);
     428                 :            :       else
     429                 :          2 :         tmp_result = setPresetTagData(entity_handles[i], tag_handle, val_ptr, tag_size);
     430                 :            : 
     431                 :          2 :       val_ptr += tag_size;
     432         [ -  + ]:          2 :       if (iBase_SUCCESS != tmp_result) result = tmp_result;
     433                 :            :     }
     434                 :          2 :     RETURN(result);
     435                 :            :   }
     436                 :            : 
     437         [ +  + ]:        342 :   for (int i = 0; i < entity_handles_size; i++) {
     438                 :        330 :     RefEntity *this_ent = (NULL == entity_handles[i] ? interface_group() : 
     439         [ -  + ]:        330 :                            entity_handles[i]);
     440                 :        330 :     CATag *catag = get_catag(this_ent, true);
     441         [ -  + ]:        330 :     assert(NULL != catag);
     442                 :        330 :     catag->set_tag_data(tag_handle, val_ptr);
     443                 :        330 :     val_ptr += tag_size;
     444                 :            :   }
     445                 :            : 
     446                 :         12 :   RETURN(iBase_SUCCESS);
     447                 :            : }
     448                 :            : 
     449                 :          0 : iBase_ErrorType CGMTagManager::rmvArrTag (/*in*/ ARRAY_IN_DECL(RefEntity*, entity_handles),
     450                 :            :                                           /*in*/ const long tag_handle)
     451                 :            : {
     452         [ #  # ]:          0 :   for (int i = 0; i < entity_handles_size; i++) {
     453                 :          0 :     CATag *catag = get_catag((entity_handles[i] == NULL ? 
     454         [ #  # ]:          0 :                                  interface_group() : entity_handles[i]));
     455         [ #  # ]:          0 :     if (NULL != catag) catag->remove_tag(tag_handle);
     456                 :            :   }
     457                 :            : 
     458                 :          0 :   RETURN(iBase_SUCCESS);
     459                 :            : }
     460                 :            : 
     461                 :        322 : iBase_ErrorType CGMTagManager::getAllTags (/*in*/ const RefEntity* entity_handle,
     462                 :            :                                            /*inout*/ ARRAY_INOUT_DECL(long, tag_handles))
     463                 :            : {
     464                 :        322 :   int i = 0, uid = 0, tag_size;
     465                 :        322 :   char *uid_ptr = (char*) &uid;
     466         [ +  - ]:        322 :   bool has_uid = getPresetTagData(entity_handle, -3, uid_ptr, tag_size);
     467         [ -  + ]:        322 :   int num_tags = (has_uid ? 3 : 2);
     468                 :            : 
     469                 :            :   RefEntity *this_ent = (NULL == entity_handle ? interface_group() : 
     470 [ -  + ][ #  # ]:        322 :                          const_cast<RefEntity*>(entity_handle));
     471                 :            :   
     472                 :            :     // const-cast because we're passing in false for create_if_missing
     473         [ +  - ]:        322 :   CATag *catag = get_catag(this_ent);
     474         [ -  + ]:        322 :   if (NULL != catag) {
     475                 :            :       // need to check whether entity has a uid
     476         [ #  # ]:          0 :     num_tags += catag->tagData.size();
     477 [ #  # ][ #  # ]:          0 :     CHECK_SIZE(*tag_handles, long, num_tags, iBase_FAILURE);
         [ #  # ][ #  # ]
                 [ #  # ]
     478 [ #  # ][ #  # ]:          0 :     for (std::map<int,void*>::iterator tag_it = catag->tagData.begin();
         [ #  # ][ #  # ]
     479         [ #  # ]:          0 :          tag_it != catag->tagData.end(); tag_it++)
     480         [ #  # ]:          0 :       (*tag_handles)[i++] = (*tag_it).first;
     481                 :            :   }
     482                 :            :   else {
     483 [ -  + ][ #  # ]:        322 :     CHECK_SIZE(*tag_handles, long, num_tags, iBase_FAILURE);
         [ -  + ][ -  + ]
                 [ #  # ]
     484                 :            :   }
     485                 :        322 :   (*tag_handles)[i++] = -1;
     486                 :        322 :   (*tag_handles)[i++] = -2;
     487         [ -  + ]:        322 :   if (has_uid) (*tag_handles)[i++] = -3;
     488                 :            : 
     489         [ +  - ]:        322 :   RETURN(iBase_SUCCESS);
     490                 :            : }
     491                 :            : 
     492                 :        996 : CATag *CGMTagManager::get_catag(RefEntity *ent, 
     493                 :            :                                   const bool create_if_missing) 
     494                 :            : {
     495                 :        996 :   CubitAttrib *this_attrib = ent->get_cubit_attrib(CATag_att_type, create_if_missing);
     496         [ +  + ]:        996 :   if (NULL != this_attrib)
     497         [ +  - ]:        667 :     return dynamic_cast<CATag*>(this_attrib);
     498                 :            :   else
     499                 :        329 :     return NULL;
     500                 :            : }
     501                 :            : 
     502                 :          0 : RefGroup *CGMTagManager::interface_group(const bool create_if_missing) 
     503                 :            : {
     504         [ #  # ]:          0 :   if (NULL == interfaceGroup) 
     505                 :            :     interfaceGroup = 
     506 [ #  # ][ #  # ]:          0 :       dynamic_cast<RefGroup*>(RefEntityName::instance()->get_refentity("interface_group"));
                 [ #  # ]
     507                 :            :   
     508 [ #  # ][ #  # ]:          0 :   if (NULL == interfaceGroup && create_if_missing)
     509                 :          0 :     interfaceGroup = RefEntityFactory::instance()->construct_RefGroup("interface_group");
     510                 :            : 
     511                 :          0 :   return interfaceGroup;
     512                 :            : }
     513                 :            :   
     514                 :          2 : iBase_ErrorType CGMTagManager::setPresetTagData(RefEntity *entity, 
     515                 :            :                                                 const long tag_handle, 
     516                 :            :                                                 const char *tag_value, 
     517                 :            :                                                 const int tag_size) 
     518                 :            : {
     519   [ +  -  -  - ]:          2 :   switch (-tag_handle) {
     520                 :            :     case 1:
     521                 :            :         // entity name
     522         [ -  + ]:          2 :       if (presetTagInfo[-tag_handle].tagLength != tag_size) {
     523         [ #  # ]:          0 :         std::string tmp_str = "Tag of type '";
     524 [ #  # ][ #  # ]:          0 :         tmp_str += presetTagInfo[-tag_handle].tagName + "' is the wrong size.";
                 [ #  # ]
     525 [ #  # ][ #  # ]:          0 :         CGM_iGeom_setLastError(iBase_INVALID_ARGUMENT, tmp_str.c_str());
     526         [ #  # ]:          0 :         return iBase_INVALID_ARGUMENT;
     527                 :            :       }
     528         [ +  - ]:          2 :       entity->entity_name(CubitString(tag_value));
     529                 :          2 :       RETURN(iBase_SUCCESS);
     530                 :            :     case 2:
     531                 :            :         // entity id
     532                 :          0 :       CGM_iGeom_setLastError( iBase_NOT_SUPPORTED, "Can't set id of entities with this implementation." );
     533                 :          0 :       return iBase_NOT_SUPPORTED;
     534                 :            :     case 3:
     535                 :            :         // unique id
     536                 :          0 :       CGM_iGeom_setLastError( iBase_NOT_SUPPORTED, "Can't set unique id of entities with this implementation." );
     537                 :          0 :       return iBase_NOT_SUPPORTED;
     538                 :            :     case 4: // mesh interval
     539                 :            :     case 5: // mesh size
     540                 :            :     case 6: // mesh interval firmness
     541                 :            :     default:
     542                 :          0 :       CGM_iGeom_setLastError( iBase_NOT_SUPPORTED, "Can't set this tag on entities with this implementation." );
     543                 :          2 :       return iBase_NOT_SUPPORTED;
     544                 :            :   }
     545                 :            : 
     546                 :            :   CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND );
     547                 :            :   return iBase_TAG_NOT_FOUND;
     548                 :            : }
     549                 :            : 
     550                 :          0 : CubitSimpleAttrib* CGMTagManager::get_simple_attrib(RefEntity* entity,
     551                 :            :                                                     const char* name )
     552                 :            : {
     553         [ #  # ]:          0 :   TopologyEntity* te_ptr = dynamic_cast<TopologyEntity*>(entity);
     554 [ #  # ][ #  # ]:          0 :   TopologyBridge* tb_ptr = te_ptr ? te_ptr->bridge_manager()->topology_bridge() : 0;
                 [ #  # ]
     555         [ #  # ]:          0 :   if (!tb_ptr) {
     556         [ #  # ]:          0 :     CGM_iGeom_setLastError( iBase_INVALID_ENTITY_HANDLE, "Entity not topology" );
     557                 :          0 :     return 0;
     558                 :            :   }
     559         [ #  # ]:          0 :   DLIList<CubitSimpleAttrib> attr_list;
     560 [ #  # ][ #  # ]:          0 :   tb_ptr->get_simple_attribute("MESH_INTERVAL", attr_list);
                 [ #  # ]
     561 [ #  # ][ #  # ]:          0 :   if (attr_list.size() == 0) {
     562         [ #  # ]:          0 :     CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND, "No MESH_INTERVAL attribute" );
     563                 :          0 :     return 0;
     564                 :            :   }
     565 [ #  # ][ #  # ]:          0 :   CubitSimpleAttrib result = attr_list.pop();
     566 [ #  # ][ #  # ]:          0 :   CubitSimpleAttrib *p_result = new CubitSimpleAttrib(result);
     567         [ #  # ]:          0 :   return p_result;
     568                 :            : }
     569                 :            : 
     570                 :            : 
     571                 :        353 : bool CGMTagManager::getPresetTagData(const RefEntity *entity, 
     572                 :            :                                      const long tag_handle, 
     573                 :            :                                      char *tag_value, 
     574                 :            :                                      int &tag_size) 
     575                 :            : {
     576                 :            :   const char *this_name;
     577                 :            :   int name_len, val;
     578                 :            :   double dval;
     579                 :            :   int *this_id;
     580                 :            :   int *this_uid;
     581                 :            :   
     582 [ +  - ][ -  + ]:        353 :   if (-tag_handle >= numPresetTag || tag_handle >= 0) {
     583         [ #  # ]:          0 :     CGM_iGeom_setLastError( iBase_INVALID_TAG_HANDLE, "Invalid tag handle" );
     584                 :          0 :     return false;
     585                 :            :   }
     586                 :            :   
     587                 :        353 :   const TagInfo& info = presetTagInfo[-tag_handle];
     588                 :        353 :   tag_size = info.tagLength;
     589                 :            :   CubitSimpleAttrib* csa;
     590         [ +  - ]:        353 :   CubitString str;
     591                 :            :   
     592   [ +  +  +  -  :        353 :   switch (-tag_handle) {
                -  -  - ]
     593                 :            :     case 1:
     594                 :            :         // entity name
     595 [ +  - ][ +  - ]:          4 :       this_name = entity->entity_name().c_str();
                 [ +  - ]
     596                 :          4 :       name_len = strlen(this_name);
     597                 :            :         // if name is too long, truncate
     598         [ -  + ]:          4 :       if (name_len > info.tagLength)
     599                 :          0 :         name_len = info.tagLength;
     600                 :          4 :       strncpy( tag_value, this_name, name_len );
     601                 :            :         // if name is too short, pad with zero bytes
     602         [ +  - ]:          4 :       if (name_len < info.tagLength)
     603                 :          4 :        memset( tag_value + name_len, 0, (info.tagLength - name_len) );
     604                 :          4 :       return true;
     605                 :            :     case 2:
     606                 :            :         // entity id
     607                 :         27 :       tag_size = sizeof(int);
     608                 :         27 :       this_id = reinterpret_cast<int*>(tag_value);
     609         [ +  - ]:         27 :       *this_id = entity->id();
     610                 :         27 :       return true;
     611                 :            :     case 3:
     612                 :            :         // unique id
     613                 :        322 :       tag_size = sizeof(int);
     614                 :        322 :       this_uid = reinterpret_cast<int*>(tag_value);
     615                 :            :         // const_cast because we're passing false for create_if_missing
     616 [ +  - ][ +  - ]:        322 :       *this_uid = TDUniqueId::get_unique_id(const_cast<RefEntity*>(entity), false);
     617                 :        322 :       return (*this_uid == 0 ? false : true);
     618                 :            :     case 4: // mesh interval
     619         [ #  # ]:          0 :       csa = get_simple_attrib( const_cast<RefEntity*>(entity), "MESH_INTERVAL" );
     620         [ #  # ]:          0 :       if (!csa)
     621                 :          0 :         return false;
     622 [ #  # ][ #  # ]:          0 :       val = csa->int_data_list()[0];
     623                 :            :         // check if interval is set
     624                 :            :         // If a) the size is set and b) the firmness is LIMP, then
     625                 :            :         // the interval count has not been set.
     626 [ #  # ][ #  # ]:          0 :       if ( csa->string_data_list().size() && 
         [ #  # ][ #  # ]
     627 [ #  # ][ #  # ]:          0 :            csa->string_data_list()[0] == "LIMP" && 
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     628 [ #  # ][ #  # ]:          0 :            csa->int_data_list().size() > 1 && 
         [ #  # ][ #  # ]
     629 [ #  # ][ #  # ]:          0 :           !csa->int_data_list()[0])
     630                 :          0 :         val = 0;
     631 [ #  # ][ #  # ]:          0 :       delete csa;
     632 [ #  # ][ #  # ]:          0 :       if (val == 0 || val == CUBIT_INT_MIN) {
     633         [ #  # ]:          0 :         if (info.defaultValue)
     634                 :          0 :           val = *(int*)info.defaultValue;
     635                 :            :         else {
     636         [ #  # ]:          0 :           CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND, "Interval not set" );
     637                 :          0 :           return 0;
     638                 :            :         }
     639                 :            :       }
     640                 :          0 :       *(int*)tag_value = val;
     641                 :          0 :       return true;
     642                 :            :     case 5: // mesh size
     643         [ #  # ]:          0 :       csa = get_simple_attrib( const_cast<RefEntity*>(entity), "MESH_INTERVAL" );
     644         [ #  # ]:          0 :       if (!csa)
     645                 :          0 :         return false;
     646                 :            :         // if size value is invalid or flag indicates size has not been set...
     647 [ #  # ][ #  # ]:          0 :       if (csa->double_data_list().size() == 0 ||
         [ #  # ][ #  # ]
     648 [ #  # ][ #  # ]:          0 :           csa->double_data_list()[0] == CUBIT_DBL_MIN ||
         [ #  # ][ #  # ]
     649 [ #  # ][ #  # ]:          0 :          (csa->int_data_list().size() > 1 && !csa->int_data_list()[1])) {
         [ #  # ][ #  # ]
                 [ #  # ]
     650         [ #  # ]:          0 :         if (info.defaultValue)
     651                 :          0 :           dval = *(double*)info.defaultValue;
     652                 :            :         else {
     653 [ #  # ][ #  # ]:          0 :           delete csa;
     654         [ #  # ]:          0 :           CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND, "Mesh size not set" );
     655                 :          0 :           return false;
     656                 :            :         }
     657                 :            :       }
     658                 :            :       else
     659 [ #  # ][ #  # ]:          0 :         dval = csa->double_data_list()[0];
     660 [ #  # ][ #  # ]:          0 :       delete csa;
     661                 :          0 :       *(double*)tag_value = dval;
     662                 :          0 :       return true;
     663                 :            :     case 6: // interval firmness
     664         [ #  # ]:          0 :       csa = get_simple_attrib( const_cast<RefEntity*>(entity), "MESH_INTERVAL" );
     665         [ #  # ]:          0 :       if (!csa)
     666                 :          0 :         return false;
     667 [ #  # ][ #  # ]:          0 :       if (csa->string_data_list().size() < 2) {
                 [ #  # ]
     668 [ #  # ][ #  # ]:          0 :         delete csa;
     669         [ #  # ]:          0 :         CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND, "Interval firmness not set" );
     670                 :          0 :         return false;
     671                 :            :       }
     672 [ #  # ][ #  # ]:          0 :       str = csa->string_data_list()[1];
                 [ #  # ]
     673         [ #  # ]:          0 :       memcpy( tag_value, str.c_str(), 4 );
     674 [ #  # ][ #  # ]:          0 :       delete csa;
     675                 :          0 :       return true;
     676                 :            :   }
     677                 :            : 
     678         [ +  - ]:        353 :   return false;
     679                 :            : }
     680                 :            :         
     681                 :         15 : std::vector<RefGroup*> *CGMTagManager::pc_list(RefEntity *gentity, int list_no, 
     682                 :            :                                                const bool create_if_missing) 
     683                 :            : {
     684         [ -  + ]:         15 :   if (NULL == gentity) return NULL;
     685                 :            :   
     686                 :         15 :   int dum_tag_size = sizeof(std::vector<RefGroup*>*);
     687                 :         15 :   int dum = 2*dum_tag_size;
     688                 :            :   std::vector<RefGroup*> *pc_lists[2];
     689                 :         15 :   char *dum_ptr = (char*) pc_lists;
     690                 :            :   iBase_ErrorType result =
     691                 :            :     getArrData(&gentity, 1, pc_tag(create_if_missing), &dum_ptr, 
     692 [ +  - ][ +  - ]:         15 :                &dum, &dum);
     693         [ -  + ]:         15 :   assert(iBase_SUCCESS == result);
     694         [ -  + ]:         15 :   if (iBase_SUCCESS != result) {
     695 [ #  # ][ #  # ]:          0 :     PRINT_ERROR("Failed to get array data.\n");
         [ #  # ][ #  # ]
     696                 :          0 :     return NULL;
     697                 :            :   }
     698                 :            :   
     699 [ +  - ][ -  + ]:         15 :   if (0 > list_no || 1 < list_no) return NULL;
     700                 :            :   
     701 [ +  + ][ +  - ]:         15 :   if (NULL == pc_lists[list_no] && create_if_missing) {
     702 [ +  - ][ +  - ]:          6 :     pc_lists[list_no] = new std::vector<RefGroup*>();
     703                 :            :     result =
     704 [ +  - ][ +  - ]:          6 :       setArrData(&gentity, 1, pc_tag(), (char*)pc_lists, 2*dum_tag_size);
     705         [ -  + ]:          6 :     assert(iBase_SUCCESS == result);
     706         [ -  + ]:          6 :     if (iBase_SUCCESS != result) {
     707 [ #  # ][ #  # ]:          0 :       PRINT_ERROR("Failed to set array data.\n");
         [ #  # ][ #  # ]
     708                 :          0 :       return NULL;
     709                 :            :     }
     710                 :            :   }
     711                 :            : 
     712                 :         15 :   return pc_lists[list_no];
     713                 :            : }
     714                 :            : 
     715                 :          3 : void CGMTagManager::pc_list(RefEntity *gentity, std::vector<RefGroup*> *&parents,
     716                 :            :                             std::vector<RefGroup*> *&children,
     717                 :            :                             const bool create_if_missing)
     718                 :            : {
     719         [ -  + ]:          6 :   if (NULL == gentity) return;
     720                 :            : 
     721                 :          3 :   int dum_tag_size = sizeof(std::vector<RefGroup*>*);
     722                 :          3 :   int dum = 2*dum_tag_size;
     723                 :            :   std::vector<RefGroup*> *pc_lists[2];
     724                 :          3 :   char *dum_ptr = (char*) pc_lists;
     725                 :            :   iBase_ErrorType result =
     726                 :            :     getArrData(&gentity, 1, pc_tag(), 
     727 [ +  - ][ +  - ]:          3 :                &dum_ptr, &dum, &dum);
     728         [ -  + ]:          3 :   assert(iBase_SUCCESS == result);
     729         [ -  + ]:          3 :   if (iBase_SUCCESS != result) {
     730 [ #  # ][ #  # ]:          0 :     PRINT_ERROR("Failed to get array data.\n");
         [ #  # ][ #  # ]
     731                 :          0 :     return;
     732                 :            :   }
     733                 :            : 
     734 [ +  + ][ +  + ]:          3 :   if ((NULL == pc_lists[0] || NULL == pc_lists[1]) && create_if_missing) {
                 [ -  + ]
     735                 :          0 :     bool must_set = false;
     736         [ #  # ]:          0 :     for (int i = 0; i < 2; i++) {
     737         [ #  # ]:          0 :       if (NULL == pc_lists[i]) {
     738 [ #  # ][ #  # ]:          0 :         pc_lists[i] = new std::vector<RefGroup*>();
     739                 :          0 :         must_set = true;
     740                 :            :       }
     741                 :            :     }
     742         [ #  # ]:          0 :     if (must_set) {
     743                 :            :       result = setArrData(&gentity, 1, pc_tag(), (char*)pc_lists, 
     744 [ #  # ][ #  # ]:          0 :                           2*dum_tag_size);
     745         [ #  # ]:          0 :       assert(iBase_SUCCESS == result);
     746         [ #  # ]:          0 :       if (iBase_SUCCESS != result) {
     747 [ #  # ][ #  # ]:          0 :         PRINT_ERROR("Failed to set array data.\n");
         [ #  # ][ #  # ]
     748                 :          0 :         return;
     749                 :            :       }
     750                 :            :     }
     751                 :            :   }
     752                 :            :   
     753                 :          3 :   parents = pc_lists[0];
     754                 :          3 :   children = pc_lists[1];
     755                 :            : }
     756                 :            : 
     757                 :          2 : void CGMTagManager::get_pc_groups(RefGroup *this_grp, const int p_or_c, const int num_hops,
     758                 :            :                                   std::vector<RefGroup *> &group_ptrs) 
     759                 :            : {
     760         [ -  + ]:          4 :   if (NULL == this_grp) return;
     761                 :            :   
     762                 :          2 :   int next_hop = num_hops - 1;
     763         [ +  - ]:          2 :   std::vector<RefGroup*> tmp_groups;
     764                 :            :   
     765                 :            :     // get my children
     766         [ +  - ]:          2 :   std::vector<RefGroup*> *my_children = pc_list(this_grp, p_or_c, false);
     767         [ +  - ]:          2 :   if (NULL != my_children)
     768         [ +  - ]:          2 :     tmp_groups = *my_children;
     769                 :            :   
     770                 :            :     // get their children if we're not out of hops
     771         [ +  - ]:          2 :   std::vector<RefGroup*>::iterator vit;
     772         [ -  + ]:          2 :   if (0 < next_hop) {
     773 [ #  # ][ #  # ]:          0 :     for (vit = tmp_groups.begin(); vit != tmp_groups.end(); vit++)
         [ #  # ][ #  # ]
                 [ #  # ]
     774 [ #  # ][ #  # ]:          0 :       get_pc_groups(*vit, p_or_c, next_hop, group_ptrs);
     775                 :            :   }
     776                 :            :   
     777                 :            :     // now add mine to the list; make sure it isn't there already
     778 [ +  - ][ +  - ]:          5 :   for (vit = tmp_groups.begin(); vit != tmp_groups.end(); vit++) {
         [ +  - ][ +  - ]
                 [ +  + ]
     779 [ +  - ][ +  - ]:          3 :     if (std::find(group_ptrs.begin(), group_ptrs.end(), *vit) == group_ptrs.end())
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     780 [ +  - ][ +  - ]:          3 :       group_ptrs.push_back(*vit); 
     781         [ +  - ]:          2 :   }
     782                 :            : }
     783                 :            : 
     784         [ +  - ]:       2061 : CATag::~CATag() 
     785                 :            : {
     786 [ +  - ][ +  - ]:       2032 :   for (std::map<int, void*>::iterator 
                 [ +  + ]
     787 [ +  - ][ +  - ]:       1703 :          mit = tagData.begin(); mit != tagData.end(); mit++)
     788 [ +  - ][ +  - ]:        329 :     if (NULL != (*mit).second) free ((*mit).second);
                 [ +  - ]
     789         [ -  + ]:       1374 : }
     790                 :            : 
     791                 :            : 
     792                 :          0 : CATag::CATag(CGMTagManager *manager, RefEntity *entity) 
     793         [ #  # ]:          0 :     : CubitAttrib(entity), myManager(manager)
     794                 :            : {
     795                 :          0 : }
     796                 :            : 
     797                 :        687 : CATag::CATag(CGMTagManager *manager, RefEntity *owner, CubitSimpleAttrib *csa_ptr) 
     798         [ +  - ]:        687 :     : CubitAttrib(owner), myManager(manager)
     799                 :            : {
     800 [ +  - ][ +  - ]:        687 :   if (NULL != csa_ptr) add_csa_data(csa_ptr);
     801                 :        687 : }
     802                 :            : 
     803                 :          0 : CubitStatus CATag::reset()
     804                 :            : {
     805 [ #  # ][ #  # ]:          0 :   for (std::map<int, void*>::iterator 
                 [ #  # ]
     806 [ #  # ][ #  # ]:          0 :          mit = tagData.begin(); mit != tagData.end(); mit++)
     807 [ #  # ][ #  # ]:          0 :     if (NULL != (*mit).second) free ((*mit).second);
                 [ #  # ]
     808                 :            : 
     809                 :          0 :   tagData.clear();
     810                 :            : 
     811                 :          0 :   return CUBIT_SUCCESS;
     812                 :            : }
     813                 :            : 
     814                 :        362 : CubitSimpleAttrib CATag::cubit_simple_attrib() 
     815                 :            : {
     816                 :            :     //if (tagData.size() == 0) return NULL;
     817                 :            :   
     818         [ +  - ]:        362 :   std::vector<int, std::allocator<int> >int_data;
     819 [ +  - ][ +  - ]:        724 :   std::vector<CubitString> str_data;
     820 [ +  - ][ +  - ]:        724 :   std::vector<double> dbl_data;
     821                 :            : 
     822 [ +  - ][ +  - ]:        362 :   str_data.push_back(myManager->CATag_NAME_INTERNAL);
                 [ +  - ]
     823                 :            : 
     824                 :            :     // int data first gets the # tags on this entity
     825 [ +  - ][ +  - ]:        362 :   int_data.push_back(tagData.size());
     826                 :            : 
     827                 :            :     // for each tag:
     828 [ +  - ][ +  - ]:        732 :   for (std::map<int, void*>::iterator 
                 [ +  + ]
     829 [ +  - ][ +  - ]:        728 :          mit = tagData.begin(); mit != tagData.end(); mit++) {
     830         [ +  - ]:          4 :     long tag_handle = (*mit).first;
     831                 :            :     CGMTagManager::TagInfo *tinfo = (tag_handle > 0 ? 
     832                 :          4 :                                      &(myManager->tagInfo[tag_handle]) :
     833 [ +  - ][ +  - ]:          4 :                                      &(myManager->presetTagInfo[-tag_handle]));
     834                 :            : 
     835                 :            :       // store the name
     836 [ +  - ][ +  - ]:          4 :     str_data.push_back(tinfo->tagName.c_str());
         [ +  - ][ +  - ]
     837                 :            :     
     838                 :            :       // store the length in bytes
     839         [ +  - ]:          4 :     int_data.push_back(tinfo->tagLength);
     840                 :            :     
     841                 :            :       // now the data
     842                 :            :       // store the raw memory interpreted as an array of ints, padded to a full int
     843                 :          4 :     int tag_ints = tinfo->tagLength/4;
     844         [ -  + ]:          4 :     if (tinfo->tagLength % 4 != 0) tag_ints++;
     845                 :            :     
     846         [ +  - ]:          4 :     int *tag_data = reinterpret_cast<int*>((*mit).second);
     847         [ +  + ]:          8 :     for (int i = 0; i < tag_ints; i++)
     848         [ +  - ]:          4 :       int_data.push_back(tag_data[i]);
     849                 :            :   }
     850                 :            : 
     851                 :            :     // store the data on the csa
     852         [ +  - ]:        362 :   CubitSimpleAttrib csa(&str_data, &dbl_data, &int_data);
     853                 :            : 
     854         [ +  - ]:        724 :   return csa;
     855                 :            : }
     856                 :            : 
     857                 :        687 : void CATag::add_csa_data(CubitSimpleAttrib *csa_ptr) 
     858                 :            : {
     859                 :            :     // make sure it's a CATag
     860 [ +  + ][ +  - ]:        687 :   static CubitString my_type("CA_TAG");
         [ +  - ][ #  # ]
     861 [ +  - ][ +  - ]:        687 :   if (csa_ptr->character_type() != my_type) 
     862                 :        687 :     return;
     863                 :            : 
     864                 :          0 :   int num_attribs = csa_ptr->int_data_list()[0];
     865                 :            : 
     866                 :            :   int *tmp_data;
     867                 :            :   
     868         [ #  # ]:          0 :   for (int i = 0; i < num_attribs; i++) {
     869                 :            : 
     870                 :            :       // map the attrib name to a tag
     871                 :            :     std::map<std::string,long>::iterator pos =
     872 [ #  # ][ #  # ]:          0 :       myManager->tagNameMap.find(std::string(csa_ptr->string_data_list()[i].c_str()));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     873                 :            : 
     874                 :          0 :     long thandle = 0;
     875                 :            :     
     876 [ #  # ][ #  # ]:          0 :     if (pos == myManager->tagNameMap.end()) {
                 [ #  # ]
     877                 :            :         // tag doesn't exist - create one
     878 [ #  # ][ #  # ]:          0 :       myManager->createTag(csa_ptr->string_data_list()[i].c_str(),
     879 [ #  # ][ #  # ]:          0 :                            csa_ptr->int_data_list()[i], iBase_BYTES,
     880 [ #  # ][ #  # ]:          0 :                            NULL, &thandle);
     881                 :            :     }
     882         [ #  # ]:          0 :     else thandle = (*pos).second;
     883                 :            : 
     884                 :            :     
     885                 :          0 :     long tag_handle = thandle;
     886                 :            : 
     887                 :            :       // copy the ints to a temporary space we can get a ptr to...
     888 [ #  # ][ #  # ]:          0 :     int int_length = csa_ptr->int_data_list()[i];
     889         [ #  # ]:          0 :     if (int_length % 4 != 0) int_length++;
     890                 :          0 :     tmp_data = (int*) malloc(int_length*sizeof(int));
     891         [ #  # ]:          0 :     for (int j = 0; j < int_length; j++) 
     892 [ #  # ][ #  # ]:          0 :       tmp_data[j] = csa_ptr->int_data_list()[j];
     893                 :            : 
     894                 :            :       // now actually set the data
     895         [ #  # ]:          0 :     this->set_tag_data(tag_handle, tmp_data, true);
     896                 :            :   }
     897                 :            : }
     898                 :            :     
     899                 :          0 : void CATag::print() 
     900                 :            : {
     901                 :          0 :   std::cout << "This entity has " << tagData.size() << " tags.  Types are: " << std::endl;
     902 [ #  # ][ #  # ]:          0 :   for (std::map<int,void*>::iterator mit = tagData.begin(); mit != tagData.end(); mit++) 
         [ #  # ][ #  # ]
                 [ #  # ]
     903                 :            :   {
     904 [ #  # ][ #  # ]:          0 :     if ((*mit).first > 0)
     905 [ #  # ][ #  # ]:          0 :       std::cout << myManager->tagInfo[(*mit).first].tagName << std::endl;
         [ #  # ][ #  # ]
     906                 :            :     else
     907 [ #  # ][ #  # ]:          0 :       std::cout << myManager->presetTagInfo[-(*mit).first].tagName << std::endl;
                 [ #  # ]
     908                 :            :   }
     909                 :          0 : }
     910                 :            : 
     911                 :        337 : iBase_ErrorType CATag::get_tag_data(long tag_handle, void *tag_data) 
     912                 :            : {
     913         [ -  + ]:        337 :   assert(NULL != tag_data);
     914                 :            : 
     915                 :            :   CGMTagManager::TagInfo *tinfo = (tag_handle > 0 ? 
     916                 :        337 :                                    &(myManager->tagInfo[tag_handle]) : 
     917 [ +  - ][ +  - ]:        337 :                                    &(myManager->presetTagInfo[-tag_handle]));
     918                 :            :   
     919                 :            :     // check if this attribute has this tag
     920         [ +  - ]:        337 :   std::map<int, void*>::iterator tdpos = tagData.find(tag_handle);
     921 [ +  - ][ +  - ]:        337 :   if (tdpos == tagData.end()) {
                 [ -  + ]
     922         [ #  # ]:          0 :     if (NULL != tinfo->defaultValue)
     923                 :          0 :       memcpy(tag_data, tinfo->defaultValue, tinfo->tagLength);
     924                 :            :     else {
     925         [ #  # ]:          0 :       CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND );
     926                 :          0 :       return iBase_TAG_NOT_FOUND;
     927                 :            :     }
     928                 :            :     
     929                 :            :   }
     930                 :            :   
     931                 :            :   else
     932         [ +  - ]:        337 :     memcpy(tag_data, (*tdpos).second, tinfo->tagLength);
     933                 :            : 
     934         [ +  - ]:        337 :   RETURN(iBase_SUCCESS);
     935                 :            : }
     936                 :            :   
     937                 :        330 : iBase_ErrorType CATag::set_tag_data(long tag_handle, const void *tag_data, 
     938                 :            :                                      const bool can_shallow_copy)
     939                 :            : {
     940                 :            :   CGMTagManager::TagInfo *tinfo = (tag_handle > 0 ? 
     941                 :        330 :                                    &(myManager->tagInfo[tag_handle]) : 
     942 [ +  - ][ +  - ]:        330 :                                    &(myManager->presetTagInfo[-tag_handle]));
     943                 :            :   
     944                 :            :     // check if this attribute has this tag
     945         [ +  - ]:        330 :   std::map<int, void*>::iterator tdpos = tagData.find(tag_handle);
     946 [ +  - ][ +  - ]:        330 :   if (tdpos == tagData.end())
                 [ +  + ]
     947                 :            :     tdpos = tagData.insert(tagData.end(),
     948                 :            :                            std::pair<int,void*>(tag_handle,
     949 [ +  - ][ +  - ]:        329 :                                                 reinterpret_cast<void*>(0))); // XXX(msvc2010): complains about NULL cast to void*?
         [ +  - ][ +  - ]
     950                 :            :     
     951         [ +  - ]:        330 :   if (!can_shallow_copy) {
     952                 :            :       // need to copy the data; might need to allocate first
     953 [ +  - ][ +  + ]:        330 :     if ((*tdpos).second == NULL)
     954         [ +  - ]:        329 :       (*tdpos).second = malloc(tinfo->tagLength);
     955                 :            : 
     956         [ +  - ]:        330 :     memcpy((*tdpos).second, tag_data, tinfo->tagLength);
     957                 :            :   }
     958                 :            :   else {
     959                 :            :       // should shallow copy; might have to delete what's there already
     960 [ #  # ][ #  # ]:          0 :     if ((*tdpos).second != NULL) free((*tdpos).second);
                 [ #  # ]
     961                 :            :   
     962                 :            :       // if shallow copying, caller is saying we can copy, so cast away const
     963         [ #  # ]:          0 :     (*tdpos).second = const_cast<void*>(tag_data);
     964                 :            :   }
     965                 :            : 
     966         [ +  - ]:        330 :   RETURN(iBase_SUCCESS);
     967                 :            : }
     968                 :            : 
     969                 :          0 : void CATag::remove_tag(long tag_handle)
     970                 :            : {
     971         [ #  # ]:          0 :   tagData.erase(tag_handle);
     972                 :          0 : }
     973                 :            : 
     974                 :        358 : CubitStatus CATag::update() 
     975                 :            : {
     976         [ +  + ]:        358 :   if (tagData.empty())
     977                 :        356 :     this->delete_attrib(true);
     978                 :            : 
     979                 :        358 :   return CUBIT_SUCCESS;
     980 [ +  - ][ +  - ]:         16 : }

Generated by: LCOV version 1.11