Skip to content
Snippets Groups Projects
Commit c847d343 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

BUG: OPstream send of tokenType may swallow characters (fixes #563)

- the tokenType was being send via write(char), which includes
  isspace filtering. If the tokenType enumeration coincides
  with a whitespace character, it would be suppressed.

  Now add character directly to the buffer.

STYLE: some additional minor private methods to help refactoring

- readStringFromBuffer, writeStringToBuffer for common string
  operation.
parent a09125c3
No related branches found
No related tags found
No related merge requests found
...@@ -56,8 +56,8 @@ inline void Foam::UIPstream::readFromBuffer(T& t) ...@@ -56,8 +56,8 @@ inline void Foam::UIPstream::readFromBuffer(T& t)
inline void Foam::UIPstream::readFromBuffer inline void Foam::UIPstream::readFromBuffer
( (
void* data, void* data,
size_t count, const size_t count,
size_t align const size_t align
) )
{ {
if (align > 1) if (align > 1)
...@@ -76,6 +76,22 @@ inline void Foam::UIPstream::readFromBuffer ...@@ -76,6 +76,22 @@ inline void Foam::UIPstream::readFromBuffer
} }
inline Foam::Istream& Foam::UIPstream::readStringFromBuffer(std::string& str)
{
size_t len;
readFromBuffer(len);
// Uses the underlying std::string::operator=()
// - no stripInvalid invoked (the sending side should have done that)
// - relies on trailing '\0' char (so cannot send anything with an embedded
// nul char)
str = &externalBuf_[externalBufPosition_];
externalBufPosition_ += len + 1;
checkEof();
return *this;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::UIPstream::~UIPstream() Foam::UIPstream::~UIPstream()
...@@ -107,7 +123,7 @@ Foam::Istream& Foam::UIPstream::read(token& t) ...@@ -107,7 +123,7 @@ Foam::Istream& Foam::UIPstream::read(token& t)
char c; char c;
// return on error // Return on error
if (!read(c)) if (!read(c))
{ {
t.setBad(); t.setBad();
...@@ -141,7 +157,7 @@ Foam::Istream& Foam::UIPstream::read(token& t) ...@@ -141,7 +157,7 @@ Foam::Istream& Foam::UIPstream::read(token& t)
} }
// Word // Word
case token::WORD : case token::tokenType::WORD :
{ {
word* pval = new word; word* pval = new word;
if (read(*pval)) if (read(*pval))
...@@ -165,30 +181,26 @@ Foam::Istream& Foam::UIPstream::read(token& t) ...@@ -165,30 +181,26 @@ Foam::Istream& Foam::UIPstream::read(token& t)
} }
// String // String
case token::VERBATIMSTRING : case token::tokenType::VERBATIMSTRING :
{ {
// Recurse to read actual string // Recurse to read actual string
read(t); read(t);
t.type() = token::VERBATIMSTRING; t.type() = token::tokenType::VERBATIMSTRING;
return *this; return *this;
} }
case token::VARIABLE : case token::tokenType::VARIABLE :
{ {
// Recurse to read actual string // Recurse to read actual string
read(t); read(t);
t.type() = token::VARIABLE; t.type() = token::tokenType::VARIABLE;
return *this; return *this;
} }
case token::STRING : case token::tokenType::STRING :
{ {
string* pval = new string; string* pval = new string;
if (read(*pval)) if (read(*pval))
{ {
t = pval; t = pval;
if (c == token::VERBATIMSTRING)
{
t.type() = token::VERBATIMSTRING;
}
} }
else else
{ {
...@@ -199,7 +211,7 @@ Foam::Istream& Foam::UIPstream::read(token& t) ...@@ -199,7 +211,7 @@ Foam::Istream& Foam::UIPstream::read(token& t)
} }
// Label // Label
case token::LABEL : case token::tokenType::LABEL :
{ {
label val; label val;
if (read(val)) if (read(val))
...@@ -214,7 +226,7 @@ Foam::Istream& Foam::UIPstream::read(token& t) ...@@ -214,7 +226,7 @@ Foam::Istream& Foam::UIPstream::read(token& t)
} }
// floatScalar // floatScalar
case token::FLOAT_SCALAR : case token::tokenType::FLOAT_SCALAR :
{ {
floatScalar val; floatScalar val;
if (read(val)) if (read(val))
...@@ -229,7 +241,7 @@ Foam::Istream& Foam::UIPstream::read(token& t) ...@@ -229,7 +241,7 @@ Foam::Istream& Foam::UIPstream::read(token& t)
} }
// doubleScalar // doubleScalar
case token::DOUBLE_SCALAR : case token::tokenType::DOUBLE_SCALAR :
{ {
doubleScalar val; doubleScalar val;
if (read(val)) if (read(val))
...@@ -272,23 +284,13 @@ Foam::Istream& Foam::UIPstream::read(char& c) ...@@ -272,23 +284,13 @@ Foam::Istream& Foam::UIPstream::read(char& c)
Foam::Istream& Foam::UIPstream::read(word& str) Foam::Istream& Foam::UIPstream::read(word& str)
{ {
size_t len; return readStringFromBuffer(str);
readFromBuffer(len);
str = &externalBuf_[externalBufPosition_];
externalBufPosition_ += len + 1;
checkEof();
return *this;
} }
Foam::Istream& Foam::UIPstream::read(string& str) Foam::Istream& Foam::UIPstream::read(string& str)
{ {
size_t len; return readStringFromBuffer(str);
readFromBuffer(len);
str = &externalBuf_[externalBufPosition_];
externalBufPosition_ += len + 1;
checkEof();
return *this;
} }
......
...@@ -80,10 +80,19 @@ class UIPstream ...@@ -80,10 +80,19 @@ class UIPstream
//- Read a T from the transfer buffer //- Read a T from the transfer buffer
template<class T> template<class T>
inline void readFromBuffer(T&); inline void readFromBuffer(T& t);
//- Read data from the transfer buffer //- Read count bytes of data from the transfer buffer
inline void readFromBuffer(void* data, size_t count, size_t align); // using align byte alignment
inline void readFromBuffer
(
void* data,
const size_t count,
const size_t align
);
//- Read string length and its content.
inline Istream& readStringFromBuffer(std::string& str);
public: public:
...@@ -139,28 +148,28 @@ public: ...@@ -139,28 +148,28 @@ public:
); );
//- Return next token from stream //- Return next token from stream
Istream& read(token&); Istream& read(token& t);
//- Read a character //- Read a character
Istream& read(char&); Istream& read(char& c);
//- Read a word //- Read a word
Istream& read(word&); Istream& read(word& str);
// Read a string (including enclosing double-quotes) // Read a string
Istream& read(string&); Istream& read(string& str);
//- Read a label //- Read a label
Istream& read(label&); Istream& read(label& val);
//- Read a floatScalar //- Read a floatScalar
Istream& read(floatScalar&); Istream& read(floatScalar& val);
//- Read a doubleScalar //- Read a doubleScalar
Istream& read(doubleScalar&); Istream& read(doubleScalar& val);
//- Read binary block //- Read binary block with 8-byte alignment.
Istream& read(char*, std::streamsize); Istream& read(char* data, const std::streamsize count);
//- Rewind and return the stream so that it may be read again //- Rewind and return the stream so that it may be read again
Istream& rewind(); Istream& rewind();
......
...@@ -51,8 +51,8 @@ inline void Foam::UOPstream::writeToBuffer(const char& c) ...@@ -51,8 +51,8 @@ inline void Foam::UOPstream::writeToBuffer(const char& c)
inline void Foam::UOPstream::writeToBuffer inline void Foam::UOPstream::writeToBuffer
( (
const void* data, const void* data,
size_t count, const size_t count,
size_t align const size_t align
) )
{ {
if (!sendBuf_.capacity()) if (!sendBuf_.capacity())
...@@ -77,6 +77,13 @@ inline void Foam::UOPstream::writeToBuffer ...@@ -77,6 +77,13 @@ inline void Foam::UOPstream::writeToBuffer
} }
inline void Foam::UOPstream::writeStringToBuffer(const std::string& str)
{
const size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
}
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
...@@ -153,14 +160,14 @@ Foam::UOPstream::~UOPstream() ...@@ -153,14 +160,14 @@ Foam::UOPstream::~UOPstream()
Foam::Ostream& Foam::UOPstream::write(const token& t) Foam::Ostream& Foam::UOPstream::write(const token& t)
{ {
// Raw token output only supported for verbatim strings for now // Raw token output only supported for verbatim strings for now
if (t.type() == token::VERBATIMSTRING) if (t.type() == token::tokenType::VERBATIMSTRING)
{ {
write(char(token::VERBATIMSTRING)); writeToBuffer(char(token::tokenType::VERBATIMSTRING));
write(t.stringToken()); write(t.stringToken());
} }
else if (t.type() == token::VARIABLE) else if (t.type() == token::tokenType::VARIABLE)
{ {
write(char(token::VARIABLE)); writeToBuffer(char(token::tokenType::VARIABLE));
write(t.stringToken()); write(t.stringToken());
} }
else else
...@@ -204,11 +211,8 @@ Foam::Ostream& Foam::UOPstream::write(const char* str) ...@@ -204,11 +211,8 @@ Foam::Ostream& Foam::UOPstream::write(const char* str)
Foam::Ostream& Foam::UOPstream::write(const word& str) Foam::Ostream& Foam::UOPstream::write(const word& str)
{ {
write(char(token::WORD)); writeToBuffer(char(token::tokenType::WORD));
writeStringToBuffer(str);
size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
return *this; return *this;
} }
...@@ -216,11 +220,8 @@ Foam::Ostream& Foam::UOPstream::write(const word& str) ...@@ -216,11 +220,8 @@ Foam::Ostream& Foam::UOPstream::write(const word& str)
Foam::Ostream& Foam::UOPstream::write(const string& str) Foam::Ostream& Foam::UOPstream::write(const string& str)
{ {
write(char(token::STRING)); writeToBuffer(char(token::tokenType::STRING));
writeStringToBuffer(str);
size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
return *this; return *this;
} }
...@@ -234,16 +235,13 @@ Foam::Ostream& Foam::UOPstream::writeQuoted ...@@ -234,16 +235,13 @@ Foam::Ostream& Foam::UOPstream::writeQuoted
{ {
if (quoted) if (quoted)
{ {
write(char(token::STRING)); writeToBuffer(char(token::tokenType::STRING));
} }
else else
{ {
write(char(token::WORD)); writeToBuffer(char(token::tokenType::WORD));
} }
writeStringToBuffer(str);
size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
return *this; return *this;
} }
...@@ -251,7 +249,7 @@ Foam::Ostream& Foam::UOPstream::writeQuoted ...@@ -251,7 +249,7 @@ Foam::Ostream& Foam::UOPstream::writeQuoted
Foam::Ostream& Foam::UOPstream::write(const int32_t val) Foam::Ostream& Foam::UOPstream::write(const int32_t val)
{ {
write(char(token::LABEL)); writeToBuffer(char(token::tokenType::LABEL));
writeToBuffer(val); writeToBuffer(val);
return *this; return *this;
} }
...@@ -259,7 +257,7 @@ Foam::Ostream& Foam::UOPstream::write(const int32_t val) ...@@ -259,7 +257,7 @@ Foam::Ostream& Foam::UOPstream::write(const int32_t val)
Foam::Ostream& Foam::UOPstream::write(const int64_t val) Foam::Ostream& Foam::UOPstream::write(const int64_t val)
{ {
write(char(token::LABEL)); writeToBuffer(char(token::tokenType::LABEL));
writeToBuffer(val); writeToBuffer(val);
return *this; return *this;
} }
...@@ -267,7 +265,7 @@ Foam::Ostream& Foam::UOPstream::write(const int64_t val) ...@@ -267,7 +265,7 @@ Foam::Ostream& Foam::UOPstream::write(const int64_t val)
Foam::Ostream& Foam::UOPstream::write(const floatScalar val) Foam::Ostream& Foam::UOPstream::write(const floatScalar val)
{ {
write(char(token::FLOAT_SCALAR)); writeToBuffer(char(token::tokenType::FLOAT_SCALAR));
writeToBuffer(val); writeToBuffer(val);
return *this; return *this;
} }
...@@ -275,13 +273,17 @@ Foam::Ostream& Foam::UOPstream::write(const floatScalar val) ...@@ -275,13 +273,17 @@ Foam::Ostream& Foam::UOPstream::write(const floatScalar val)
Foam::Ostream& Foam::UOPstream::write(const doubleScalar val) Foam::Ostream& Foam::UOPstream::write(const doubleScalar val)
{ {
write(char(token::DOUBLE_SCALAR)); writeToBuffer(char(token::tokenType::DOUBLE_SCALAR));
writeToBuffer(val); writeToBuffer(val);
return *this; return *this;
} }
Foam::Ostream& Foam::UOPstream::write(const char* data, std::streamsize count) Foam::Ostream& Foam::UOPstream::write
(
const char* data,
const std::streamsize count
)
{ {
if (format() != BINARY) if (format() != BINARY)
{ {
......
...@@ -74,13 +74,23 @@ class UOPstream ...@@ -74,13 +74,23 @@ class UOPstream
//- Write a T to the transfer buffer //- Write a T to the transfer buffer
template<class T> template<class T>
inline void writeToBuffer(const T&); inline void writeToBuffer(const T& t);
//- Write a char to the transfer buffer //- Write a char to the transfer buffer
inline void writeToBuffer(const char&); inline void writeToBuffer(const char& c);
//- Write data to the transfer buffer //- Write count bytes of data to the transfer buffer
inline void writeToBuffer(const void* data, size_t count, size_t align); // using align byte alignment
inline void writeToBuffer
(
const void* data,
const size_t count,
const size_t align
);
//- Write string length and content.
// The content includes the trailing nul char.
inline void writeStringToBuffer(const std::string& str);
public: public:
...@@ -102,7 +112,7 @@ public: ...@@ -102,7 +112,7 @@ public:
); );
//- Construct given buffers //- Construct given buffers
UOPstream(const int toProcNo, PstreamBuffers&); UOPstream(const int toProcNo, PstreamBuffers& buffers);
//- Destructor //- Destructor
...@@ -134,42 +144,43 @@ public: ...@@ -134,42 +144,43 @@ public:
); );
//- Write next token to stream //- Write next token to stream
Ostream& write(const token&); Ostream& write(const token& t);
//- Write character //- Write single character. Whitespace is suppressed.
Ostream& write(const char); Ostream& write(const char c);
//- Write character string //- Write the word-characters of a character string.
Ostream& write(const char*); // Sends as a single char, or as word.
Ostream& write(const char* str);
//- Write word //- Write word
Ostream& write(const word&); Ostream& write(const word& str);
//- Write string //- Write string
Ostream& write(const string&); Ostream& write(const string& str);
//- Write std::string surrounded by quotes. //- Write std::string surrounded by quotes.
// Optional write without quotes. // Optional write without quotes.
Ostream& writeQuoted Ostream& writeQuoted
( (
const std::string&, const std::string& str,
const bool quoted=true const bool quoted=true
); );
//- Write int32_t //- Write int32_t as a label
virtual Ostream& write(const int32_t); virtual Ostream& write(const int32_t val);
//- Write int64_t //- Write int64_t as a label
Ostream& write(const int64_t); Ostream& write(const int64_t val);
//- Write floatScalar //- Write floatScalar
Ostream& write(const floatScalar); Ostream& write(const floatScalar val);
//- Write doubleScalar //- Write doubleScalar
Ostream& write(const doubleScalar); Ostream& write(const doubleScalar val);
//- Write binary block //- Write binary block with 8-byte alignment.
Ostream& write(const char*, std::streamsize); Ostream& write(const char* data, const std::streamsize count);
//- Add indentation characters //- Add indentation characters
void indent() void indent()
...@@ -223,7 +234,7 @@ public: ...@@ -223,7 +234,7 @@ public:
// Print // Print
//- Print description of IOstream to Ostream //- Print description of IOstream to Ostream
void print(Ostream&) const; void print(Ostream& os) const;
}; };
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright 2015-2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment