int32IO.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2014-2016 OpenFOAM Foundation
9  Copyright (C) 2016-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "int32.H"
30 #include "error.H"
31 #include "parsing.H"
32 #include "IOstreams.H"
33 #include <cinttypes>
34 #include <cmath>
35 
36 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
37 
38 int32_t Foam::readInt32(const char* buf)
39 {
40  char *endptr = nullptr;
41  errno = 0;
42  const intmax_t parsed = ::strtoimax(buf, &endptr, 10);
43 
44  const int32_t val = int32_t(parsed);
45 
46  const parsing::errorType err =
47  (
48  (parsed < INT32_MIN || parsed > INT32_MAX)
49  ? parsing::errorType::RANGE
50  : parsing::checkConversion(buf, endptr)
51  );
52 
53  if (err != parsing::errorType::NONE)
54  {
55  FatalIOErrorInFunction("unknown")
56  << parsing::errorNames[err] << " '" << buf << "'"
57  << exit(FatalIOError);
58  }
59 
60  return val;
61 }
62 
63 
64 bool Foam::readInt32(const char* buf, int32_t& val)
65 {
66  char *endptr = nullptr;
67  errno = 0;
68  const intmax_t parsed = ::strtoimax(buf, &endptr, 10);
69 
70  val = int32_t(parsed);
71 
72  return
73  (
74  (parsed < INT32_MIN || parsed > INT32_MAX)
75  ? false
76  : (parsing::checkConversion(buf, endptr) == parsing::errorType::NONE)
77  );
78 }
79 
80 
82 {
83  int32_t val(0);
84  is >> val;
85 
86  return val;
87 }
88 
89 
91 {
92  token t(is);
93 
94  if (!t.good())
95  {
97  << "Bad token - could not get int32"
98  << exit(FatalIOError);
99  is.setBad();
100  return is;
101  }
102 
103  // Accept separated '-' (or '+') while expecting a number.
104  // This can arise during dictionary expansions (Eg, -$value)
105 
106  char prefix = 0;
107  if (t.isPunctuation())
108  {
109  prefix = t.pToken();
110  if (prefix == token::PLUS || prefix == token::MINUS)
111  {
112  is >> t;
113  }
114  }
115 
116  if (t.isLabel())
117  {
118  val = int32_t
119  (
120  (prefix == token::MINUS)
121  ? (0 - t.labelToken())
122  : t.labelToken()
123  );
124  }
125  else if (t.isScalar())
126  {
127  const scalar sval
128  (
129  (prefix == token::MINUS)
130  ? (0 - t.scalarToken())
131  : t.scalarToken()
132  );
133  const intmax_t parsed = intmax_t(std::round(sval));
134  val = 0 + int32_t(parsed);
135 
136  // Accept integral floating-point values.
137  // Eg, from string expression evaluation (#1696)
138 
139  if (parsed < INT32_MIN || parsed > INT32_MAX)
140  {
142  << "Expected integral (int32), value out-of-range "
143  << t.info()
144  << exit(FatalIOError);
145  is.setBad();
146  return is;
147  }
148  else if (1e-4 < std::abs(sval - scalar(parsed)))
149  {
151  << "Expected integral (int32), found non-integral value "
152  << t.info()
153  << exit(FatalIOError);
154  is.setBad();
155  return is;
156  }
157  }
158  else
159  {
161  << "Wrong token type - expected label (int32), found ";
162  if (prefix == token::PLUS || prefix == token::MINUS)
163  {
164  FatalIOError << '\'' << prefix << "' followed by ";
165  }
166  FatalIOError << t.info() << exit(FatalIOError);
167  is.setBad();
168  return is;
169  }
170 
171  is.check(FUNCTION_NAME);
172  return is;
173 }
174 
175 
177 {
178  os.write(label(val));
179  os.check(FUNCTION_NAME);
180  return os;
181 }
182 
183 
184 #if (__SIZEOF_LONG__ == 4)
185 Foam::Istream& Foam::operator>>(Istream& is, long& val)
186 {
187  return operator>>(is, reinterpret_cast<int32_t&>(val));
188 }
189 
190 Foam::Ostream& Foam::operator<<(Ostream& os, const long val)
191 {
192  return (os << int32_t(val));
193 }
194 #endif
195 
196 
197 // ************************************************************************* //
Foam::token::labelToken
label labelToken() const
Return label value.
Definition: tokenI.H:513
IOstreams.H
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Foam::token::isLabel
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:497
Foam::parsing::checkConversion
errorType checkConversion(const char *buf, char *endptr)
Sanity check after strtof, strtod, etc.
Definition: parsingI.H:29
parsing.H
Foam::FatalIOError
IOerror FatalIOError
Foam::operator>>
Istream & operator>>(Istream &, directionInfo &)
Definition: directionInfo.C:230
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::token::pToken
punctuationToken pToken() const
Return punctuation character.
Definition: tokenI.H:485
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
error.H
Foam::token::info
InfoProxy< token > info() const
Return info proxy for printing token information to a stream.
Definition: token.H:586
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::token::isPunctuation
bool isPunctuation() const noexcept
Token is PUNCTUATION.
Definition: tokenI.H:459
Foam::parsing::errorNames
const Foam::Enum< errorType > errorNames
Strings corresponding to the errorType.
Foam::parsing::errorType
errorType
Enumeration for possible parsing error.
Definition: parsing.H:57
Foam::IOstream::check
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:58
os
OBJstream os(runTime.globalPath()/outputName)
Foam::readInt32
int32_t readInt32(Istream &is)
Read int32_t from stream.
Definition: int32IO.C:81
Foam::token::isScalar
bool isScalar() const noexcept
Token is FLOAT or DOUBLE.
Definition: tokenI.H:561
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
int32.H
32bit signed integer
Foam::token::good
bool good() const noexcept
True if token is not UNDEFINED or ERROR.
Definition: tokenI.H:405
Foam::token::scalarToken
scalar scalarToken() const
Return float or double value.
Definition: tokenI.H:571
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::IOstream::setBad
void setBad()
Set stream state to be 'bad'.
Definition: IOstream.H:369
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56