UOPstream.C 6.8 KB
Newer Older
mattijs's avatar
mattijs committed
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
5
    \\  /    A nd           | Copyright (C) 2011-2017 OpenFOAM Foundation
6
     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
mattijs's avatar
mattijs committed
7
8
9
10
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

11
12
13
14
    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.
mattijs's avatar
mattijs committed
15
16
17
18
19
20
21

    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
22
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
mattijs's avatar
mattijs committed
23
24
25
26
27
28
29
30
31

\*---------------------------------------------------------------------------*/

#include "UOPstream.H"
#include "int.H"
#include "token.H"

#include <cctype>

32
// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
mattijs's avatar
mattijs committed
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

template<class T>
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,
54
55
    const size_t count,
    const size_t align
mattijs's avatar
mattijs committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
)
{
    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);

74
75
    const char* dataPtr = reinterpret_cast<const char*>(data);
    size_t i = count;
mattijs's avatar
mattijs committed
76
77
78
79
    while (i--) sendBuf_[alignedPos++] = *dataPtr++;
}


80
81
82
83
84
85
86
inline void Foam::UOPstream::writeStringToBuffer(const std::string& str)
{
    const size_t len = str.size();
    writeToBuffer(len);
    writeToBuffer(str.c_str(), len + 1, 1);
}

mattijs's avatar
mattijs committed
87
88
89
90
91
92
93
94

// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //

Foam::UOPstream::UOPstream
(
    const commsTypes commsType,
    const int toProcNo,
    DynamicList<char>& sendBuf,
95
    const int tag,
96
    const label comm,
mattijs's avatar
mattijs committed
97
98
99
100
101
102
103
104
105
106
    const bool sendAtDestruct,
    streamFormat format,
    versionNumber version
)
:
    UPstream(commsType),
    Ostream(format, version),
    toProcNo_(toProcNo),
    sendBuf_(sendBuf),
    tag_(tag),
107
    comm_(comm),
mattijs's avatar
mattijs committed
108
109
110
111
112
113
114
115
116
117
118
119
120
121
    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_),
122
    comm_(buffers.comm_),
123
    sendAtDestruct_(buffers.commsType_ != UPstream::commsTypes::nonBlocking)
mattijs's avatar
mattijs committed
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
{
    setOpened();
    setGood();
}


// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //

Foam::UOPstream::~UOPstream()
{
    if (sendAtDestruct_)
    {
        if
        (
           !UOPstream::write
            (
                commsType_,
                toProcNo_,
                sendBuf_.begin(),
143
                sendBuf_.size(),
144
145
                tag_,
                comm_
mattijs's avatar
mattijs committed
146
147
148
            )
        )
        {
149
            FatalErrorInFunction
mattijs's avatar
mattijs committed
150
151
152
153
154
155
156
157
158
159
                << "Failed sending outgoing message of size " << sendBuf_.size()
                << " to processor " << toProcNo_
                << Foam::abort(FatalError);
        }
    }
}


// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //

160
Foam::Ostream& Foam::UOPstream::write(const token& t)
mattijs's avatar
mattijs committed
161
{
162
    // Raw token output only supported for verbatim strings for now
163
    if (t.type() == token::tokenType::VERBATIMSTRING)
164
    {
165
        writeToBuffer(char(token::tokenType::VERBATIMSTRING));
166
167
        write(t.stringToken());
    }
168
    else if (t.type() == token::tokenType::VARIABLE)
169
    {
170
        writeToBuffer(char(token::tokenType::VARIABLE));
171
172
        write(t.stringToken());
    }
173
174
    else
    {
175
        NotImplemented;
176
177
        setBad();
    }
mattijs's avatar
mattijs committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    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)
{
195
    const word nonWhiteChars(string::validate<word>(str));
mattijs's avatar
mattijs committed
196
197
198

    if (nonWhiteChars.size() == 1)
    {
199
        return write(nonWhiteChars[0]);
mattijs's avatar
mattijs committed
200
201
202
203
204
205
206
207
208
209
210
211
212
213
    }
    else if (nonWhiteChars.size())
    {
        return write(nonWhiteChars);
    }
    else
    {
        return *this;
    }
}


Foam::Ostream& Foam::UOPstream::write(const word& str)
{
214
215
    writeToBuffer(char(token::tokenType::WORD));
    writeStringToBuffer(str);
mattijs's avatar
mattijs committed
216
217
218
219
220
221
222

    return *this;
}


Foam::Ostream& Foam::UOPstream::write(const string& str)
{
223
224
    writeToBuffer(char(token::tokenType::STRING));
    writeStringToBuffer(str);
mattijs's avatar
mattijs committed
225
226
227
228
229

    return *this;
}


230
231
232
233
234
Foam::Ostream& Foam::UOPstream::writeQuoted
(
    const std::string& str,
    const bool quoted
)
mattijs's avatar
mattijs committed
235
{
236
237
    if (quoted)
    {
238
        writeToBuffer(char(token::tokenType::STRING));
239
240
241
    }
    else
    {
242
        writeToBuffer(char(token::tokenType::WORD));
243
    }
244
    writeStringToBuffer(str);
mattijs's avatar
mattijs committed
245
246
247
248
249

    return *this;
}


250
251
Foam::Ostream& Foam::UOPstream::write(const int32_t val)
{
252
    writeToBuffer(char(token::tokenType::LABEL));
253
254
255
256
257
258
    writeToBuffer(val);
    return *this;
}


Foam::Ostream& Foam::UOPstream::write(const int64_t val)
mattijs's avatar
mattijs committed
259
{
260
    writeToBuffer(char(token::tokenType::LABEL));
mattijs's avatar
mattijs committed
261
262
263
264
265
266
267
    writeToBuffer(val);
    return *this;
}


Foam::Ostream& Foam::UOPstream::write(const floatScalar val)
{
268
    writeToBuffer(char(token::tokenType::FLOAT_SCALAR));
mattijs's avatar
mattijs committed
269
270
271
272
273
274
275
    writeToBuffer(val);
    return *this;
}


Foam::Ostream& Foam::UOPstream::write(const doubleScalar val)
{
276
    writeToBuffer(char(token::tokenType::DOUBLE_SCALAR));
mattijs's avatar
mattijs committed
277
278
279
280
281
    writeToBuffer(val);
    return *this;
}


282
283
284
285
286
Foam::Ostream& Foam::UOPstream::write
(
    const char* data,
    const std::streamsize count
)
mattijs's avatar
mattijs committed
287
288
289
{
    if (format() != BINARY)
    {
290
        FatalErrorInFunction
mattijs's avatar
mattijs committed
291
292
293
294
295
296
297
298
299
300
301
302
303
            << "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_
304
305
        << " to processor " << myProcNo() << " in communicator " << comm_
        << " and tag " << tag_ << Foam::endl;
mattijs's avatar
mattijs committed
306
307
308
309
}


// ************************************************************************* //