BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / surfMesh / surfaceFormats / stl / STLsurfaceFormatASCII.L
blob2699c9510c83954592f7cce3bc138250c6deeae6
1 /*--------------------------------*- C++ -*----------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
28 #undef yyFlexLexer
30  /* ------------------------------------------------------------------------ *\
31    ------ local definitions
32  \* ------------------------------------------------------------------------ */
34 #include "STLsurfaceFormatCore.H"
36 using namespace Foam;
38 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
39 //! \cond dummy
40 int yyFlexLexer::yylex()
42     FatalErrorIn("yyFlexLexer::yylex()")
43         << "Should not have called this function"
44         << abort(FatalError);
45     return 0;
47 //! \endcond
49 // Dummy yywrap to keep yylex happy at compile time.
50 // It is called by yylex but is not used as the mechanism to change file.
51 // See <<EOF>>
52 //! \cond dummy
53 #if YY_FLEX_SUBMINOR_VERSION < 34
54 extern "C" int yywrap()
55 #else
56 int yyFlexLexer::yywrap()
57 #endif
59     return 1;
61 //! \endcond
64 //- A lexer for parsing STL ASCII files.
65 //  Returns DynamicList(s) of points and facets (zoneIds).
66 //  The facets are within a solid/endsolid grouping
67 class STLASCIILexer
69     public yyFlexLexer
71     // Private data
73         bool  sorted_;
74         label groupID_;      // current solid group
75         label lineNo_;
76         word  startError_;
78         DynamicList<point> points_;
79         DynamicList<label> facets_;
80         DynamicList<word>  names_;
81         DynamicList<label> sizes_;
82         HashTable<label>   lookup_;
84 public:
86     // Constructors
88         //- From input stream and the approximate number of vertices in the STL
89         STLASCIILexer(istream* is, const label approxNpoints);
92     // Member Functions
94         //- The lexer function itself
95         int lex();
97     // Access
99         //- Do all the solid groups appear in order
100         bool sorted() const
101         {
102             return sorted_;
103         }
105         //- A list of points corresponding to a pointField
106         DynamicList<point>& points()
107         {
108             return points_;
109         }
111         //- A list of facet IDs (group IDs)
112         //  corresponds to the number of triangles
113         DynamicList<label>& facets()
114         {
115             return facets_;
116         }
118         //- Names
119         DynamicList<word>& names()
120         {
121             return names_;
122         }
124         //- Sizes
125         DynamicList<label>& sizes()
126         {
127             return sizes_;
128         }
132 STLASCIILexer::STLASCIILexer(istream* is, const label approxNpoints)
134     yyFlexLexer(is),
135     sorted_(true),
136     groupID_(-1),
137     lineNo_(1),
138     points_(approxNpoints),
139     facets_(approxNpoints)
143  /* ------------------------------------------------------------------------ *\
144    ------ cppLexer::yylex()
145  \* ------------------------------------------------------------------------ */
147 #define YY_DECL int STLASCIILexer::lex()
151 one_space             [ \t\f\r]
152 space                 {one_space}*
153 some_space            {one_space}+
155 alpha                 [_A-Za-z]
156 digit                 [0-9]
158 integer               {digit}+
159 signedInteger         [-+]?{integer}
161 word                  ([[:alnum:]]|[[:punct:]])*
162 string                {word}({some_space}{word})*
164 exponent_part         [eE][-+]?{digit}+
165 fractional_constant   [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
167 floatNum              (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
169 x                     {floatNum}
170 y                     {floatNum}
171 z                     {floatNum}
173 solid                 {space}("solid"|"SOLID"){space}
174 color                 {space}("color"|"COLOR"){some_space}{floatNum}{some_space}{floatNum}{some_space}{floatNum}{space}
175 facet                 {space}("facet"|"FACET"){space}
176 normal                {space}("normal"|"NORMAL"){space}
177 point                 {space}{x}{some_space}{y}{some_space}{z}{space}
178 outerloop             {space}("outer"{some_space}"loop")|("OUTER"{some_space}"LOOP"){space}
179 vertex                {space}("vertex"|"VERTEX"){space}
180 endloop               {space}("endloop"|"ENDLOOP"){space}
181 endfacet              {space}("endfacet"|"ENDFACET"){space}
182 endsolid              {space}("endsolid"|"ENDSOLID")({some_space}{word})*
185  /* ------------------------------------------------------------------------ *\
186                       -----  Exclusive start states -----
187  \* ------------------------------------------------------------------------ */
189 %option stack
191 %x readSolidName
192 %x readFacet
193 %x readNormal
194 %x readVertices
195 %x readVertex
196 %x stlError
201     // End of read character pointer returned by strtof
202     // char* endPtr;
204     STLpoint normal;
205     STLpoint vertex;
206     label cmpt = 0;   // component index used for reading vertex
208     static const char* stateNames[7] =
209     {
210         "reading solid",
211         "reading solid name",
212         "reading facet",
213         "reading normal",
214         "reading vertices",
215         "reading vertex",
216         "error"
217     };
219     static const char* stateExpects[7] =
220     {
221         "'solid', 'color', 'facet' or 'endsolid'",
222         "<string>",
223         "'normal', 'outer loop' or 'endfacet'",
224         "<float> <float> <float>",
225         "'vertex' or 'endloop'",
226         "<float> <float> <float>",
227         ""
228     };
232  /* ------------------------------------------------------------------------ *\
233                             ------ Start Lexing ------
234  \* ------------------------------------------------------------------------ */
236  /*                      ------ Reading control header ------                */
238 {solid} {
239         BEGIN(readSolidName);
240     }
242 <readSolidName>{string} {
243         word name(Foam::string::validate<word>(YYText()));
245         HashTable<label>::const_iterator fnd = lookup_.find(name);
246         if (fnd != lookup_.end())
247         {
248             if (groupID_ != fnd())
249             {
250                 // group appeared out of order
251                 sorted_ = false;
252             }
253             groupID_ = fnd();
254         }
255         else
256         {
257             groupID_ = sizes_.size();
258             lookup_.insert(name, groupID_);
259             names_.append(name);
260             sizes_.append(0);
261         }
262         BEGIN(INITIAL);
263     }
265 <readSolidName>{space}\n {
266         word name("solid");
268         HashTable<label>::const_iterator fnd = lookup_.find(name);
269         if (fnd != lookup_.end())
270         {
271             if (groupID_ != fnd())
272             {
273                 // group appeared out of order
274                 sorted_ = false;
275             }
276             groupID_ = fnd();
277         }
278         else
279         {
280             groupID_ = sizes_.size();
281             lookup_.insert(name, groupID_);
282             names_.append(name);
283             sizes_.append(0);
284         }
286         lineNo_++;
287         BEGIN(INITIAL);
288     }
290 {color} {
291     }
293 {facet} {
294         BEGIN(readFacet);
295     }
297 <readFacet>{normal} {
298         BEGIN(readNormal);
299     }
301 <readNormal>{point} {
302         /*
303          skip reading normals:
304          normal.x() = strtof(YYText(), &endPtr);
305          normal.y() = strtof(endPtr, &endPtr);
306          normal.z() = strtof(endPtr, &endPtr);
307          normals_.append(normal);
308          */
309         BEGIN(readFacet);
310     }
312 <readFacet>{outerloop} {
313         BEGIN(readVertices);
314     }
316 <readVertices>{vertex} {
317         BEGIN(readVertex);
318     }
320 <readVertex>{space}{signedInteger}{space} {
321         vertex[cmpt++] = atol(YYText());
323         if (cmpt == 3)
324         {
325             cmpt = 0;
326             points_.append(vertex);
327             BEGIN(readVertices);
328         }
329     }
331 <readVertex>{space}{floatNum}{space} {
332         vertex[cmpt++] = atof(YYText());
334         if (cmpt == 3)
335         {
336             cmpt = 0;
337             points_.append(vertex);
338             BEGIN(readVertices);
339         }
340     }
342 <readVertices>{endloop} {
343         BEGIN(readFacet);
344     }
346 <readFacet>{endfacet} {
347         facets_.append(groupID_);
348         sizes_[groupID_]++;
349         BEGIN(INITIAL);
350     }
352 {endsolid} {
353     }
356  /* ------------------ Ignore remaining space and \n s. -------------------- */
358 <*>{space} {}
359 <*>\n      { lineNo_++; }
362  /* ------------------- Any other characters are errors -------------------- */
364 <*>. {
365         startError_ = YYText();
366         yy_push_state(stlError);
367     }
370  /* ---------------------------- Error handler ----------------------------- */
372 <stlError>.* {
373         yy_pop_state();
374         FatalErrorIn
375         (
376             "fileFormats::STLsurfaceFormatCore::readASCII(const fileName&)"
377         )   << "while " << stateNames[YY_START] << " on line " << lineNo_ << nl
378             << "    expected " << stateExpects[YY_START]
379             << " but found '" << startError_.c_str() << YYText() << "'"
380             << exit(FatalError);
381     }
384  /*  ------------------------ On EOF terminate ----------------------------  */
386 <<EOF>> {
387             yyterminate();
388     }
393 // member function
395 bool Foam::fileFormats::STLsurfaceFormatCore::readASCII
397     istream& is,
398     const off_t dataFileSize
401     // Create the lexer with the approximate number of vertices in the STL
402     // from the file size
403     STLASCIILexer lexer(&is, dataFileSize/400);
404     while (lexer.lex() != 0) {}
406     sorted_ = lexer.sorted();
408     // transfer to normal lists
409     points_.transfer(lexer.points());
410     zoneIds_.transfer(lexer.facets());
411     names_.transfer(lexer.names());
412     sizes_.transfer(lexer.sizes());
414     return true;
417  /* ------------------------------------------------------------------------ *\
418     ------ End of STLfileFormatASCII.L
419  \* ------------------------------------------------------------------------ */