diff --git a/ArdusatLogging.cpp b/ArdusatLogging.cpp index c103882..384ccda 100644 --- a/ArdusatLogging.cpp +++ b/ArdusatLogging.cpp @@ -79,9 +79,9 @@ int logBytes(const unsigned char *buffer, unsigned char numBytes) * * @return number of bytes written */ -int logAcceleration(const char *sensorName, acceleration_t & data) +int logSensor(const char *sensorName, Acceleration & sensor) { - return logString(accelerationToCSV(sensorName, data)); + return logString(sensor.toCSV(sensorName)); } /** @@ -92,9 +92,9 @@ int logAcceleration(const char *sensorName, acceleration_t & data) * * @return number of bytes written */ -int logMagnetic(const char *sensorName, magnetic_t & data) +int logSensor(const char *sensorName, Magnetic & sensor) { - return logString(magneticToCSV(sensorName, data)); + return logString(sensor.toCSV(sensorName)); } /** @@ -105,9 +105,9 @@ int logMagnetic(const char *sensorName, magnetic_t & data) * * @return number of bytes written */ -int logGyro(const char *sensorName, gyro_t & data) +int logSensor(const char *sensorName, Gyro & sensor) { - return logString(gyroToCSV(sensorName, data)); + return logString(sensor.toCSV(sensorName)); } /** @@ -118,9 +118,9 @@ int logGyro(const char *sensorName, gyro_t & data) * * @return number of bytes written */ -int logTemperature(const char *sensorName, temperature_t & data) +int logSensor(const char *sensorName, Temperature & sensor) { - return logString(temperatureToCSV(sensorName, data)); + return logString(sensor.toCSV(sensorName)); } /** @@ -131,9 +131,9 @@ int logTemperature(const char *sensorName, temperature_t & data) * * @return number of bytes written */ -int logLuminosity(const char *sensorName, luminosity_t & data) +int logSensor(const char *sensorName, Luminosity & sensor) { - return logString(luminosityToCSV(sensorName, data)); + return logString(sensor.toCSV(sensorName)); } /** @@ -144,9 +144,9 @@ int logLuminosity(const char *sensorName, luminosity_t & data) * * @return number of bytes written */ -int logUVLight(const char *sensorName, uvlight_t & data) +int logSensor(const char *sensorName, UVLight & sensor) { - return logString(uvlightToCSV(sensorName, data)); + return logString(sensor.toCSV(sensorName)); } /** @@ -157,9 +157,9 @@ int logUVLight(const char *sensorName, uvlight_t & data) * * @return number of bytes written */ -int logOrientation(const char *sensorName, orientation_t & data) +int logSensor(const char *sensorName, Orientation & sensor) { - return logString(orientationToCSV(sensorName, data)); + return logString(sensor.toCSV(sensorName)); } /** @@ -170,85 +170,85 @@ int logOrientation(const char *sensorName, orientation_t & data) * * @return number of bytes written */ -int logPressure(const char *sensorName, pressure_t & data) +int logSensor(const char *sensorName, Pressure & sensor) { - return logString(pressureToCSV(sensorName, data)); + return logString(sensor.toCSV(sensorName)); } #define init_data_struct(type_def, type_enum) \ type_def bin_data; \ bin_data.type = type_enum; \ bin_data.id = sensorId; \ - bin_data.timestamp = data.header.timestamp; + bin_data.timestamp = sensor.header.timestamp; -int binaryLogAcceleration(const unsigned char sensorId, acceleration_t & data) +int binaryLogSensor(const unsigned char sensorId, Acceleration & sensor) { init_data_struct(acceleration_bin_t, ARDUSAT_SENSOR_TYPE_ACCELERATION) - bin_data.x = data.x; - bin_data.y = data.y; - bin_data.z = data.z; + bin_data.x = sensor.x; + bin_data.y = sensor.y; + bin_data.z = sensor.z; return logBytes((unsigned char *) &bin_data, sizeof(acceleration_bin_t)); } -int binaryLogMagnetic(const unsigned char sensorId, magnetic_t & data) +int binaryLogSensor(const unsigned char sensorId, Magnetic & sensor) { init_data_struct(magnetic_bin_t, ARDUSAT_SENSOR_TYPE_MAGNETIC) - bin_data.x = data.x; - bin_data.y = data.y; - bin_data.z = data.z; + bin_data.x = sensor.x; + bin_data.y = sensor.y; + bin_data.z = sensor.z; return logBytes((unsigned char *) &bin_data, sizeof(magnetic_bin_t)); } -int binaryLogGyro(const unsigned char sensorId, gyro_t & data) +int binaryLogSensor(const unsigned char sensorId, Gyro & sensor) { init_data_struct(gyro_bin_t, ARDUSAT_SENSOR_TYPE_GYRO) - bin_data.x = data.x; - bin_data.y = data.y; - bin_data.z = data.z; + bin_data.x = sensor.x; + bin_data.y = sensor.y; + bin_data.z = sensor.z; return logBytes((unsigned char *) &bin_data, sizeof(gyro_bin_t)); } -int binaryLogTemperature(const unsigned char sensorId, temperature_t & data) +int binaryLogSensor(const unsigned char sensorId, Temperature & sensor) { init_data_struct(temperature_bin_t, ARDUSAT_SENSOR_TYPE_TEMPERATURE) - bin_data.temp = data.t; + bin_data.temp = sensor.t; return logBytes((unsigned char *) &bin_data, sizeof(temperature_bin_t)); } -int binaryLogLuminosity(const unsigned char sensorId, luminosity_t & data) +int binaryLogSensor(const unsigned char sensorId, Luminosity & sensor) { init_data_struct(luminosity_bin_t, ARDUSAT_SENSOR_TYPE_LUMINOSITY) - bin_data.luminosity = data.lux; + bin_data.luminosity = sensor.lux; return logBytes((unsigned char *) &bin_data, sizeof(luminosity_bin_t)); } -int binaryLogUVLight(const unsigned char sensorId, uvlight_t & data) +int binaryLogSensor(const unsigned char sensorId, UVLight & sensor) { init_data_struct(uv_light_bin_t, ARDUSAT_SENSOR_TYPE_UV) - bin_data.uv = data.uvindex; + bin_data.uv = sensor.uvindex; return logBytes((unsigned char *) &bin_data, sizeof(uv_light_bin_t)); } -int binaryLogOrientation(const unsigned char sensorId, orientation_t & data) +int binaryLogSensor(const unsigned char sensorId, Orientation & sensor) { init_data_struct(orientation_bin_t, ARDUSAT_SENSOR_TYPE_ORIENTATION) - bin_data.roll = data.roll; - bin_data.pitch = data.pitch; - bin_data.heading = data.heading; + bin_data.roll = sensor.roll; + bin_data.pitch = sensor.pitch; + bin_data.heading = sensor.heading; return logBytes((unsigned char *) &bin_data, sizeof(orientation_bin_t)); } -int binaryLogPressure(const unsigned char sensorId, pressure_t & data) +int binaryLogSensor(const unsigned char sensorId, Pressure & sensor) { init_data_struct(pressure_bin_t, ARDUSAT_SENSOR_TYPE_PRESSURE) - bin_data.pressure = data.pressure; + bin_data.pressure = sensor.pressure; return logBytes((unsigned char *) &bin_data, sizeof(pressure_bin_t)); } diff --git a/ArdusatLogging.h b/ArdusatLogging.h index d543701..1439425 100644 --- a/ArdusatLogging.h +++ b/ArdusatLogging.h @@ -17,10 +17,6 @@ #include "ArdusatSDK.h" -#ifdef __cplusplus -extern "C" { -#endif - /** * Log functions take care of persisting data to an SD card * @@ -37,23 +33,25 @@ extern "C" { */ int logString(const char *output_buf); int logBytes(const unsigned char *buffer, unsigned char numBytes); -int logAcceleration(const char *sensorName, acceleration_t & data); -int logMagnetic(const char *sensorName, magnetic_t & data); -int logGyro(const char *sensorName, gyro_t & data); -int logTemperature(const char *sensorName, temperature_t & data); -int logLuminosity(const char *sensorName, luminosity_t & data); -int logUVLight(const char *sensorName, uvlight_t & data); -int logOrientation(const char *sensorName, orientation_t & data); -int logPressure(const char *sensorName, pressure_t & data); +int logSensor(const char *sensorName, Acceleration & sensor); +int logSensor(const char *sensorName, Gyro & sensor); +int logSensor(const char *sensorName, Luminosity & sensor); +int logSensor(const char *sensorName, Magnetic & sensor); +int logSensor(const char *sensorName, Orientation & sensor); +int logSensor(const char *sensorName, Pressure & sensor); +int logSensor(const char *sensorName, RGBLight & sensor); +int logSensor(const char *sensorName, Temperature & sensor); +int logSensor(const char *sensorName, UVLight & sensor); -int binaryLogAcceleration(const unsigned char sensorId, acceleration_t & data); -int binaryLogMagnetic(const unsigned char sensorId, magnetic_t & data); -int binaryLogGyro(const unsigned char sensorId, gyro_t & data); -int binaryLogTemperature(const unsigned char sensorId, temperature_t & data); -int binaryLogLuminosity(const unsigned char sensorId, luminosity_t & data); -int binaryLogUVLight(const unsigned char sensorId, uvlight_t & data); -int binaryLogOrientation(const unsigned char sensorId, orientation_t & data); -int binaryLogPressure(const unsigned char sensorId, pressure_t & data); +int binaryLogSensor(const unsigned char sensorId, Acceleration & sensor); +int binaryLogSensor(const unsigned char sensorId, Gyro & sensor); +int binaryLogSensor(const unsigned char sensorId, Luminosity & sensor); +int binaryLogSensor(const unsigned char sensorId, Magnetic & sensor); +int binaryLogSensor(const unsigned char sensorId, Orientation & sensor); +int binaryLogSensor(const unsigned char sensorId, Pressure & sensor); +int binaryLogSensor(const unsigned char sensorId, RGBLight & sensor); +int binaryLogSensor(const unsigned char sensorId, Temperature & sensor); +int binaryLogSensor(const unsigned char sensorId, UVLight & sensor); bool beginDataLog(int chipSelectPin, const char *fileNamePrefix, bool csvData); @@ -68,8 +66,4 @@ bool setRTC(); int logRTCTimestamp(); int binaryLogRTCTimestamp(); -#ifdef __cplusplus -} // extern "C" -#endif - #endif /* ARDUSATLOGGING_H_ */ diff --git a/examples/sd_card/sd_card.ino b/examples/sd_card/sd_card.ino index 0251074..a3a11ef 100644 --- a/examples/sd_card/sd_card.ino +++ b/examples/sd_card/sd_card.ino @@ -53,12 +53,13 @@ const short SD_CS_PIN = 10; static char LOG_FILE_PREFIX[] = "MYLOG"; static bool LOG_CSV_DATA = true; // otherwise, binary data is logged -temperature_t temp; -luminosity_t luminosity; -uvlight_t uv_light; -acceleration_t accel; -magnetic_t mag; -gyro_t orientation; +Acceleration accel; +Gyro gyro; +Luminosity luminosity; +Magnetic mag; +Temperature am_temp; +TemperatureMLX ir_temp; +UVLight uv_light; /* * === FUNCTION ====================================================================== @@ -74,13 +75,13 @@ void setup() while (true); } - beginAccelerationSensor(); - beginTemperatureSensor(); - beginInfraredTemperatureSensor(); - beginLuminositySensor(); - beginUVLightSensor(); - beginGyroSensor(); - beginMagneticSensor(); + accel.begin(); + gyro.begin(); + luminosity.begin(); + mag.begin(); + am_temp.begin(); + ir_temp.begin(); + uv_light.begin(); } /* @@ -94,33 +95,30 @@ void setup() */ void loop() { - readAcceleration(accel); - readTemperature(temp); - readMagnetic(mag); - readGyro(orientation); - readLuminosity(luminosity); - readUVLight(uv_light); + accel.read(); + gyro.read(); + luminosity.read(); + mag.read(); + am_temp.read(); + ir_temp.read(); + uv_light.read(); if (LOG_CSV_DATA) { - logAcceleration("accel", accel); - logMagnetic("mag", mag); - logGyro("gyro", orientation); - logTemperature("temp", temp); - - readInfraredTemperature(temp); - logTemperature("ir", temp); - - logLuminosity("lux", luminosity); - logUVLight("uv", uv_light); + logSensor("accel", accel); + logSensor("gyro", gyro); + logSensor("lux", luminosity); + logSensor("mag", mag); + logSensor("temp", am_temp); + logSensor("ir", ir_temp); + logSensor("uv", uv_light); } else { - binaryLogAcceleration(0, accel); - binaryLogMagnetic(1, mag); - binaryLogGyro(2, orientation); - binaryLogTemperature(3, temp); - readInfraredTemperature(temp); - binaryLogTemperature(4, temp); - binaryLogLuminosity(5, luminosity); - binaryLogUVLight(6, uv_light); + binaryLogSensor(1, accel); + binaryLogSensor(3, gyro); + binaryLogSensor(6, luminosity); + binaryLogSensor(2, mag); + binaryLogSensor(4, am_temp); + binaryLogSensor(5, ir_temp); + binaryLogSensor(7, uv_light); } delay(READ_INTERVAL); diff --git a/utility/ArduinoStream.h b/utility/ArduinoStream.h new file mode 100644 index 0000000..ab7b4c9 --- /dev/null +++ b/utility/ArduinoStream.h @@ -0,0 +1,119 @@ +/* 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 + * . + */ +#ifndef ArduinoStream_h +#define ArduinoStream_h +/** + * \file + * \brief ArduinoInStream and ArduinoOutStream classes + */ +#include +//============================================================================== +/** + * \class ArduinoInStream + * \brief Input stream for Arduino Stream objects + */ +class ArduinoInStream : public ibufstream { + public: + /** + * Constructor + * \param[in] hws hardware stream + * \param[in] buf buffer for input line + * \param[in] size size of input buffer + */ + ArduinoInStream(Stream &hws, char* buf, size_t size) { + m_hw = &hws; + m_line = buf; + m_size = size; + } + /** read a line. */ + void readline() { + size_t i = 0; + uint32_t t; + m_line[0] = '\0'; + while (!m_hw->available()) {} + + while (1) { + t = millis(); + while (!m_hw->available()) { + if ((millis() - t) > 10) goto done; + } + if (i >= (m_size - 1)) { + setstate(failbit); + return; + } + m_line[i++] = m_hw->read(); + m_line[i] = '\0'; + } + done: + init(m_line); + } + + protected: + /** Internal - do not use. + * \param[in] off + * \param[in] way + * \return true/false. + */ + bool seekoff(off_type off, seekdir way) {return false;} + /** Internal - do not use. + * \param[in] pos + * \return true/false. + */ + bool seekpos(pos_type pos) {return false;} + + private: + char *m_line; + size_t m_size; + Stream* m_hw; +}; +//============================================================================== +/** + * \class ArduinoOutStream + * \brief Output stream for Arduino Print objects + */ +class ArduinoOutStream : public ostream { + public: + /** constructor + * + * \param[in] pr Print object for this ArduinoOutStream. + */ + explicit ArduinoOutStream(Print& pr) : m_pr(&pr) {} + + protected: + /// @cond SHOW_PROTECTED + /** + * Internal do not use + * \param[in] c + */ + void putch(char c) { + if (c == '\n') m_pr->write('\r'); + m_pr->write(c); + } + void putstr(const char* str) {m_pr->write(str);} + bool seekoff(off_type off, seekdir way) {return false;} + bool seekpos(pos_type pos) {return false;} + bool sync() {return true;} + pos_type tellpos() {return 0;} + /// @endcond + private: + ArduinoOutStream() {} + Print* m_pr; +}; +#endif // ArduinoStream_h diff --git a/utility/bufstream.h b/utility/bufstream.h new file mode 100644 index 0000000..8ecd395 --- /dev/null +++ b/utility/bufstream.h @@ -0,0 +1,146 @@ +/* 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 + * . + */ +#ifndef bufstream_h +#define bufstream_h +/** + * \file + * \brief \ref ibufstream and \ref obufstream classes + */ +#include +//============================================================================== +/** + * \class ibufstream + * \brief parse a char string + */ +class ibufstream : public istream { + public: + /** Constructor */ + ibufstream() : m_buf(0), m_len(0) {} + /** Constructor + * \param[in] str pointer to string to be parsed + * Warning: The string will not be copied so must stay in scope. + */ + explicit ibufstream(const char* str) { + init(str); + } + /** Initialize an ibufstream + * \param[in] str pointer to string to be parsed + * Warning: The string will not be copied so must stay in scope. + */ + void init(const char* str) { + m_buf = str; + m_len = strlen(m_buf); + m_pos = 0; + clear(); + } + + protected: + /// @cond SHOW_PROTECTED + int16_t getch() { + if (m_pos < m_len) return m_buf[m_pos++]; + setstate(eofbit); + return -1; + } + void getpos(FatPos_t *pos) { + pos->position = m_pos; + } + bool seekoff(off_type off, seekdir way) {return false;} + bool seekpos(pos_type pos) { + if (pos < m_len) { + m_pos = pos; + return true; + } + return false; + } + void setpos(FatPos_t *pos) { + m_pos = pos->position; + } + pos_type tellpos() { + return m_pos; + } + /// @endcond + private: + const char* m_buf; + size_t m_len; + size_t m_pos; +}; +//============================================================================== +/** + * \class obufstream + * \brief format a char string + */ +class obufstream : public ostream { + public: + /** constructor */ + obufstream() : m_in(0) {} + /** Constructor + * \param[in] buf buffer for formatted string + * \param[in] size buffer size + */ + obufstream(char *buf, size_t size) { + init(buf, size); + } + /** Initialize an obufstream + * \param[in] buf buffer for formatted string + * \param[in] size buffer size + */ + void init(char *buf, size_t size) { + m_buf = buf; + buf[0] = '\0'; + m_size = size; + m_in = 0; + } + /** \return a pointer to the buffer */ + char* buf() {return m_buf;} + /** \return the length of the formatted string */ + size_t length() {return m_in;} + + protected: + /// @cond SHOW_PROTECTED + void putch(char c) { + if (m_in >= (m_size - 1)) { + setstate(badbit); + return; + } + m_buf[m_in++] = c; + m_buf[m_in]= '\0'; + } + void putstr(const char *str) { + while (*str) putch(*str++); + } + bool seekoff(off_type off, seekdir way) {return false;} + bool seekpos(pos_type pos) { + if (pos > m_in) return false; + m_in = pos; + m_buf[m_in] = '\0'; + return true; + } + bool sync() {return true;} + + pos_type tellpos() { + return m_in; + } + /// @endcond + private: + char *m_buf; + size_t m_size; + size_t m_in; +}; +#endif // bufstream_h diff --git a/utility/ios.h b/utility/ios.h new file mode 100644 index 0000000..2206afd --- /dev/null +++ b/utility/ios.h @@ -0,0 +1,394 @@ +/* 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 + * . + */ +#ifndef ios_h +#define ios_h +#include +/** + * \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(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 diff --git a/utility/iostream.h b/utility/iostream.h new file mode 100644 index 0000000..e580248 --- /dev/null +++ b/utility/iostream.h @@ -0,0 +1,153 @@ +/* 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 + * . + */ +#ifndef iostream_h +#define iostream_h +/** + * \file + * \brief \ref iostream class + */ +#include +#include +/** Skip white space + * \param[in] is the Stream + * \return The stream + */ +inline istream& ws(istream& is) { + is.skipWhite(); + return is; +} +/** insert endline + * \param[in] os The Stream + * \return The stream + */ +inline ostream& endl(ostream& os) { + os.put('\n'); +#if ENDL_CALLS_FLUSH + os.flush(); +#endif // ENDL_CALLS_FLUSH + return os; +} +/** flush manipulator + * \param[in] os The stream + * \return The stream + */ +inline ostream& flush(ostream& os) { + os.flush(); + return os; +} +/** + * \struct setfill + * \brief type for setfill manipulator + */ +struct setfill { + /** fill character */ + char c; + /** constructor + * + * \param[in] arg new fill character + */ + explicit setfill(char arg) : c(arg) {} +}; +/** setfill manipulator + * \param[in] os the stream + * \param[in] arg set setfill object + * \return the stream + */ +inline ostream &operator<< (ostream &os, const setfill &arg) { + os.fill(arg.c); + return os; +} +/** setfill manipulator + * \param[in] obj the stream + * \param[in] arg set setfill object + * \return the stream + */ +inline istream &operator>>(istream &obj, const setfill &arg) { + obj.fill(arg.c); + return obj; +} +//------------------------------------------------------------------------------ +/** \struct setprecision + * \brief type for setprecision manipulator + */ +struct setprecision { + /** precision */ + unsigned int p; + /** constructor + * \param[in] arg new precision + */ + explicit setprecision(unsigned int arg) : p(arg) {} +}; +/** setprecision manipulator + * \param[in] os the stream + * \param[in] arg set setprecision object + * \return the stream + */ +inline ostream &operator<< (ostream &os, const setprecision &arg) { + os.precision(arg.p); + return os; +} +/** setprecision manipulator + * \param[in] is the stream + * \param[in] arg set setprecision object + * \return the stream + */ +inline istream &operator>>(istream &is, const setprecision &arg) { + is.precision(arg.p); + return is; +} +//------------------------------------------------------------------------------ +/** \struct setw + * \brief type for setw manipulator + */ +struct setw { + /** width */ + unsigned w; + /** constructor + * \param[in] arg new width + */ + explicit setw(unsigned arg) : w(arg) {} +}; +/** setw manipulator + * \param[in] os the stream + * \param[in] arg set setw object + * \return the stream + */ +inline ostream &operator<< (ostream &os, const setw &arg) { + os.width(arg.w); + return os; +} +/** setw manipulator + * \param[in] is the stream + * \param[in] arg set setw object + * \return the stream + */ +inline istream &operator>>(istream &is, const setw &arg) { + is.width(arg.w); + return is; +} +//============================================================================== +/** + * \class iostream + * \brief Input/Output stream + */ +class iostream : public istream, public ostream { +}; +#endif // iostream_h