ENH: allow null pointer when reading binary block

- have read(nullptr, count) and readRaw(nullptr, count) act like a
  forward seek instead of failing.
  This lets it be used to advance through a file without needing to
  allocate (and discard) storage space etc.
This commit is contained in:
Mark Olesen
2023-04-21 10:35:26 +02:00
parent ce282dfbbf
commit d9533e561b
5 changed files with 57 additions and 19 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2022 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -161,8 +161,10 @@ public:
//- Read a double //- Read a double
virtual Istream& read(double&) = 0; virtual Istream& read(double&) = 0;
//- Read binary block //- Read binary block (with any possible block delimiters).
virtual Istream& read(char*, std::streamsize) = 0; //- Reading into a null pointer shall ideally behave like a seek
//- operation.
virtual Istream& read(char* data, std::streamsize count) = 0;
//- Start of low-level raw binary read //- Start of low-level raw binary read
virtual bool beginRawRead() = 0; virtual bool beginRawRead() = 0;
@ -170,8 +172,10 @@ public:
//- End of low-level raw binary read //- End of low-level raw binary read
virtual bool endRawRead() = 0; virtual bool endRawRead() = 0;
//- Low-level raw binary read //- Low-level raw binary read (without possible block delimiters).
virtual Istream& readRaw(char*, std::streamsize) = 0; //- Reading into a null pointer shall ideally behave like a seek
//- operation.
virtual Istream& readRaw(char* data, std::streamsize count) = 0;
//- Rewind the stream so that it may be read again //- Rewind the stream so that it may be read again
virtual void rewind() = 0; virtual void rewind() = 0;

View File

@ -75,6 +75,7 @@ class UIPstreamBase
//- Read count bytes of data from the receive buffer. //- Read count bytes of data from the receive buffer.
// Prior data alignment is done by prepareBuffer // Prior data alignment is done by prepareBuffer
// Reading into a null pointer behaves like a forward seek
inline void readFromBuffer(void* data, const size_t count); inline void readFromBuffer(void* data, const size_t count);
//- Read string length and string content //- Read string length and string content
@ -181,9 +182,13 @@ public:
Istream& read(double& val); Istream& read(double& val);
//- Read binary block with 8-byte alignment. //- Read binary block with 8-byte alignment.
//- Reading into a null pointer behaves like a forward seek of
//- count characters.
Istream& read(char* data, std::streamsize count); Istream& read(char* data, std::streamsize count);
//- Low-level raw binary read //- Low-level raw binary read.
//- Reading into a null pointer behaves like a forward seek of
//- count characters.
Istream& readRaw(char* data, std::streamsize count); Istream& readRaw(char* data, std::streamsize count);
//- Start of low-level raw binary read //- Start of low-level raw binary read

View File

@ -105,6 +105,8 @@ inline void Foam::UIPstreamBase::readFromBuffer
void* data, void* data,
const size_t count const size_t count
) )
{
if (data)
{ {
const char* const __restrict__ buf = &recvBuf_[recvBufPos_]; const char* const __restrict__ buf = &recvBuf_[recvBufPos_];
char* const __restrict__ output = reinterpret_cast<char*>(data); char* const __restrict__ output = reinterpret_cast<char*>(data);
@ -113,6 +115,7 @@ inline void Foam::UIPstreamBase::readFromBuffer
{ {
output[i] = buf[i]; output[i] = buf[i];
} }
}
recvBufPos_ += count; recvBufPos_ += count;
checkEof(); checkEof();

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2022 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -1018,19 +1018,41 @@ Foam::Istream& Foam::ISstream::read(double& val)
} }
Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count) Foam::Istream& Foam::ISstream::read(char* data, std::streamsize count)
{ {
beginRawRead(); beginRawRead();
readRaw(buf, count); readRaw(data, count);
endRawRead(); endRawRead();
return *this; return *this;
} }
Foam::Istream& Foam::ISstream::readRaw(char* buf, std::streamsize count) Foam::Istream& Foam::ISstream::readRaw(char* data, std::streamsize count)
{ {
is_.read(buf, count); if (count)
{
if (data)
{
is_.read(data, count);
}
else
{
// Forward seek
is_.seekg(is_.tellg() + 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();
return *this; return *this;
} }

View File

@ -222,10 +222,14 @@ public:
//- Read a double //- Read a double
virtual Istream& read(double& val); virtual Istream& read(double& val);
//- Read binary block //- Read binary block (with any possible block delimiters).
virtual Istream& read(char* buf, std::streamsize count); //- Reading into a null pointer behaves like a forward seek of
//- count characters.
virtual Istream& read(char* data, std::streamsize count);
//- Low-level raw binary read //- Low-level raw binary read (without possible block delimiters).
//- Reading into a null pointer behaves like a forward seek of
//- count characters.
virtual Istream& readRaw(char* data, std::streamsize count); virtual Istream& readRaw(char* data, std::streamsize count);
//- Start of low-level raw binary read //- Start of low-level raw binary read