FreeFOAM The Cross-Platform CFD Toolkit
IPstream.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include <OpenFOAM/error.H>
27 #include "IPstream.H"
28 #include <OpenFOAM/int.H>
29 #include <OpenFOAM/token.H>
30 #include <cctype>
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 Foam::autoPtr<Foam::IPstreamImpl> Foam::IPstream::impl_;
35 
36 // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
37 
39 (
40  const commsTypes commsType,
41  const int fromProcNo,
42  const label bufSize,
44  versionNumber version
45 )
46 :
47  Pstream(commsType, bufSize),
48  Istream(format, version),
49  fromProcNo_(fromProcNo),
50  messageSize_(0)
51 {
52  setOpened();
53  setGood();
54 
55  impl()->init(commsType, bufSize, fromProcNo_, messageSize_, buf_);
56 
57 }
58 
59 // * * * * * * * * * * * * * Private member functions * * * * * * * * * * * //
60 
61 inline void Foam::IPstream::checkEof()
62 {
63  if (bufPosition_ == messageSize_)
64  {
65  setEof();
66  }
67 }
68 
69 
70 template<class T>
71 inline void Foam::IPstream::readFromBuffer(T& t)
72 {
73  const size_t align = sizeof(T);
74  bufPosition_ = align + ((bufPosition_ - 1) & ~(align - 1));
75 
76  t = reinterpret_cast<T&>(buf_[bufPosition_]);
77  bufPosition_ += sizeof(T);
78  checkEof();
79 }
80 
81 
82 inline void Foam::IPstream::readFromBuffer
83 (
84  void* data,
85  size_t count,
86  size_t align
87 )
88 {
89  if (align > 1)
90  {
91  bufPosition_ = align + ((bufPosition_ - 1) & ~(align - 1));
92  }
93 
94  register const char* bufPtr = &buf_[bufPosition_];
95  register char* dataPtr = reinterpret_cast<char*>(data);
96  register size_t i = count;
97  while (i--) *dataPtr++ = *bufPtr++;
98  bufPosition_ += count;
99  checkEof();
100 }
101 
102 
103 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
104 
106 {}
107 
108 
109 
110 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
111 
113 {
114  // Return the put back token if it exists
115  if (Istream::getBack(t))
116  {
117  return *this;
118  }
119 
120  char c;
121 
122  // return on error
123  if (!read(c))
124  {
125  t.setBad();
126  return *this;
127  }
128 
129  // Set the line number of this token to the current stream line number
130  t.lineNumber() = lineNumber();
131 
132  // Analyse input starting with this character.
133  switch (c)
134  {
135  // Punctuation
136  case token::END_STATEMENT :
137  case token::BEGIN_LIST :
138  case token::END_LIST :
139  case token::BEGIN_SQR :
140  case token::END_SQR :
141  case token::BEGIN_BLOCK :
142  case token::END_BLOCK :
143  case token::COLON :
144  case token::COMMA :
145  case token::ASSIGN :
146  case token::ADD :
147  case token::SUBTRACT :
148  case token::MULTIPLY :
149  case token::DIVIDE :
150  {
152  return *this;
153  }
154 
155  // Word
156  case token::WORD :
157  {
158  word* pval = new word;
159  if (read(*pval))
160  {
161  if (token::compound::isCompound(*pval))
162  {
163  t = token::compound::New(*pval, *this).ptr();
164  delete pval;
165  }
166  else
167  {
168  t = pval;
169  }
170  }
171  else
172  {
173  delete pval;
174  t.setBad();
175  }
176  return *this;
177  }
178 
179  // String
180  case token::STRING :
181  {
182  string* pval = new string;
183  if (read(*pval))
184  {
185  t = pval;
186  }
187  else
188  {
189  delete pval;
190  t.setBad();
191  }
192  return *this;
193  }
194 
195  // Label
196  case token::LABEL :
197  {
198  label val;
199  if (read(val))
200  {
201  t = val;
202  }
203  else
204  {
205  t.setBad();
206  }
207  return *this;
208  }
209 
210  // floatScalar
211  case token::FLOAT_SCALAR :
212  {
213  floatScalar val;
214  if (read(val))
215  {
216  t = val;
217  }
218  else
219  {
220  t.setBad();
221  }
222  return *this;
223  }
224 
225  // doubleScalar
226  case token::DOUBLE_SCALAR :
227  {
228  doubleScalar val;
229  if (read(val))
230  {
231  t = val;
232  }
233  else
234  {
235  t.setBad();
236  }
237  return *this;
238  }
239 
240  // Character (returned as a single character word) or error
241  default:
242  {
243  if (isalpha(c))
244  {
245  t = word(c);
246  return *this;
247  }
248 
249  setBad();
250  t.setBad();
251 
252  return *this;
253  }
254  }
255 }
256 
257 
259 {
260  c = buf_[bufPosition_];
261  bufPosition_++;
262  checkEof();
263  return *this;
264 }
265 
266 
268 {
269  size_t len;
270  readFromBuffer(len);
271  str = &buf_[bufPosition_];
272  bufPosition_ += len + 1;
273  checkEof();
274  return *this;
275 }
276 
277 
279 {
280  size_t len;
281  readFromBuffer(len);
282  str = &buf_[bufPosition_];
283  bufPosition_ += len + 1;
284  checkEof();
285  return *this;
286 }
287 
288 
290 {
291  readFromBuffer(val);
292  return *this;
293 }
294 
295 
297 {
298  readFromBuffer(val);
299  return *this;
300 }
301 
302 
304 {
305  readFromBuffer(val);
306  return *this;
307 }
308 
309 
310 Foam::Istream& Foam::IPstream::read(char* data, std::streamsize count)
311 {
312  if (format() != BINARY)
313  {
314  FatalErrorIn("IPstream::read(char*, std::streamsize)")
315  << "stream format not binary"
317  }
318 
319  readFromBuffer(data, count, 8);
320  return *this;
321 }
322 
323 
325 {
326  bufPosition_ = 0;
327  return *this;
328 }
329 
330 
331 // ************************ vim: set sw=4 sts=4 et: ************************ //