1
2 /*
3 * NIST STEP Core Class Library
4 * clstepcore/STEPaggregate.cc
5 * April 1997
6 * K. C. Morris
7 * David Sauder
8
9 * Development of this software was funded by the United States Government,
10 * and is not subject to copyright.
11 */
12
13 #include <stdio.h>
14
15 #include <read_func.h>
16 #include <STEPaggregate.h>
17 #include <STEPattribute.h>
18 #include <instmgr.h>
19 #include <ExpDict.h>
20 #include "sc_memmgr.h"
21
22 const int Real_Num_Precision = REAL_NUM_PRECISION; // from STEPattribute.h
23
24
25 /******************************************************************************
26 ** \file STEPaggregate.cc Functions for manipulating aggregate attributes
27 ** FIXME KNOWN BUGs:
28 ** -- treatment of aggregates of reals or ints is inconsistent with
29 ** other aggregates (there's no classes for these)
30 ** -- no two- dimensional aggregates are implemented
31 **/
32
33 STEPaggregate NilSTEPaggregate;
34
35
STEPaggregate()36 STEPaggregate::STEPaggregate() {
37 _null = 1;
38 }
39
~STEPaggregate()40 STEPaggregate::~STEPaggregate() {
41 STEPnode * node;
42
43 node = ( STEPnode * ) head;
44 while( node ) {
45 head = node->NextNode();
46 delete node;
47 node = ( STEPnode * ) head;
48 }
49 }
50
ShallowCopy(const STEPaggregate & a)51 STEPaggregate & STEPaggregate::ShallowCopy( const STEPaggregate & a ) {
52 (void) a; // unused
53 cerr << "Internal error: " << __FILE__ << ": " << __LINE__
54 << "\n" << _POC_ "\n";
55 cerr << "function: STEPaggregate::ShallowCopy \n" << "\n";
56 return *this;
57 }
58
59 /// do not require exchange file format
AggrValidLevel(const char * value,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int optional,char * tokenList,int addFileId,int clearError)60 Severity STEPaggregate::AggrValidLevel( const char * value, ErrorDescriptor * err,
61 const TypeDescriptor * elem_type, InstMgrBase * insts,
62 int optional, char * tokenList, int addFileId,
63 int clearError ) {
64 std::string buf;
65 if( clearError ) {
66 err->ClearErrorMsg();
67 }
68
69 istringstream in( ( char * )value ); // sz defaults to length of s
70
71 ReadValue( in, err, elem_type, insts, addFileId, 0, 0 );
72 CheckRemainingInput( in, err, elem_type->AttrTypeName( buf ), tokenList );
73 if( optional && ( err->severity() == SEVERITY_INCOMPLETE ) ) {
74 err->severity( SEVERITY_NULL );
75 }
76 return err->severity();
77 }
78
79 /// require exchange file format
AggrValidLevel(istream & in,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int optional,char * tokenList,int addFileId,int clearError)80 Severity STEPaggregate::AggrValidLevel( istream & in, ErrorDescriptor * err,
81 const TypeDescriptor * elem_type, InstMgrBase * insts,
82 int optional, char * tokenList, int addFileId,
83 int clearError ) {
84 std::string buf;
85 if( clearError ) {
86 err->ClearErrorMsg();
87 }
88
89 ReadValue( in, err, elem_type, insts, addFileId, 0, 1 );
90 CheckRemainingInput( in, err, elem_type->AttrTypeName( buf ), tokenList );
91 if( optional && ( err->severity() == SEVERITY_INCOMPLETE ) ) {
92 err->severity( SEVERITY_NULL );
93 }
94 return err->severity();
95 }
96
97 /// if exchangeFileFormat == 1 then paren delims are required.
98
ReadValue(istream & in,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId,int assignVal,int exchangeFileFormat,const char *)99 Severity STEPaggregate::ReadValue( istream & in, ErrorDescriptor * err,
100 const TypeDescriptor * elem_type, InstMgrBase * insts,
101 int addFileId, int assignVal, int exchangeFileFormat,
102 const char * ) {
103 (void) insts; //not used in ReadValue() for this class
104 (void) addFileId; //not used in ReadValue() for this class
105
106 ErrorDescriptor errdesc;
107 char errmsg[BUFSIZ];
108 int value_cnt = 0;
109 std::string buf;
110
111 if( assignVal ) {
112 Empty(); // read new values and discard existing ones
113 }
114
115 char c;
116
117 in >> ws; // skip white space
118
119 c = in.peek(); // does not advance input
120
121 if( in.eof() || c == '$' ) {
122 _null = 1;
123 err->GreaterSeverity( SEVERITY_INCOMPLETE );
124 return SEVERITY_INCOMPLETE;
125 }
126
127 if( c == '(' ) {
128 in.get( c );
129 } else if( exchangeFileFormat ) {
130 // error did not find opening delim
131 // cannot recover so give up and let STEPattribute recover
132 err->GreaterSeverity( SEVERITY_INPUT_ERROR );
133 return SEVERITY_INPUT_ERROR;
134 } else if( !in.good() ) {
135 // this should actually have been caught by skipping white space above
136 err->GreaterSeverity( SEVERITY_INCOMPLETE );
137 return SEVERITY_INCOMPLETE;
138 }
139
140 STEPnode * item = 0;
141
142 in >> ws;
143 // take a peek to see if there are any elements before committing to an
144 // element
145 c = in.peek(); // does not advance input
146 if( c == ')' ) {
147 in.get( c );
148 }
149 // if not assigning values only need one node. So only one node is created.
150 // It is used to read the values
151 else if( !assignVal ) {
152 item = ( STEPnode * )NewNode();
153 }
154
155 // ')' is the end of the aggregate
156 while( in.good() && ( c != ')' ) ) {
157 value_cnt++;
158 if( assignVal ) { // create a new node each time through the loop
159 item = ( STEPnode * )NewNode();
160 }
161
162 errdesc.ClearErrorMsg();
163
164 if( exchangeFileFormat ) {
165 item->STEPread( in, &errdesc );
166 } else {
167 item->StrToVal( in, &errdesc );
168 }
169
170 // read up to the next delimiter and set errors if garbage is
171 // found before specified delims (i.e. comma and quote)
172 CheckRemainingInput( in, &errdesc, elem_type->AttrTypeName( buf ), ",)" );
173
174 if( errdesc.severity() < SEVERITY_INCOMPLETE ) {
175 sprintf( errmsg, " index: %d\n", value_cnt );
176 errdesc.PrependToDetailMsg( errmsg );
177 err->AppendFromErrorArg( &errdesc );
178 }
179 if( assignVal ) { // pass the node to STEPaggregate
180 AddNode( item );
181 }
182
183 in >> ws; // skip white space (although should already be skipped)
184 in.get( c ); // read delim
185
186 // CheckRemainingInput should have left the input right at the delim
187 // so that it would be read in in.get() above. Since it did not find
188 // the delim this does not know how to find it either!
189 if( ( c != ',' ) && ( c != ')' ) ) {
190 // cannot recover so give up and let STEPattribute recover
191 err->GreaterSeverity( SEVERITY_INPUT_ERROR );
192 return SEVERITY_INPUT_ERROR;
193 }
194 }
195 if( c == ')' ) {
196 _null = 0;
197 } else { // expectation for end paren delim has not been met
198 err->GreaterSeverity( SEVERITY_INPUT_ERROR );
199 err->AppendToUserMsg( "Missing close paren for aggregate value" );
200 return SEVERITY_INPUT_ERROR;
201 }
202 return err->severity();
203 }
204
StrToVal(const char * s,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId)205 Severity STEPaggregate::StrToVal( const char * s, ErrorDescriptor * err,
206 const TypeDescriptor * elem_type, InstMgrBase * insts,
207 int addFileId ) {
208 istringstream in( ( char * )s );
209 return ReadValue( in, err, elem_type, insts, addFileId, 1, 0 );
210 }
211
212 ///////////////////////////////////////////////////////////////////////////////
213
STEPread(istream & in,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId,const char * currSch)214 Severity STEPaggregate::STEPread( istream & in, ErrorDescriptor * err,
215 const TypeDescriptor * elem_type, InstMgrBase * insts,
216 int addFileId, const char * currSch ) {
217 return ReadValue( in, err, elem_type, insts, addFileId, 1, 1, currSch );
218 }
219
asStr(std::string & s) const220 const char * STEPaggregate::asStr( std::string & s ) const {
221 s.clear();
222
223 if( !_null ) {
224 s = "(";
225 STEPnode * n = ( STEPnode * ) head;
226 std::string tmp;
227 while( n ) {
228 s.append( n->STEPwrite( tmp ) );
229 n = ( STEPnode * ) n -> NextNode();
230 if( n ) {
231 s.append( "," );
232 }
233 }
234 s.append( ")" );
235 }
236 return const_cast<char *>( s.c_str() );
237 }
238
STEPwrite(ostream & out,const char * currSch) const239 void STEPaggregate::STEPwrite( ostream & out, const char * currSch ) const {
240 if( !_null ) {
241 out << '(';
242 STEPnode * n = ( STEPnode * )head;
243 std::string s;
244 while( n ) {
245 out << n->STEPwrite( s, currSch );
246 n = ( STEPnode * ) n -> NextNode();
247 if( n ) {
248 out << ',';
249 }
250 }
251 out << ')';
252 } else {
253 out << '$';
254 }
255 }
256
NewNode()257 SingleLinkNode * STEPaggregate::NewNode() {
258 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n" ;
259 cerr << "function: STEPaggregate::NewNode \n" << _POC_ << "\n";
260 return 0;
261 }
262
AddNode(SingleLinkNode * n)263 void STEPaggregate::AddNode( SingleLinkNode * n ) {
264 SingleLinkList::AppendNode( n );
265 _null = 0;
266 }
267
Empty()268 void STEPaggregate::Empty() {
269 SingleLinkList::Empty();
270 _null = 1;
271 }
272
273
274 ///////////////////////////////////////////////////////////////////////////////
275 // STEPnode
276 ///////////////////////////////////////////////////////////////////////////////
277
StrToVal(const char * s,ErrorDescriptor * err)278 Severity STEPnode::StrToVal( const char * s, ErrorDescriptor * err ) {
279 // defined in subtypes
280 (void) s; //unused
281 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n" ;
282 err->AppendToDetailMsg(
283 " function: STEPnode::StrToVal() called instead of virtual function.\n"
284 );
285 err->AppendToDetailMsg( "Aggr. attr value: '\n" );
286 err->AppendToDetailMsg( "not assigned.\n" );
287 err->AppendToDetailMsg( _POC_ );
288 err->GreaterSeverity( SEVERITY_BUG );
289 return SEVERITY_BUG;
290 }
291
StrToVal(istream & in,ErrorDescriptor * err)292 Severity STEPnode::StrToVal( istream & in, ErrorDescriptor * err ) {
293 // defined in subtypes
294 (void) in; //unused
295 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n" ;
296 err->AppendToDetailMsg(
297 " function: STEPnode::StrToVal() called instead of virtual function.\n"
298 );
299 err->AppendToDetailMsg( "Aggr. attr value: '\n" );
300 err->AppendToDetailMsg( "not assigned.\n" );
301 err->AppendToDetailMsg( _POC_ );
302 err->GreaterSeverity( SEVERITY_BUG );
303 return SEVERITY_BUG;
304 }
305
STEPread(const char * s,ErrorDescriptor * err)306 Severity STEPnode::STEPread( const char * s, ErrorDescriptor * err ) {
307 // defined in subclasses
308 (void) s; //unused
309 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n" ;
310 cerr << "function: STEPnode::STEPread called instead of virtual function.\n"
311 << _POC_ << "\n";
312
313 err->AppendToDetailMsg(
314 " function: STEPnode::STEPread() called instead of virtual function.\n"
315 );
316 err->AppendToDetailMsg( _POC_ );
317 err->GreaterSeverity( SEVERITY_BUG );
318
319 return SEVERITY_BUG;
320 }
321
STEPread(istream & in,ErrorDescriptor * err)322 Severity STEPnode::STEPread( istream & in, ErrorDescriptor * err ) {
323 (void) in; //unused
324 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n" ;
325 cerr << "function: STEPnode::STEPread called instead of virtual function.\n"
326 << _POC_ << "\n";
327
328 err->AppendToDetailMsg(
329 " function: STEPnode::STEPread() called instead of virtual function.\n"
330 );
331 err->AppendToDetailMsg( _POC_ );
332 err->GreaterSeverity( SEVERITY_BUG );
333 return SEVERITY_BUG;
334 }
335
asStr(std::string & s)336 const char * STEPnode::asStr( std::string & s ) {
337 // defined in subclasses
338 (void) s; //unused
339 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n" ;
340 cerr << "function: STEPnode::asStr called instead of virtual function.\n"
341 << _POC_ << "\n";
342
343 return "";
344 }
345
346 /**
347 * NOTE - second argument will contain name of current schema. We may need
348 * this if STEPnode belongs to an aggregate of selects. If so, each node
349 * will be written out by calling STEPwrite on its select, and to write a
350 * select out, the name of its underlying type will be written. Finally,
351 * the underlying type's name depends on the current schema. This is be-
352 * cause e.g. type X may be defined in schema A, and may be USEd in schema
353 * B and renamed to Y (i.e., "USE from A (X as Y)"). Thus, if currSch = B,
354 * Y will have to be written out rather than X. Actually, this concern
355 * only applies for SelectNode. To accomodate those cases, all the signa-
356 * tures of STEPwrite(std::string) contain currSch. (As an additional note,
357 * 2D aggregates should make use of currSch in case they are 2D aggrs of
358 * selects. But since currently (3/27/97) the SCL handles 2D+ aggrs using
359 * SCLundefined's, this is not implemented.)
360 */
STEPwrite(std::string & s,const char * currSch)361 const char * STEPnode::STEPwrite( std::string & s, const char * currSch ) {
362 (void) s; //unused
363 (void) currSch; //unused
364 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n" ;
365 cerr << "function: STEPnode::STEPwrite called instead of virtual function.\n"
366 << _POC_ << "\n";
367 return "";
368 }
369
STEPwrite(ostream & out)370 void STEPnode::STEPwrite( ostream & out ) {
371 (void) out; //unused
372 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n" ;
373 cerr << "function: STEPnode::STEPwrite called instead of virtual function.\n"
374 << _POC_ << "\n";
375 }
376
377 ///////////////////////////////////////////////////////////////////////////////
378 // GenericAggregate
379 ///////////////////////////////////////////////////////////////////////////////
380
GenericAggregate()381 GenericAggregate::GenericAggregate() {
382 }
383
~GenericAggregate()384 GenericAggregate::~GenericAggregate() {
385 }
386
NewNode()387 SingleLinkNode * GenericAggregate::NewNode() {
388 return new GenericAggrNode();
389 }
390
ShallowCopy(const STEPaggregate & a)391 STEPaggregate & GenericAggregate::ShallowCopy( const STEPaggregate & a ) {
392 Empty();
393
394 SingleLinkNode * next = a.GetHead();
395 SingleLinkNode * copy;
396
397 while( next ) {
398 copy = new GenericAggrNode( *( GenericAggrNode * )next );
399 AddNode( copy );
400 next = next->NextNode();
401 }
402 if( head ) {
403 _null = 0;
404 } else {
405 _null = 1;
406 }
407 return *this;
408
409 }
410
411 ///////////////////////////////////////////////////////////////////////////////
412 // GenericAggrNode
413 ///////////////////////////////////////////////////////////////////////////////
414
GenericAggrNode(const char * str)415 GenericAggrNode::GenericAggrNode( const char * str ) {
416 value = str;
417 }
418
GenericAggrNode(GenericAggrNode & gan)419 GenericAggrNode::GenericAggrNode( GenericAggrNode & gan ) {
420 value = gan.value;
421 }
422
GenericAggrNode()423 GenericAggrNode::GenericAggrNode() {
424 }
425
~GenericAggrNode()426 GenericAggrNode::~GenericAggrNode() {
427 }
428
NewNode()429 SingleLinkNode * GenericAggrNode::NewNode() {
430 return new GenericAggrNode();
431 }
432
StrToVal(const char * s,ErrorDescriptor * err)433 Severity GenericAggrNode::StrToVal( const char * s, ErrorDescriptor * err ) {
434 return value.STEPread( s, err );
435 }
436
437 //TODO
StrToVal(istream & in,ErrorDescriptor * err)438 Severity GenericAggrNode::StrToVal( istream & in, ErrorDescriptor * err ) {
439 return value.STEPread( in, err );
440 }
441
STEPread(const char * s,ErrorDescriptor * err)442 Severity GenericAggrNode::STEPread( const char * s, ErrorDescriptor * err ) {
443 istringstream in( ( char * ) s );
444 return value.STEPread( in, err );
445 }
446
STEPread(istream & in,ErrorDescriptor * err)447 Severity GenericAggrNode::STEPread( istream & in, ErrorDescriptor * err ) {
448 return value.STEPread( in, err );
449 }
450
asStr(std::string & s)451 const char * GenericAggrNode::asStr( std::string & s ) {
452 s.clear();
453 value.asStr( s );
454 return const_cast<char *>( s.c_str() );
455 }
456
STEPwrite(std::string & s,const char * currSch)457 const char * GenericAggrNode::STEPwrite( std::string & s, const char * currSch ) {
458 (void) currSch; //unused
459 return value.STEPwrite( s );
460 }
461
STEPwrite(ostream & out)462 void GenericAggrNode::STEPwrite( ostream & out ) {
463 value.STEPwrite( out );
464 }
465
466 ///////////////////////////////////////////////////////////////////////////////
467 // EntityAggregate
468 ///////////////////////////////////////////////////////////////////////////////
469
EntityAggregate()470 EntityAggregate::EntityAggregate() {
471 }
472
~EntityAggregate()473 EntityAggregate::~EntityAggregate() {
474 }
475
476
477 /// if exchangeFileFormat == 1 then delims are required.
ReadValue(istream & in,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId,int assignVal,int exchangeFileFormat,const char *)478 Severity EntityAggregate::ReadValue( istream & in, ErrorDescriptor * err,
479 const TypeDescriptor * elem_type, InstMgrBase * insts,
480 int addFileId, int assignVal,
481 int exchangeFileFormat, const char * ) {
482 ErrorDescriptor errdesc;
483 char errmsg[BUFSIZ];
484 int value_cnt = 0;
485 std::string buf;
486
487 if( assignVal ) {
488 Empty(); // read new values and discard existing ones
489 }
490
491 char c;
492
493 in >> ws; // skip white space
494
495 c = in.peek(); // does not advance input
496
497 if( in.eof() || ( c == '$' ) ) {
498 _null = 1;
499 err->GreaterSeverity( SEVERITY_INCOMPLETE );
500 return SEVERITY_INCOMPLETE;
501 }
502
503 if( c == '(' ) {
504 in.get( c );
505 } else if( exchangeFileFormat ) {
506 // error did not find opening delim
507 // give up because you do not know where to stop reading.
508 err->GreaterSeverity( SEVERITY_INPUT_ERROR );
509 return SEVERITY_INPUT_ERROR;
510 } else if( !in.good() ) {
511 // this should actually have been caught by skipping white space above
512 err->GreaterSeverity( SEVERITY_INCOMPLETE );
513 return SEVERITY_INCOMPLETE;
514 }
515
516 EntityNode * item = 0;
517
518 in >> ws;
519 // take a peek to see if there are any elements before committing to an
520 // element
521 c = in.peek(); // does not advance input
522 if( c == ')' ) {
523 in.get( c );
524 }
525 // if not assigning values only need one node. So only one node is created.
526 // It is used to read the values
527 else if( !assignVal ) {
528 item = new EntityNode();
529 }
530
531 while( in.good() && ( c != ')' ) ) {
532 value_cnt++;
533 if( assignVal ) { // create a new node each time through the loop
534 item = new EntityNode();
535 }
536
537 errdesc.ClearErrorMsg();
538
539 if( exchangeFileFormat ) {
540 item->STEPread( in, &errdesc, elem_type, insts, addFileId );
541 } else {
542 item->StrToVal( in, &errdesc, elem_type, insts, addFileId );
543 }
544
545 // read up to the next delimiter and set errors if garbage is
546 // found before specified delims (i.e. comma and quote)
547 CheckRemainingInput( in, &errdesc, elem_type->AttrTypeName( buf ), ",)" );
548
549 if( errdesc.severity() < SEVERITY_INCOMPLETE ) {
550 sprintf( errmsg, " index: %d\n", value_cnt );
551 errdesc.PrependToDetailMsg( errmsg );
552 err->AppendFromErrorArg( &errdesc );
553 }
554 if( assignVal ) {
555 AddNode( item );
556 }
557
558 in >> ws; // skip white space (although should already be skipped)
559 in.get( c ); // read delim
560
561 // CheckRemainingInput should have left the input right at the delim
562 // so that it would be read in in.get() above. Since it did not find
563 // the delim this does not know how to find it either!
564 if( ( c != ',' ) && ( c != ')' ) ) {
565 // cannot recover so give up and let STEPattribute recover
566 err->GreaterSeverity( SEVERITY_INPUT_ERROR );
567 return SEVERITY_INPUT_ERROR;
568 }
569 }
570 if( c == ')' ) {
571 _null = 0;
572 } else { // expectation for end paren delim has not been met
573 err->GreaterSeverity( SEVERITY_INPUT_ERROR );
574 err->AppendToUserMsg( "Missing close paren for aggregate value" );
575 return SEVERITY_INPUT_ERROR;
576 }
577 return err->severity();
578 }
579
580
ShallowCopy(const STEPaggregate & a)581 STEPaggregate & EntityAggregate::ShallowCopy( const STEPaggregate & a ) {
582 const EntityNode * tmp = ( const EntityNode * ) a.GetHead();
583 while( tmp ) {
584 AddNode( new EntityNode( tmp -> node ) );
585 tmp = ( const EntityNode * ) tmp -> NextNode();
586 }
587 if( head ) {
588 _null = 0;
589 } else {
590 _null = 1;
591 }
592
593 return *this;
594 }
595
596
NewNode()597 SingleLinkNode * EntityAggregate::NewNode() {
598 return new EntityNode();
599 }
600
601 ///////////////////////////////////////////////////////////////////////////////
602 // EntityNode
603 ///////////////////////////////////////////////////////////////////////////////
604
EntityNode()605 EntityNode::EntityNode() {
606 }
607
~EntityNode()608 EntityNode::~EntityNode() {
609 }
610
EntityNode(SDAI_Application_instance * e)611 EntityNode::EntityNode( SDAI_Application_instance * e ) : node( e ) {
612 }
613
NewNode()614 SingleLinkNode * EntityNode::NewNode() {
615 return new EntityNode();
616 }
617 ///////////////////////////////////////////////////////////////////////////////
618
StrToVal(const char * s,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId)619 Severity EntityNode::StrToVal( const char * s, ErrorDescriptor * err,
620 const TypeDescriptor * elem_type,
621 InstMgrBase * insts, int addFileId ) {
622 SDAI_Application_instance * se = ReadEntityRef( s, err, ",)", insts,
623 addFileId );
624 if( se != S_ENTITY_NULL ) {
625 ErrorDescriptor error;
626 if( EntityValidLevel( se, elem_type, &error ) == SEVERITY_NULL ) {
627 node = se;
628 } else {
629 node = S_ENTITY_NULL;
630 err->AppendToDetailMsg( error.DetailMsg() );
631 err->AppendToUserMsg( error.UserMsg() );
632 err->GreaterSeverity( error.severity() );
633 }
634 } else {
635 node = S_ENTITY_NULL;
636 }
637 return err->severity();
638 }
639
StrToVal(istream & in,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId)640 Severity EntityNode::StrToVal( istream & in, ErrorDescriptor * err,
641 const TypeDescriptor * elem_type,
642 InstMgrBase * insts, int addFileId ) {
643 return STEPread( in, err, elem_type, insts, addFileId );
644 }
645
STEPread(const char * s,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId)646 Severity EntityNode::STEPread( const char * s, ErrorDescriptor * err,
647 const TypeDescriptor * elem_type,
648 InstMgrBase * insts, int addFileId ) {
649 istringstream in( ( char * )s );
650 return STEPread( in, err, elem_type, insts, addFileId );
651 }
652
STEPread(istream & in,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId)653 Severity EntityNode::STEPread( istream & in, ErrorDescriptor * err,
654 const TypeDescriptor * elem_type,
655 InstMgrBase * insts, int addFileId ) {
656 SDAI_Application_instance * se = ReadEntityRef( in, err, ",)", insts,
657 addFileId );
658 if( se != S_ENTITY_NULL ) {
659 ErrorDescriptor error;
660 if( EntityValidLevel( se, elem_type, &error ) == SEVERITY_NULL ) {
661 node = se;
662 } else {
663 node = S_ENTITY_NULL;
664 err->AppendToDetailMsg( error.DetailMsg() );
665 err->AppendToUserMsg( error.UserMsg() );
666 err->GreaterSeverity( error.severity() );
667 }
668 } else {
669 node = S_ENTITY_NULL;
670 }
671 return err->severity();
672 }
673
asStr(std::string & s)674 const char * EntityNode::asStr( std::string & s ) {
675 s.clear();
676 if( !node || ( node == S_ENTITY_NULL ) ) { // nothing
677 return "";
678 } else { // otherwise return entity id
679 char tmp [64];
680 sprintf( tmp, "#%d", node->STEPfile_id );
681 s = tmp;
682 }
683 return const_cast<char *>( s.c_str() );
684 }
685
STEPwrite(std::string & s,const char *)686 const char * EntityNode::STEPwrite( std::string & s, const char * ) {
687 if( !node || ( node == S_ENTITY_NULL ) ) { // nothing
688 s = "$";
689 return const_cast<char *>( s.c_str() );
690 }
691 asStr( s );
692 return const_cast<char *>( s.c_str() );
693 }
694
STEPwrite(ostream & out)695 void EntityNode::STEPwrite( ostream & out ) {
696 if( !node || ( node == S_ENTITY_NULL ) ) { // nothing
697 out << "$";
698 }
699 std::string s;
700 out << asStr( s );
701 }
702
703
704 ///////////////////////////////////////////////////////////////////////////////
705 // SelectAggregate
706 ///////////////////////////////////////////////////////////////////////////////
707
SelectAggregate()708 SelectAggregate::SelectAggregate() {
709 }
710
~SelectAggregate()711 SelectAggregate::~SelectAggregate() {
712 }
713
714
715 /// if exchangeFileFormat == 1 then delims are required.
ReadValue(istream & in,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId,int assignVal,int exchangeFileFormat,const char * currSch)716 Severity SelectAggregate::ReadValue( istream & in, ErrorDescriptor * err,
717 const TypeDescriptor * elem_type, InstMgrBase * insts,
718 int addFileId, int assignVal,
719 int exchangeFileFormat, const char * currSch ) {
720 ErrorDescriptor errdesc;
721 char errmsg[BUFSIZ];
722 int value_cnt = 0;
723 std::string buf;
724
725 if( assignVal ) {
726 Empty(); // read new values and discard existing ones
727 }
728
729 char c;
730
731 in >> ws; // skip white space
732
733 c = in.peek(); // does not advance input
734
735 if( in.eof() || ( c == '$' ) ) {
736 _null = 1;
737 err->GreaterSeverity( SEVERITY_INCOMPLETE );
738 return SEVERITY_INCOMPLETE;
739 }
740
741 if( c == '(' ) {
742 in.get( c );
743 } else if( exchangeFileFormat ) {
744 // error did not find opening delim
745 // give up because you do not know where to stop reading.
746 err->GreaterSeverity( SEVERITY_INPUT_ERROR );
747 return SEVERITY_INPUT_ERROR;
748 } else if( !in.good() ) {
749 // this should actually have been caught by skipping white space above
750 err->GreaterSeverity( SEVERITY_INCOMPLETE );
751 return SEVERITY_INCOMPLETE;
752 }
753
754 SelectNode * item = 0;
755
756 in >> ws;
757 // take a peek to see if there are any elements before committing to an
758 // element
759 c = in.peek(); // does not advance input
760 if( c == ')' ) {
761 in.get( c );
762 }
763 // if not assigning values only need one node. So only one node is created.
764 // It is used to read the values
765 else if( !assignVal ) {
766 item = ( SelectNode * ) NewNode();
767 }
768
769 while( in.good() && ( c != ')' ) ) {
770 value_cnt++;
771 if( assignVal ) { // create a new node each time through the loop
772 item = ( SelectNode * ) NewNode();
773 }
774
775 errdesc.ClearErrorMsg();
776
777 if( exchangeFileFormat ) {
778 item->STEPread( in, &errdesc, elem_type, insts, addFileId, currSch );
779 } else {
780 item->StrToVal( in, &errdesc, elem_type, insts, addFileId, currSch );
781 }
782
783 // read up to the next delimiter and set errors if garbage is
784 // found before specified delims (i.e. comma and quote)
785 CheckRemainingInput( in, &errdesc, elem_type->AttrTypeName( buf ), ",)" );
786
787 if( errdesc.severity() < SEVERITY_INCOMPLETE ) {
788 sprintf( errmsg, " index: %d\n", value_cnt );
789 errdesc.PrependToDetailMsg( errmsg );
790 err->AppendFromErrorArg( &errdesc );
791 }
792 if( assignVal ) {
793 AddNode( item );
794 }
795
796 in >> ws; // skip white space (although should already be skipped)
797 in.get( c ); // read delim
798
799 // CheckRemainingInput should have left the input right at the delim
800 // so that it would be read in in.get() above. Since it did not find
801 // the delim this does not know how to find it either!
802 if( ( c != ',' ) && ( c != ')' ) ) {
803 // cannot recover so give up and let STEPattribute recover
804 err->GreaterSeverity( SEVERITY_INPUT_ERROR );
805 return SEVERITY_INPUT_ERROR;
806 }
807 }
808 if( c == ')' ) {
809 _null = 0;
810 } else { // expectation for end paren delim has not been met
811 err->GreaterSeverity( SEVERITY_INPUT_ERROR );
812 err->AppendToUserMsg( "Missing close paren for aggregate value" );
813 return SEVERITY_INPUT_ERROR;
814 }
815 return err->severity();
816 }
817
818
ShallowCopy(const STEPaggregate & a)819 STEPaggregate & SelectAggregate::ShallowCopy( const STEPaggregate & a ) {
820 const SelectNode * tmp = ( const SelectNode * ) a.GetHead();
821 while( tmp ) {
822 AddNode( new SelectNode( tmp -> node ) );
823
824 tmp = ( const SelectNode * ) tmp -> NextNode();
825 }
826 if( head ) {
827 _null = 0;
828 } else {
829 _null = 1;
830 }
831
832 return *this;
833 }
834
835
NewNode()836 SingleLinkNode * SelectAggregate::NewNode() {
837 return new SelectNode();
838 }
839
840 ///////////////////////////////////////////////////////////////////////////////
841 // SelectNode
842 ///////////////////////////////////////////////////////////////////////////////
843
SelectNode(SDAI_Select * s)844 SelectNode::SelectNode( SDAI_Select * s ) : node( s ) {
845 }
846
SelectNode()847 SelectNode::SelectNode() {
848 }
849
~SelectNode()850 SelectNode::~SelectNode() {
851 delete node;
852 }
853
NewNode()854 SingleLinkNode * SelectNode::NewNode() {
855 return new SelectNode();
856 }
857 ///////////////////////////////////////////////////////////////////////////////
858
StrToVal(const char * s,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId)859 Severity SelectNode::StrToVal( const char * s, ErrorDescriptor * err,
860 const TypeDescriptor * elem_type,
861 InstMgrBase * insts, int addFileId ) {
862 (void) elem_type; //unused
863 (void) addFileId; //unused
864 istringstream in( ( char * )s );
865 if( err->severity( node->STEPread( in, err, insts ) ) != SEVERITY_NULL ) {
866 err->AppendToDetailMsg( node ->Error() );
867 }
868 return err->severity();
869 }
870
StrToVal(istream & in,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId,const char * currSch)871 Severity SelectNode::StrToVal( istream & in, ErrorDescriptor * err,
872 const TypeDescriptor * elem_type,
873 InstMgrBase * insts, int addFileId, const char * currSch ) {
874 return STEPread( in, err, elem_type, insts, addFileId, currSch );
875 }
876
STEPread(const char * s,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId)877 Severity SelectNode::STEPread( const char * s, ErrorDescriptor * err,
878 const TypeDescriptor * elem_type,
879 InstMgrBase * insts, int addFileId ) {
880 istringstream in( ( char * )s );
881 return STEPread( in, err, elem_type, insts, addFileId );
882 }
883
STEPread(istream & in,ErrorDescriptor * err,const TypeDescriptor * elem_type,InstMgrBase * insts,int addFileId,const char * currSch)884 Severity SelectNode::STEPread( istream & in, ErrorDescriptor * err,
885 const TypeDescriptor * elem_type,
886 InstMgrBase * insts, int addFileId, const char * currSch ) {
887 (void) elem_type; //unused
888 if( !node ) {
889 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n"
890 << _POC_ "\n";
891 cerr << "function: SelectNode::STEPread \n" << "\n";
892 return SEVERITY_BUG;
893 }
894 err->severity( node->STEPread( in, err, insts, 0, addFileId, currSch ) );
895 CheckRemainingInput( in, err, "select", ",)" );
896 return err->severity();
897 }
898
asStr(std::string & s)899 const char * SelectNode::asStr( std::string & s ) {
900 s.clear();
901 if( !node || ( node->is_null() ) ) { // nothing
902 return "";
903 } else { // otherwise return entity id
904 node -> STEPwrite( s );
905 return const_cast<char *>( s.c_str() );
906 }
907 }
908
STEPwrite(std::string & s,const char * currSch)909 const char * SelectNode::STEPwrite( std::string & s, const char * currSch ) {
910 s.clear();
911 if( !node || ( node->is_null() ) ) { // nothing
912 s = "$";
913 return "$";
914 }
915 node -> STEPwrite( s, currSch );
916 return const_cast<char *>( s.c_str() );
917 }
918
STEPwrite(ostream & out)919 void SelectNode::STEPwrite( ostream & out ) {
920 if( !node || ( node->is_null() ) ) { // nothing
921 out << "$";
922 }
923 std::string s;
924 out << asStr( s );
925 }
926
927 ///////////////////////////////////////////////////////////////////////////////
928 // StringAggregate
929 ///////////////////////////////////////////////////////////////////////////////
930
StringAggregate()931 StringAggregate::StringAggregate() {
932 }
933
~StringAggregate()934 StringAggregate::~StringAggregate() {
935 }
936
ShallowCopy(const STEPaggregate & a)937 STEPaggregate & StringAggregate::ShallowCopy( const STEPaggregate & a ) {
938 Empty();
939
940 SingleLinkNode * next = a.GetHead();
941 SingleLinkNode * copy;
942
943 while( next ) {
944 copy = new StringNode( *( StringNode * )next );
945 AddNode( copy );
946 next = next->NextNode();
947 }
948 if( head ) {
949 _null = 0;
950 } else {
951 _null = 1;
952 }
953 return *this;
954
955 }
956
NewNode()957 SingleLinkNode * StringAggregate::NewNode() {
958 return new StringNode();
959 }
960
961 ///////////////////////////////////////////////////////////////////////////////
962 // StringNode
963 ///////////////////////////////////////////////////////////////////////////////
964
StringNode()965 StringNode::StringNode() {
966 value = "";
967 }
968
~StringNode()969 StringNode::~StringNode() {
970 }
971
StringNode(StringNode & sn)972 StringNode::StringNode( StringNode & sn ) {
973 value = sn.value.c_str();
974 }
975
StringNode(const char * sStr)976 StringNode::StringNode( const char * sStr ) {
977 // value is an SDAI_String (the memory is copied)
978 value = sStr;
979 }
980
NewNode()981 SingleLinkNode * StringNode::NewNode() {
982 return new StringNode();
983 }
984
985 /**
986 * non-whitespace chars following s are considered garbage and is an error.
987 * a valid value will still be assigned if it exists before the garbage.
988 */
StrToVal(const char * s,ErrorDescriptor * err)989 Severity StringNode::StrToVal( const char * s, ErrorDescriptor * err ) {
990 return STEPread( s, err );
991 }
992
993 /**
994 * this function assumes you will check for garbage following input
995 */
StrToVal(istream & in,ErrorDescriptor * err)996 Severity StringNode::StrToVal( istream & in, ErrorDescriptor * err ) {
997 return value.STEPread( in, err );
998 }
999
1000 /**
1001 * non-whitespace chars following s are considered garbage and is an error.
1002 * a valid value will still be assigned if it exists before the garbage.
1003 */
STEPread(const char * s,ErrorDescriptor * err)1004 Severity StringNode::STEPread( const char * s, ErrorDescriptor * err ) {
1005 istringstream in( ( char * )s );
1006
1007 value.STEPread( in, err );
1008 CheckRemainingInput( in, err, "string", ",)" );
1009 return err->severity();
1010 }
1011
1012 /**
1013 * this function assumes you will check for garbage following input
1014 */
STEPread(istream & in,ErrorDescriptor * err)1015 Severity StringNode::STEPread( istream & in, ErrorDescriptor * err ) {
1016 return value.STEPread( in, err );
1017 }
1018
asStr(std::string & s)1019 const char * StringNode::asStr( std::string & s ) {
1020 value.asStr( s );
1021 return const_cast<char *>( s.c_str() );
1022 }
1023
STEPwrite(std::string & s,const char *)1024 const char * StringNode::STEPwrite( std::string & s, const char * ) {
1025 value.STEPwrite( s );
1026 return const_cast<char *>( s.c_str() );
1027 }
1028
STEPwrite(ostream & out)1029 void StringNode::STEPwrite( ostream & out ) {
1030 value.STEPwrite( out );
1031 }
1032 ///////////////////////////////////////////////////////////////////////////////
1033 // BinaryAggregate
1034 ///////////////////////////////////////////////////////////////////////////////
1035
BinaryAggregate()1036 BinaryAggregate::BinaryAggregate() {
1037 }
1038
~BinaryAggregate()1039 BinaryAggregate::~BinaryAggregate() {
1040 }
1041
ShallowCopy(const STEPaggregate & a)1042 STEPaggregate & BinaryAggregate::ShallowCopy( const STEPaggregate & a ) {
1043 Empty();
1044
1045 SingleLinkNode * next = a.GetHead();
1046 SingleLinkNode * copy;
1047
1048 while( next ) {
1049 copy = new BinaryNode( *( BinaryNode * )next );
1050 AddNode( copy );
1051 next = next->NextNode();
1052 }
1053 if( head ) {
1054 _null = 0;
1055 } else {
1056 _null = 1;
1057 }
1058 return *this;
1059
1060 }
1061
NewNode()1062 SingleLinkNode * BinaryAggregate::NewNode() {
1063 return new BinaryNode();
1064 }
1065
1066 ///////////////////////////////////////////////////////////////////////////////
1067 // BinaryNode
1068 ///////////////////////////////////////////////////////////////////////////////
1069
BinaryNode()1070 BinaryNode::BinaryNode() {
1071 value = 0;
1072 }
1073
~BinaryNode()1074 BinaryNode::~BinaryNode() {
1075 }
1076
BinaryNode(BinaryNode & bn)1077 BinaryNode::BinaryNode( BinaryNode & bn ) {
1078 value = bn.value.c_str();
1079 }
1080
BinaryNode(const char * sStr)1081 BinaryNode::BinaryNode( const char * sStr ) {
1082 // value is an SDAI_Binary (the memory is copied)
1083 value = sStr;
1084 }
1085
1086 SingleLinkNode *
NewNode()1087 BinaryNode::NewNode() {
1088 return new BinaryNode();
1089 }
1090
1091 /**
1092 * non-whitespace chars following s are considered garbage and is an error.
1093 * a valid value will still be assigned if it exists before the garbage.
1094 */
StrToVal(const char * s,ErrorDescriptor * err)1095 Severity BinaryNode::StrToVal( const char * s, ErrorDescriptor * err ) {
1096 return STEPread( s, err );
1097 }
1098
1099 /**
1100 * this function assumes you will check for garbage following input
1101 */
StrToVal(istream & in,ErrorDescriptor * err)1102 Severity BinaryNode::StrToVal( istream & in, ErrorDescriptor * err ) {
1103 return value.STEPread( in, err );
1104 }
1105
1106 /**
1107 * non-whitespace chars following s are considered garbage and is an error.
1108 * a valid value will still be assigned if it exists before the garbage.
1109 */
STEPread(const char * s,ErrorDescriptor * err)1110 Severity BinaryNode::STEPread( const char * s, ErrorDescriptor * err ) {
1111 istringstream in( ( char * )s );
1112
1113 value.STEPread( in, err );
1114 CheckRemainingInput( in, err, "binary", ",)" );
1115 return err->severity();
1116 }
1117
1118 /**
1119 * this function assumes you will check for garbage following input
1120 */
STEPread(istream & in,ErrorDescriptor * err)1121 Severity BinaryNode::STEPread( istream & in, ErrorDescriptor * err ) {
1122 return value.STEPread( in, err );
1123 }
1124
asStr(std::string & s)1125 const char * BinaryNode::asStr( std::string & s ) {
1126 s = value.c_str();
1127 return const_cast<char *>( s.c_str() );
1128 }
1129
STEPwrite(std::string & s,const char *)1130 const char * BinaryNode::STEPwrite( std::string & s, const char * ) {
1131 value.STEPwrite( s );
1132 return const_cast<char *>( s.c_str() );
1133 }
1134
STEPwrite(ostream & out)1135 void BinaryNode::STEPwrite( ostream & out ) {
1136 value.STEPwrite( out );
1137 }
1138
1139 ///////////////////////////////////////////////////////////////////////////////
1140 // EnumAggregate
1141 ///////////////////////////////////////////////////////////////////////////////
1142
1143 /// COPY
ShallowCopy(const STEPaggregate & a)1144 STEPaggregate & EnumAggregate::ShallowCopy( const STEPaggregate & a ) {
1145 const EnumNode * tmp = ( const EnumNode * ) a.GetHead();
1146 EnumNode * to;
1147
1148 while( tmp ) {
1149 to = ( EnumNode * ) NewNode();
1150 to -> node -> put( tmp -> node ->asInt() );
1151 AddNode( to );
1152 tmp = ( const EnumNode * ) tmp -> NextNode();
1153 }
1154 if( head ) {
1155 _null = 0;
1156 } else {
1157 _null = 1;
1158 }
1159
1160 return *this;
1161 }
1162
EnumAggregate()1163 EnumAggregate::EnumAggregate() {
1164
1165 }
1166
~EnumAggregate()1167 EnumAggregate::~EnumAggregate() {
1168
1169 }
1170
1171 /******************************************************************
1172 ** \returns a new EnumNode which is of the correct derived type
1173 ** \details creates a node to put in an list of enumerated values
1174 ** function is virtual so that the right node will be
1175 ** created
1176 ** Status: ok 2/91
1177 ******************************************************************/
NewNode()1178 SingleLinkNode * EnumAggregate::NewNode() {
1179 // defined in subclass
1180 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n" ;
1181 cerr << "function: EnumAggregate::NewNode () called instead of virtual function. \n"
1182 << _POC_ << "\n";
1183 return 0;
1184 }
1185
1186 ///////////////////////////////////////////////////////////////////////////////
1187 // EnumNode
1188 ///////////////////////////////////////////////////////////////////////////////
1189
EnumNode(SDAI_Enum * e)1190 EnumNode::EnumNode( SDAI_Enum * e ) : node( e ) {
1191 }
1192
EnumNode()1193 EnumNode::EnumNode() {
1194 }
1195
~EnumNode()1196 EnumNode::~EnumNode() {
1197 }
1198
1199 /// defined in subclass
NewNode()1200 SingleLinkNode * EnumNode::NewNode() {
1201 cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n" ;
1202 cerr << "function: EnumNode::NewNode () called instead of virtual function. \n"
1203 << _POC_ << "\n";
1204 return 0;
1205 }
1206
1207 /**
1208 * non-whitespace chars following s are considered garbage and is an error.
1209 * a valid value will still be assigned if it exists before the garbage.
1210 */
StrToVal(const char * s,ErrorDescriptor * err)1211 Severity EnumNode::StrToVal( const char * s, ErrorDescriptor * err ) {
1212 return STEPread( s, err );
1213 }
1214 /**
1215 * this function assumes you will check for garbage following input
1216 */
StrToVal(istream & in,ErrorDescriptor * err)1217 Severity EnumNode::StrToVal( istream & in, ErrorDescriptor * err ) {
1218 return node->STEPread( in, err );
1219 }
1220
1221 /**
1222 * non-whitespace chars following s are considered garbage and is an error.
1223 * a valid value will still be assigned if it exists before the garbage.
1224 */
STEPread(const char * s,ErrorDescriptor * err)1225 Severity EnumNode::STEPread( const char * s, ErrorDescriptor * err ) {
1226 istringstream in( ( char * )s ); // sz defaults to length of s
1227
1228 int nullable = 0;
1229 node->STEPread( in, err, nullable );
1230 CheckRemainingInput( in, err, "enumeration", ",)" );
1231 return err->severity();
1232 }
1233
1234 /**
1235 * this function assumes you will check for garbage following input
1236 */
STEPread(istream & in,ErrorDescriptor * err)1237 Severity EnumNode::STEPread( istream & in, ErrorDescriptor * err ) {
1238 int nullable = 0;
1239 node->STEPread( in, err, nullable );
1240 return err->severity();
1241 }
1242
asStr(std::string & s)1243 const char * EnumNode::asStr( std::string & s ) {
1244 node -> asStr( s );
1245 return const_cast<char *>( s.c_str() );
1246 }
1247
STEPwrite(std::string & s,const char *)1248 const char * EnumNode::STEPwrite( std::string & s, const char * ) {
1249 node->STEPwrite( s );
1250 return const_cast<char *>( s.c_str() );
1251 }
1252
STEPwrite(ostream & out)1253 void EnumNode::STEPwrite( ostream & out ) {
1254 node->STEPwrite( out );
1255 }
1256
1257 ///////////////////////////////////////////////////////////////////////////////
1258 // LOGICALS
1259 ///////////////////////////////////////////////////////////////////////////////
1260
LOGICALS()1261 LOGICALS::LOGICALS() {
1262 }
1263
~LOGICALS()1264 LOGICALS::~LOGICALS() {
1265 }
1266
NewNode()1267 SingleLinkNode * LOGICALS::NewNode() {
1268 return new EnumNode( new SDAI_LOGICAL );
1269 }
1270
create_LOGICALS()1271 LOGICALS * create_LOGICALS() {
1272 return new LOGICALS;
1273 }
1274
1275 ///////////////////////////////////////////////////////////////////////////////
1276 // BOOLEANS
1277 ///////////////////////////////////////////////////////////////////////////////
1278
BOOLEANS()1279 BOOLEANS::BOOLEANS() {
1280 }
1281
~BOOLEANS()1282 BOOLEANS::~BOOLEANS() {
1283 }
1284
NewNode()1285 SingleLinkNode * BOOLEANS::NewNode() {
1286 return new EnumNode( new SDAI_BOOLEAN );
1287 }
1288
create_BOOLEANS()1289 BOOLEANS * create_BOOLEANS() {
1290 return new BOOLEANS ;
1291 }
1292
1293 ///////////////////////////////////////////////////////////////////////////////
1294 // RealAggregate
1295 ///////////////////////////////////////////////////////////////////////////////
1296
RealAggregate()1297 RealAggregate::RealAggregate() {
1298 }
1299
~RealAggregate()1300 RealAggregate::~RealAggregate() {
1301 }
1302
NewNode()1303 SingleLinkNode * RealAggregate::NewNode() {
1304 return new RealNode();
1305 }
1306
1307 // COPY
ShallowCopy(const STEPaggregate & a)1308 STEPaggregate & RealAggregate::ShallowCopy( const STEPaggregate & a ) {
1309 const RealNode * tmp = ( const RealNode * ) a.GetHead();
1310 RealNode * to;
1311
1312 while( tmp ) {
1313 to = ( RealNode * ) NewNode();
1314 to -> value = tmp -> value;
1315 AddNode( to );
1316 tmp = ( const RealNode * ) tmp -> NextNode();
1317 }
1318 if( head ) {
1319 _null = 0;
1320 } else {
1321 _null = 1;
1322 }
1323 return *this;
1324 }
1325
1326 ///////////////////////////////////////////////////////////////////////////////
1327 // IntAggregate
1328 ///////////////////////////////////////////////////////////////////////////////
1329
IntAggregate()1330 IntAggregate::IntAggregate() {
1331 }
1332
~IntAggregate()1333 IntAggregate::~IntAggregate() {
1334 }
1335
NewNode()1336 SingleLinkNode * IntAggregate::NewNode() {
1337 return new IntNode();
1338 }
1339
1340 /// COPY
ShallowCopy(const STEPaggregate & a)1341 STEPaggregate & IntAggregate::ShallowCopy( const STEPaggregate & a ) {
1342 const IntNode * tmp = ( const IntNode * ) a.GetHead();
1343 IntNode * to;
1344
1345 while( tmp ) {
1346 to = ( IntNode * ) NewNode();
1347 to -> value = tmp -> value;
1348 AddNode( to );
1349 tmp = ( const IntNode * ) tmp -> NextNode();
1350 }
1351 if( head ) {
1352 _null = 0;
1353 } else {
1354 _null = 1;
1355 }
1356 return *this;
1357 }
1358
1359 ///////////////////////////////////////////////////////////////////////////////
1360 // RealNode
1361 ///////////////////////////////////////////////////////////////////////////////
1362
RealNode()1363 RealNode::RealNode() {
1364 value = S_REAL_NULL;
1365 }
1366
RealNode(SDAI_Real v)1367 RealNode::RealNode( SDAI_Real v) {
1368 value = v;
1369 }
1370
~RealNode()1371 RealNode::~RealNode() {
1372 }
1373
NewNode()1374 SingleLinkNode * RealNode::NewNode() {
1375 return new RealNode();
1376 }
1377
StrToVal(const char * s,ErrorDescriptor * err)1378 Severity RealNode::StrToVal( const char * s, ErrorDescriptor * err ) {
1379 if( ReadReal( value, s, err, ",)" ) ) { // returns true if value is assigned
1380 _null = 0;
1381 } else {
1382 set_null();
1383 value = S_REAL_NULL;
1384 }
1385 return err->severity();
1386 }
1387
StrToVal(istream & in,ErrorDescriptor * err)1388 Severity RealNode::StrToVal( istream & in, ErrorDescriptor * err ) {
1389 if( ReadReal( value, in, err, ",)" ) ) { // returns true if value is assigned
1390 _null = 0;
1391 } else {
1392 set_null();
1393 value = S_REAL_NULL;
1394 }
1395 return err->severity();
1396 }
1397
STEPread(const char * s,ErrorDescriptor * err)1398 Severity RealNode::STEPread( const char * s, ErrorDescriptor * err ) {
1399 if( ReadReal( value, s, err, ",)" ) ) { // returns true if value is assigned
1400 _null = 0;
1401 } else {
1402 set_null();
1403 value = S_REAL_NULL;
1404 }
1405 return err->severity();
1406 }
1407
STEPread(istream & in,ErrorDescriptor * err)1408 Severity RealNode::STEPread( istream & in, ErrorDescriptor * err ) {
1409 if( ReadReal( value, in, err, ",)" ) ) { // returns true if value is assigned
1410 _null = 0;
1411 } else {
1412 set_null();
1413 value = S_REAL_NULL;
1414 }
1415 return err->severity();
1416 }
1417
asStr(std::string & s)1418 const char * RealNode::asStr( std::string & s ) {
1419 STEPwrite( s );
1420 return const_cast<char *>( s.c_str() );
1421 }
1422
STEPwrite(std::string & s,const char *)1423 const char * RealNode::STEPwrite( std::string & s, const char * ) {
1424 if( value != S_REAL_NULL ) {
1425 s = WriteReal( value );
1426 } else {
1427 s.clear();
1428 }
1429 return s.c_str();
1430 }
1431
STEPwrite(ostream & out)1432 void RealNode::STEPwrite( ostream & out ) {
1433 std::string s;
1434 out << STEPwrite( s );
1435 }
1436
1437 ///////////////////////////////////////////////////////////////////////////////
1438 // IntNode
1439 ///////////////////////////////////////////////////////////////////////////////
1440
IntNode()1441 IntNode::IntNode() {
1442 value = S_INT_NULL;
1443 }
1444
IntNode(SDAI_Integer v)1445 IntNode::IntNode( SDAI_Integer v ) {
1446 value = v;
1447 }
1448
~IntNode()1449 IntNode::~IntNode() {
1450 }
1451
NewNode()1452 SingleLinkNode * IntNode::NewNode() {
1453 return new IntNode();
1454 }
1455
StrToVal(const char * s,ErrorDescriptor * err)1456 Severity IntNode::StrToVal( const char * s, ErrorDescriptor * err ) {
1457 if( ReadInteger( value, s, err, ",)" ) ) { // returns true if value is assigned
1458 _null = 0;
1459 } else {
1460 set_null();
1461 value = S_INT_NULL;
1462 }
1463 return err->severity();
1464 }
1465
StrToVal(istream & in,ErrorDescriptor * err)1466 Severity IntNode::StrToVal( istream & in, ErrorDescriptor * err ) {
1467 if( ReadInteger( value, in, err, ",)" ) ) { // returns true if value is assigned
1468 _null = 0;
1469 } else {
1470 set_null();
1471 value = S_INT_NULL;
1472 }
1473 return err->severity();
1474 }
1475
STEPread(const char * s,ErrorDescriptor * err)1476 Severity IntNode::STEPread( const char * s, ErrorDescriptor * err ) {
1477 if( ReadInteger( value, s, err, ",)" ) ) { // returns true if value is assigned
1478 _null = 0;
1479 } else {
1480 set_null();
1481 value = S_INT_NULL;
1482 }
1483 return err->severity();
1484 }
1485
STEPread(istream & in,ErrorDescriptor * err)1486 Severity IntNode::STEPread( istream & in, ErrorDescriptor * err ) {
1487 if( ReadInteger( value, in, err, ",)" ) ) { // returns true if value is assigned
1488 _null = 0;
1489 } else {
1490 set_null();
1491 value = S_INT_NULL;
1492 }
1493 return err->severity();
1494 }
1495
asStr(std::string & s)1496 const char * IntNode::asStr( std::string & s ) {
1497 STEPwrite( s );
1498 return const_cast<char *>( s.c_str() );
1499 }
1500
STEPwrite(std::string & s,const char *)1501 const char * IntNode::STEPwrite( std::string & s, const char * ) {
1502 char tmp[BUFSIZ];
1503 if( value != S_INT_NULL ) {
1504 sprintf( tmp, "%ld", value );
1505 s = tmp;
1506 } else {
1507 s.clear();
1508 }
1509 return const_cast<char *>( s.c_str() );
1510 }
1511
STEPwrite(ostream & out)1512 void IntNode::STEPwrite( ostream & out ) {
1513 std::string s;
1514 out << STEPwrite( s );
1515 }
1516