|
- /* Arduino SdFat Library
- * Copyright (C) 2012 by William Greiman
- *
- * This file is part of the Arduino SdFat Library
- *
- * This Library 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.
- *
- * This Library 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 the Arduino SdFat Library. If not, see
- * <http://www.gnu.org/licenses/>.
- */
- #ifndef ios_h
- #define ios_h
- #include <SdBaseFile.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
|