mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improve robustness of raw reading, file size checks
- use ignore instead of seekg/tellg to swallow input (robuster) - check for bad gcount() values - wrap Foam::fileSize() compressed/uncompressed handling into IFstream. - improve handling of compressed files in masterUncollatedFileOperation. Previously read into a string via stream iterators. Now read chunk-wise into a List of char for fewer reallocations.
This commit is contained in:
committed by
Andrew Heather
parent
a341d09afc
commit
459aaad0f9
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2020 OpenCFD Ltd.
|
Copyright (C) 2020-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -33,6 +33,7 @@ Description
|
|||||||
|
|
||||||
#include "argList.H"
|
#include "argList.H"
|
||||||
#include "Fstream.H"
|
#include "Fstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
#include "etcFiles.H"
|
#include "etcFiles.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
@ -44,11 +45,14 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
argList::noBanner();
|
argList::noBanner();
|
||||||
argList::noParallel();
|
argList::noParallel();
|
||||||
|
argList::noParallel();
|
||||||
|
argList::addOption("ignore", "file", "Test readRaw with ignore");
|
||||||
|
|
||||||
#include "setRootCase.H"
|
#include "setRootCase.H"
|
||||||
|
|
||||||
// Test with etc/controlDict (mandatory, from distribution)
|
// Test with etc/controlDict (mandatory, from distribution)
|
||||||
|
|
||||||
|
if (!args.found("ignore"))
|
||||||
{
|
{
|
||||||
const fileName inputFile
|
const fileName inputFile
|
||||||
(
|
(
|
||||||
@ -97,6 +101,43 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileName testFile;
|
||||||
|
if (args.readIfPresent("ignore", testFile))
|
||||||
|
{
|
||||||
|
if (testFile.has_ext("gz"))
|
||||||
|
{
|
||||||
|
testFile.remove_ext();
|
||||||
|
Info<< "stripping extraneous .gz ending" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFstream is(testFile);
|
||||||
|
auto& stdStream = is.stdStream();
|
||||||
|
|
||||||
|
List<char> buffer(1000);
|
||||||
|
|
||||||
|
Info<< "Test readRaw with: " << is.name()
|
||||||
|
<< " compressed:" << int(is.compression())
|
||||||
|
<< " file-size:" << is.fileSize() << nl;
|
||||||
|
|
||||||
|
for (int iter = 0; is.good() && iter < 1000; ++iter)
|
||||||
|
{
|
||||||
|
Info<< "iter:" << iter;
|
||||||
|
if (iter % 2)
|
||||||
|
{
|
||||||
|
Info<< " [read] ";
|
||||||
|
is.readRaw(buffer.data(), buffer.size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< " [ignore]";
|
||||||
|
is.readRaw(nullptr, buffer.size() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< " : " << stdStream.gcount() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Info<< "\nEnd\n" << endl;
|
Info<< "\nEnd\n" << endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,7 +130,7 @@ static List<char> slurpFile
|
|||||||
// 66% compression = 3 iterations
|
// 66% compression = 3 iterations
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
const off_t inputSize = Foam::fileSize(pathname + ".gz");
|
const auto inputSize = Foam::fileSize(pathname + ".gz");
|
||||||
|
|
||||||
const uint64_t chunkSize =
|
const uint64_t chunkSize =
|
||||||
(
|
(
|
||||||
@ -202,7 +202,7 @@ static List<char> slurpFile
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const off_t inputSize = Foam::fileSize(pathname);
|
const auto inputSize = Foam::fileSize(pathname);
|
||||||
|
|
||||||
if (inputSize >= 0)
|
if (inputSize >= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -27,7 +27,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "IFstream.H"
|
#include "IFstream.H"
|
||||||
#include "OSspecific.H"
|
#include "OSspecific.H" // For isFile(), fileSize()
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -91,6 +91,45 @@ Foam::IFstream::IFstream
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
std::streamsize Foam::IFstream::fileSize() const
|
||||||
|
{
|
||||||
|
const std::istream* ptr = ifstreamPointer::get();
|
||||||
|
|
||||||
|
if (!ptr || this->name().empty())
|
||||||
|
{
|
||||||
|
return std::streamsize(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t fileLen = -1;
|
||||||
|
|
||||||
|
if (IOstreamOption::COMPRESSED == ifstreamPointer::whichCompression())
|
||||||
|
{
|
||||||
|
fileLen = Foam::fileSize(this->name() + ".gz");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TBD: special handing for wrapped icharstream
|
||||||
|
// if
|
||||||
|
// (
|
||||||
|
// const Foam::icharstream* charstr
|
||||||
|
// = dynamic_cast<const Foam::icharstream*>(ptr)>(ptr)
|
||||||
|
// )
|
||||||
|
// {
|
||||||
|
// return charstr->capacity();
|
||||||
|
// }
|
||||||
|
|
||||||
|
fileLen = Foam::fileSize(this->name());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileLen >= 0)
|
||||||
|
{
|
||||||
|
return std::streamsize(fileLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::streamsize(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::istream& Foam::IFstream::stdStream()
|
std::istream& Foam::IFstream::stdStream()
|
||||||
{
|
{
|
||||||
std::istream* ptr = ifstreamPointer::get();
|
std::istream* ptr = ifstreamPointer::get();
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011 OpenFOAM Foundation
|
Copyright (C) 2011 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -94,6 +94,13 @@ public:
|
|||||||
//- Read/write access to the name of the stream
|
//- Read/write access to the name of the stream
|
||||||
using ISstream::name;
|
using ISstream::name;
|
||||||
|
|
||||||
|
//- Return the size of the underlying file (-1 on error).
|
||||||
|
//- This corresponds to Foam::fileSize() but with extra handling of
|
||||||
|
//- compressed files.
|
||||||
|
// The return type is \c std::streamsize instead of \c off_t.
|
||||||
|
// \note Use sparingly since it involves a file stat()!
|
||||||
|
std::streamsize fileSize() const;
|
||||||
|
|
||||||
|
|
||||||
// STL stream
|
// STL stream
|
||||||
|
|
||||||
|
|||||||
@ -1051,20 +1051,7 @@ Foam::Istream& Foam::ISstream::readRaw(char* data, std::streamsize count)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Forward seek
|
is_.ignore(count);
|
||||||
// - use absolute positioning (see C++ notes about std::ifstream)
|
|
||||||
is_.seekg(is_.tellg() + std::istream::pos_type(count));
|
|
||||||
|
|
||||||
// Not sure if this is needed (as per rewind)
|
|
||||||
// some documentation indicates that ifstream needs
|
|
||||||
// seekg with values from a tellg
|
|
||||||
//
|
|
||||||
// stdStream().rdbuf()->pubseekpos
|
|
||||||
// (
|
|
||||||
// count,
|
|
||||||
// std::ios_base::seekdir::cur,
|
|
||||||
// std::ios_base::in
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
syncState();
|
syncState();
|
||||||
@ -1102,8 +1089,11 @@ void Foam::ISstream::rewind()
|
|||||||
stdStream().clear(); // Clear the iostate error state flags
|
stdStream().clear(); // Clear the iostate error state flags
|
||||||
setGood(); // Sync local copy of iostate
|
setGood(); // Sync local copy of iostate
|
||||||
|
|
||||||
// pubseekpos() rather than seekg() so that it works with gzstream
|
|
||||||
stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);
|
stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);
|
||||||
|
|
||||||
|
// NOTE: this form of rewind does not work with igzstream.
|
||||||
|
// However, igzstream is usually wrapped as IFstream which has its
|
||||||
|
// own dedicated rewind treatment for igzstream.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -76,9 +76,10 @@ inline int Foam::ISstream::peek()
|
|||||||
inline Foam::ISstream& Foam::ISstream::getLine(std::string& str, char delim)
|
inline Foam::ISstream& Foam::ISstream::getLine(std::string& str, char delim)
|
||||||
{
|
{
|
||||||
std::getline(is_, str, delim);
|
std::getline(is_, str, delim);
|
||||||
|
std::streamsize count = is_.gcount();
|
||||||
syncState();
|
syncState();
|
||||||
|
|
||||||
if (delim == '\n')
|
if (delim == '\n' && count > 0)
|
||||||
{
|
{
|
||||||
++lineNumber_;
|
++lineNumber_;
|
||||||
}
|
}
|
||||||
@ -90,11 +91,10 @@ inline Foam::ISstream& Foam::ISstream::getLine(std::string& str, char delim)
|
|||||||
inline std::streamsize Foam::ISstream::getLine(std::nullptr_t, char delim)
|
inline std::streamsize Foam::ISstream::getLine(std::nullptr_t, char delim)
|
||||||
{
|
{
|
||||||
is_.ignore(std::numeric_limits<std::streamsize>::max(), delim);
|
is_.ignore(std::numeric_limits<std::streamsize>::max(), delim);
|
||||||
|
std::streamsize count = is_.gcount();
|
||||||
syncState();
|
syncState();
|
||||||
|
|
||||||
std::streamsize count = is_.gcount();
|
if (delim == '\n' && count > 0)
|
||||||
|
|
||||||
if (delim == '\n' && count)
|
|
||||||
{
|
{
|
||||||
++lineNumber_;
|
++lineNumber_;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,7 +73,11 @@ static void broadcastFile_single
|
|||||||
if (UPstream::master(comm))
|
if (UPstream::master(comm))
|
||||||
{
|
{
|
||||||
// Read (see newIFstream)
|
// Read (see newIFstream)
|
||||||
lengthAndMode.first() = Foam::fileSize(srcName);
|
auto fileLen = Foam::fileSize(srcName);
|
||||||
|
if (fileLen > 0)
|
||||||
|
{
|
||||||
|
lengthAndMode.first() = uint64_t(fileLen);
|
||||||
|
}
|
||||||
lengthAndMode.second() = Foam::mode(srcName);
|
lengthAndMode.second() = Foam::mode(srcName);
|
||||||
|
|
||||||
srcStream.reset
|
srcStream.reset
|
||||||
|
|||||||
@ -83,6 +83,101 @@ namespace fileOperations
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Get file contents (compressed or uncompressed)
|
||||||
|
static DynamicList<char> slurpFile(IFstream& ifs)
|
||||||
|
{
|
||||||
|
DynamicList<char> buffer;
|
||||||
|
|
||||||
|
auto& iss = ifs.stdStream();
|
||||||
|
|
||||||
|
const auto inputSize = ifs.fileSize();
|
||||||
|
|
||||||
|
if (IOstreamOption::COMPRESSED == ifs.compression())
|
||||||
|
{
|
||||||
|
// For compressed files, no idea how large the result will be.
|
||||||
|
// So read chunk-wise.
|
||||||
|
// Using the compressed size for the chunk size:
|
||||||
|
// 50% compression = 2 iterations
|
||||||
|
// 66% compression = 3 iterations
|
||||||
|
// ...
|
||||||
|
|
||||||
|
const uint64_t chunkSize =
|
||||||
|
(
|
||||||
|
(inputSize <= 1024)
|
||||||
|
? uint64_t(4096)
|
||||||
|
: uint64_t(2*inputSize)
|
||||||
|
);
|
||||||
|
|
||||||
|
uint64_t beg = 0;
|
||||||
|
|
||||||
|
for (int iter = 1; iter < 100000; ++iter)
|
||||||
|
{
|
||||||
|
// Manual resizing to use incremental vs doubling
|
||||||
|
buffer.setCapacity(label(iter * chunkSize));
|
||||||
|
buffer.resize(buffer.capacity());
|
||||||
|
|
||||||
|
ifs.readRaw(buffer.data() + beg, chunkSize);
|
||||||
|
const std::streamsize nread = iss.gcount();
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
nread < 0
|
||||||
|
|| nread == std::numeric_limits<std::streamsize>::max()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Failed, but treat as normal 'done'
|
||||||
|
buffer.resize(label(beg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
beg += uint64_t(nread);
|
||||||
|
if (nread >= 0 && uint64_t(nread) < chunkSize)
|
||||||
|
{
|
||||||
|
// normalExit = true;
|
||||||
|
buffer.resize(label(beg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (inputSize >= 0)
|
||||||
|
{
|
||||||
|
buffer.setCapacity(label(inputSize));
|
||||||
|
buffer.resize(buffer.capacity());
|
||||||
|
|
||||||
|
ifs.readRaw(buffer.data(), buffer.size_bytes());
|
||||||
|
const std::streamsize nread = iss.gcount();
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
nread < 0
|
||||||
|
|| nread == std::numeric_limits<std::streamsize>::max()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Failed, but treat as normal 'done'
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer.resize(label(nread)); // Safety
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::word
|
Foam::word
|
||||||
@ -447,56 +542,25 @@ void Foam::fileOperations::masterUncollatedFileOperation::readAndSend
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "masterUncollatedFileOperation::readAndSend :"
|
Info<< "masterUncollatedFileOperation::readAndSend :"
|
||||||
<< " compressed:" << bool(ifs.compression()) << " "
|
<< " compressed:" << bool(ifs.compression()) << " "
|
||||||
<< filePath << endl;
|
<< filePath << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifs.compression() == IOstreamOption::COMPRESSED)
|
// Read file contents (compressed or uncompressed) into a character buffer
|
||||||
|
DynamicList<char> buf(slurpFile(ifs));
|
||||||
|
|
||||||
|
for (const label proci : recvProcs)
|
||||||
{
|
{
|
||||||
// Could use Foam::fileSize, estimate uncompressed size (eg, 2x)
|
UOPstream os(proci, pBufs);
|
||||||
// and then string reserve followed by string assign...
|
os.write(buf.cdata_bytes(), buf.size_bytes());
|
||||||
|
|
||||||
// Uncompress and read file contents into a character buffer
|
|
||||||
const std::string buf
|
|
||||||
(
|
|
||||||
std::istreambuf_iterator<char>(ifs.stdStream()),
|
|
||||||
std::istreambuf_iterator<char>()
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const label proci : recvProcs)
|
|
||||||
{
|
|
||||||
UOPstream os(proci, pBufs);
|
|
||||||
os.write(buf.data(), buf.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "masterUncollatedFileOperation::readStream :"
|
|
||||||
<< " From " << filePath << " sent " << buf.size()
|
|
||||||
<< " bytes" << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (debug)
|
||||||
{
|
{
|
||||||
const off_t count(Foam::fileSize(filePath));
|
Info<< "masterUncollatedFileOperation::readStream :"
|
||||||
|
<< " From " << filePath << " sent " << buf.size()
|
||||||
// Read file contents into a character buffer
|
<< " bytes" << endl;
|
||||||
List<char> buf(static_cast<label>(count));
|
|
||||||
ifs.stdStream().read(buf.data(), count);
|
|
||||||
|
|
||||||
for (const label proci : recvProcs)
|
|
||||||
{
|
|
||||||
UOPstream os(proci, pBufs);
|
|
||||||
os.write(buf.cdata(), count);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "masterUncollatedFileOperation::readStream :"
|
|
||||||
<< " From " << filePath << " sent " << buf.size()
|
|
||||||
<< " bytes" << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,12 +50,10 @@ Foam::ensightReadFile::detectBinaryHeader(const fileName& pathname)
|
|||||||
// Binary string is *exactly* 80 characters
|
// Binary string is *exactly* 80 characters
|
||||||
string buf(size_t(80), '\0');
|
string buf(size_t(80), '\0');
|
||||||
iss.read(&buf[0], 80);
|
iss.read(&buf[0], 80);
|
||||||
|
const std::streamsize gcount = iss.gcount();
|
||||||
|
buf.erase(gcount <= 0 ? 0 : gcount); // Truncated?
|
||||||
|
|
||||||
if (!iss)
|
// Could exit on truncated input, but no real advantage
|
||||||
{
|
|
||||||
// Truncated?
|
|
||||||
buf.erase(iss.gcount());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Truncate at the first embedded '\0'
|
// Truncate at the first embedded '\0'
|
||||||
const auto endp = buf.find('\0');
|
const auto endp = buf.find('\0');
|
||||||
@ -119,15 +117,13 @@ Foam::Istream& Foam::ensightReadFile::read(string& value)
|
|||||||
// Binary string is *exactly* 80 characters
|
// Binary string is *exactly* 80 characters
|
||||||
value.resize(80, '\0');
|
value.resize(80, '\0');
|
||||||
iss.read(&value[0], 80);
|
iss.read(&value[0], 80);
|
||||||
|
const std::streamsize gcount = iss.gcount();
|
||||||
|
value.erase(gcount <= 0 ? 0 : gcount); // Truncated?
|
||||||
|
|
||||||
|
// Could exit on truncated input, but no real advantage
|
||||||
|
|
||||||
syncState();
|
syncState();
|
||||||
|
|
||||||
if (!iss)
|
|
||||||
{
|
|
||||||
// Truncated - could also exit here, but no real advantage
|
|
||||||
value.erase(iss.gcount());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Truncate at the first embedded '\0'
|
// Truncate at the first embedded '\0'
|
||||||
auto endp = value.find('\0');
|
auto endp = value.find('\0');
|
||||||
|
|
||||||
|
|||||||
@ -112,8 +112,8 @@ public:
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- From input stream and the approximate number of vertices in the STL
|
//- Construct with the estimated number of triangles in the STL
|
||||||
inline STLAsciiParse(const label approxNpoints);
|
inline STLAsciiParse(const label nTrisEstimated);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2018 OpenCFD Ltd.
|
Copyright (C) 2016-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -89,10 +89,10 @@ public:
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- From input stream and the approximate number of vertices in the STL
|
//- From input stream, with the estimated number of triangles in the STL
|
||||||
STLAsciiParseFlex(istream* is, const label approxNpoints)
|
STLAsciiParseFlex(istream* is, const label nTrisEstimated)
|
||||||
:
|
:
|
||||||
Detail::STLAsciiParse(approxNpoints),
|
Detail::STLAsciiParse(nTrisEstimated),
|
||||||
yySTLFlexLexer(is)
|
yySTLFlexLexer(is)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -306,9 +306,8 @@ endsolid {space}("endsolid"|"ENDSOLID")({some_space}{word})*
|
|||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
||||||
//
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
// Member Function
|
|
||||||
//
|
|
||||||
bool Foam::fileFormats::STLReader::readAsciiFlex
|
bool Foam::fileFormats::STLReader::readAsciiFlex
|
||||||
(
|
(
|
||||||
const fileName& filename
|
const fileName& filename
|
||||||
@ -322,8 +321,20 @@ bool Foam::fileFormats::STLReader::readAsciiFlex
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create with approx number of vertices in the STL (from file size)
|
// Create with estimated number of triangles in the STL.
|
||||||
STLAsciiParseFlex lexer(&(is.stdStream()), Foam::fileSize(filename)/400);
|
// 180 bytes / triangle. For simplicity, ignore compression
|
||||||
|
|
||||||
|
const auto fileLen = is.fileSize();
|
||||||
|
|
||||||
|
const label nTrisEstimated =
|
||||||
|
(
|
||||||
|
(fileLen > 0)
|
||||||
|
? max(label(100), label(fileLen/180))
|
||||||
|
: label(100)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
STLAsciiParseFlex lexer(&(is.stdStream()), nTrisEstimated);
|
||||||
lexer.execute();
|
lexer.execute();
|
||||||
|
|
||||||
transfer(lexer);
|
transfer(lexer);
|
||||||
@ -331,6 +342,5 @@ bool Foam::fileFormats::STLReader::readAsciiFlex
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ *\
|
|
||||||
------ End of STLReaderASCII.L
|
// ************************************************************************* //
|
||||||
\* ------------------------------------------------------------------------ */
|
|
||||||
|
|||||||
@ -131,15 +131,15 @@ inline void Foam::Detail::STLAsciiParse::endFacet()
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
inline Foam::Detail::STLAsciiParse::STLAsciiParse(const label approxNpoints)
|
inline Foam::Detail::STLAsciiParse::STLAsciiParse(const label nTrisEstimated)
|
||||||
:
|
:
|
||||||
sorted_(true),
|
sorted_(true),
|
||||||
groupId_(-1),
|
groupId_(-1),
|
||||||
lineNum_(1),
|
lineNum_(1),
|
||||||
nFacetPoints_(0),
|
nFacetPoints_(0),
|
||||||
nVertexCmpt_(0),
|
nVertexCmpt_(0),
|
||||||
points_(approxNpoints),
|
points_(3*nTrisEstimated),
|
||||||
facets_(approxNpoints/2)
|
facets_(nTrisEstimated)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2018 OpenCFD Ltd.
|
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -30,7 +30,6 @@ Description
|
|||||||
|
|
||||||
#include "STLAsciiParse.H"
|
#include "STLAsciiParse.H"
|
||||||
#include "STLReader.H"
|
#include "STLReader.H"
|
||||||
#include "OSspecific.H"
|
|
||||||
#include "stringOps.H"
|
#include "stringOps.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
@ -127,10 +126,10 @@ class STLAsciiParseManual
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- From input stream and the approximate number of vertices in the STL
|
//- Construct with the estimated number of triangles in the STL
|
||||||
STLAsciiParseManual(const label approxNpoints)
|
STLAsciiParseManual(const label nTrisEstimated)
|
||||||
:
|
:
|
||||||
Detail::STLAsciiParse(approxNpoints)
|
Detail::STLAsciiParse(nTrisEstimated)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Execute parser
|
//- Execute parser
|
||||||
@ -179,7 +178,7 @@ void Foam::Detail::STLAsciiParseManual::execute(std::istream& is)
|
|||||||
is.read(data, buflen);
|
is.read(data, buflen);
|
||||||
const std::streamsize gcount = is.gcount();
|
const std::streamsize gcount = is.gcount();
|
||||||
|
|
||||||
if (!gcount)
|
if (gcount <= 0)
|
||||||
{
|
{
|
||||||
// EOF
|
// EOF
|
||||||
// If scanning for next "solid" this is a valid way to exit, but
|
// If scanning for next "solid" this is a valid way to exit, but
|
||||||
@ -398,11 +397,8 @@ void Foam::Detail::STLAsciiParseManual::execute(std::istream& is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
//
|
|
||||||
// Member Function
|
|
||||||
//
|
|
||||||
bool Foam::fileFormats::STLReader::readAsciiManual
|
bool Foam::fileFormats::STLReader::readAsciiManual
|
||||||
(
|
(
|
||||||
const fileName& filename
|
const fileName& filename
|
||||||
@ -416,8 +412,20 @@ bool Foam::fileFormats::STLReader::readAsciiManual
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create with the approximate number of vertices in the STL from file size
|
// Create with estimated number of triangles in the STL.
|
||||||
Detail::STLAsciiParseManual lexer(Foam::fileSize(filename)/400);
|
// 180 bytes / triangle. For simplicity, ignore compression
|
||||||
|
|
||||||
|
const auto fileLen = is.fileSize();
|
||||||
|
|
||||||
|
const label nTrisEstimated =
|
||||||
|
(
|
||||||
|
(fileLen > 0)
|
||||||
|
? max(label(100), label(fileLen/180))
|
||||||
|
: label(100)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Detail::STLAsciiParseManual lexer(nTrisEstimated);
|
||||||
lexer.execute(is.stdStream());
|
lexer.execute(is.stdStream());
|
||||||
|
|
||||||
transfer(lexer);
|
transfer(lexer);
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2018 OpenCFD Ltd.
|
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -35,7 +35,6 @@ Description
|
|||||||
|
|
||||||
#include "STLAsciiParse.H"
|
#include "STLAsciiParse.H"
|
||||||
#include "STLReader.H"
|
#include "STLReader.H"
|
||||||
#include "OSspecific.H"
|
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||||
#pragma GCC diagnostic ignored "-Wunused-const-variable"
|
#pragma GCC diagnostic ignored "-Wunused-const-variable"
|
||||||
@ -69,6 +68,7 @@ Description
|
|||||||
// - Only look for initial 'facet '. Ignore 'normal ...'
|
// - Only look for initial 'facet '. Ignore 'normal ...'
|
||||||
// - Ignore name for 'endsolid'
|
// - Ignore name for 'endsolid'
|
||||||
//
|
//
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
// Ragel machine definition
|
// Ragel machine definition
|
||||||
// Ragel variables (p, pe, eof, cs, top, stack, ts, te, act) defined later...
|
// Ragel variables (p, pe, eof, cs, top, stack, ts, te, act) defined later...
|
||||||
@ -121,10 +121,10 @@ class STLAsciiParseRagel
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- From input stream and the approximate number of vertices in the STL
|
//- From input stream, with the estimated number of triangles in the STL
|
||||||
STLAsciiParseRagel(const label approxNpoints)
|
STLAsciiParseRagel(const label nTrisEstimated)
|
||||||
:
|
:
|
||||||
Detail::STLAsciiParse(approxNpoints)
|
Detail::STLAsciiParse(nTrisEstimated)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Execute lexer
|
//- Execute lexer
|
||||||
@ -184,7 +184,7 @@ void Foam::Detail::STLAsciiParseRagel::execute(std::istream& is)
|
|||||||
|
|
||||||
is.read(data, buflen);
|
is.read(data, buflen);
|
||||||
const std::streamsize gcount = is.gcount();
|
const std::streamsize gcount = is.gcount();
|
||||||
if (!gcount)
|
if (gcount <= 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2970,9 +2970,7 @@ void Foam::Detail::STLAsciiParseRagel::die
|
|||||||
const char *pe
|
const char *pe
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
auto error = FatalErrorInFunction;
|
FatalErrorInFunction
|
||||||
|
|
||||||
error
|
|
||||||
<< nl
|
<< nl
|
||||||
<< "Parsing error at or near line " << lineNum_
|
<< "Parsing error at or near line " << lineNum_
|
||||||
<<", while parsing for " << what << nl
|
<<", while parsing for " << what << nl
|
||||||
@ -2984,22 +2982,19 @@ void Foam::Detail::STLAsciiParseRagel::die
|
|||||||
for (unsigned i=0; i < 80; ++i)
|
for (unsigned i=0; i < 80; ++i)
|
||||||
{
|
{
|
||||||
if (*parsing == '\n' || parsing == pe) break;
|
if (*parsing == '\n' || parsing == pe) break;
|
||||||
error << *parsing;
|
FatalError << *parsing;
|
||||||
++parsing;
|
++parsing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error
|
FatalError
|
||||||
<< "'\n"
|
<< "'\n"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
//
|
|
||||||
// Member Function
|
|
||||||
//
|
|
||||||
bool Foam::fileFormats::STLReader::readAsciiRagel
|
bool Foam::fileFormats::STLReader::readAsciiRagel
|
||||||
(
|
(
|
||||||
const fileName& filename
|
const fileName& filename
|
||||||
@ -3013,8 +3008,20 @@ bool Foam::fileFormats::STLReader::readAsciiRagel
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create with approx number of vertices in the STL (from file size)
|
// Create with estimated number of triangles in the STL.
|
||||||
Detail::STLAsciiParseRagel lexer(Foam::fileSize(filename)/400);
|
// 180 bytes / triangle. For simplicity, ignore compression
|
||||||
|
|
||||||
|
const auto fileLen = is.fileSize();
|
||||||
|
|
||||||
|
const label nTrisEstimated =
|
||||||
|
(
|
||||||
|
(fileLen > 0)
|
||||||
|
? max(label(100), label(fileLen/180))
|
||||||
|
: label(100)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Detail::STLAsciiParseRagel lexer(nTrisEstimated);
|
||||||
lexer.execute(is.stdStream());
|
lexer.execute(is.stdStream());
|
||||||
|
|
||||||
transfer(lexer);
|
transfer(lexer);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2018 OpenCFD Ltd.
|
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -33,7 +33,6 @@ Description
|
|||||||
|
|
||||||
#include "STLAsciiParse.H"
|
#include "STLAsciiParse.H"
|
||||||
#include "STLReader.H"
|
#include "STLReader.H"
|
||||||
#include "OSspecific.H"
|
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||||
#pragma GCC diagnostic ignored "-Wunused-const-variable"
|
#pragma GCC diagnostic ignored "-Wunused-const-variable"
|
||||||
@ -67,6 +66,7 @@ Description
|
|||||||
// - Only look for initial 'facet '. Ignore 'normal ...'
|
// - Only look for initial 'facet '. Ignore 'normal ...'
|
||||||
// - Ignore name for 'endsolid'
|
// - Ignore name for 'endsolid'
|
||||||
//
|
//
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
// Ragel machine definition
|
// Ragel machine definition
|
||||||
// Ragel variables (p, pe, eof, cs, top, stack, ts, te, act) defined later...
|
// Ragel variables (p, pe, eof, cs, top, stack, ts, te, act) defined later...
|
||||||
@ -176,10 +176,10 @@ class STLAsciiParseRagel
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- From input stream and the approximate number of vertices in the STL
|
//- From input stream, with the estimated number of triangles in the STL
|
||||||
STLAsciiParseRagel(const label approxNpoints)
|
STLAsciiParseRagel(const label nTrisEstimated)
|
||||||
:
|
:
|
||||||
Detail::STLAsciiParse(approxNpoints)
|
Detail::STLAsciiParse(nTrisEstimated)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Execute lexer
|
//- Execute lexer
|
||||||
@ -232,7 +232,7 @@ void Foam::Detail::STLAsciiParseRagel::execute(std::istream& is)
|
|||||||
|
|
||||||
is.read(data, buflen);
|
is.read(data, buflen);
|
||||||
const std::streamsize gcount = is.gcount();
|
const std::streamsize gcount = is.gcount();
|
||||||
if (!gcount)
|
if (gcount <= 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -303,9 +303,7 @@ void Foam::Detail::STLAsciiParseRagel::die
|
|||||||
const char *pe
|
const char *pe
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
auto error = FatalErrorInFunction;
|
FatalErrorInFunction
|
||||||
|
|
||||||
error
|
|
||||||
<< nl
|
<< nl
|
||||||
<< "Parsing error at or near line " << lineNum_
|
<< "Parsing error at or near line " << lineNum_
|
||||||
<<", while parsing for " << what << nl
|
<<", while parsing for " << what << nl
|
||||||
@ -317,22 +315,19 @@ void Foam::Detail::STLAsciiParseRagel::die
|
|||||||
for (unsigned i=0; i < 80; ++i)
|
for (unsigned i=0; i < 80; ++i)
|
||||||
{
|
{
|
||||||
if (*parsing == '\n' || parsing == pe) break;
|
if (*parsing == '\n' || parsing == pe) break;
|
||||||
error << *parsing;
|
FatalError << *parsing;
|
||||||
++parsing;
|
++parsing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error
|
FatalError
|
||||||
<< "'\n"
|
<< "'\n"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
//
|
|
||||||
// Member Function
|
|
||||||
//
|
|
||||||
bool Foam::fileFormats::STLReader::readAsciiRagel
|
bool Foam::fileFormats::STLReader::readAsciiRagel
|
||||||
(
|
(
|
||||||
const fileName& filename
|
const fileName& filename
|
||||||
@ -346,8 +341,20 @@ bool Foam::fileFormats::STLReader::readAsciiRagel
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create with approx number of vertices in the STL (from file size)
|
// Create with estimated number of triangles in the STL.
|
||||||
Detail::STLAsciiParseRagel lexer(Foam::fileSize(filename)/400);
|
// 180 bytes / triangle. For simplicity, ignore compression
|
||||||
|
|
||||||
|
const auto fileLen = is.fileSize();
|
||||||
|
|
||||||
|
const label nTrisEstimated =
|
||||||
|
(
|
||||||
|
(fileLen > 0)
|
||||||
|
? max(label(100), label(fileLen/180))
|
||||||
|
: label(100)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Detail::STLAsciiParseRagel lexer(nTrisEstimated);
|
||||||
lexer.execute(is.stdStream());
|
lexer.execute(is.stdStream());
|
||||||
|
|
||||||
transfer(lexer);
|
transfer(lexer);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2018-2022 OpenCFD Ltd.
|
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -645,7 +645,8 @@ Foam::label Foam::vtk::seriesWriter::scan
|
|||||||
|
|
||||||
header.resize(1024);
|
header.resize(1024);
|
||||||
is.read(&(header.front()), header.size());
|
is.read(&(header.front()), header.size());
|
||||||
header.resize(is.gcount());
|
const std::streamsize gcount = is.gcount();
|
||||||
|
header.erase(gcount <= 0 ? 0 : gcount);
|
||||||
|
|
||||||
// DebugInfo
|
// DebugInfo
|
||||||
// << "got header:\n=====\n" << header << "\n=====\n" << nl;
|
// << "got header:\n=====\n" << header << "\n=====\n" << nl;
|
||||||
|
|||||||
Reference in New Issue
Block a user