diff --git a/applications/test/parallel/Test-parallel.C b/applications/test/parallel/Test-parallel.C index 14ba97f7a5..ec5546c675 100644 --- a/applications/test/parallel/Test-parallel.C +++ b/applications/test/parallel/Test-parallel.C @@ -120,6 +120,24 @@ void testMapDistribute() } +// Print to Perr +template +Ostream& perrInfo(const T& data) +{ + Perr<< data; + return Perr; +} + + +// Print to Perr +template<> +Ostream& perrInfo(const string& data) +{ + Perr<< data << " (size: " << data.size() << ")"; + return Perr; +} + + template void testTransfer(const T& input) { @@ -127,7 +145,8 @@ void testTransfer(const T& input) if (Pstream::master()) { - Perr<<"test transfer (" << (typeid(T).name()) << "): " << data << nl << endl; + Perr<<"test transfer (" << (typeid(T).name()) << "): "; + perrInfo(data) << nl << endl; } if (Pstream::myProcNo() != Pstream::masterNo()) @@ -141,7 +160,7 @@ void testTransfer(const T& input) Perr<< "slave receiving from master " << Pstream::masterNo() << endl; IPstream fromMaster(Pstream::commsTypes::blocking, Pstream::masterNo()); fromMaster >> data; - Perr<< data << endl; + perrInfo(data) << endl; } else { @@ -155,7 +174,7 @@ void testTransfer(const T& input) Perr<< "master receiving from slave " << slave << endl; IPstream fromSlave(Pstream::commsTypes::blocking, slave); fromSlave >> data; - Perr<< data << endl; + perrInfo(data) << endl; } for @@ -258,6 +277,15 @@ int main(int argc, char *argv[]) testTransfer(scalar(3.14159)); testTransfer(string("test string")); testTransfer(string(" x ")); + + { + // Slightly roundabout way to construct with a nul in string + string str1("embedded. nul character in string"); + str1[8] = '\0'; + + Info<< "len: " << str1.size() << endl; + testTransfer(str1); + } testTransfer(word("3.141 59")); // bad word, but transfer doesn't care testTokenized(label(1234)); diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C index 21b412fce3..0e40098fa5 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C @@ -42,12 +42,12 @@ inline void Foam::UIPstream::checkEof() template -inline void Foam::UIPstream::readFromBuffer(T& t) +inline void Foam::UIPstream::readFromBuffer(T& val) { const size_t align = sizeof(T); externalBufPosition_ = align + ((externalBufPosition_ - 1) & ~(align - 1)); - t = reinterpret_cast(externalBuf_[externalBufPosition_]); + val = reinterpret_cast(externalBuf_[externalBufPosition_]); externalBufPosition_ += sizeof(T); checkEof(); } @@ -67,10 +67,14 @@ inline void Foam::UIPstream::readFromBuffer + ((externalBufPosition_ - 1) & ~(align - 1)); } - const char* bufPtr = &externalBuf_[externalBufPosition_]; - char* dataPtr = reinterpret_cast(data); - size_t i = count; - while (i--) *dataPtr++ = *bufPtr++; + const char* const __restrict__ buf = &externalBuf_[externalBufPosition_]; + char* const __restrict__ output = reinterpret_cast(data); + + for (size_t i = 0; i < count; ++i) + { + output[i] = buf[i]; + } + externalBufPosition_ += count; checkEof(); } @@ -78,14 +82,15 @@ inline void Foam::UIPstream::readFromBuffer inline Foam::Istream& Foam::UIPstream::readStringFromBuffer(std::string& str) { + // Use std::string::assign() to copy content, including '\0'. + // Stripping (when desired) is the responsibility of the sending side. + 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; + + str.assign(&externalBuf_[externalBufPosition_], len); + + externalBufPosition_ += len; checkEof(); return *this; @@ -276,7 +281,7 @@ Foam::Istream& Foam::UIPstream::read(token& t) Foam::Istream& Foam::UIPstream::read(char& c) { c = externalBuf_[externalBufPosition_]; - externalBufPosition_++; + ++externalBufPosition_; checkEof(); return *this; } diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H index d0c0f86552..04115646f1 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H @@ -80,7 +80,7 @@ class UIPstream //- Read a T from the transfer buffer template - inline void readFromBuffer(T& t); + inline void readFromBuffer(T& val); //- Read count bytes of data from the transfer buffer // using align byte alignment diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C index eb54b5ea61..b94ede4056 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C @@ -109,7 +109,7 @@ inline void Foam::UOPstream::writeStringToBuffer(const std::string& str) { const size_t len = str.size(); writeToBuffer(len); - writeToBuffer(str.c_str(), len + 1, 1); + writeToBuffer(str.data(), len, 1); }