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