forked from greiman/SdFat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ios.h
423 lines (417 loc) · 11.5 KB
/
ios.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
/**
* Copyright (c) 2011-2018 Bill Greiman
* This file is part of the SdFat library for SD memory cards.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef ios_h
#define ios_h
#include "FatFile.h"
/**
* \file
* \brief \ref ios_base and \ref ios classes
*/
//==============================================================================
/**
* \class ios_base
* \brief Base class for all streams
*/
class ios_base {
public:
/** typedef for iostate bitmask */
typedef unsigned char iostate;
// State flags.
/** iostate for no flags */
static const iostate goodbit = 0x00;
/** iostate bad bit for a nonrecoverable error. */
static const iostate badbit = 0X01;
/** iostate bit for end of file reached */
static const iostate eofbit = 0x02;
/** iostate fail bit for nonfatal error */
static const iostate failbit = 0X04;
/**
* unsigned size that can represent maximum file size.
* (violates spec - should be signed)
*/
typedef uint32_t streamsize;
/** type for absolute seek position */
typedef uint32_t pos_type;
/** type for relative seek offset */
typedef int32_t off_type;
/** enumerated type for the direction of relative seeks */
enum seekdir {
/** seek relative to the beginning of the stream */
beg,
/** seek relative to the current stream position */
cur,
/** seek relative to the end of the stream */
end
};
/** type for format flags */
typedef unsigned int fmtflags;
/** left adjust fields */
static const fmtflags left = 0x0001;
/** right adjust fields */
static const fmtflags right = 0x0002;
/** fill between sign/base prefix and number */
static const fmtflags internal = 0x0004;
/** base 10 flag*/
static const fmtflags dec = 0x0008;
/** base 16 flag */
static const fmtflags hex = 0x0010;
/** base 8 flag */
static const fmtflags oct = 0x0020;
// static const fmtflags fixed = 0x0040;
// static const fmtflags scientific = 0x0080;
/** use strings true/false for bool */
static const fmtflags boolalpha = 0x0100;
/** use prefix 0X for hex and 0 for oct */
static const fmtflags showbase = 0x0200;
/** always show '.' for floating numbers */
static const fmtflags showpoint = 0x0400;
/** show + sign for nonnegative numbers */
static const fmtflags showpos = 0x0800;
/** skip initial white space */
static const fmtflags skipws = 0x1000;
// static const fmtflags unitbuf = 0x2000;
/** use uppercase letters in number representations */
static const fmtflags uppercase = 0x4000;
/** mask for adjustfield */
static const fmtflags adjustfield = left | right | internal;
/** mask for basefield */
static const fmtflags basefield = dec | hex | oct;
// static const fmtflags floatfield = scientific | fixed;
//----------------------------------------------------------------------------
/** typedef for iostream open mode */
typedef uint8_t openmode;
// Openmode flags.
/** seek to end before each write */
static const openmode app = 0X4;
/** open and seek to end immediately after opening */
static const openmode ate = 0X8;
/** perform input and output in binary mode (as opposed to text mode) */
static const openmode binary = 0X10;
/** open for input */
static const openmode in = 0X20;
/** open for output */
static const openmode out = 0X40;
/** truncate an existing stream when opening */
static const openmode trunc = 0X80;
//----------------------------------------------------------------------------
ios_base() : m_fill(' '), m_fmtflags(dec | right | skipws)
, m_precision(2), m_width(0) {}
/** \return fill character */
char fill() {
return m_fill;
}
/** Set fill character
* \param[in] c new fill character
* \return old fill character
*/
char fill(char c) {
char r = m_fill;
m_fill = c;
return r;
}
/** \return format flags */
fmtflags flags() const {
return m_fmtflags;
}
/** set format flags
* \param[in] fl new flag
* \return old flags
*/
fmtflags flags(fmtflags fl) {
fmtflags tmp = m_fmtflags;
m_fmtflags = fl;
return tmp;
}
/** \return precision */
int precision() const {
return m_precision;
}
/** set precision
* \param[in] n new precision
* \return old precision
*/
int precision(unsigned int n) {
int r = m_precision;
m_precision = n;
return r;
}
/** set format flags
* \param[in] fl new flags to be or'ed in
* \return old flags
*/
fmtflags setf(fmtflags fl) {
fmtflags r = m_fmtflags;
m_fmtflags |= fl;
return r;
}
/** modify format flags
* \param[in] mask flags to be removed
* \param[in] fl flags to be set after mask bits have been cleared
* \return old flags
*/
fmtflags setf(fmtflags fl, fmtflags mask) {
fmtflags r = m_fmtflags;
m_fmtflags &= ~mask;
m_fmtflags |= fl;
return r;
}
/** clear format flags
* \param[in] fl flags to be cleared
* \return old flags
*/
void unsetf(fmtflags fl) {
m_fmtflags &= ~fl;
}
/** \return width */
unsigned width() {
return m_width;
}
/** set width
* \param[in] n new width
* \return old width
*/
unsigned width(unsigned n) {
unsigned r = m_width;
m_width = n;
return r;
}
protected:
/** \return current number base */
uint8_t flagsToBase() {
uint8_t f = flags() & basefield;
return f == oct ? 8 : f != hex ? 10 : 16;
}
private:
char m_fill;
fmtflags m_fmtflags;
unsigned char m_precision;
unsigned int m_width;
};
//------------------------------------------------------------------------------
/** function for boolalpha manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& boolalpha(ios_base& str) {
str.setf(ios_base::boolalpha);
return str;
}
/** function for dec manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& dec(ios_base& str) {
str.setf(ios_base::dec, ios_base::basefield);
return str;
}
/** function for hex manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& hex(ios_base& str) {
str.setf(ios_base::hex, ios_base::basefield);
return str;
}
/** function for internal manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& internal(ios_base& str) {
str.setf(ios_base::internal, ios_base::adjustfield);
return str;
}
/** function for left manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& left(ios_base& str) {
str.setf(ios_base::left, ios_base::adjustfield);
return str;
}
/** function for noboolalpha manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& noboolalpha(ios_base& str) {
str.unsetf(ios_base::boolalpha);
return str;
}
/** function for noshowbase manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& noshowbase(ios_base& str) {
str.unsetf(ios_base::showbase);
return str;
}
/** function for noshowpoint manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& noshowpoint(ios_base& str) {
str.unsetf(ios_base::showpoint);
return str;
}
/** function for noshowpos manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& noshowpos(ios_base& str) {
str.unsetf(ios_base::showpos);
return str;
}
/** function for noskipws manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& noskipws(ios_base& str) {
str.unsetf(ios_base::skipws);
return str;
}
/** function for nouppercase manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& nouppercase(ios_base& str) {
str.unsetf(ios_base::uppercase);
return str;
}
/** function for oct manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& oct(ios_base& str) {
str.setf(ios_base::oct, ios_base::basefield);
return str;
}
/** function for right manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& right(ios_base& str) {
str.setf(ios_base::right, ios_base::adjustfield);
return str;
}
/** function for showbase manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& showbase(ios_base& str) {
str.setf(ios_base::showbase);
return str;
}
/** function for showpos manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& showpos(ios_base& str) {
str.setf(ios_base::showpos);
return str;
}
/** function for showpoint manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& showpoint(ios_base& str) {
str.setf(ios_base::showpoint);
return str;
}
/** function for skipws manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& skipws(ios_base& str) {
str.setf(ios_base::skipws);
return str;
}
/** function for uppercase manipulator
* \param[in] str The stream
* \return The stream
*/
inline ios_base& uppercase(ios_base& str) {
str.setf(ios_base::uppercase);
return str;
}
//==============================================================================
/**
* \class ios
* \brief Error and state information for all streams
*/
class ios : public ios_base {
public:
/** Create ios with no error flags set */
ios() : m_iostate(0) {}
/** \return null pointer if fail() is true. */
operator const void*() const {
return !fail() ? reinterpret_cast<const void*>(this) : 0;
}
/** \return true if fail() else false. */
bool operator!() const {
return fail();
}
/** \return The iostate flags for this file. */
iostate rdstate() const {
return m_iostate;
}
/** \return True if no iostate flags are set else false. */
bool good() const {
return m_iostate == goodbit;
}
/** \return true if end of file has been reached else false.
*
* Warning: An empty file returns false before the first read.
*
* Moral: eof() is only useful in combination with fail(), to find out
* whether EOF was the cause for failure
*/
bool eof() const {
return m_iostate & eofbit;
}
/** \return true if any iostate bit other than eof are set else false. */
bool fail() const {
return m_iostate & (failbit | badbit);
}
/** \return true if bad bit is set else false. */
bool bad() const {
return m_iostate & badbit;
}
/** Clear iostate bits.
*
* \param[in] state The flags you want to set after clearing all flags.
**/
void clear(iostate state = goodbit) {
m_iostate = state;
}
/** Set iostate bits.
*
* \param[in] state Bitts to set.
**/
void setstate(iostate state) {
m_iostate |= state;
}
private:
iostate m_iostate;
};
#endif // ios_h