home *** CD-ROM | disk | FTP | other *** search
/ ftptest.leeds.ac.uk / 2015.02.ftptest.leeds.ac.uk.tar / ftptest.leeds.ac.uk / bionet / CAE-GROUP / SCL-WIN3x / SCL.EXE / ATTRIBUT.CPP < prev    next >
C/C++ Source or Header  |  1994-08-29  |  26KB  |  1,010 lines

  1. /*
  2. * NIST STEP Core Class Library
  3. * clstepcore/STEPattribute.cc
  4. * February, 1994
  5. * K. C. Morris
  6. * David Sauder
  7.  
  8. * Development of this software was funded by the United States Government,
  9. * and is not subject to copyright.
  10. */
  11.  
  12. /* $Id: STEPattribute.cc,v 2.0.1.2 1994/04/05 16:39:30 sauderd Exp $ */
  13.  
  14. //static char rcsid[] ="$Id: STEPattribute.cc,v 2.0.1.2 1994/04/05 16:39:30 sauderd Exp $";
  15.  
  16.  
  17. #include <read_func.h>
  18. #include <attribute.h>
  19. #include <sdai.h>
  20. #include <instmgr.h>
  21. #include <undefined.h>
  22. #include <aggregate.h>
  23. #include <Sentity.h>
  24. #include <select.h>
  25. #include <Binary.h>
  26.  
  27. const int Real_Num_Precision = 15;
  28.  
  29. /******************************************************************
  30. **      Functions for manipulating attribute
  31.  
  32. **  KNOWN BUGS:  
  33. **    -- error reporting does not include line number information
  34. **    -- null attributes are only handled through the attribute pointer class
  35. **       direct access of a null attribute will not indicate whether the 
  36. **       attribute is null in all cases (although a null value is available
  37. **       for entities and enumerations.) 
  38. **/
  39.  
  40.  
  41. ///////////////////////////////////////////////////////////////////////////////
  42. ///////////////////////////////////////////////////////////////////////////////
  43. // STEPattribute Functions
  44. ///////////////////////////////////////////////////////////////////////////////
  45. ///////////////////////////////////////////////////////////////////////////////
  46.  
  47. /******************************************************************
  48. // the value of the attribute is assigned from the supplied string
  49.  ******************************************************************/
  50.  
  51. Severity 
  52. STEPattribute::StrToVal (const char* s, InstMgr * instances, int addFileId)
  53. {
  54.     _error.ClearErrorMsg();    // also sets Severity to SEVERITY_NULL
  55.  
  56.     //  set the value to be null (reinitialize the attribute value)
  57.     set_null();
  58.  
  59.     int nullable = (AttrDescriptor->Optional().asInt() == sdaiTRUE);
  60.  
  61.     // an empty str gets assigned NULL
  62.     if (!s || (s[0] == '\0') )
  63.     {
  64.     if(nullable)
  65.         return SEVERITY_NULL;
  66.     else
  67.         _error.severity(SEVERITY_INCOMPLETE);
  68.         return SEVERITY_INCOMPLETE;
  69.     }
  70.  
  71.     istrstream in ((char *)s); // sz defaults to length of s
  72.     int valAssigned = 0;
  73.  
  74.     // read in value for attribute
  75.     switch (NonRefType())
  76.     {
  77.       case INTEGER_TYPE:
  78.       {
  79.       valAssigned = ReadInteger(*(ptr.i), s, &_error, 0);
  80.       break;
  81.       }
  82.       case REAL_TYPE:
  83.       {
  84.       valAssigned = ReadReal(*(ptr.r), s, &_error, 0);
  85.       break;
  86.       }
  87.       case NUMBER_TYPE:
  88.       {
  89.       valAssigned = ReadNumber(*(ptr.r), s, &_error, 0);
  90.       break;
  91.       }
  92.  
  93.       case ENTITY_TYPE:
  94.       {
  95.       STEPentity *se = ReadEntityRef(s, &_error, 0, instances, addFileId);
  96.       if( se != S_ENTITY_NULL )
  97.       {
  98.           if(EntityValidLevel(se, AttrDescriptor->NonRefTypeDescriptor(), 
  99.                   &_error) 
  100.          == SEVERITY_NULL)
  101.           *(ptr.c) = se;
  102.           else
  103.           *(ptr.c) = S_ENTITY_NULL;
  104.       }
  105.       else
  106.           *(ptr.c) = S_ENTITY_NULL;
  107.       break;
  108.       }
  109.  
  110.       case BINARY_TYPE:
  111.       {
  112.       ptr.b->StrToVal(s, &_error); // call class SdaiBinary::StrToVal()
  113.       break;
  114.       }
  115.       case STRING_TYPE:
  116.       {
  117.       *(ptr.S) = s; // using string class - don't need to declare space
  118.       break;
  119.       }
  120.  
  121.       case BOOLEAN_TYPE:
  122.       case LOGICAL_TYPE:
  123.       case ENUM_TYPE:
  124.     {
  125.         ptr.e->StrToVal (s, &_error, nullable);
  126.         break;
  127.     }
  128.  
  129.       case AGGREGATE_TYPE:
  130.         ptr.a -> StrToVal (s, &_error, 
  131.                AttrDescriptor -> AggrElemTypeDescriptor (), 
  132.                instances, addFileId);
  133.     break;
  134.  
  135.       case SELECT_TYPE:
  136.     if (_error.severity( ptr.sh->STEPread(in, &_error, instances) ) 
  137.         != SEVERITY_NULL)
  138.     _error.AppendToDetailMsg (ptr.sh ->Error ());
  139.         break;
  140.  
  141. //      case UNKNOWN_TYPE: // should never have this case
  142.       case GENERIC_TYPE:
  143.       default:
  144.     // other cases are the same for StrToVal and file
  145.     return STEPread(in, instances, addFileId);
  146.       }
  147.     return _error.severity();
  148. }
  149.  
  150.  
  151. /******************************************************************
  152.  ** Procedure:  STEPread
  153.  ** Returns:  Severity, which indicates success, or failure
  154.  **         value >= SEVERITY_WARNING means program can continue parsing input,
  155.  **         value <= SEVERITY_INPUT_ERROR  is fatal read error
  156.  ** Description:  the value of the attribute is read from istream
  157.  **               the format expected is STEP exchange file
  158.  **          modified to accept '$' as value for OPTIONAL ATTRIBUTE,
  159.  **             (since this function is used for reading files in both
  160.  **              formats, the function accepts either '$' (new format),
  161.  **              or nothing (old format)) 31-Jul-1992
  162.  ******************************************************************/
  163. // does not read the delimiter separating individual attributes (i.e. ',') or 
  164. // the delim separating the last attribute from the end of the entity (')').
  165.  
  166. Severity
  167. STEPattribute::STEPread (istream& in, InstMgr * instances, int addFileId)
  168. {
  169.  
  170.     char errStr[BUFSIZ];
  171.     errStr[0] = '\0';
  172.     char c ='\0';
  173.  
  174.     _error.ClearErrorMsg();    // also sets Severity to SEVERITY_NULL
  175.  
  176.     //  set the value to be null (reinitialize the attribute value)
  177.     set_null();
  178.  
  179.     in >> ws; // skip whitespace
  180.     in >> c;
  181.     in.putback (c);    //  leave input stream alone
  182.  
  183.     //  check for NULL or derived attribute value, return if either
  184.     switch (c)
  185.     {
  186.       case '$':
  187.       case ',':
  188.       case ')':
  189.     if (c == '$') 
  190.     {
  191.         in.get(c);
  192.         CheckRemainingInput(in, &_error, AttrDescriptor->TypeName(), ",)");
  193.     }
  194.     if(Nullable())  {
  195.         _error.severity(SEVERITY_NULL);
  196.     }
  197.     else {
  198.         _error.severity(SEVERITY_INCOMPLETE);
  199.         sprintf(errStr, " missing and required\n");
  200. //            " Warning: attribute '%s : %s' is missing and required.\n",
  201. //            Name(), TypeName());
  202.         _error.AppendToDetailMsg(errStr);
  203.     }
  204.     return _error.severity();
  205.  
  206.       case '*':
  207.     in.get(c);  // take * off the istream
  208.     if (IsDerived ())  
  209.         _error.severity(SEVERITY_NULL);
  210.     else {
  211.         _error.severity(SEVERITY_INCOMPLETE);
  212.         sprintf(errStr, " attribute not derived\n");
  213.         _error.AppendToDetailMsg(errStr);
  214.     }
  215.     CheckRemainingInput(in, &_error, AttrDescriptor->TypeName(), ",)");
  216.     return _error.severity();
  217.     }
  218.  
  219.     enum BASE_TYPE attrBaseType = NonRefType();
  220.     switch( attrBaseType )
  221.     {
  222.       case INTEGER_TYPE:
  223.       {
  224.         int valAssigned = ReadInteger(*(ptr.i), in, &_error, ",)");
  225.         return _error.severity();
  226.     }
  227.       case REAL_TYPE:
  228.       {
  229.         int valAssigned = ReadReal(*(ptr.r), in, &_error, ",)");
  230.         return _error.severity();
  231.     }
  232.       case NUMBER_TYPE:
  233.       {
  234.         int valAssigned = ReadNumber(*(ptr.r), in, &_error, ",)");
  235.         return _error.severity();
  236.     }
  237.       case STRING_TYPE: 
  238.       {
  239.         ptr.S->STEPread (in, &_error);
  240.         CheckRemainingInput(in, &_error, "string", ",)");
  241.         return _error.severity();
  242.     }
  243.       case BINARY_TYPE:
  244.     {    // call class SdaiBinary::STEPread()
  245.         ptr.b->STEPread(in, &_error);
  246.         CheckRemainingInput(in, &_error, "binary", ",)");
  247.         return _error.severity();
  248.     }
  249.       case BOOLEAN_TYPE:
  250.       {
  251. //        int nullable = (AttrDescriptor->Optional().asInt() == sdaiTRUE);
  252.         ptr.e->STEPread (in, &_error,  Nullable());
  253.         CheckRemainingInput(in, &_error, "boolean", ",)");
  254.         return _error.severity();
  255.     }
  256.       case LOGICAL_TYPE:
  257.       {
  258.         ptr.e->STEPread (in, &_error,  Nullable());
  259.         CheckRemainingInput(in, &_error, "logical", ",)");
  260.         return _error.severity();
  261.     }
  262.       case ENUM_TYPE:
  263.       {
  264.         ptr.e->STEPread (in, &_error,  Nullable());
  265.         CheckRemainingInput(in, &_error, "enumeration", ",)");
  266.         return _error.severity();
  267.     }
  268.       case AGGREGATE_TYPE:
  269.       {
  270.         ptr.a->STEPread(in, &_error, 
  271.                 AttrDescriptor->AggrElemTypeDescriptor(), 
  272.                 instances, addFileId);
  273.  
  274.         // cannot recover so give up and let STEPentity recover
  275.         if(_error.severity() < SEVERITY_WARNING)
  276.         return _error.severity();
  277.  
  278.         // check for garbage following the aggregate
  279.         CheckRemainingInput(in, &_error, "aggregate", ",)");
  280.         return _error.severity();
  281.     }
  282.       case ENTITY_TYPE:
  283.       {
  284.         STEPentity *se = ReadEntityRef(in, &_error, ",)", instances, 
  285.                        addFileId);
  286.         if( se != S_ENTITY_NULL )
  287.         {
  288.         if(EntityValidLevel(se, 
  289.                     AttrDescriptor->NonRefTypeDescriptor(), 
  290.                     &_error) == SEVERITY_NULL)
  291.             *(ptr.c) = se;
  292.         else
  293.         {
  294.             *(ptr.c) = S_ENTITY_NULL;
  295.         }
  296.         }
  297.         else
  298.         *(ptr.c) = S_ENTITY_NULL;
  299. //        CheckRemainingInput(in, &_error, "enumeration", ",)");
  300.         return _error.severity();
  301.  
  302.     }
  303.       case SELECT_TYPE:
  304.         if (_error.severity( ptr.sh->STEPread(in, &_error, instances, addFileId) ) 
  305.           != SEVERITY_NULL)
  306.         _error.AppendToDetailMsg (ptr.sh ->Error ());
  307.         CheckRemainingInput(in, &_error, "select", ",)");
  308.         return _error.severity();
  309.  
  310.       case GENERIC_TYPE:
  311.       {
  312.        cerr << "Internal error:  " << __FILE__ <<  __LINE__
  313.            << "\n" << _POC_ "\n";
  314.        _error.GreaterSeverity (SEVERITY_BUG);
  315.         return _error.severity();
  316.     }
  317.  
  318.       case UNKNOWN_TYPE:
  319.       case REFERENCE_TYPE:
  320.       default:
  321.       {
  322.         // bug
  323.        cerr << "Internal error:  " << __FILE__ <<  __LINE__
  324.            << "\n" << _POC_ "\n";
  325.        _error.GreaterSeverity (SEVERITY_BUG);
  326.         return _error.severity();
  327.     }
  328.     }
  329. }
  330.  
  331. /******************************************************************
  332.  ** Procedure:  asStr
  333.  ** Parameters:  
  334.  ** Returns:  
  335.  ** Description:  the value of the attribute is returned as a string.
  336.  ** Side Effects:  
  337.  ** Status:  complete 3/91
  338.  ******************************************************************/
  339. const char *
  340. STEPattribute::asStr (SCLstring& str) const
  341. {
  342. //  char attrVal[BUFSIZ];
  343. //  attrVal[0] = '\0';
  344.  
  345.     str.set_null();
  346.     if (is_null ()) return str = "";
  347.  
  348.     switch (NonRefType()) {
  349.       case INTEGER_TYPE:
  350.       str.Append (*(ptr.i));
  351. //    sprintf ( attrVal,"%ld",*(ptr.i));
  352.     break;
  353.  
  354.       case NUMBER_TYPE:
  355.       case REAL_TYPE:
  356.       str.Append (*(ptr.r));
  357. //    sprintf (attrVal, "%.*g", (int) Real_Num_Precision, *(ptr.r));
  358.     break;      
  359.  
  360.       case ENTITY_TYPE:
  361.     // print instance id only if not empty pointer
  362.     // and has value assigned
  363.     if ((*(ptr.c) == S_ENTITY_NULL) || (*(ptr.c) == 0))
  364.         break;
  365.     else
  366.     {
  367.         (*(ptr.c))->STEPwrite_reference (str);
  368. //        strncpy(attrVal, str.chars(), str.Length()+1);
  369.     }
  370.     break;      
  371.     
  372.       case BINARY_TYPE:
  373.     if( !( (ptr.b)->is_null() ) )
  374.         (ptr.b) -> STEPwrite (str);
  375. //        strncpy(attrVal, str.chars(), str.Length()+1);
  376.     break;
  377.  
  378.       case STRING_TYPE:
  379.     if( !( (ptr.S)->is_null() ) )
  380.         return (ptr.S) -> asStr (str);
  381.     break;
  382.     
  383.       case AGGREGATE_TYPE:
  384.       return  ptr.a->asStr(str) ;
  385. //    sprintf ( attrVal, "%s", ptr.a->asStr() );
  386.  
  387.       case ENUM_TYPE:
  388.       case BOOLEAN_TYPE:
  389.       case LOGICAL_TYPE:
  390.         return ptr.e -> asStr(str);
  391.  
  392.       case SELECT_TYPE:
  393.       ptr.sh -> STEPwrite (str);
  394.       return str;
  395. //      strncpy (attrVal, tmp.chars(), BUFSIZ);
  396.  
  397.       case REFERENCE_TYPE:
  398.       case GENERIC_TYPE:
  399.        cerr << "Internal error:  " << __FILE__ <<  __LINE__
  400.            << "\n" << _POC_ "\n";
  401.        return 0;
  402.  
  403.       case UNKNOWN_TYPE:
  404.       default:
  405.     return (ptr.u -> asStr (str));
  406.     }
  407. //    return (attrVal);
  408.     return str;
  409. }
  410.  
  411. // The value of the attribute is printed to the output stream specified by out.
  412. // The output is in physical file format.
  413.  
  414. void
  415. STEPattribute::STEPwrite (ostream& out) 
  416.     if (is_null ()) {
  417.     out << "$";
  418.     return;
  419.     }
  420.  
  421.     if (IsDerived ())  {
  422.       out << "*";
  423.       return;
  424.     }
  425.  
  426.     switch (NonRefType())
  427.     {
  428.       case INTEGER_TYPE:
  429.     out << *(ptr.i);
  430.     break;
  431.  
  432.       case NUMBER_TYPE:
  433.       case REAL_TYPE:
  434.       {
  435.       real tmp = *(ptr.r) ; 
  436.       char* temp=new char[100];
  437.       if(tmp > -.00000001 && tmp < .00000001){
  438.       sprintf (temp, "%#.2g", *(ptr.r));
  439.       out << temp;
  440.       }
  441.       else{
  442.       sprintf (temp, "%#g", *(ptr.r));
  443.          out << temp;
  444.          }
  445.     break; 
  446.       }
  447.  
  448.       case ENTITY_TYPE:
  449.     // print instance id only if not empty pointer
  450.     if ((*(ptr.c) == 0) ||  
  451.         // no value was assigned  <-- this would be a BUG
  452.         (*(ptr.c) == S_ENTITY_NULL) )
  453.     {
  454.         out << "$";
  455.         cerr << "Internal error:  " << __FILE__ <<  __LINE__
  456.          << "\n" << _POC_ "\n";
  457.  
  458.         char errStr[BUFSIZ];
  459.         errStr[0] = '\0';
  460.         _error.GreaterSeverity(SEVERITY_BUG);
  461.         sprintf(errStr,
  462.            " Warning: attribute '%s : %s' is null and shouldn't be.\n",
  463.             Name(), TypeName());
  464.         _error.AppendToUserMsg(errStr);
  465.         _error.AppendToDetailMsg(errStr);
  466.     }
  467.     else  (*(ptr.c)) -> STEPwrite_reference (out);
  468.     break;      
  469.  
  470.       case STRING_TYPE:
  471.     // if null pointer or pointer to a string of length zero
  472.     if(ptr.S)
  473.         (ptr.S) -> STEPwrite (out);
  474.     else
  475.     {
  476.         out << "$";
  477.         cerr << "Internal error:  " << __FILE__ <<  __LINE__
  478.          << "\n" << _POC_ "\n";
  479.  
  480.         char errStr[BUFSIZ];
  481.         errStr[0] = '\0';
  482.         _error.GreaterSeverity(SEVERITY_BUG);
  483.         sprintf(errStr,
  484.            " Warning: attribute '%s : %s' should be pointing at %s",
  485.             Name(), TypeName(), "an SdaiString.\n");
  486.         _error.AppendToUserMsg(errStr);
  487.         _error.AppendToDetailMsg(errStr);
  488.     }
  489.     break;
  490.  
  491.       case BINARY_TYPE:    
  492.     // if null pointer or pointer to a string of length zero
  493.     if(ptr.b)
  494.         (ptr.b) -> STEPwrite (out);
  495.     else
  496.     {
  497.         out << "$";
  498.         cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__
  499.          << "\n" << _POC_ "\n";
  500.  
  501.         char errStr[BUFSIZ];
  502.         errStr[0] = '\0';
  503.         _error.GreaterSeverity(SEVERITY_BUG);
  504.         sprintf(errStr,
  505.            " Warning: attribute '%s : %s' should be pointing at %s",
  506.             Name(), TypeName(), "an SdaiBinary.\n");
  507.         _error.AppendToUserMsg(errStr);
  508.         _error.AppendToDetailMsg(errStr);
  509.     }
  510.     break;
  511.  
  512.       case AGGREGATE_TYPE:
  513.     ptr.a -> STEPwrite (out);
  514.     break;
  515.  
  516.       case ENUM_TYPE:
  517.       case BOOLEAN_TYPE:
  518.       case LOGICAL_TYPE:
  519.     if(ptr.e)
  520.         ptr.e -> STEPwrite (out);
  521.     else
  522.     {
  523.         out << "$";
  524.         cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__
  525.          << "\n" << _POC_ "\n";
  526.  
  527.         char errStr[BUFSIZ];
  528.         errStr[0] = '\0';
  529.         _error.GreaterSeverity(SEVERITY_BUG);
  530.         sprintf(errStr,
  531.            " Warning: attribute '%s : %s' should be pointing at %s",
  532.             Name(), TypeName(), "a STEPenumeration class.\n");
  533.         _error.AppendToUserMsg(errStr);
  534.         _error.AppendToDetailMsg(errStr);
  535.     }
  536.     break;
  537.  
  538.       case SELECT_TYPE:
  539.     if(ptr.sh)
  540.         ptr.sh -> STEPwrite (out);
  541.     else
  542.     {
  543.         out << "$";
  544.         cerr << "Internal error:  " << __FILE__ <<  __LINE__
  545.          << "\n" << _POC_ "\n";
  546.  
  547.         char errStr[BUFSIZ];
  548.         errStr[0] = '\0';
  549.         _error.GreaterSeverity(SEVERITY_BUG);
  550.         sprintf(errStr,
  551.            " Warning: attribute '%s : %s' should be pointing at %s",
  552.             Name(), TypeName(), "a STEPselect class.\n");
  553.         _error.AppendToUserMsg(errStr);
  554.         _error.AppendToDetailMsg(errStr);
  555.     }
  556.     break;
  557.  
  558.       case REFERENCE_TYPE:
  559.       case GENERIC_TYPE:
  560.     cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__
  561.          << "\n" << _POC_ "\n";
  562.     _error.GreaterSeverity (SEVERITY_BUG);
  563.     return;
  564.  
  565.       case UNKNOWN_TYPE:
  566.       default:
  567.     ptr.u -> STEPwrite (out);
  568.     break;
  569.       
  570.     }
  571. }
  572.  
  573.  
  574. BOOLEAN 
  575. STEPattribute::ShallowCopy(STEPattribute *sa)
  576. {
  577.     switch(sa->NonRefType())
  578.     {
  579.       case INTEGER_TYPE:
  580.         *ptr.i = *(sa->ptr.i);
  581.         break;
  582.       case BINARY_TYPE:
  583.         *(ptr.b) = *(sa->ptr.b);
  584.         break;
  585.       case STRING_TYPE:
  586.         *(ptr.S) = *(sa->ptr.S);
  587.         break;
  588.       case REAL_TYPE:
  589.       case NUMBER_TYPE:
  590.         *ptr.r = *(sa->ptr.r);
  591.         break;
  592.       case ENTITY_TYPE:
  593.         *ptr.c = *(sa->ptr.c);
  594.         break;
  595.       case AGGREGATE_TYPE:
  596.         ptr.a -> ShallowCopy (*(sa -> ptr.a));
  597.         break;
  598.       case SELECT_TYPE:
  599.         *ptr.sh = *(sa->ptr.sh);
  600.         break;
  601.       case ENUM_TYPE:
  602.       case BOOLEAN_TYPE:
  603.       case LOGICAL_TYPE:
  604.         ptr.e->put(sa->ptr.e->asInt());
  605.         break;
  606.  
  607.       default:
  608.         *ptr.u = *(sa->ptr.u);
  609.         break;
  610.     }
  611.     return 1;
  612. }
  613.  
  614. Severity 
  615. STEPattribute::set_null()
  616. {  
  617.     switch (NonRefType()) {
  618.       case INTEGER_TYPE:
  619.     *(ptr.i) = S_INT_NULL;
  620.     break;
  621.  
  622.       case NUMBER_TYPE:
  623.     *(ptr.r) = S_NUMBER_NULL;
  624.     break;      
  625.  
  626.       case REAL_TYPE:
  627.     *(ptr.r) = S_REAL_NULL;
  628.     break;      
  629.  
  630.       case ENTITY_TYPE:
  631.     *(ptr.c) = S_ENTITY_NULL;
  632.     break;
  633.     
  634.       case STRING_TYPE:
  635.     ptr.S -> set_null ();
  636.     break;
  637.  
  638.       case BINARY_TYPE:
  639.     ptr.b -> set_null ();
  640.     break;
  641.  
  642.       case AGGREGATE_TYPE:
  643.       {
  644.     ptr.a -> Empty ();
  645.     break;
  646.       }
  647.  
  648.       case ENUM_TYPE:
  649.       case BOOLEAN_TYPE:
  650.       case LOGICAL_TYPE:
  651.     ptr.e -> set_null();
  652.     break;
  653.  
  654.       case SELECT_TYPE:
  655.     ptr.sh -> set_null();
  656.     break;
  657.  
  658.       case REFERENCE_TYPE:  
  659.       case GENERIC_TYPE:    
  660.     cerr << "Internal error:  " << __FILE__ <<  __LINE__
  661.          << "\n" << _POC_ "\n";
  662.     return SEVERITY_BUG;
  663.  
  664.       case UNKNOWN_TYPE:
  665.       default:
  666.       {
  667.     ptr.u -> set_null();
  668.     char errStr[BUFSIZ];
  669.     errStr[0] = '\0';
  670.     sprintf(errStr, " Warning: attribute '%s : %s : %d' - %s.\n",
  671.         Name(), TypeName(), Type(),
  672.         "Don't know how to make attribute NULL");
  673.     _error.AppendToDetailMsg(errStr);
  674.     _error.GreaterSeverity(SEVERITY_WARNING);
  675.     return SEVERITY_WARNING;
  676.       }
  677.     }
  678.     if(Nullable())
  679.     return SEVERITY_NULL;
  680.     else
  681.     return SEVERITY_INCOMPLETE;
  682. }
  683.  
  684. BOOLEAN
  685. STEPattribute::is_null ()  const
  686. {
  687.     switch ( NonRefType() )  
  688.       {
  689.     case INTEGER_TYPE:
  690.       return (*(ptr.i) == S_INT_NULL);
  691.  
  692.     case NUMBER_TYPE:
  693.       return  (*(ptr.r) == S_NUMBER_NULL);
  694.  
  695.     case REAL_TYPE:
  696.       return  (*(ptr.r) == S_REAL_NULL);
  697.  
  698.     case ENTITY_TYPE:
  699.       return  (*(ptr.c) == S_ENTITY_NULL);
  700.  
  701.     case STRING_TYPE:
  702.       return ptr.S -> is_null ();
  703.  
  704.     case BINARY_TYPE:
  705.       return ptr.b -> is_null ();
  706.  
  707.     case AGGREGATE_TYPE:
  708.     {
  709.       return  ( ptr.a -> is_null() );
  710.     }
  711.  
  712.     case ENUM_TYPE:
  713.     case BOOLEAN_TYPE:
  714.     case LOGICAL_TYPE:
  715.       return ( ptr.e -> is_null() );
  716.  
  717.     case SELECT_TYPE:
  718.       return( ptr.sh->is_null() );
  719.  
  720.     case REFERENCE_TYPE:
  721.     case GENERIC_TYPE:
  722.       cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__
  723.            << "\n" << _POC_ "\n";
  724.       return SEVERITY_BUG;
  725.  
  726.         case UNKNOWN_TYPE:
  727.     default:
  728.       return (ptr.u -> is_null());
  729.       }
  730. }    
  731.  
  732. /******************************************************************
  733.  ** Procedure:  operator == 
  734.  ** Parameters:  STEPattribute & a1 and a2
  735.  ** Returns:  int -- if 0 => not equal
  736.  ** Description:  evaluates the equality of two attributes
  737.  ** Side Effects:  none
  738.  ** Status:  stub -- needs alot of work
  739.  ******************************************************************/
  740.  
  741. //    equality for STEPattribute
  742. int operator == (STEPattribute &a1, STEPattribute &a2)
  743. {
  744.   cerr << "Internal error:  " << __FILE__ << ": " <<  __LINE__
  745.        << "\n" << _POC_ "\n";
  746.     if (a1.AttrDescriptor->NonRefType() == a2.AttrDescriptor->NonRefType()) 
  747.     ;
  748.     return 0;
  749. }    
  750.  
  751.  
  752.  
  753. ///////////////////////////////////////////////////////////////////////////////
  754. // returns the severity level that the parameter attrValue would pass at if it 
  755. // was the value for this attribute.
  756. ///////////////////////////////////////////////////////////////////////////////
  757.  
  758. Severity 
  759. STEPattribute::ValidLevel (const char *attrValue, ErrorDescriptor *error, 
  760.               InstMgr *im, int clearError)
  761. {
  762.     if(clearError)
  763.     ClearErrorMsg();
  764.  
  765.     int optional = Nullable();
  766.  
  767.     if( !attrValue || (attrValue[0] == '\0') )
  768.     {
  769.     if(optional)
  770.         return error->severity();
  771.     else
  772.     {
  773.         error->GreaterSeverity(SEVERITY_INCOMPLETE);
  774.         return SEVERITY_INCOMPLETE;
  775.     }
  776.     }
  777.  
  778.     switch (NonRefType() ) {
  779.       case INTEGER_TYPE:
  780.         return IntValidLevel(attrValue, error, clearError, optional, 0);
  781.  
  782.       case STRING_TYPE:
  783.         // if a value exists (checked above) then that is the string value
  784.         return SEVERITY_NULL;
  785.     
  786.       case REAL_TYPE:
  787.         return RealValidLevel(attrValue, error, clearError, optional, 0);
  788.  
  789.       case NUMBER_TYPE:
  790.         return NumberValidLevel(attrValue, error, clearError, optional, 0);
  791.  
  792.       case ENTITY_TYPE:
  793.         return EntityValidLevel(attrValue, 
  794.                     AttrDescriptor->NonRefTypeDescriptor(), 
  795.                     error, im, 0);
  796.       case BINARY_TYPE:
  797.         return ptr.b->BinaryValidLevel(attrValue, &_error, optional, 0);
  798.  
  799.       case AGGREGATE_TYPE:
  800.       {
  801.     return ptr.a->AggrValidLevel(attrValue, error, 
  802.                   AttrDescriptor->AggrElemTypeDescriptor(), im, 
  803.                   optional, 0, 0, 0);
  804.       }
  805.       case ENUM_TYPE:
  806.       case BOOLEAN_TYPE:
  807.       case LOGICAL_TYPE:
  808.         return ptr.e->EnumValidLevel(attrValue, error, optional, 0, 0, 1);
  809.       case SELECT_TYPE:
  810.         return ptr.sh->SelectValidLevel(attrValue, error, im, 0);
  811.  
  812.       default:
  813.         cerr << "Internal error:  " << __FILE__ <<  __LINE__
  814.          << "\n" << _POC_ "\n";
  815.         return error->severity();
  816.     }
  817. }
  818.   
  819. /******************************************************************
  820.  ** Procedure:  operator <<
  821.  ** Parameters:  ostream & out -- output stream
  822.  **              STEPattribute & a -- attribute to output
  823.  ** Returns:  ostream &
  824.  ** Description:  overloads the output operator to print an attribute 
  825.  ******************************************************************/
  826.  
  827. ostream &operator<< ( ostream& out, STEPattribute& a )
  828. {
  829.     a.STEPwrite (out);
  830.     return out;
  831.  
  832. }
  833.  
  834.  
  835. ///////////////////////////// AddErrorInfo() //////////////////////////////////
  836. // This adds prepends attribute information to the detailed error msg.  This 
  837. // is intended to add information to the error msgs written by Enumerations, 
  838. // Aggregates, and STEPstrings which don't know they are a STEPattribute value.
  839. ///////////////////////////////////////////////////////////////////////////////
  840.  
  841. void 
  842. STEPattribute::AddErrorInfo()
  843. {
  844.     char errStr[BUFSIZ];
  845.     errStr[0] = '\0';
  846.  
  847.     if(SEVERITY_INPUT_ERROR < _error.severity() &&
  848.        _error.severity() < SEVERITY_NULL)
  849.     {
  850.     sprintf(errStr, " Warning: ATTRIBUTE '%s : %s : %d' - ",
  851.         Name(), TypeName(), Type());
  852.     _error.PrependToDetailMsg(errStr);
  853.     }
  854.     else if(_error.severity() == SEVERITY_INPUT_ERROR)
  855.     {
  856.     sprintf(errStr, " Error: ATTRIBUTE '%s : %s : %d' - ",
  857.         Name(), TypeName(), Type());
  858.     _error.PrependToDetailMsg(errStr);
  859.     }
  860.     else if(_error.severity() <= SEVERITY_BUG)
  861.     {
  862.     sprintf(errStr, " BUG: ATTRIBUTE '%s : %s : %d' - ",
  863.         Name(), TypeName(), Type());
  864.     _error.PrependToDetailMsg(errStr);
  865.     }
  866. }
  867.  
  868. ///////////////////////////////////////////////////////////////////////////////
  869.  
  870. // this function reads until it hits eof or one of the StopChars.
  871. // if it hits one of StopChars it puts it back.
  872. // RETURNS: the last char it read.
  873. char
  874. STEPattribute::SkipBadAttr(istream& in, char *StopChars)
  875. {
  876.     //int sk = in.skip(0);  //turn skipping whitespace off
  877.  
  878.     // read bad data until end of this attribute or entity.
  879.     char *foundCh = 0;
  880.     char c = '\0';
  881.     char errStr[BUFSIZ];
  882.     errStr[0] = '\0';
  883.  
  884.     _error.GreaterSeverity(SEVERITY_WARNING);
  885.     in >> c;
  886.     while( !in.eof() && !(foundCh = strchr(StopChars, c)) )
  887.       in >> c;
  888.     if(in.eof())
  889.     {
  890.     _error.GreaterSeverity(SEVERITY_INPUT_ERROR);
  891.     sprintf(errStr, " Error: attribute '%s : %s : %d' - %s.\n",
  892.         Name(), TypeName(), Type(),
  893.         "Unexpected EOF when skipping bad attr value");
  894.     _error.AppendToDetailMsg(errStr);
  895.     }
  896.     else
  897.     {
  898.     sprintf(errStr, " Error: attribute '%s : %s : %d' - %s.\n",
  899.         Name(), TypeName(), Type(), "Invalid value");
  900.     _error.AppendToDetailMsg(errStr);
  901.     }
  902.     in.putback (c);
  903.    // in.skip(sk);     //set skip whitespace to its original state
  904.     return c;
  905. }
  906.  
  907.  
  908. /////////////////// READ 
  909.  
  910. #ifdef OBSOLETE
  911.  
  912. // appends char 'c' to char * 's' starting at index 'index'.  'index' is 
  913. // incremented by one and returned.  If assigning 'c' will cause 's' to be 
  914. // larger than size 'sSize' then 's' is deleted and reallocated and 's' and 
  915. // 'sSize' are changed and returned appropriately.
  916.  
  917. void
  918. AppendChar(char c, int& index, char *&s, int& sSize)
  919. {
  920.     if(index >= sSize - 1)
  921.     {
  922.     char *tmp = s;
  923.     s = new char[sSize * 2];
  924.     strcpy(s, tmp);
  925.     delete [] tmp;
  926.     sSize = sSize * 2;
  927.     }
  928.     s[index] = c;
  929.     index++;
  930.     s[index] = '\0';
  931. }
  932.  
  933.  
  934. /////////////////// STEPread_reference()
  935.  
  936. STEPentity *
  937. STEPread_reference (const char * s, ErrorDescriptor *err, InstMgr * instances, 
  938.              int addFileId)
  939. {
  940.     char errStr[BUFSIZ];
  941.     errStr[0] = '\0';
  942.  
  943.     int fileId = -1;
  944.     int numfound;
  945.     if( numfound = sscanf((char *)s, " #%d ", &fileId) )
  946.     ;
  947.     else ( numfound = sscanf((char *)s, " @%d ", &fileId) )
  948.     ;
  949.     if( (numfound != EOF) && (numfound > 0) )
  950.     {
  951.     fileId = fileId + addFileId;
  952.  
  953.     if (!instances)
  954.     {
  955.         sprintf(errStr, "STEPread_reference(): %s - entity #%d %s.\n",
  956.             "BUG - cannot read reference without the InstMgr", fileId, 
  957.             "is unknown to attribute");
  958.         err->AppendToDetailMsg(errStr);
  959.         err->GreaterSeverity(SEVERITY_BUG);
  960.         return S_ENTITY_NULL;
  961.     }
  962.     
  963.     //  lookup which object has id as its instance fileId
  964.     STEPentity* inst;
  965.     /* If there is a ManagerNode it should have a STEPentity */
  966.     MgrNode* mn = 0;
  967.     mn = instances->FindFileId(fileId);
  968.     if (mn)
  969.     {
  970.         inst =  mn->GetSTEPentity() ;
  971.         if (inst) { return (inst); }
  972.         else
  973.         {
  974.         sprintf(errStr, 
  975.             "%s - entity #%d %s.\n",
  976.                 "BUG - MgrNode::GetSTEPentity returned NULL pointer",
  977.             fileId, "is unknown to attribute");
  978.         err->AppendToDetailMsg(errStr);
  979.         err->GreaterSeverity(SEVERITY_BUG);
  980.         return S_ENTITY_NULL;
  981.         }
  982.     }
  983.     else
  984.     {
  985.         sprintf(errStr,"Reference to non-existent ENTITY #%d.\n", fileId);
  986.         err->AppendToDetailMsg(errStr);
  987.         err->GreaterSeverity(SEVERITY_WARNING);
  988.         return S_ENTITY_NULL;
  989.     }
  990.     }
  991.     else
  992.     {
  993.     numfound = sscanf((char *)s, " %*s ");
  994.     if(numfound == EOF)
  995.     {
  996.         err->GreaterSeverity(SEVERITY_INCOMPLETE);
  997.     }
  998.     else 
  999.     {
  1000.         sprintf(errStr,"  Invalid entity identifier # %s.\n", s);
  1001.         err->AppendToDetailMsg(errStr);
  1002.         err->GreaterSeverity(SEVERITY_WARNING);
  1003.     }
  1004.     return S_ENTITY_NULL;
  1005.     }
  1006. }
  1007.  
  1008. #endif
  1009.