1 
2 /*
3 * NIST STEP Core Class Library
4 * cleditor/STEPfile.inline.cc
5 * April 1997
6 * Peter Carr
7 * K. C. Morris
8 * David Sauder
9 
10 * Development of this software was funded by the United States Government,
11 * and is not subject to copyright.
12 */
13 
14 #include <STEPfile.h>
15 #include <SdaiHeaderSchema.h>
16 #include <STEPaggregate.h>
17 #include <cmath>
18 
19 #include <cstring>
20 #include "sc_memmgr.h"
21 
22 extern void HeaderSchemaInit( Registry & reg );
23 
24 //To Be inline functions
25 
26 //constructor & destructor
27 
STEPfile(Registry & r,InstMgr & i,const std::string filename,bool strict)28 STEPfile::STEPfile( Registry & r, InstMgr & i, const std::string filename, bool strict ) :
29         _instances( i ), _reg( r ), _fileIdIncr( 0 ), _headerId( 0 ), _iFileSize( 0 ),
30         _iFileCurrentPosition( 0 ), _iFileStage1Done( false ), _oFileInstsWritten( 0 ),
31         _entsNotCreated( 0 ), _entsInvalid( 0 ), _entsIncomplete( 0 ), _entsWarning( 0 ),
32         _errorCount( 0 ), _warningCount( 0 ), _maxErrorCount( 100000 ), _strict( strict ) {
33     SetFileType( VERSION_CURRENT );
34     SetFileIdIncrement();
35     _currentDir = new DirObj( "" );
36     _headerRegistry = new Registry( HeaderSchemaInit );
37     _headerInstances = new InstMgr;
38     if( !filename.empty() ) {
39         ReadExchangeFile( filename );
40     }
41 }
42 
~STEPfile()43 STEPfile::~STEPfile() {
44     delete _currentDir;
45 
46     delete _headerRegistry;
47 
48     _headerInstances->DeleteInstances();
49     delete _headerInstances;
50 }
51 
SetFileType(FileTypeCode ft)52 int STEPfile::SetFileType( FileTypeCode ft ) {
53     FileType( ft );
54 
55     switch( _fileType ) {
56         case( VERSION_OLD ):
57             ENTITY_NAME_DELIM = '@';
58             FILE_DELIM = "STEP;";
59             END_FILE_DELIM = "ENDSTEP;";
60             break;
61         case( VERSION_UNKNOWN ):
62         case( VERSION_CURRENT ):
63             ENTITY_NAME_DELIM = '#';
64             FILE_DELIM = "ISO-10303-21;";
65             END_FILE_DELIM = "END-ISO-10303-21;";
66             break;
67         case( WORKING_SESSION ):
68             ENTITY_NAME_DELIM = '#';
69             FILE_DELIM = "STEP_WORKING_SESSION;";
70             END_FILE_DELIM = "END-STEP_WORKING_SESSION;";
71             break;
72 
73         default:
74             // some kind of error
75             cerr << "Internal error:  " << __FILE__ <<  __LINE__
76                  << "\n" << _POC_ "\n";
77             return 0;
78     }
79     return 1;
80 }
81 
82 
83 /******************************************************
84 ** remove any slashes, and anything before the slash,
85 ** from filename
86 */
TruncFileName(const std::string filename) const87 std::string STEPfile::TruncFileName( const std::string filename ) const {
88 #if defined(__WIN32__) && !defined(__mingw32__)
89     char slash = '\\';
90 #else
91     char slash = '/';
92 #endif
93     size_t l = filename.find_last_of( slash );
94     if( l == std::string::npos ) {
95         return filename;
96     } else {
97         return filename.substr( l );
98     }
99 }
100 
101 
102 /******************************************************/
ReadExchangeFile(const std::string filename,bool useTechCor)103 Severity STEPfile::ReadExchangeFile( const std::string filename, bool useTechCor ) {
104     _error.ClearErrorMsg();
105     _errorCount = 0;
106     istream * in = OpenInputFile( filename );
107     if( _error.severity() < SEVERITY_WARNING ) {
108         CloseInputFile( in );
109         return _error.severity();
110     }
111 
112     instances().ClearInstances();
113     if( _headerInstances ) {
114         _headerInstances->ClearInstances();
115     }
116     _headerId = 5;
117     Severity rval = AppendFile( in, useTechCor );
118     CloseInputFile( in );
119     return rval;
120 }
121 
AppendExchangeFile(const std::string filename,bool useTechCor)122 Severity STEPfile::AppendExchangeFile( const std::string filename, bool useTechCor ) {
123     _error.ClearErrorMsg();
124     _errorCount = 0;
125     istream * in = OpenInputFile( filename );
126     if( _error.severity() < SEVERITY_WARNING ) {
127         CloseInputFile( in );
128         return _error.severity();
129     }
130     Severity rval = AppendFile( in, useTechCor );
131     CloseInputFile( in );
132     return rval;
133 }
134 
135 /******************************************************/
ReadWorkingFile(const std::string filename,bool useTechCor)136 Severity STEPfile::ReadWorkingFile( const std::string filename, bool useTechCor ) {
137     _error.ClearErrorMsg();
138     _errorCount = 0;
139     istream * in = OpenInputFile( filename );
140     if( _error.severity() < SEVERITY_WARNING ) {
141         CloseInputFile( in );
142         return _error.severity();
143     }
144 
145     instances().ClearInstances();
146     _headerInstances->ClearInstances();
147     SetFileType( WORKING_SESSION );
148 
149     Severity rval = AppendFile( in, useTechCor );
150     SetFileType();
151     CloseInputFile( in );
152     return rval;
153 }
154 
155 
AppendWorkingFile(const std::string filename,bool useTechCor)156 Severity STEPfile::AppendWorkingFile( const std::string filename, bool useTechCor ) {
157     _error.ClearErrorMsg();
158     _errorCount = 0;
159     istream * in = OpenInputFile( filename );
160     if( _error.severity() < SEVERITY_WARNING ) {
161         CloseInputFile( in );
162         return _error.severity();
163     }
164     SetFileType( WORKING_SESSION );
165     Severity rval = AppendFile( in, useTechCor );
166     SetFileType();
167     CloseInputFile( in );
168     return rval;
169 }
170 
171 /******************************************************/
OpenInputFile(const std::string filename)172 istream * STEPfile::OpenInputFile( const std::string filename ) {
173     _iFileCurrentPosition = 0;
174 
175     //  if there's no filename to use, fail
176     if( filename.empty() && FileName().empty() ) {
177         _error.AppendToUserMsg( "Unable to open file for input. No current file name.\n" );
178         _error.GreaterSeverity( SEVERITY_INPUT_ERROR );
179         return( 0 );
180     } else {
181         if( SetFileName( filename ).empty() && ( filename.compare( "-" ) != 0 ) ) {
182             char msg[BUFSIZ];
183             sprintf( msg, "Unable to find file for input: \'%s\'. File not read.\n", filename.c_str() );
184             _error.AppendToUserMsg( msg );
185             _error.GreaterSeverity( SEVERITY_INPUT_ERROR );
186             return( 0 );
187         }
188     }
189 
190     std::istream * in;
191 
192     if( filename.compare( "-" ) == 0 ) {
193         in = &std::cin;
194     } else {
195         in = new ifstream( FileName().c_str() );
196     }
197 
198     if( !in || !( in -> good() ) ) {
199         char msg[BUFSIZ];
200         sprintf( msg, "Unable to open file for input: \'%s\'. File not read.\n", filename.c_str() );
201         _error.AppendToUserMsg( msg );
202         _error.GreaterSeverity( SEVERITY_INPUT_ERROR );
203         return ( 0 );
204     }
205 
206     //check size of file
207     in->seekg( 0, std::ifstream::end );
208     _iFileSize = in->tellg();
209     in->seekg( 0, std::ifstream::beg );
210     return in;
211 }
212 
213 /******************************************************/
CloseInputFile(istream * in)214 void STEPfile::CloseInputFile( istream * in ) {
215     if (in != &std::cin) {
216         delete in;
217     }
218 
219     //reset file size
220     _iFileSize = 0;
221     _iFileCurrentPosition = 0;
222 }
223 
224 
225 /******************************************************/
OpenOutputFile(std::string filename)226 ofstream * STEPfile::OpenOutputFile( std::string filename ) {
227     if( filename.empty() ) {
228         if( FileName().empty() ) {
229             _error.AppendToUserMsg( "No current file name.\n" );
230             _error.GreaterSeverity( SEVERITY_INPUT_ERROR );
231         }
232     } else {
233         if( SetFileName( filename ).empty() ) {
234             char msg[BUFSIZ];
235             sprintf( msg, "can't find file: %s\nFile not written.\n", filename.c_str() );
236             _error.AppendToUserMsg( msg );
237             _error.GreaterSeverity( SEVERITY_INPUT_ERROR );
238         }
239     }
240 
241     if( _currentDir->FileExists( TruncFileName( filename ) ) ) {
242         MakeBackupFile();
243     }
244     ofstream * out  = new ofstream( filename.c_str() );
245     if( !out ) {
246         _error.AppendToUserMsg( "unable to open file for output\n" );
247         _error.GreaterSeverity( SEVERITY_INPUT_ERROR );
248     }
249     _oFileInstsWritten = 0;
250     return out;
251 }
252 
CloseOutputFile(ostream * out)253 void STEPfile::CloseOutputFile( ostream * out ) {
254     _oFileInstsWritten = 0;
255     delete out;
256 }
257 
258 /******************************************************/
IncrementFileId(int fileid)259 int STEPfile::IncrementFileId( int fileid ) {
260     return ( fileid + FileIdIncr() );
261 }
262 
263 
SetFileIdIncrement()264 void STEPfile::SetFileIdIncrement() {
265     if( instances().MaxFileId() < 0 ) {
266         _fileIdIncr = 0;
267     } else {
268         _fileIdIncr = ( int )( ( ceil( ( instances().MaxFileId() + 99.0 ) / 1000.0 ) + 1.0 ) * 1000.0 );
269     }
270 }
271 
272 /**
273  * Returns the schema name from the file schema header section (or the 1st
274  * one if more than one exists).  Copies this value into schName.  If there
275  * is no header section or no value for file schema, NULL is returned and
276  * schName is unset.
277  */
schemaName()278 std::string STEPfile::schemaName() {
279     SdaiFile_schema * fs;
280     std::string schName;
281     STEPnode * n;
282 
283     if( _headerInstances == NULL ) {
284         return schName;
285     }
286     fs = ( SdaiFile_schema * )_headerInstances->GetApplication_instance( "File_Schema" );
287     if( fs == ENTITY_NULL ) {
288         return schName;
289     }
290 
291     n = ( STEPnode * )fs->schema_identifiers_()->GetHead();
292     // (take the first one)
293     if( n == NULL ) {
294         return schName;
295     }
296     n->STEPwrite( schName );
297     if( schName.empty() || schName[0] == '$' ) {
298         schName.clear();
299         return schName;
300     } else if( schName[0] == '\0' ) {
301         //probably never - it seems that putting null in std::string takes effort
302         _error.AppendToUserMsg( "In STEPfile::schemaName: schName contains \\0 - it should be empty." );
303         _error.GreaterSeverity( SEVERITY_WARNING );
304         schName.clear();
305         return schName;
306     }
307     if( schName[ schName.length() - 1 ] == '\'' ) {
308         schName = schName.substr( 1, schName.length() - 2 );
309     } else {
310         _error.AppendToUserMsg( "In STEPfile::schemaName: schName was truncated." );
311         _error.GreaterSeverity( SEVERITY_WARNING );
312 
313         schName = schName.substr( 1, schName.length() - 1 );
314     }
315     return schName;
316 }
317