/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "UOPstream.H" #include "int.H" #include "token.H" #include // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template inline void Foam::UOPstream::writeToBuffer(const T& t) { writeToBuffer(&t, sizeof(T), sizeof(T)); } inline void Foam::UOPstream::writeToBuffer(const char& c) { if (!sendBuf_.capacity()) { sendBuf_.setCapacity(1000); } sendBuf_.append(c); } inline void Foam::UOPstream::writeToBuffer ( const void* data, const size_t count, const size_t align ) { if (!sendBuf_.capacity()) { sendBuf_.setCapacity(1000); } label alignedPos = sendBuf_.size(); if (align > 1) { // Align bufPosition. Pads sendBuf_.size() - oldPos characters. alignedPos = align + ((sendBuf_.size() - 1) & ~(align - 1)); } // Extend if necessary sendBuf_.setSize(alignedPos + count); const char* dataPtr = reinterpret_cast(data); size_t i = count; while (i--) sendBuf_[alignedPos++] = *dataPtr++; } 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 * * * * * * * * * * * * * * * // Foam::UOPstream::UOPstream ( const commsTypes commsType, const int toProcNo, DynamicList& sendBuf, const int tag, const label comm, const bool sendAtDestruct, streamFormat format, versionNumber version ) : UPstream(commsType), Ostream(format, version), toProcNo_(toProcNo), sendBuf_(sendBuf), tag_(tag), comm_(comm), sendAtDestruct_(sendAtDestruct) { setOpened(); setGood(); } Foam::UOPstream::UOPstream(const int toProcNo, PstreamBuffers& buffers) : UPstream(buffers.commsType_), Ostream(buffers.format_, buffers.version_), toProcNo_(toProcNo), sendBuf_(buffers.sendBuf_[toProcNo]), tag_(buffers.tag_), comm_(buffers.comm_), sendAtDestruct_(buffers.commsType_ != UPstream::commsTypes::nonBlocking) { setOpened(); setGood(); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::UOPstream::~UOPstream() { if (sendAtDestruct_) { if ( !UOPstream::write ( commsType_, toProcNo_, sendBuf_.begin(), sendBuf_.size(), tag_, comm_ ) ) { FatalErrorInFunction << "Failed sending outgoing message of size " << sendBuf_.size() << " to processor " << toProcNo_ << Foam::abort(FatalError); } } } // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // Foam::Ostream& Foam::UOPstream::write(const token& t) { // Raw token output only supported for verbatim strings for now if (t.type() == token::tokenType::VERBATIMSTRING) { writeToBuffer(char(token::tokenType::VERBATIMSTRING)); write(t.stringToken()); } else if (t.type() == token::tokenType::VARIABLE) { writeToBuffer(char(token::tokenType::VARIABLE)); write(t.stringToken()); } else { NotImplemented; setBad(); } return *this; } Foam::Ostream& Foam::UOPstream::write(const char c) { if (!isspace(c)) { writeToBuffer(c); } return *this; } Foam::Ostream& Foam::UOPstream::write(const char* str) { const word nonWhiteChars(string::validate(str)); if (nonWhiteChars.size() == 1) { return write(nonWhiteChars[0]); } else if (nonWhiteChars.size()) { return write(nonWhiteChars); } else { return *this; } } Foam::Ostream& Foam::UOPstream::write(const word& str) { writeToBuffer(char(token::tokenType::WORD)); writeStringToBuffer(str); return *this; } Foam::Ostream& Foam::UOPstream::write(const string& str) { writeToBuffer(char(token::tokenType::STRING)); writeStringToBuffer(str); return *this; } Foam::Ostream& Foam::UOPstream::writeQuoted ( const std::string& str, const bool quoted ) { if (quoted) { writeToBuffer(char(token::tokenType::STRING)); } else { writeToBuffer(char(token::tokenType::WORD)); } writeStringToBuffer(str); return *this; } Foam::Ostream& Foam::UOPstream::write(const int32_t val) { writeToBuffer(char(token::tokenType::LABEL)); writeToBuffer(val); return *this; } Foam::Ostream& Foam::UOPstream::write(const int64_t val) { writeToBuffer(char(token::tokenType::LABEL)); writeToBuffer(val); return *this; } Foam::Ostream& Foam::UOPstream::write(const floatScalar val) { writeToBuffer(char(token::tokenType::FLOAT_SCALAR)); writeToBuffer(val); return *this; } Foam::Ostream& Foam::UOPstream::write(const doubleScalar val) { writeToBuffer(char(token::tokenType::DOUBLE_SCALAR)); writeToBuffer(val); return *this; } Foam::Ostream& Foam::UOPstream::write ( const char* data, const std::streamsize count ) { if (format() != BINARY) { FatalErrorInFunction << "stream format not binary" << Foam::abort(FatalError); } writeToBuffer(data, count, 8); return *this; } void Foam::UOPstream::print(Ostream& os) const { os << "Writing from processor " << toProcNo_ << " to processor " << myProcNo() << " in communicator " << comm_ << " and tag " << tag_ << Foam::endl; } // ************************************************************************* //